53 #include "table/strings.h"
117 for (uint i = 0; i < GSF_END; i++) {
121 memset(this->spritegroups, 0,
sizeof(this->spritegroups));
134 assert(feature < GSF_END);
135 for (uint i = 0; i < numsets; i++) {
137 set.sprite = first_sprite + i * numents;
138 set.num_sprites = numents;
150 assert(feature < GSF_END);
163 assert(feature < GSF_END);
176 return this->
spritesets[feature].find(
set)->second.sprite;
188 return this->
spritesets[feature].find(
set)->second.num_sprites;
201 template <VehicleType T>
204 return image_index == 0xFD || IsValidImageIndex<T>(image_index);
216 ByteReader(byte *data, byte *end) : data(data), end(end) { }
218 inline byte ReadByte()
220 if (data < end)
return *(data)++;
226 uint16 val = ReadByte();
227 return val | (ReadByte() << 8);
230 uint16 ReadExtendedByte()
232 uint16 val = ReadByte();
233 return val == 0xFF ? ReadWord() : val;
238 uint32 val = ReadWord();
239 return val | (ReadWord() << 16);
242 uint32 ReadVarSize(byte size)
245 case 1:
return ReadByte();
246 case 2:
return ReadWord();
247 case 4:
return ReadDWord();
254 const char *ReadString()
256 char *
string =
reinterpret_cast<char *
>(data);
257 size_t string_length =
ttd_strnlen(
string, Remaining());
259 if (string_length == Remaining()) {
261 string[string_length - 1] =
'\0';
262 grfmsg(7,
"String was not terminated with a zero byte.");
272 inline size_t Remaining()
const
277 inline bool HasData(
size_t count = 1)
const
279 return data + count <= end;
287 inline void Skip(
size_t len)
296 typedef void (*SpecialSpriteHandler)(
ByteReader *buf);
309 uint16 cargo_allowed;
310 uint16 cargo_disallowed;
311 RailTypeLabel railtypelabel;
348 GRFLocation(uint32 grfid, uint32 nfoline) : grfid(grfid), nfoline(nfoline) { }
352 return this->grfid < other.grfid || (this->grfid == other.grfid && this->nfoline < other.nfoline);
357 return this->grfid == other.grfid && this->nfoline == other.nfoline;
361 static std::map<GRFLocation, SpriteID> _grm_sprites;
362 typedef std::map<GRFLocation, byte*> GRFLineToSpriteOverride;
363 static GRFLineToSpriteOverride _grf_line_to_action6_sprite_override;
375 void CDECL
grfmsg(
int severity,
const char *str, ...)
394 const GRFFile *
const *end = _grf_files.
End();
395 for (
GRFFile *
const *file = _grf_files.
Begin(); file != end; file++) {
396 if ((*file)->grfid == grfid)
return *file;
408 const GRFFile *
const *end = _grf_files.
End();
409 for (
GRFFile *
const *file = _grf_files.
Begin(); file != end; file++) {
410 if (strcmp((*file)->filename, filename) == 0)
return *file;
436 if (config != NULL) {
447 if (message != STR_NULL) {
448 delete config->error;
449 config->error =
new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, message);
453 return config->error;
474 *target = STR_UNDEFINED;
491 static const StringID units_volume[] = {
492 STR_ITEMS, STR_PASSENGERS, STR_TONS, STR_BAGS,
493 STR_LITERS, STR_ITEMS, STR_CRATES, STR_TONS,
494 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
495 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
496 STR_TONS, STR_TONS, STR_BAGS, STR_LITERS,
497 STR_TONS, STR_LITERS, STR_TONS, STR_ITEMS,
498 STR_BAGS, STR_LITERS, STR_TONS, STR_ITEMS,
499 STR_TONS, STR_ITEMS, STR_LITERS, STR_ITEMS
505 #define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
506 assert_compile(stringend - stringid == end - begin); \
507 if (str >= begin && str <= end) return str + (stringid - begin)
510 TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING, STR_CARGO_PLURAL_FIZZY_DRINKS);
511 TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING, STR_CARGO_SINGULAR_FIZZY_DRINK);
512 if (str >= 0x004E && str <= 0x006D)
return units_volume[str - 0x004E];
513 TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING, STR_QUANTITY_FIZZY_DRINKS);
514 TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING, STR_ABBREV_FIZZY_DRINKS);
515 TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE, STR_COLOUR_WHITE);
520 TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1);
521 TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1);
522 TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1);
525 TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE, STR_INDUSTRY_NAME_SUGAR_MINE);
526 TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_PLANTED);
527 TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES);
528 TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM);
529 TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM);
532 case 0x4830:
return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY;
533 case 0x4831:
return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED;
534 case 0x483B:
return STR_ERROR_CAN_ONLY_BE_POSITIONED;
536 #undef TEXTID_TO_STRINGID
538 if (str == STR_NULL)
return STR_EMPTY;
540 DEBUG(grf, 0,
"Unknown StringID 0x%04X remapped to STR_EMPTY. Please open a Feature Request if you need it", str);
579 static std::map<uint32, uint32> _grf_id_overrides;
588 _grf_id_overrides[source_grfid] = target_grfid;
589 grfmsg(5,
"SetNewGRFOverride: Added override of 0x%X to 0x%X",
BSWAP32(source_grfid),
BSWAP32(target_grfid));
604 uint32 scope_grfid = INVALID_GRFID;
607 scope_grfid = file->grfid;
608 uint32
override = _grf_id_overrides[file->grfid];
610 scope_grfid =
override;
612 if (grf_match == NULL) {
613 grfmsg(5,
"Tried mapping from GRFID %x to %x but target is not loaded",
BSWAP32(file->grfid),
BSWAP32(
override));
620 EngineID engine = _engine_mngr.
GetID(type, internal_id, scope_grfid);
629 EngineID engine = _engine_mngr.
GetID(type, internal_id, INVALID_GRFID);
635 grfmsg(5,
"Replaced engine at index %d for GRFID %x, type %d, index %d", e->
index,
BSWAP32(file->grfid), type, internal_id);
639 if (!static_access) {
641 eid->
grfid = scope_grfid;
647 if (static_access)
return NULL;
650 grfmsg(0,
"Can't allocate any more engines");
664 eid->grfid = scope_grfid;
665 eid->internal_id = internal_id;
674 memset(_gted + engine_pool_size, 0, len);
680 grfmsg(5,
"Created new engine at index %d for GRFID %x, type %d, index %d", e->
index,
BSWAP32(file->grfid), type, internal_id);
697 uint32 scope_grfid = INVALID_GRFID;
699 scope_grfid = file->grfid;
700 uint32
override = _grf_id_overrides[file->grfid];
701 if (
override != 0) scope_grfid =
override;
704 return _engine_mngr.
GetID(type, internal_id, scope_grfid);
744 grf_sprite->
sprite = buf->ReadWord();
745 grf_sprite->
pal = buf->ReadWord();
750 bool custom_sprite =
HasBit(grf_sprite->
pal, 15) != invert_action1_flag;
754 uint index =
GB(grf_sprite->
sprite, 0, 14);
756 grfmsg(1,
"ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d", index);
757 grf_sprite->
sprite = SPR_IMG_QUERY;
758 grf_sprite->
pal = PAL_NONE;
761 if (max_sprite_offset != NULL) *max_sprite_offset = use_cur_spritesets ? _cur.
GetNumEnts(feature, index) : UINT16_MAX;
766 grfmsg(1,
"ReadSpriteLayoutSprite: Spritelayout specifies var10 value for non-action-1 sprite");
767 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
773 uint index =
GB(grf_sprite->
pal, 0, 14);
775 grfmsg(1,
"ReadSpriteLayoutSprite: Spritelayout uses undefined custom spriteset %d for 'palette'", index);
776 grf_sprite->
pal = PAL_NONE;
779 if (max_palette_offset != NULL) *max_palette_offset = use_cur_spritesets ? _cur.
GetNumEnts(feature, index) : UINT16_MAX;
784 grfmsg(1,
"ReadSpriteLayoutRegisters: Spritelayout specifies var10 value for non-action-1 palette");
785 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
814 regs.delta.
parent[0] = buf->ReadByte();
815 regs.delta.
parent[1] = buf->ReadByte();
827 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
836 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
855 bool has_flags =
HasBit(num_building_sprites, 6);
856 ClrBit(num_building_sprites, 6);
859 dts->
Allocate(num_building_sprites);
861 uint16 *max_sprite_offset =
AllocaM(uint16, num_building_sprites + 1);
862 uint16 *max_palette_offset =
AllocaM(uint16, num_building_sprites + 1);
863 MemSetT(max_sprite_offset, 0, num_building_sprites + 1);
864 MemSetT(max_palette_offset, 0, num_building_sprites + 1);
871 grfmsg(1,
"ReadSpriteLayout: Spritelayout uses invalid flag 0x%x for ground sprite", flags & ~(valid_flags & ~
TLF_NON_GROUND_FLAGS));
872 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
879 for (uint i = 0; i < num_building_sprites; i++) {
882 flags =
ReadSpriteLayoutSprite(buf, has_flags,
false, use_cur_spritesets, feature, &seq->image, max_sprite_offset + i + 1, max_palette_offset + i + 1);
885 if (flags & ~valid_flags) {
886 grfmsg(1,
"ReadSpriteLayout: Spritelayout uses unknown flag 0x%x", flags & ~valid_flags);
887 DisableGrf(STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT);
891 seq->
delta_x = buf->ReadByte();
892 seq->delta_y = buf->ReadByte();
894 if (!no_z_position) seq->
delta_z = buf->ReadByte();
897 seq->size_x = buf->ReadByte();
898 seq->size_y = buf->ReadByte();
899 seq->size_z = buf->ReadByte();
907 bool is_consistent =
true;
909 for (uint i = 0; i < num_building_sprites + 1; i++) {
910 if (max_sprite_offset[i] > 0) {
914 is_consistent =
false;
918 if (max_palette_offset[i] > 0) {
922 is_consistent =
false;
931 if (!is_consistent || dts->registers != NULL) {
935 for (uint i = 0; i < num_building_sprites + 1; i++) {
969 if (base_pointer == 0) {
970 *index = INVALID_PRICE;
974 static const uint32 start = 0x4B34;
975 static const uint32 size = 6;
977 if (base_pointer < start || (base_pointer - start) % size != 0 || (base_pointer - start) / size >= PR_END) {
978 grfmsg(1,
"%s: Unsupported running cost base 0x%04X, ignoring", error_location, base_pointer);
982 *index = (
Price)((base_pointer - start) / size);
1011 ei->decay_speed = buf->ReadByte();
1028 ei->load_amount = buf->ReadByte();
1050 for (
int i = 0; i < numinfo; i++) {
1059 uint8 tracktype = buf->ReadByte();
1061 if (tracktype < _cur.grffile->railtype_list.Length()) {
1066 switch (tracktype) {
1067 case 0: _gted[e->
index].railtypelabel = rvi->
engclass >= 2 ? RAILTYPE_ELECTRIC_LABEL : RAILTYPE_RAIL_LABEL;
break;
1068 case 1: _gted[e->
index].railtypelabel = RAILTYPE_MONO_LABEL;
break;
1069 case 2: _gted[e->
index].railtypelabel = RAILTYPE_MAGLEV_LABEL;
break;
1071 grfmsg(1,
"RailVehicleChangeInfo: Invalid track type %d specified, ignoring", tracktype);
1084 uint16 speed = buf->ReadWord();
1085 if (speed == 0xFFFF) speed = 0;
1092 rvi->
power = buf->ReadWord();
1095 if (rvi->
power != 0) {
1113 uint8 spriteid = buf->ReadByte();
1114 uint8 orig_spriteid = spriteid;
1118 if (spriteid < 0xFD) spriteid >>= 1;
1120 if (IsValidNewGRFImageIndex<VEH_TRAIN>(spriteid)) {
1121 rvi->image_index = spriteid;
1123 grfmsg(1,
"RailVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1124 rvi->image_index = 0;
1130 uint8 dual = buf->ReadByte();
1135 rvi->railveh_type = rvi->
power == 0 ?
1147 uint8 ctype = buf->ReadByte();
1149 if (ctype == 0xFF) {
1152 }
else if (_cur.
grffile->grf_version >= 8) {
1157 ei->cargo_type = ctype;
1160 grfmsg(2,
"RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1166 SB(rvi->
weight, 0, 8, buf->ReadByte());
1174 grfmsg(2,
"RailVehicleChangeInfo: Property 0x18 'AI rank' not used by NoAI, ignored.");
1186 uint8 traction = buf->ReadByte();
1189 if (traction <= 0x07) {
1191 }
else if (traction <= 0x27) {
1193 }
else if (traction <= 0x31) {
1195 }
else if (traction <= 0x37) {
1197 }
else if (traction <= 0x41) {
1206 if (_gted[e->
index].railtypelabel == RAILTYPE_RAIL_LABEL && engclass >=
EC_ELECTRIC) _gted[e->
index].railtypelabel = RAILTYPE_ELECTRIC_LABEL;
1207 if (_gted[e->
index].railtypelabel == RAILTYPE_ELECTRIC_LABEL && engclass <
EC_ELECTRIC) _gted[e->
index].railtypelabel = RAILTYPE_RAIL_LABEL;
1223 ei->refit_cost = buf->ReadByte();
1227 uint32 mask = buf->ReadDWord();
1265 byte weight = buf->ReadByte();
1268 grfmsg(2,
"RailVehicleChangeInfo: Nonsensical weight of %d tons, ignoring", weight << 8);
1290 _gted[e->
index].cargo_allowed = buf->ReadWord();
1296 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1310 uint8 count = buf->ReadByte();
1344 for (
int i = 0; i < numinfo; i++) {
1357 rvi->running_cost = buf->ReadByte();
1365 uint8 spriteid = buf->ReadByte();
1366 uint8 orig_spriteid = spriteid;
1369 if (spriteid == 0xFF) spriteid = 0xFD;
1371 if (spriteid < 0xFD) spriteid >>= 1;
1373 if (IsValidNewGRFImageIndex<VEH_ROAD>(spriteid)) {
1374 rvi->image_index = spriteid;
1376 grfmsg(1,
"RoadVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1377 rvi->image_index = 0;
1383 rvi->capacity = buf->ReadByte();
1388 uint8 ctype = buf->ReadByte();
1390 if (ctype == 0xFF) {
1393 }
else if (_cur.
grffile->grf_version >= 8) {
1398 ei->cargo_type = ctype;
1401 grfmsg(2,
"RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1407 rvi->cost_factor = buf->ReadByte();
1415 rvi->
power = buf->ReadByte();
1419 rvi->
weight = buf->ReadByte();
1427 uint32 mask = buf->ReadDWord();
1447 ei->refit_cost = buf->ReadByte();
1460 _gted[e->
index].cargo_allowed = buf->ReadWord();
1466 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1498 uint8 count = buf->ReadByte();
1532 for (
int i = 0; i < numinfo; i++) {
1541 uint8 spriteid = buf->ReadByte();
1542 uint8 orig_spriteid = spriteid;
1545 if (spriteid == 0xFF) spriteid = 0xFD;
1547 if (spriteid < 0xFD) spriteid >>= 1;
1549 if (IsValidNewGRFImageIndex<VEH_SHIP>(spriteid)) {
1550 svi->image_index = spriteid;
1552 grfmsg(1,
"ShipVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1553 svi->image_index = 0;
1563 svi->cost_factor = buf->ReadByte();
1572 uint8 ctype = buf->ReadByte();
1574 if (ctype == 0xFF) {
1577 }
else if (_cur.
grffile->grf_version >= 8) {
1582 ei->cargo_type = ctype;
1585 grfmsg(2,
"RailVehicleChangeInfo: Invalid cargo type %d, using first refittable", ctype);
1591 svi->capacity = buf->ReadWord();
1595 svi->running_cost = buf->ReadByte();
1603 uint32 mask = buf->ReadDWord();
1615 ei->refit_cost = buf->ReadByte();
1636 _gted[e->
index].cargo_allowed = buf->ReadWord();
1642 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1670 uint8 count = buf->ReadByte();
1704 for (
int i = 0; i < numinfo; i++) {
1713 uint8 spriteid = buf->ReadByte();
1714 uint8 orig_spriteid = spriteid;
1717 if (spriteid == 0xFF) spriteid = 0xFD;
1719 if (spriteid < 0xFD) spriteid >>= 1;
1721 if (IsValidNewGRFImageIndex<VEH_AIRCRAFT>(spriteid)) {
1722 avi->image_index = spriteid;
1724 grfmsg(1,
"AircraftVehicleChangeInfo: Invalid Sprite %d specified, ignoring", orig_spriteid);
1725 avi->image_index = 0;
1731 if (buf->ReadByte() == 0) {
1739 SB(avi->
subtype, 1, 1, (buf->ReadByte() != 0 ? 1 : 0));
1743 avi->cost_factor = buf->ReadByte();
1747 avi->
max_speed = (buf->ReadByte() * 128) / 10;
1751 avi->acceleration = buf->ReadByte();
1755 avi->running_cost = buf->ReadByte();
1771 uint32 mask = buf->ReadDWord();
1783 ei->refit_cost = buf->ReadByte();
1796 _gted[e->
index].cargo_allowed = buf->ReadWord();
1802 _gted[e->
index].cargo_disallowed = buf->ReadWord();
1820 uint8 count = buf->ReadByte();
1866 for (
int i = 0; i < numinfo; i++) {
1870 if (statspec == NULL && prop != 0x08) {
1871 grfmsg(2,
"StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i);
1880 if (*spec == NULL) *spec = CallocT<StationSpec>(1);
1883 uint32 classid = buf->ReadDWord();
1884 (*spec)->cls_id = StationClass::Allocate(
BSWAP32(classid));
1889 statspec->
tiles = buf->ReadExtendedByte();
1893 for (uint t = 0; t < statspec->
tiles; t++) {
1897 if (buf->HasData(4) && *(uint32*)buf->Data() == 0) {
1900 dts->
Clone(&_station_display_datas_rail[t % 8]);
1915 dtss->
delta_x = buf->ReadByte();
1917 dtss->delta_y = buf->ReadByte();
1918 dtss->
delta_z = buf->ReadByte();
1919 dtss->size_x = buf->ReadByte();
1920 dtss->size_y = buf->ReadByte();
1921 dtss->size_z = buf->ReadByte();
1932 byte srcid = buf->ReadByte();
1935 if (srcstatspec == NULL) {
1936 grfmsg(1,
"StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i);
1944 for (uint t = 0; t < statspec->
tiles; t++) {
1963 statspec->copied_layouts =
false;
1965 while (buf->HasData()) {
1966 byte length = buf->ReadByte();
1967 byte number = buf->ReadByte();
1968 StationLayout layout;
1971 if (length == 0 || number == 0)
break;
1973 if (length > statspec->lengths) {
1974 statspec->platforms =
ReallocT(statspec->platforms, length);
1975 memset(statspec->platforms + statspec->lengths, 0, length - statspec->lengths);
1977 statspec->layouts =
ReallocT(statspec->layouts, length);
1978 memset(statspec->layouts + statspec->lengths, 0,
1979 (length - statspec->lengths) *
sizeof(*statspec->layouts));
1981 statspec->lengths = length;
1985 if (number > statspec->platforms[l]) {
1986 statspec->layouts[l] =
ReallocT(statspec->layouts[l], number);
1988 memset(statspec->layouts[l] + statspec->platforms[l], 0,
1989 (number - statspec->platforms[l]) *
sizeof(**statspec->layouts));
1991 statspec->platforms[l] = number;
1995 layout = MallocT<byte>(length * number);
1997 for (l = 0; l < length; l++) {
1998 for (p = 0; p < number; p++) {
1999 layout[l * number + p] = buf->ReadByte();
2009 free(statspec->layouts[l][p]);
2010 statspec->layouts[l][p] = layout;
2015 byte srcid = buf->ReadByte();
2018 if (srcstatspec == NULL) {
2019 grfmsg(1,
"StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i);
2023 statspec->lengths = srcstatspec->lengths;
2024 statspec->platforms = srcstatspec->platforms;
2025 statspec->layouts = srcstatspec->layouts;
2026 statspec->copied_layouts =
true;
2035 statspec->
pylons = buf->ReadByte();
2040 if (_cur.
grffile->grf_version >= 7) {
2046 statspec->
flags = buf->ReadByte();
2050 statspec->
wires = buf->ReadByte();
2054 statspec->
blocked = buf->ReadByte();
2058 statspec->animation.
frames = buf->ReadByte();
2059 statspec->animation.
status = buf->ReadByte();
2063 statspec->animation.
speed = buf->ReadByte();
2067 statspec->animation.
triggers = buf->ReadWord();
2071 statspec->
tiles = buf->ReadExtendedByte();
2075 for (uint t = 0; t < statspec->
tiles; t++) {
2077 uint num_building_sprites = buf->ReadByte();
2104 if (
id + numinfo > CF_END) {
2105 grfmsg(1,
"CanalChangeInfo: Canal feature %u is invalid, max %u, ignoring",
id + numinfo, CF_END);
2109 for (
int i = 0; i < numinfo; i++) {
2118 cp->
flags = buf->ReadByte();
2143 grfmsg(1,
"BridgeChangeInfo: Bridge %u is invalid, max %u, ignoring", brid + numinfo,
MAX_BRIDGES);
2147 for (
int i = 0; i < numinfo; i++) {
2153 byte year = buf->ReadByte();
2168 bridge->
price = buf->ReadByte();
2172 bridge->
speed = buf->ReadWord();
2176 byte tableid = buf->ReadByte();
2177 byte numtables = buf->ReadByte();
2184 for (; numtables-- != 0; tableid++) {
2186 grfmsg(1,
"BridgeChangeInfo: Table %d >= 7, skipping", tableid);
2187 for (byte sprite = 0; sprite < 32; sprite++) buf->ReadDWord();
2192 bridge->
sprite_table[tableid] = MallocT<PalSpriteID>(32);
2195 for (byte sprite = 0; sprite < 32; sprite++) {
2209 bridge->
flags = buf->ReadByte();
2218 if (newone != STR_UNDEFINED) bridge->
material = newone;
2225 if (newone != STR_UNDEFINED) bridge->
transport_name[prop - 0x11] = newone;
2230 bridge->
price = buf->ReadWord();
2287 for (uint j = 0; j < 4; j++) buf->ReadByte();
2291 byte count = buf->ReadByte();
2292 for (byte j = 0; j < count; j++) buf->ReadByte();
2316 grfmsg(1,
"TownHouseChangeInfo: Too many houses loaded (%u), max (%u). Ignoring.", hid + numinfo,
NUM_HOUSES_PER_GRF);
2321 if (_cur.
grffile->housespec == NULL) {
2325 for (
int i = 0; i < numinfo; i++) {
2328 if (prop != 0x08 && housespec == NULL) {
2331 if (cir > ret) ret = cir;
2338 byte subs_id = buf->ReadByte();
2340 if (subs_id == 0xFF) {
2343 HouseSpec::Get(hid + i)->
enabled =
false;
2347 grfmsg(2,
"TownHouseChangeInfo: Attempt to use new house %u as substitute house for %u. Ignoring.", subs_id, hid + i);
2352 if (*house == NULL) *house = CallocT<HouseSpec>(1);
2356 MemCpyT(housespec, HouseSpec::Get(subs_id));
2358 housespec->enabled =
true;
2359 housespec->grf_prop.local_id = hid + i;
2360 housespec->grf_prop.subst_id = subs_id;
2361 housespec->grf_prop.grffile = _cur.
grffile;
2362 housespec->random_colour[0] = 0x04;
2363 housespec->random_colour[1] = 0x08;
2364 housespec->random_colour[2] = 0x0C;
2365 housespec->random_colour[3] = 0x06;
2372 housespec->cargo_acceptance[2] = 0;
2384 uint16 years = buf->ReadWord();
2404 int8 goods = buf->ReadByte();
2440 byte
override = buf->ReadByte();
2444 grfmsg(2,
"TownHouseChangeInfo: Attempt to override new house %u with house id %u. Ignoring.",
override, hid + i);
2448 _house_mngr.
Add(hid + i, _cur.
grffile->grfid,
override);
2457 for (uint j = 0; j < 4; j++) housespec->
random_colour[j] = buf->ReadByte();
2479 housespec->
class_id = AllocateHouseClassID(buf->ReadByte(), _cur.
grffile->grfid);
2487 uint32 cargotypes = buf->ReadDWord();
2490 if (cargotypes == 0xFFFFFFFF)
break;
2492 for (uint j = 0; j < 3; j++) {
2494 uint8 cargo_part =
GB(cargotypes, 8 * j, 8);
2512 byte count = buf->ReadByte();
2513 for (byte j = 0; j < count; j++) {
2521 housespec->
min_year = buf->ReadWord();
2525 housespec->
max_year = buf->ReadWord();
2559 template <
typename T>
2563 grfmsg(1,
"LoadTranslationTable: %s translation table must start at zero", name);
2567 translation_table.Clear();
2568 for (
int i = 0; i < numinfo; i++) {
2569 uint32 item = buf->ReadDWord();
2570 *translation_table.Append() =
BSWAP32(item);
2600 for (
int i = 0; i < numinfo; i++) {
2603 int factor = buf->ReadByte();
2604 uint price = gvid + i;
2606 if (price < PR_END) {
2609 grfmsg(1,
"GlobalVarChangeInfo: Price %d out of range, ignoring", price);
2618 if ((newone != STR_UNDEFINED) && (curidx <
CURRENCY_END)) {
2626 uint32 rate = buf->ReadDWord();
2634 grfmsg(1,
"GlobalVarChangeInfo: Currency multipliers %d out of range, ignoring", curidx);
2641 uint16 options = buf->ReadWord();
2650 grfmsg(1,
"GlobalVarChangeInfo: Currency option %d out of range, ignoring", curidx);
2657 uint32 tempfix = buf->ReadDWord();
2663 grfmsg(1,
"GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2670 uint32 tempfix = buf->ReadDWord();
2676 grfmsg(1,
"GlobalVarChangeInfo: Currency symbol %d out of range, ignoring", curidx);
2683 Year year_euro = buf->ReadWord();
2688 grfmsg(1,
"GlobalVarChangeInfo: Euro intro date %d out of range, ignoring", curidx);
2695 grfmsg(1,
"GlobalVarChangeInfo: The snowline can only be set once (%d)", numinfo);
2697 grfmsg(1,
"GlobalVarChangeInfo: Not enough entries set in the snowline table (" PRINTF_SIZE
")", buf->Remaining());
2703 table[i][j] = buf->ReadByte();
2704 if (_cur.
grffile->grf_version >= 8) {
2707 if (table[i][j] >= 128) {
2729 uint curidx = gvid + i;
2732 grfmsg(1,
"GlobalVarChangeInfo: Language %d is not known, ignoring", curidx);
2737 while (buf->ReadByte() != 0) {
2747 uint plural_form = buf->ReadByte();
2748 if (plural_form >= LANGUAGE_MAX_PLURAL) {
2749 grfmsg(1,
"GlobalVarChanceInfo: Plural form %d is out of range, ignoring", plural_form);
2756 byte newgrf_id = buf->ReadByte();
2757 while (newgrf_id != 0) {
2758 const char *name = buf->ReadString();
2773 grfmsg(1,
"GlobalVarChangeInfo: Gender name %s is not known, ignoring", name);
2780 grfmsg(1,
"GlobalVarChangeInfo: Case name %s is not known, ignoring", name);
2785 newgrf_id = buf->ReadByte();
2815 for (
int i = 0; i < numinfo; i++) {
2839 uint32 s = buf->ReadDWord();
2840 uint32 t = buf->ReadDWord();
2847 while (buf->ReadByte() != 0) {
2875 grfmsg(2,
"CargoChangeInfo: Cargo type %d out of range (max %d)", cid + numinfo,
NUM_CARGO - 1);
2879 for (
int i = 0; i < numinfo; i++) {
2884 cs->
bitnum = buf->ReadByte();
2922 cs->
sprite = buf->ReadWord();
2926 cs->
weight = buf->ReadByte();
2930 cs->transit_days[0] = buf->ReadByte();
2934 cs->transit_days[1] = buf->ReadByte();
2938 cs->initial_payment = buf->ReadDWord();
2942 cs->rating_colour = buf->ReadByte();
2946 cs->legend_colour = buf->ReadByte();
2954 cs->
classes = buf->ReadWord();
2958 cs->
label = buf->ReadDWord();
2963 uint8 substitute_type = buf->ReadByte();
2965 switch (substitute_type) {
2972 grfmsg(1,
"CargoChangeInfo: Unknown town growth substitute value %d, setting to none.", substitute_type);
2988 cs->
multiplier = max<uint16>(1u, buf->ReadWord());
3013 if (_cur.
grffile->sound_offset == 0) {
3014 grfmsg(1,
"SoundEffectChangeInfo: No effects defined, skipping");
3019 grfmsg(1,
"SoundEffectChangeInfo: Attempting to change undefined sound effect (%u), max (%u). Ignoring.", sid + numinfo,
ORIGINAL_SAMPLE_COUNT + _cur.
grffile->num_sounds);
3023 for (
int i = 0; i < numinfo; i++) {
3028 sound->volume = buf->ReadByte();
3032 sound->priority = buf->ReadByte();
3036 SoundID orig_sound = buf->ReadByte();
3041 SoundEntry *old_sound = GetSound(orig_sound);
3044 *old_sound = *sound;
3110 if (_cur.
grffile->indtspec == NULL) {
3114 for (
int i = 0; i < numinfo; i++) {
3117 if (prop != 0x08 && tsp == NULL) {
3119 if (cir > ret) ret = cir;
3126 byte subs_id = buf->ReadByte();
3130 grfmsg(2,
"IndustryTilesChangeInfo: Attempt to use new industry tile %u as substitute industry tile for %u. Ignoring.", subs_id, indtid + i);
3135 if (*tilespec == NULL) {
3136 *tilespec = CallocT<IndustryTileSpec>(1);
3139 memcpy(tsp, &_industry_tile_specs[subs_id],
sizeof(_industry_tile_specs[subs_id]));
3140 tsp->enabled =
true;
3148 tsp->grf_prop.local_id = indtid + i;
3149 tsp->grf_prop.subst_id = subs_id;
3150 tsp->grf_prop.grffile = _cur.
grffile;
3157 byte ovrid = buf->ReadByte();
3161 grfmsg(2,
"IndustryTilesChangeInfo: Attempt to override new industry tile %u with industry tile id %u. Ignoring.", ovrid, indtid + i);
3165 _industile_mngr.
Add(indtid + i, _cur.
grffile->grfid, ovrid);
3172 uint16 acctp = buf->ReadWord();
3258 byte num_table = buf->ReadByte();
3259 for (byte j = 0; j < num_table; j++) {
3260 for (uint k = 0;; k++) {
3261 byte x = buf->ReadByte();
3262 if (x == 0xFE && k == 0) {
3268 byte y = buf->ReadByte();
3269 if (x == 0 && y == 0x80)
break;
3271 byte gfx = buf->ReadByte();
3272 if (gfx == 0xFE) buf->ReadWord();
3279 for (byte j = 0; j < 3; j++) buf->ReadByte();
3283 byte number_of_sounds = buf->ReadByte();
3284 for (uint8 j = 0; j < number_of_sounds; j++) {
3305 for (
int i = 0; i < size - 1; i++) {
3306 for (
int j = i + 1; j < size; j++) {
3307 if (layout[i].ti.x == layout[j].ti.
x &&
3308 layout[i].ti.
y == layout[j].ti.
y) {
3320 for (
int j = 0; j < ind->
num_table; j++) {
3348 if (_cur.
grffile->industryspec == NULL) {
3352 for (
int i = 0; i < numinfo; i++) {
3355 if (prop != 0x08 && indsp == NULL) {
3357 if (cir > ret) ret = cir;
3364 byte subs_id = buf->ReadByte();
3366 if (subs_id == 0xFF) {
3369 _industry_specs[indid + i].
enabled =
false;
3373 grfmsg(2,
"_industry_specs: Attempt to use new industry %u as substitute industry for %u. Ignoring.", subs_id, indid + i);
3380 if (*indspec == NULL) {
3381 *indspec = CallocT<IndustrySpec>(1);
3384 memcpy(indsp, &_origin_industry_specs[subs_id],
sizeof(_industry_specs[subs_id]));
3385 indsp->enabled =
true;
3386 indsp->grf_prop.local_id = indid + i;
3387 indsp->grf_prop.subst_id = subs_id;
3388 indsp->grf_prop.grffile = _cur.
grffile;
3397 byte ovrid = buf->ReadByte();
3401 grfmsg(2,
"IndustriesChangeInfo: Attempt to override new industry %u with industry id %u. Ignoring.", ovrid, indid + i);
3405 _industry_mngr.
Add(indid + i, _cur.
grffile->grfid, ovrid);
3410 byte new_num_layouts = buf->ReadByte();
3416 uint32 def_num_tiles = buf->ReadDWord() / 3 + 1;
3423 for (byte j = 0; j < new_num_layouts; j++) {
3424 for (uint k = 0;; k++) {
3425 if (k >= def_num_tiles) {
3426 grfmsg(3,
"IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid);
3429 itt = ReallocT<IndustryTileTable>(itt, def_num_tiles);
3432 itt[k].ti.x = buf->ReadByte();
3434 if (itt[k].ti.x == 0xFE && k == 0) {
3436 IndustryType type = buf->ReadByte();
3437 byte laynbr = buf->ReadByte();
3439 copy_from = _origin_industry_specs[type].table[laynbr];
3440 for (size = 1;; size++) {
3441 if (copy_from[size - 1].ti.x == -0x80 && copy_from[size - 1].ti.
y == 0)
break;
3446 itt[k].ti.
y = buf->ReadByte();
3448 if (itt[k].ti.x == 0 && itt[k].ti.y == 0x80) {
3451 itt[k].ti.x = -0x80;
3460 itt[k].gfx = buf->ReadByte();
3462 if (itt[k].gfx == 0xFE) {
3464 int local_tile_id = buf->ReadWord();
3467 int tempid = _industile_mngr.
GetID(local_tile_id, _cur.
grffile->grfid);
3470 grfmsg(2,
"IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid);
3473 itt[k].gfx = tempid;
3477 }
else if (itt[k].gfx == 0xFF) {
3478 itt[k].ti.
x = (int8)
GB(itt[k].ti.x, 0, 8);
3479 itt[k].ti.y = (int8)
GB(itt[k].ti.y, 0, 8);
3488 if (_cur.
grffile->grf_version < 8 && itt[k].ti.x < 0) itt[k].ti.y += 1;
3494 grfmsg(1,
"IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid);
3498 tile_table[j] = CallocT<IndustryTileTable>(size);
3499 memcpy(tile_table[j], copy_from,
sizeof(*copy_from) * size);
3503 for (
int i = 0; i < new_num_layouts; i++) {
3504 free(tile_table[i]);
3515 indsp->
table = tile_table;
3542 for (byte j = 0; j < 2; j++) {
3548 for (byte j = 0; j < 3; j++) {
3556 indsp->production_rate[prop - 0x12] = buf->ReadByte();
3569 sounds[j] = buf->ReadByte();
3585 for (byte j = 0; j < 3; j++) indsp->
conflicting[j] = buf->ReadByte();
3611 uint32 multiples = buf->ReadDWord();
3627 byte aflag = buf->ReadByte();
3637 uint16 str = buf->ReadWord();
3663 for (
int i = 0; i < as->
num_table; i++) {
3668 }
while ((++it)->ti.x != -0x80);
3669 table_list[i] = MallocT<AirportTileTable>(num_tiles);
3672 as->
table = table_list;
3694 grfmsg(1,
"AirportChangeInfo: Too many airports, trying id (%u), max (%u). Ignoring.", airport + numinfo,
NUM_AIRPORTS_PER_GRF);
3699 if (_cur.
grffile->airportspec == NULL) {
3703 for (
int i = 0; i < numinfo; i++) {
3706 if (as == NULL && prop != 0x08 && prop != 0x09) {
3707 grfmsg(2,
"AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i);
3713 byte subs_id = buf->ReadByte();
3715 if (subs_id == 0xFF) {
3722 grfmsg(2,
"AirportChangeInfo: Attempt to use new airport %u as substitute airport for %u. Ignoring.", subs_id, airport + i);
3730 if (*spec == NULL) {
3731 *spec = MallocT<AirportSpec>(1);
3736 as->grf_prop.local_id = airport + i;
3737 as->grf_prop.subst_id = subs_id;
3738 as->grf_prop.grffile = _cur.
grffile;
3740 _airport_mngr.
Add(airport + i, _cur.
grffile->grfid, subs_id);
3751 uint32 defsize = buf->ReadDWord();
3757 for (byte j = 0; j < as->
num_table; j++) {
3759 for (
int k = 0;; k++) {
3760 att[k].ti.x = buf->ReadByte();
3761 att[k].ti.y = buf->ReadByte();
3763 if (att[k].ti.x == 0 && att[k].ti.y == 0x80) {
3766 att[k].ti.x = -0x80;
3775 att[k].
gfx = buf->ReadByte();
3777 if (att[k].gfx == 0xFE) {
3779 int local_tile_id = buf->ReadWord();
3782 uint16 tempid = _airporttile_mngr.
GetID(local_tile_id, _cur.
grffile->grfid);
3785 grfmsg(2,
"AirportChangeInfo: Attempt to use airport tile %u with airport id %u, not yet defined. Ignoring.", local_tile_id, airport + i);
3788 att[k].gfx = tempid;
3792 }
else if (att[k].gfx == 0xFF) {
3793 att[k].
ti.
x = (int8)
GB(att[k].ti.x, 0, 8);
3794 att[k].ti.y = (int8)
GB(att[k].ti.y, 0, 8);
3805 tile_table[j] = CallocT<AirportTileTable>(size);
3806 memcpy(tile_table[j], copy_from,
sizeof(*copy_from) * size);
3809 as->
table = tile_table;
3812 for (
int i = 0; i < as->
num_table; i++) {
3813 free(tile_table[i]);
3919 if (_cur.
grffile->objectspec == NULL) {
3923 for (
int i = 0; i < numinfo; i++) {
3926 if (prop != 0x08 && spec == NULL) {
3929 if (cir > ret) ret = cir;
3938 if (*ospec == NULL) {
3939 *ospec = CallocT<ObjectSpec>(1);
3940 (*ospec)->
views = 1;
3944 uint32 classid = buf->ReadDWord();
3945 (*ospec)->cls_id = ObjectClass::Allocate(
BSWAP32(classid));
3946 (*ospec)->enabled =
true;
3961 spec->
climate = buf->ReadByte();
3965 spec->
size = buf->ReadByte();
4008 spec->
height = buf->ReadByte();
4012 spec->
views = buf->ReadByte();
4014 grfmsg(2,
"ObjectChangeInfo: Invalid number of views (%u) for object id %u. Ignoring.", spec->
views,
id + i);
4047 grfmsg(1,
"RailTypeChangeInfo: Rail type %u is invalid, max %u, ignoring",
id + numinfo,
RAILTYPE_END);
4051 for (
int i = 0; i < numinfo; i++) {
4064 uint16 str = buf->ReadWord();
4066 if (_cur.
grffile->grf_version < 8) {
4096 int n = buf->ReadByte();
4097 for (
int j = 0; j != n; j++) {
4098 RailTypeLabel label = buf->ReadDWord();
4158 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4177 grfmsg(1,
"RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring",
id + numinfo,
RAILTYPE_END);
4181 for (
int i = 0; i < numinfo; i++) {
4185 RailTypeLabel rtl = buf->ReadDWord();
4194 _cur.
grffile->railtype_map[
id + i] = rt;
4212 int n = buf->ReadByte();
4213 for (
int j = 0; j != n; j++) {
4218 grfmsg(1,
"RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set",
id + i);
4225 for (
int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
4260 if (_cur.
grffile->airtspec == NULL) {
4264 for (
int i = 0; i < numinfo; i++) {
4267 if (prop != 0x08 && tsp == NULL) {
4268 grfmsg(2,
"AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i);
4275 byte subs_id = buf->ReadByte();
4279 grfmsg(2,
"AirportTileChangeInfo: Attempt to use new airport tile %u as substitute airport tile for %u. Ignoring.", subs_id, airtid + i);
4284 if (*tilespec == NULL) {
4285 *tilespec = CallocT<AirportTileSpec>(1);
4289 tsp->enabled =
true;
4293 tsp->grf_prop.local_id = airtid + i;
4294 tsp->grf_prop.subst_id = subs_id;
4295 tsp->grf_prop.grffile = _cur.
grffile;
4302 byte
override = buf->ReadByte();
4306 grfmsg(2,
"AirportTileChangeInfo: Attempt to override new airport tile %u with airport tile id %u. Ignoring.",
override, airtid + i);
4310 _airporttile_mngr.
Add(airtid + i, _cur.
grffile->grfid,
override);
4315 tsp->callback_mask = buf->ReadByte();
4319 tsp->animation.frames = buf->ReadByte();
4320 tsp->animation.status = buf->ReadByte();
4324 tsp->animation.speed = buf->ReadByte();
4328 tsp->animation.triggers = buf->ReadByte();
4340 static bool HandleChangeInfoResult(
const char *caller,
ChangeInfoResult cir, uint8 feature, uint8 property)
4343 default: NOT_REACHED();
4353 grfmsg(1,
"%s: Ignoring property 0x%02X of feature 0x%02X (not implemented)", caller, property, feature);
4357 grfmsg(0,
"%s: Unknown property 0x%02X of feature 0x%02X, disabling", caller, property, feature);
4370 static void FeatureChangeInfo(
ByteReader *buf)
4383 static const VCI_Handler handler[] = {
4401 AirportTilesChangeInfo,
4404 uint8 feature = buf->ReadByte();
4405 uint8 numprops = buf->ReadByte();
4406 uint numinfo = buf->ReadByte();
4407 uint engine = buf->ReadExtendedByte();
4409 grfmsg(6,
"FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
4410 feature, numprops, engine, numinfo);
4412 if (feature >=
lengthof(handler) || handler[feature] == NULL) {
4413 if (feature != GSF_CARGOES)
grfmsg(1,
"FeatureChangeInfo: Unsupported feature %d, skipping", feature);
4420 while (numprops-- && buf->HasData()) {
4421 uint8 prop = buf->ReadByte();
4424 if (HandleChangeInfoResult(
"FeatureChangeInfo", cir, feature, prop))
return;
4431 uint8 feature = buf->ReadByte();
4432 uint8 numprops = buf->ReadByte();
4433 uint numinfo = buf->ReadByte();
4434 buf->ReadExtendedByte();
4436 if (feature == GSF_BRIDGES && numprops == 1) {
4437 uint8 prop = buf->ReadByte();
4440 if (prop == 0x0D)
return;
4441 }
else if (feature == GSF_GLOBALVAR && numprops == 1) {
4442 uint8 prop = buf->ReadByte();
4445 bool is_safe =
true;
4446 for (uint i = 0; i < numinfo; i++) {
4447 uint32 s = buf->ReadDWord();
4455 if (is_safe)
return;
4466 static void ReserveChangeInfo(
ByteReader *buf)
4468 uint8 feature = buf->ReadByte();
4470 if (feature != GSF_CARGOES && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES)
return;
4472 uint8 numprops = buf->ReadByte();
4473 uint8 numinfo = buf->ReadByte();
4474 uint8 index = buf->ReadExtendedByte();
4476 while (numprops-- && buf->HasData()) {
4477 uint8 prop = buf->ReadByte();
4481 default: NOT_REACHED();
4487 cir = GlobalVarReserveInfo(index, numinfo, prop, buf);
4491 cir = RailTypeReserveInfo(index, numinfo, prop, buf);
4495 if (HandleChangeInfoResult(
"ReserveChangeInfo", cir, feature, prop))
return;
4516 uint8 feature = buf->ReadByte();
4517 uint16 num_sets = buf->ReadByte();
4518 uint16 first_set = 0;
4520 if (num_sets == 0 && buf->HasData(3)) {
4523 first_set = buf->ReadExtendedByte();
4524 num_sets = buf->ReadExtendedByte();
4526 uint16 num_ents = buf->ReadExtendedByte();
4530 grfmsg(7,
"New sprite set at %d of type %d, consisting of %d sets with %d views each (total %d)",
4531 _cur.
spriteid, feature, num_sets, num_ents, num_sets * num_ents
4534 for (
int i = 0; i < num_sets * num_ents; i++) {
4544 uint16 num_sets = buf->ReadByte();
4546 if (num_sets == 0 && buf->HasData(3)) {
4549 buf->ReadExtendedByte();
4550 num_sets = buf->ReadExtendedByte();
4552 uint16 num_ents = buf->ReadExtendedByte();
4561 static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
4563 if (
HasBit(groupid, 15)) {
4568 if (groupid >
MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
4569 grfmsg(1,
"GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
4573 return _cur.spritegroups[groupid];
4586 if (
HasBit(spriteid, 15)) {
4592 grfmsg(1,
"CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid);
4597 uint num_sprites = _cur.
GetNumEnts(feature, spriteid);
4600 assert(spriteset_start + num_sprites <= _cur.
spriteid);
4621 uint8 feature = buf->ReadByte();
4622 uint8 setid = buf->ReadByte();
4623 uint8 type = buf->ReadByte();
4646 switch (
GB(type, 2, 2)) {
4647 default: NOT_REACHED();
4648 case 0: group->size = DSG_SIZE_BYTE; varsize = 1;
break;
4649 case 1: group->size = DSG_SIZE_WORD; varsize = 2;
break;
4650 case 2: group->size = DSG_SIZE_DWORD; varsize = 4;
break;
4663 adjust->variable = buf->ReadByte();
4664 if (adjust->variable == 0x7E) {
4666 adjust->subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
4671 varadjust = buf->ReadByte();
4672 adjust->shift_num =
GB(varadjust, 0, 5);
4673 adjust->type = (DeterministicSpriteGroupAdjustType)
GB(varadjust, 6, 2);
4674 adjust->and_mask = buf->ReadVarSize(varsize);
4676 if (adjust->type != DSGA_TYPE_NONE) {
4677 adjust->add_val = buf->ReadVarSize(varsize);
4678 adjust->divmod_val = buf->ReadVarSize(varsize);
4680 adjust->add_val = 0;
4681 adjust->divmod_val = 0;
4685 }
while (
HasBit(varadjust, 5));
4687 group->num_adjusts = adjusts.
Length();
4688 group->adjusts = MallocT<DeterministicSpriteGroupAdjust>(group->num_adjusts);
4689 MemCpyT(group->adjusts, adjusts.
Begin(), group->num_adjusts);
4691 std::vector<DeterministicSpriteGroupRange> ranges;
4692 ranges.resize(buf->ReadByte());
4693 for (uint i = 0; i < ranges.size(); i++) {
4694 ranges[i].group = GetGroupFromGroupID(setid, type, buf->ReadWord());
4695 ranges[i].low = buf->ReadVarSize(varsize);
4696 ranges[i].high = buf->ReadVarSize(varsize);
4699 group->default_group = GetGroupFromGroupID(setid, type, buf->ReadWord());
4700 group->error_group = ranges.size() > 0 ? ranges[0].group : group->default_group;
4702 group->calculated_result = ranges.size() == 0;
4705 std::vector<uint32> bounds;
4706 for (uint i = 0; i < ranges.size(); i++) {
4707 bounds.push_back(ranges[i].low);
4708 if (ranges[i].high != UINT32_MAX) bounds.push_back(ranges[i].high + 1);
4710 std::sort(bounds.begin(), bounds.end());
4711 bounds.erase(std::unique(bounds.begin(), bounds.end()), bounds.end());
4713 std::vector<const SpriteGroup *> target;
4714 for (uint j = 0; j < bounds.size(); ++j) {
4715 uint32 v = bounds[j];
4717 for (uint i = 0; i < ranges.size(); i++) {
4718 if (ranges[i].low <= v && v <= ranges[i].high) {
4719 t = ranges[i].group;
4723 target.push_back(t);
4725 assert(target.size() == bounds.size());
4727 std::vector<DeterministicSpriteGroupRange> optimised;
4728 for (uint j = 0; j < bounds.size(); ) {
4729 if (target[j] != group->default_group) {
4731 r.group = target[j];
4733 while (j < bounds.size() && target[j] == r.group) {
4736 r.high = j < bounds.size() ? bounds[j] - 1 : UINT32_MAX;
4737 optimised.push_back(r);
4743 group->num_ranges = optimised.size();
4744 if (group->num_ranges > 0) {
4745 group->ranges = MallocT<DeterministicSpriteGroupRange>(group->num_ranges);
4746 MemCpyT(group->ranges, &optimised.front(), group->num_ranges);
4763 group->count = buf->ReadByte();
4766 uint8 triggers = buf->ReadByte();
4767 group->triggers =
GB(triggers, 0, 7);
4768 group->
cmp_mode =
HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
4773 for (uint i = 0; i < group->
num_groups; i++) {
4774 group->
groups[i] = GetGroupFromGroupID(setid, type, buf->ReadWord());
4785 case GSF_ROADVEHICLES:
4794 byte num_loaded = type;
4795 byte num_loading = buf->ReadByte();
4798 grfmsg(0,
"NewSpriteGroup: No sprite set to work on! Skipping");
4808 if (num_loaded > 0) group->
loaded = CallocT<const SpriteGroup*>(num_loaded);
4809 if (num_loading > 0) group->
loading = CallocT<const SpriteGroup*>(num_loading);
4811 grfmsg(6,
"NewSpriteGroup: New SpriteGroup 0x%02X, %u loaded, %u loading",
4812 setid, num_loaded, num_loading);
4814 for (uint i = 0; i < num_loaded; i++) {
4815 uint16 spriteid = buf->ReadWord();
4817 grfmsg(8,
"NewSpriteGroup: + rg->loaded[%i] = subset %u", i, spriteid);
4820 for (uint i = 0; i < num_loading; i++) {
4821 uint16 spriteid = buf->ReadWord();
4823 grfmsg(8,
"NewSpriteGroup: + rg->loading[%i] = subset %u", i, spriteid);
4830 case GSF_AIRPORTTILES:
4832 case GSF_INDUSTRYTILES: {
4833 byte num_building_sprites =
max((uint8)1, type);
4840 if (
ReadSpriteLayout(buf, num_building_sprites,
true, feature,
false, type == 0, &group->dts))
return;
4844 case GSF_INDUSTRIES: {
4846 grfmsg(1,
"NewSpriteGroup: Unsupported industry production version %d, skipping", type);
4853 group->version = type;
4855 for (uint i = 0; i < 3; i++) {
4856 group->subtract_input[i] = (int16)buf->ReadWord();
4858 for (uint i = 0; i < 2; i++) {
4859 group->add_output[i] = buf->ReadWord();
4861 group->again = buf->ReadByte();
4863 for (uint i = 0; i < 3; i++) {
4864 group->subtract_input[i] = buf->ReadByte();
4866 for (uint i = 0; i < 2; i++) {
4867 group->add_output[i] = buf->ReadByte();
4869 group->again = buf->ReadByte();
4875 default:
grfmsg(1,
"NewSpriteGroup: Unsupported feature %d, skipping", feature);
4880 _cur.spritegroups[setid] = act_group;
4883 static CargoID TranslateCargo(uint8 feature, uint8 ctype)
4885 if (feature == GSF_OBJECTS) {
4890 grfmsg(1,
"TranslateCargo: Invalid cargo bitnum %d for objects, skipping.", ctype);
4895 if (feature == GSF_STATIONS && ctype == 0xFE)
return CT_DEFAULT_NA;
4896 if (ctype == 0xFF)
return CT_PURCHASE;
4901 grfmsg(1,
"TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype);
4906 FOR_ALL_CARGOSPECS(cs) {
4907 if (cs->
bitnum == ctype) {
4908 grfmsg(6,
"TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->
Index());
4913 grfmsg(5,
"TranslateCargo: Cargo bitnum %d not available in this climate, skipping.", ctype);
4926 grfmsg(5,
"TranslateCargo: Cargo type %d not available in this climate, skipping.", ctype);
4932 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));
4936 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);
4941 static bool IsValidGroupID(uint16 groupid,
const char *
function)
4943 if (groupid >
MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) {
4944 grfmsg(1,
"%s: Spritegroup 0x%04X out of range or empty, skipping.",
function, groupid);
4951 static void VehicleMapSpriteGroup(
ByteReader *buf, byte feature, uint8 idcount)
4954 static uint last_engines_count;
4955 bool wagover =
false;
4958 if (
HasBit(idcount, 7)) {
4961 idcount =
GB(idcount, 0, 7);
4963 if (last_engines_count == 0) {
4964 grfmsg(0,
"VehicleMapSpriteGroup: WagonOverride: No engine to do override with");
4968 grfmsg(6,
"VehicleMapSpriteGroup: WagonOverride: %u engines, %u wagons",
4969 last_engines_count, idcount);
4971 if (last_engines_count != idcount) {
4972 last_engines =
ReallocT(last_engines, idcount);
4973 last_engines_count = idcount;
4978 for (uint i = 0; i < idcount; i++) {
4984 HandleChangeInfoResult(
"VehicleMapSpriteGroup",
CIR_INVALID_ID, 0, 0);
4988 engines[i] = e->
index;
4989 if (!wagover) last_engines[i] = engines[i];
4992 uint8 cidcount = buf->ReadByte();
4993 for (uint c = 0; c < cidcount; c++) {
4994 uint8 ctype = buf->ReadByte();
4995 uint16 groupid = buf->ReadWord();
4996 if (!IsValidGroupID(groupid,
"VehicleMapSpriteGroup"))
continue;
4998 grfmsg(8,
"VehicleMapSpriteGroup: * [%d] Cargo type 0x%X, group id 0x%02X", c, ctype, groupid);
5000 ctype = TranslateCargo(feature, ctype);
5003 for (uint i = 0; i < idcount; i++) {
5006 grfmsg(7,
"VehicleMapSpriteGroup: [%d] Engine %d...", i, engine);
5009 SetWagonOverrideSprites(engine, ctype, _cur.spritegroups[groupid], last_engines, last_engines_count);
5011 SetCustomEngineSprites(engine, ctype, _cur.spritegroups[groupid]);
5016 uint16 groupid = buf->ReadWord();
5017 if (!IsValidGroupID(groupid,
"VehicleMapSpriteGroup"))
return;
5019 grfmsg(8,
"-- Default group id 0x%04X", groupid);
5021 for (uint i = 0; i < idcount; i++) {
5025 SetWagonOverrideSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid], last_engines, last_engines_count);
5027 SetCustomEngineSprites(engine, CT_DEFAULT, _cur.spritegroups[groupid]);
5034 static void CanalMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5037 for (uint i = 0; i < idcount; i++) {
5041 uint8 cidcount = buf->ReadByte();
5042 buf->Skip(cidcount * 3);
5044 uint16 groupid = buf->ReadWord();
5045 if (!IsValidGroupID(groupid,
"CanalMapSpriteGroup"))
return;
5047 for (uint i = 0; i < idcount; i++) {
5051 grfmsg(1,
"CanalMapSpriteGroup: Canal subset %d out of range, skipping", cf);
5061 static void StationMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5063 uint8 *stations =
AllocaM(uint8, idcount);
5064 for (uint i = 0; i < idcount; i++) {
5065 stations[i] = buf->ReadByte();
5068 uint8 cidcount = buf->ReadByte();
5069 for (uint c = 0; c < cidcount; c++) {
5070 uint8 ctype = buf->ReadByte();
5071 uint16 groupid = buf->ReadWord();
5072 if (!IsValidGroupID(groupid,
"StationMapSpriteGroup"))
continue;
5074 ctype = TranslateCargo(GSF_STATIONS, ctype);
5077 for (uint i = 0; i < idcount; i++) {
5080 if (statspec == NULL) {
5081 grfmsg(1,
"StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5089 uint16 groupid = buf->ReadWord();
5090 if (!IsValidGroupID(groupid,
"StationMapSpriteGroup"))
return;
5092 for (uint i = 0; i < idcount; i++) {
5095 if (statspec == NULL) {
5096 grfmsg(1,
"StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]);
5101 grfmsg(1,
"StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]);
5108 StationClass::Assign(statspec);
5113 static void TownHouseMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5115 uint8 *houses =
AllocaM(uint8, idcount);
5116 for (uint i = 0; i < idcount; i++) {
5117 houses[i] = buf->ReadByte();
5121 uint8 cidcount = buf->ReadByte();
5122 buf->Skip(cidcount * 3);
5124 uint16 groupid = buf->ReadWord();
5125 if (!IsValidGroupID(groupid,
"TownHouseMapSpriteGroup"))
return;
5127 if (_cur.
grffile->housespec == NULL) {
5128 grfmsg(1,
"TownHouseMapSpriteGroup: No houses defined, skipping");
5132 for (uint i = 0; i < idcount; i++) {
5136 grfmsg(1,
"TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]);
5144 static void IndustryMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5146 uint8 *industries =
AllocaM(uint8, idcount);
5147 for (uint i = 0; i < idcount; i++) {
5148 industries[i] = buf->ReadByte();
5152 uint8 cidcount = buf->ReadByte();
5153 buf->Skip(cidcount * 3);
5155 uint16 groupid = buf->ReadWord();
5156 if (!IsValidGroupID(groupid,
"IndustryMapSpriteGroup"))
return;
5158 if (_cur.
grffile->industryspec == NULL) {
5159 grfmsg(1,
"IndustryMapSpriteGroup: No industries defined, skipping");
5163 for (uint i = 0; i < idcount; i++) {
5166 if (indsp == NULL) {
5167 grfmsg(1,
"IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]);
5175 static void IndustrytileMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5177 uint8 *indtiles =
AllocaM(uint8, idcount);
5178 for (uint i = 0; i < idcount; i++) {
5179 indtiles[i] = buf->ReadByte();
5183 uint8 cidcount = buf->ReadByte();
5184 buf->Skip(cidcount * 3);
5186 uint16 groupid = buf->ReadWord();
5187 if (!IsValidGroupID(groupid,
"IndustrytileMapSpriteGroup"))
return;
5189 if (_cur.
grffile->indtspec == NULL) {
5190 grfmsg(1,
"IndustrytileMapSpriteGroup: No industry tiles defined, skipping");
5194 for (uint i = 0; i < idcount; i++) {
5197 if (indtsp == NULL) {
5198 grfmsg(1,
"IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]);
5206 static void CargoMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5209 for (uint i = 0; i < idcount; i++) {
5210 cargoes[i] = buf->ReadByte();
5214 uint8 cidcount = buf->ReadByte();
5215 buf->Skip(cidcount * 3);
5217 uint16 groupid = buf->ReadWord();
5218 if (!IsValidGroupID(groupid,
"CargoMapSpriteGroup"))
return;
5220 for (uint i = 0; i < idcount; i++) {
5224 grfmsg(1,
"CargoMapSpriteGroup: Cargo ID %d out of range, skipping", cid);
5230 cs->group = _cur.spritegroups[groupid];
5234 static void ObjectMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5236 if (_cur.
grffile->objectspec == NULL) {
5237 grfmsg(1,
"ObjectMapSpriteGroup: No object tiles defined, skipping");
5241 uint8 *objects =
AllocaM(uint8, idcount);
5242 for (uint i = 0; i < idcount; i++) {
5243 objects[i] = buf->ReadByte();
5246 uint8 cidcount = buf->ReadByte();
5247 for (uint c = 0; c < cidcount; c++) {
5248 uint8 ctype = buf->ReadByte();
5249 uint16 groupid = buf->ReadWord();
5250 if (!IsValidGroupID(groupid,
"ObjectMapSpriteGroup"))
continue;
5252 ctype = TranslateCargo(GSF_OBJECTS, ctype);
5255 for (uint i = 0; i < idcount; i++) {
5259 grfmsg(1,
"ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5267 uint16 groupid = buf->ReadWord();
5268 if (!IsValidGroupID(groupid,
"ObjectMapSpriteGroup"))
return;
5270 for (uint i = 0; i < idcount; i++) {
5274 grfmsg(1,
"ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]);
5279 grfmsg(1,
"ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]);
5289 static void RailTypeMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5291 uint8 *railtypes =
AllocaM(uint8, idcount);
5292 for (uint i = 0; i < idcount; i++) {
5293 railtypes[i] = _cur.
grffile->railtype_map[buf->ReadByte()];
5296 uint8 cidcount = buf->ReadByte();
5297 for (uint c = 0; c < cidcount; c++) {
5298 uint8 ctype = buf->ReadByte();
5299 uint16 groupid = buf->ReadWord();
5300 if (!IsValidGroupID(groupid,
"RailTypeMapSpriteGroup"))
continue;
5302 if (ctype >= RTSG_END)
continue;
5305 for (uint i = 0; i < idcount; i++) {
5310 rti->
group[ctype] = _cur.spritegroups[groupid];
5319 static void AirportMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5321 uint8 *airports =
AllocaM(uint8, idcount);
5322 for (uint i = 0; i < idcount; i++) {
5323 airports[i] = buf->ReadByte();
5327 uint8 cidcount = buf->ReadByte();
5328 buf->Skip(cidcount * 3);
5330 uint16 groupid = buf->ReadWord();
5331 if (!IsValidGroupID(groupid,
"AirportMapSpriteGroup"))
return;
5333 if (_cur.
grffile->airportspec == NULL) {
5334 grfmsg(1,
"AirportMapSpriteGroup: No airports defined, skipping");
5338 for (uint i = 0; i < idcount; i++) {
5342 grfmsg(1,
"AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]);
5350 static void AirportTileMapSpriteGroup(
ByteReader *buf, uint8 idcount)
5352 uint8 *airptiles =
AllocaM(uint8, idcount);
5353 for (uint i = 0; i < idcount; i++) {
5354 airptiles[i] = buf->ReadByte();
5358 uint8 cidcount = buf->ReadByte();
5359 buf->Skip(cidcount * 3);
5361 uint16 groupid = buf->ReadWord();
5362 if (!IsValidGroupID(groupid,
"AirportTileMapSpriteGroup"))
return;
5364 if (_cur.
grffile->airtspec == NULL) {
5365 grfmsg(1,
"AirportTileMapSpriteGroup: No airport tiles defined, skipping");
5369 for (uint i = 0; i < idcount; i++) {
5372 if (airtsp == NULL) {
5373 grfmsg(1,
"AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]);
5383 static void FeatureMapSpriteGroup(
ByteReader *buf)
5399 uint8 feature = buf->ReadByte();
5400 uint8 idcount = buf->ReadByte();
5406 uint16 groupid = buf->ReadWord();
5407 if (!IsValidGroupID(groupid,
"FeatureMapSpriteGroup"))
return;
5409 grfmsg(6,
"FeatureMapSpriteGroup: Adding generic feature callback for feature %d", feature);
5418 grfmsg(6,
"FeatureMapSpriteGroup: Feature %d, %d ids", feature, idcount);
5422 case GSF_ROADVEHICLES:
5425 VehicleMapSpriteGroup(buf, feature, idcount);
5429 CanalMapSpriteGroup(buf, idcount);
5433 StationMapSpriteGroup(buf, idcount);
5437 TownHouseMapSpriteGroup(buf, idcount);
5440 case GSF_INDUSTRIES:
5441 IndustryMapSpriteGroup(buf, idcount);
5444 case GSF_INDUSTRYTILES:
5445 IndustrytileMapSpriteGroup(buf, idcount);
5449 CargoMapSpriteGroup(buf, idcount);
5453 AirportMapSpriteGroup(buf, idcount);
5457 ObjectMapSpriteGroup(buf, idcount);
5461 RailTypeMapSpriteGroup(buf, idcount);
5464 case GSF_AIRPORTTILES:
5465 AirportTileMapSpriteGroup(buf, idcount);
5469 grfmsg(1,
"FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
5493 bool new_scheme = _cur.
grffile->grf_version >= 7;
5495 uint8 feature = buf->ReadByte();
5496 uint8 lang = buf->ReadByte();
5497 uint8 num = buf->ReadByte();
5498 bool generic =
HasBit(lang, 7);
5501 id = buf->ReadWord();
5502 }
else if (feature <= GSF_AIRCRAFT) {
5503 id = buf->ReadExtendedByte();
5505 id = buf->ReadByte();
5510 uint16 endid =
id + num;
5512 grfmsg(6,
"FeatureNewName: About to rename engines %d..%d (feature %d) in language 0x%02X",
5513 id, endid, feature, lang);
5515 for (;
id < endid && buf->HasData();
id++) {
5516 const char *name = buf->ReadString();
5517 grfmsg(8,
"FeatureNewName: 0x%04X <- %s",
id, name);
5521 case GSF_ROADVEHICLES:
5526 if (e == NULL)
break;
5540 switch (
GB(
id, 8, 8)) {
5542 if (_cur.
grffile->stations == NULL || _cur.
grffile->stations[
GB(
id, 0, 8)] == NULL) {
5543 grfmsg(1,
"FeatureNewName: Attempt to name undefined station 0x%X, ignoring",
GB(
id, 0, 8));
5551 if (_cur.
grffile->stations == NULL || _cur.
grffile->stations[
GB(
id, 0, 8)] == NULL) {
5552 grfmsg(1,
"FeatureNewName: Attempt to name undefined station 0x%X, ignoring",
GB(
id, 0, 8));
5559 if (_cur.
grffile->airtspec == NULL || _cur.
grffile->airtspec[
GB(
id, 0, 8)] == NULL) {
5560 grfmsg(1,
"FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring",
GB(
id, 0, 8));
5567 if (_cur.
grffile->housespec == NULL || _cur.
grffile->housespec[
GB(
id, 0, 8)] == NULL) {
5568 grfmsg(1,
"FeatureNewName: Attempt to name undefined house 0x%X, ignoring.",
GB(
id, 0, 8));
5575 grfmsg(7,
"FeatureNewName: Unsupported ID (0x%04X)",
id);
5594 if (offset >= max_sprites) {
5595 grfmsg(1,
"GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
5596 uint orig_num = num;
5601 if (offset + num > max_sprites) {
5602 grfmsg(4,
"GraphicsNew: %s sprite overflow, truncating...", name);
5603 uint orig_num = num;
5604 num =
max(max_sprites - offset, 0);
5605 return orig_num - num;
5634 {
A5BLOCK_ALLOW_OFFSET, SPR_SIGNALS_BASE, 1, PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT,
"Signal graphics" },
5636 {
A5BLOCK_ALLOW_OFFSET, SPR_SLOPES_BASE, 1, NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT,
"Foundation graphics" },
5667 uint8 type = buf->ReadByte();
5668 uint16 num = buf->ReadExtendedByte();
5669 uint16 offset =
HasBit(type, 7) ? buf->ReadExtendedByte() : 0;
5675 grfmsg(2,
"GraphicsNew: Loading 10 missing shore sprites from extra grf.");
5692 grfmsg(2,
"GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)", type, num);
5697 const Action5Type *action5_type = &_action5_types[type];
5703 grfmsg(1,
"GraphicsNew: %s (type 0x%02X) do not allow an <offset> field. Ignoring offset.", action5_type->
name, type);
5710 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);
5720 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);
5722 for (; num > 0; num--) {
5795 *value = (major << 24) | (minor << 20) | (revision << 16) | build;
5825 *value = _game_mode;
5859 *value =
Clamp(snowline * (grffile->grf_version >= 8 ? 1 :
TILE_HEIGHT), 0, 0xFE);
5868 *value = _openttd_newgrf_version;
5883 default:
return false;
5887 static uint32 GetParamVal(byte param, uint32 *cond_val)
5905 if (cond_val == NULL) {
5924 grfmsg(1,
"Unsupported in-game variable 0x%02X", param);
5947 byte *preload_sprite = NULL;
5951 preload_sprite = MallocT<byte>(num);
5959 grfmsg(2,
"CfgApply: Ignoring (next sprite is real, unsupported)");
5960 free(preload_sprite);
5965 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
5966 if (it != _grf_line_to_action6_sprite_override.end()) {
5967 free(preload_sprite);
5968 preload_sprite = _grf_line_to_action6_sprite_override[location];
5970 _grf_line_to_action6_sprite_override[location] = preload_sprite;
5983 param_num = buf->ReadByte();
5984 if (param_num == 0xFF)
break;
5988 param_size = buf->ReadByte();
5992 add_value =
HasBit(param_size, 7);
5993 param_size =
GB(param_size, 0, 7);
5996 offset = buf->ReadExtendedByte();
6000 if (param_num < 0x80 && (param_num + (param_size - 1) / 4) >= _cur.
grffile->
param_end) {
6001 grfmsg(2,
"CfgApply: Ignoring (param %d not set)", (param_num + (param_size - 1) / 4));
6005 grfmsg(8,
"CfgApply: Applying %u bytes from parameter 0x%02X at offset 0x%04X", param_size, param_num, offset);
6008 for (i = 0; i < param_size && offset + i < num; i++) {
6009 uint32 value = GetParamVal(param_num + i / 4, NULL);
6012 if (i % 4 == 0) carry =
false;
6015 uint new_value = preload_sprite[offset + i] +
GB(value, (i % 4) * 8, 8) + (carry ? 1 : 0);
6016 preload_sprite[offset + i] =
GB(new_value, 0, 8);
6018 carry = new_value >= 256;
6020 preload_sprite[offset + i] =
GB(value, (i % 4) * 8, 8);
6053 uint32 cond_val = 0;
6057 uint8 param = buf->ReadByte();
6058 uint8 paramsize = buf->ReadByte();
6059 uint8 condtype = buf->ReadByte();
6066 switch (paramsize) {
6067 case 8: cond_val = buf->ReadDWord(); mask = buf->ReadDWord();
break;
6068 case 4: cond_val = buf->ReadDWord(); mask = 0xFFFFFFFF;
break;
6069 case 2: cond_val = buf->ReadWord(); mask = 0x0000FFFF;
break;
6070 case 1: cond_val = buf->ReadByte(); mask = 0x000000FF;
break;
6074 if (param < 0x80 && _cur.grffile->param_end <= param) {
6075 grfmsg(7,
"SkipIf: Param %d undefined, skipping test", param);
6079 uint32 param_val = GetParamVal(param, &cond_val);
6081 grfmsg(7,
"SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
6091 if (param == 0x88 && (condtype < 0x0B || condtype > 0x0E)) {
6101 if (condtype != 10 && c == NULL) {
6102 grfmsg(7,
"SkipIf: GRFID 0x%08X unknown, skipping test",
BSWAP32(cond_val));
6129 default:
grfmsg(1,
"SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype);
return;
6134 case 0x00: result = !!(param_val & (1 << cond_val));
6136 case 0x01: result = !(param_val & (1 << cond_val));
6138 case 0x02: result = (param_val & mask) == cond_val;
6140 case 0x03: result = (param_val & mask) != cond_val;
6142 case 0x04: result = (param_val & mask) < cond_val;
6144 case 0x05: result = (param_val & mask) > cond_val;
6155 default:
grfmsg(1,
"SkipIf: Unsupported condition type %02X. Ignoring", condtype);
return;
6160 grfmsg(2,
"SkipIf: Not skipping sprites, test was false");
6164 uint8 numsprites = buf->ReadByte();
6172 if (label->label != numsprites)
continue;
6175 if (choice == NULL) choice = label;
6177 if (label->nfo_line > _cur.
nfo_line) {
6183 if (choice != NULL) {
6184 grfmsg(2,
"SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line);
6190 grfmsg(2,
"SkipIf: Skipping %d sprites, test was true", numsprites);
6209 uint8 grf_version = buf->ReadByte();
6210 uint32 grfid = buf->ReadDWord();
6211 const char *name = buf->ReadString();
6215 if (grf_version < 2 || grf_version > 8) {
6217 DEBUG(grf, 0,
"%s: NewGRF \"%s\" (GRFID %08X) uses GRF version %d, which is incompatible with this version of OpenTTD.", _cur.
grfconfig->
filename, name,
BSWAP32(grfid), grf_version);
6225 if (buf->HasData()) {
6226 const char *info = buf->ReadString();
6244 uint8 version = buf->ReadByte();
6245 uint32 grfid = buf->ReadDWord();
6246 const char *name = buf->ReadString();
6249 DisableGrf(STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
6253 if (_cur.
grffile->grfid != grfid) {
6254 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));
6258 _cur.
grffile->grf_version = version;
6276 uint8 num_sets = buf->ReadByte();
6278 for (uint i = 0; i < num_sets; i++) {
6279 uint8 num_sprites = buf->ReadByte();
6280 uint16 first_sprite = buf->ReadWord();
6282 grfmsg(2,
"SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
6283 i, num_sprites, first_sprite
6286 for (uint j = 0; j < num_sprites; j++) {
6287 int load_index = first_sprite + j;
6293 if (
IsInsideMM(load_index, SPR_ORIGINALSHORE_START, SPR_ORIGINALSHORE_END + 1)) {
6303 uint8 num_sets = buf->ReadByte();
6305 for (uint i = 0; i < num_sets; i++) {
6334 STR_NEWGRF_ERROR_VERSION_NUMBER,
6335 STR_NEWGRF_ERROR_DOS_OR_WINDOWS,
6336 STR_NEWGRF_ERROR_UNSET_SWITCH,
6337 STR_NEWGRF_ERROR_INVALID_PARAMETER,
6338 STR_NEWGRF_ERROR_LOAD_BEFORE,
6339 STR_NEWGRF_ERROR_LOAD_AFTER,
6340 STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
6344 STR_NEWGRF_ERROR_MSG_INFO,
6345 STR_NEWGRF_ERROR_MSG_WARNING,
6346 STR_NEWGRF_ERROR_MSG_ERROR,
6347 STR_NEWGRF_ERROR_MSG_FATAL
6350 byte severity = buf->ReadByte();
6351 byte lang = buf->ReadByte();
6352 byte message_id = buf->ReadByte();
6355 if (!CheckGrfLangID(lang, _cur.
grffile->grf_version))
return;
6359 if (!
HasBit(severity, 7) && _cur.
stage == GLS_INIT) {
6360 grfmsg(7,
"GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur.
stage);
6365 if (severity >=
lengthof(sevstr)) {
6366 grfmsg(7,
"GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
6368 }
else if (severity == 3) {
6378 if (message_id >=
lengthof(msgstr) && message_id != 0xFF) {
6379 grfmsg(7,
"GRFLoadError: Invalid message id.");
6383 if (buf->Remaining() <= 1) {
6384 grfmsg(7,
"GRFLoadError: No message data supplied.");
6393 if (message_id == 0xFF) {
6395 if (buf->HasData()) {
6396 const char *message = buf->ReadString();
6400 grfmsg(7,
"GRFLoadError: No custom message supplied.");
6404 error->
message = msgstr[message_id];
6407 if (buf->HasData()) {
6408 const char *data = buf->ReadString();
6412 grfmsg(7,
"GRFLoadError: No message data supplied.");
6418 uint param_number = buf->ReadByte();
6432 if (!buf->HasData())
return;
6434 const char *text = buf->ReadString();
6435 grfmsg(2,
"GRFComment: %s", text);
6441 uint8 target = buf->ReadByte();
6444 if (target < 0x80 || target == 0x9E)
return;
6458 static uint32 GetPatchVariable(uint8 param)
6468 case 0x0F:
return 0;
6484 case 0x11:
return SPR_2CCMAP_BASE;
6501 byte max_edge =
max(log_X, log_Y);
6503 if (log_X == log_Y) {
6506 if (max_edge == log_Y)
SetBit(map_bits, 1);
6509 return (map_bits << 24) | (
min(log_X, log_Y) << 20) | (max_edge << 16) |
6510 (log_X << 12) | (log_Y << 8) | (log_X + log_Y);
6519 return SPR_SLOPES_BASE;
6526 grfmsg(2,
"ParamSet: Unknown Patch variable 0x%02X.", param);
6532 static uint32 PerformGRM(uint32 *grm, uint16 num_ids, uint16 count, uint8 op, uint8 target,
const char *type)
6545 for (uint i = start; i < num_ids; i++) {
6549 if (op == 2 || op == 3)
break;
6554 if (size == count)
break;
6557 if (size == count) {
6559 if (op == 0 || op == 3) {
6560 grfmsg(2,
"ParamSet: GRM: Reserving %d %s at %d", count, type, start);
6561 for (uint i = 0; i < count; i++) grm[start + i] = _cur.
grffile->grfid;
6567 if (op != 4 && op != 5) {
6569 grfmsg(0,
"ParamSet: GRM: Unable to allocate %d %s, deactivating", count, type);
6574 grfmsg(1,
"ParamSet: GRM: Unable to allocate %d %s", count, type);
6604 uint8 target = buf->ReadByte();
6605 uint8 oper = buf->ReadByte();
6606 uint32 src1 = buf->ReadByte();
6607 uint32 src2 = buf->ReadByte();
6610 if (buf->Remaining() >= 4) data = buf->ReadDWord();
6619 if (target < 0x80 && target < _cur.grffile->param_end) {
6620 grfmsg(7,
"ParamSet: Param %u already defined, skipping", target);
6624 oper =
GB(oper, 0, 7);
6628 if (
GB(data, 0, 8) == 0xFF) {
6629 if (data == 0x0000FFFF) {
6631 src1 = GetPatchVariable(src1);
6635 uint8 feature =
GB(data, 8, 8);
6636 uint16 count =
GB(data, 16, 16);
6638 if (_cur.
stage == GLS_RESERVE) {
6639 if (feature == 0x08) {
6643 if (_cur.
spriteid + count >= 16384) {
6644 grfmsg(0,
"ParamSet: GRM: Unable to allocate %d sprites; try changing NewGRF order", count);
6650 grfmsg(4,
"ParamSet: GRM: Allocated %d sprites at %d", count, _cur.
spriteid);
6657 }
else if (_cur.
stage == GLS_ACTIVATION) {
6686 grfmsg(4,
"ParamSet: GRM: Using pre-allocated sprites at %d", src1);
6694 grfmsg(1,
"ParamSet: GRM: Unsupported operation %d for general sprites", op);
6705 default:
grfmsg(1,
"ParamSet: GRM: Unsupported feature 0x%X", feature);
return;
6722 }
else if (src1 == 0xFE) {
6734 src1 = (src1 == 0xFF) ? data : GetParamVal(src1, NULL);
6735 src2 = (src2 == 0xFF) ? data : GetParamVal(src2, NULL);
6763 res = (int32)src1 * (int32)src2;
6767 if ((int32)src2 < 0) {
6768 res = src1 >> -(int32)src2;
6770 res = src1 << (src2 & 0x1F);
6775 if ((int32)src2 < 0) {
6776 res = (int32)src1 >> -(int32)src2;
6778 res = (int32)src1 << (src2 & 0x1F);
6802 res = (int32)src1 / (int32)src2;
6818 res = (int32)src1 % (int32)src2;
6822 default:
grfmsg(0,
"ParamSet: Unknown operation %d, skipping", oper);
return;
6851 grfmsg(7,
"ParamSet: Skipping unimplemented target 0x%02X", target);
6862 uint32 safe_bits = 0;
6863 SetBit(safe_bits, GMB_SECOND_ROCKY_TILE_SET);
6872 grfmsg(7,
"ParamSet: Skipping unimplemented target 0x%02X", target);
6876 if (target < 0x80) {
6877 _cur.
grffile->param[target] = res;
6881 grfmsg(7,
"ParamSet: Skipping unknown target 0x%02X", target);
6895 uint8 num = buf->ReadByte();
6897 for (uint i = 0; i < num; i++) {
6898 uint32 grfid = buf->ReadDWord();
6920 uint8 num = buf->ReadByte();
6922 for (uint i = 0; i < num; i++) {
6923 uint32 grfid = buf->ReadDWord();
6927 if (file != NULL && file != _cur.
grfconfig) {
6945 uint32 grfid = _cur.
grffile->grfid;
6949 byte
id = buf->ReadByte();
6950 grfmsg(6,
"FeatureTownName: definition 0x%02X",
id & 0x7F);
6955 bool new_scheme = _cur.
grffile->grf_version >= 7;
6957 byte lang = buf->ReadByte();
6959 byte nb_gen = townname->nb_gen;
6963 const char *name = buf->ReadString();
6966 grfmsg(6,
"FeatureTownName: lang 0x%X -> '%s'", lang, lang_name);
6969 townname->name[nb_gen] =
AddGRFString(grfid,
id, lang, new_scheme,
false, name, STR_UNDEFINED);
6971 lang = buf->ReadByte();
6972 }
while (lang != 0);
6973 townname->id[nb_gen] = id;
6977 byte nb = buf->ReadByte();
6978 grfmsg(6,
"FeatureTownName: %u parts", nb);
6980 townname->nbparts[id] = nb;
6981 townname->partlist[id] = CallocT<NamePartList>(nb);
6983 for (
int i = 0; i < nb; i++) {
6984 byte nbtext = buf->ReadByte();
6985 townname->partlist[id][i].bitstart = buf->ReadByte();
6986 townname->partlist[id][i].bitcount = buf->ReadByte();
6987 townname->partlist[id][i].maxprob = 0;
6988 townname->partlist[id][i].partcount = nbtext;
6989 townname->partlist[id][i].parts = CallocT<NamePart>(nbtext);
6990 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);
6992 for (
int j = 0; j < nbtext; j++) {
6993 byte prob = buf->ReadByte();
6996 byte ref_id = buf->ReadByte();
6998 if (townname->nbparts[ref_id] == 0) {
6999 grfmsg(0,
"FeatureTownName: definition 0x%02X doesn't exist, deactivating", ref_id);
7000 DelGRFTownName(grfid);
7005 grfmsg(6,
"FeatureTownName: part %d, text %d, uses intermediate definition 0x%02X (with probability %d)", i, j, ref_id, prob & 0x7F);
7006 townname->partlist[id][i].parts[j].data.
id = ref_id;
7008 const char *text = buf->ReadString();
7010 grfmsg(6,
"FeatureTownName: part %d, text %d, '%s' (with probability %d)", i, j, townname->partlist[
id][i].parts[j].data.
text, prob);
7012 townname->partlist[id][i].parts[j].
prob = prob;
7013 townname->partlist[id][i].maxprob +=
GB(prob, 0, 7);
7015 grfmsg(6,
"FeatureTownName: part %d, total probability %d", i, townname->partlist[
id][i].maxprob);
7027 byte nfo_label = buf->ReadByte();
7029 GRFLabel *label = MallocT<GRFLabel>(1);
7030 label->label = nfo_label;
7041 for (l = _cur.
grffile->
label; l->next != NULL; l = l->next) {}
7045 grfmsg(2,
"DefineGotoLabel: GOTO target with label 0x%02X", label->label);
7059 if (file == NULL || file->sound_offset == 0) {
7060 grfmsg(1,
"ImportGRFSound: Source file not available");
7064 if (sound_id >= file->num_sounds) {
7065 grfmsg(1,
"ImportGRFSound: Sound effect %d is invalid", sound_id);
7069 grfmsg(2,
"ImportGRFSound: Copying sound %d (%d) from file %X", sound_id, file->sound_offset + sound_id, grfid);
7071 *sound = *GetSound(file->sound_offset + sound_id);
7074 sound->volume = 128;
7075 sound->priority = 0;
7086 sound->volume = 0x80;
7087 sound->priority = 0;
7089 if (offs != SIZE_MAX) {
7092 sound->file_offset = offs;
7104 uint16 num = buf->ReadWord();
7105 if (num == 0)
return;
7108 if (_cur.
grffile->sound_offset == 0) {
7109 _cur.
grffile->sound_offset = GetNumSounds();
7110 _cur.
grffile->num_sounds = num;
7113 sound = GetSound(_cur.
grffile->sound_offset);
7116 for (
int i = 0; i < num; i++) {
7121 bool invalid = i >= _cur.
grffile->num_sounds;
7131 grfmsg(1,
"GRFSound: Sound index out of range (multiple Action 11?)");
7133 }
else if (len != 4) {
7134 grfmsg(1,
"GRFSound: Invalid sprite section import");
7144 grfmsg(1,
"GRFSound: Unexpected RealSprite found, skipping");
7151 grfmsg(1,
"GRFSound: Sound index out of range (multiple Action 11?)");
7159 if (_cur.
stage == GLS_INIT) {
7161 grfmsg(1,
"GRFSound: Inline sounds are not supported for container version >= 2");
7170 if (_cur.
stage == GLS_ACTIVATION) {
7181 grfmsg(1,
"GRFSound: Unexpected Action %x found, skipping", action);
7210 uint8 num_def = buf->ReadByte();
7212 for (uint i = 0; i < num_def; i++) {
7214 uint8 num_char = buf->ReadByte();
7215 uint16 base_char = buf->ReadWord();
7217 if (size >= FS_END) {
7218 grfmsg(1,
"LoadFontGlyph: Size %u is not supported, ignoring", size);
7221 grfmsg(7,
"LoadFontGlyph: Loading %u glyph(s) at 0x%04X for size %u", num_char, base_char, size);
7223 for (uint c = 0; c < num_char; c++) {
7241 uint8 num_def = buf->ReadByte();
7243 for (uint i = 0; i < num_def; i++) {
7267 uint32 grfid = buf->ReadDWord();
7270 grfmsg(7,
"TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13",
BSWAP32(grfid));
7280 GetString(tmp, STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE,
lastof(tmp));
7291 byte language = _cur.
grffile->grf_version >= 8 ? buf->ReadByte() : 0x7F;
7292 byte num_strings = buf->ReadByte();
7293 uint16 first_id = buf->ReadWord();
7295 if (!((first_id >= 0xD000 && first_id + num_strings <= 0xD400) || (first_id >= 0xD800 && first_id + num_strings <= 0xE000))) {
7296 grfmsg(7,
"TranslateGRFStrings: Attempting to set out-of-range string IDs in action 13 (first: 0x%4X, number: 0x%2X)", first_id, num_strings);
7300 for (uint i = 0; i < num_strings && buf->HasData(); i++) {
7301 const char *
string = buf->ReadString();
7304 grfmsg(7,
"TranslateGRFString: Ignoring empty string.");
7308 AddGRFString(grfid, first_id + i, language,
true,
true,
string, STR_UNDEFINED);
7337 grfmsg(2,
"StaticGRFInfo: expected only 1 byte for 'INFO'->'NPAR' but got " PRINTF_SIZE
", ignoring this field", len);
7349 grfmsg(2,
"StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE
", ignoring this field", len);
7352 char data = buf->ReadByte();
7360 grfmsg(2,
"StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
7375 grfmsg(2,
"StaticGRFInfo: expected only 1 byte for 'INFO'->'BLTR' but got " PRINTF_SIZE
", ignoring this field", len);
7378 char data = buf->ReadByte();
7384 grfmsg(2,
"StaticGRFInfo: unexpected value '%02x' for 'INFO'->'BLTR', ignoring this field", data);
7397 grfmsg(2,
"StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE
", ignoring this field", len);
7410 grfmsg(2,
"StaticGRFInfo: expected 4 bytes for 'INFO'->'MINV' but got " PRINTF_SIZE
", ignoring this field", len);
7415 grfmsg(2,
"StaticGRFInfo: 'MINV' defined before 'VRSN' or 'VRSN' set to 0, ignoring this field");
7446 grfmsg(2,
"StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE
", ignoring this field", len);
7451 _cur_parameter->
type = type;
7453 grfmsg(3,
"StaticGRFInfo: unknown parameter type %d, ignoring this field", type);
7463 grfmsg(2,
"StaticGRFInfo: 'INFO'->'PARA'->'LIMI' is only valid for parameters with type uint/enum, ignoring this field");
7465 }
else if (len != 8) {
7466 grfmsg(2,
"StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE
", ignoring this field", len);
7469 _cur_parameter->
min_value = buf->ReadDWord();
7470 _cur_parameter->
max_value = buf->ReadDWord();
7478 if (len < 1 || len > 3) {
7479 grfmsg(2,
"StaticGRFInfo: expected 1 to 3 bytes for 'INFO'->'PARA'->'MASK' but got " PRINTF_SIZE
", ignoring this field", len);
7482 byte param_nr = buf->ReadByte();
7484 grfmsg(2,
"StaticGRFInfo: invalid parameter number in 'INFO'->'PARA'->'MASK', param %d, ignoring this field", param_nr);
7487 _cur_parameter->
param_nr = param_nr;
7488 if (len >= 2) _cur_parameter->
first_bit =
min(buf->ReadByte(), 31);
7489 if (len >= 3) _cur_parameter->
num_bit =
min(buf->ReadByte(), 32 - _cur_parameter->
first_bit);
7500 grfmsg(2,
"StaticGRFInfo: expected 4 bytes for 'INFO'->'PARA'->'DEFA' but got " PRINTF_SIZE
", ignoring this field", len);
7503 _cur_parameter->
def_value = buf->ReadDWord();
7536 this->handler.data = handler;
7548 this->handler.text = handler;
7560 this->handler.call_handler =
true;
7561 this->handler.u.branch = handler;
7573 this->handler.call_handler =
false;
7574 this->handler.u.subtags =
subtags;
7603 byte type = buf->ReadByte();
7605 uint32
id = buf->ReadDWord();
7606 if (type !=
'T' ||
id > _cur_parameter->
max_value) {
7607 grfmsg(2,
"StaticGRFInfo: all child nodes of 'INFO'->'PARA'->param_num->'VALU' should have type 't' and the value/bit number as id");
7609 type = buf->ReadByte();
7613 byte langid = buf->ReadByte();
7614 const char *name_string = buf->ReadString();
7625 type = buf->ReadByte();
7650 byte type = buf->ReadByte();
7652 uint32
id = buf->ReadDWord();
7654 grfmsg(2,
"StaticGRFInfo: all child nodes of 'INFO'->'PARA' should have type 'C' and their parameter number as id");
7656 type = buf->ReadByte();
7663 MemSetT<GRFParameterInfo *>(newdata, 0, num_to_add);
7670 if (!
HandleNodes(buf, _tags_parameters))
return false;
7671 type = buf->ReadByte();
7708 byte new_type = buf->ReadByte();
7709 while (new_type != 0) {
7712 new_type = buf->ReadByte();
7723 uint16 size = buf->ReadWord();
7747 while ((tag = &subtags[i++])->type != 0) {
7750 default: NOT_REACHED();
7753 byte langid = buf->ReadByte();
7754 return tag->handler.
text(langid, buf->ReadString());
7758 size_t len = buf->ReadWord();
7759 if (buf->Remaining() < len)
return false;
7760 return tag->handler.
data(len, buf);
7765 return tag->handler.u.branch(buf);
7771 grfmsg(2,
"StaticGRFInfo: unknown type/id combination found, type=%c, id=%x", type,
id);
7783 byte type = buf->ReadByte();
7785 uint32
id = buf->ReadDWord();
7786 if (!
HandleNode(type,
id, buf, subtags))
return false;
7787 type = buf->ReadByte();
7904 const GRFFile *
const *end = _grf_files.
End();
7905 for (
GRFFile **file = _grf_files.
Begin(); file != end; file++) {
7907 if (stations == NULL)
continue;
7909 if (stations[i] == NULL)
continue;
7915 if (!statspec->copied_layouts) {
7916 for (uint l = 0; l < statspec->lengths; l++) {
7917 for (uint p = 0; p < statspec->platforms[l]; p++) {
7918 free(statspec->layouts[l][p]);
7920 free(statspec->layouts[l]);
7922 free(statspec->layouts);
7923 free(statspec->platforms);
7939 const GRFFile *
const *end = _grf_files.
End();
7940 for (
GRFFile **file = _grf_files.
Begin(); file != end; file++) {
7941 HouseSpec **&housespec = (*file)->housespec;
7942 if (housespec == NULL)
continue;
7955 const GRFFile *
const *end = _grf_files.
End();
7956 for (
GRFFile **file = _grf_files.
Begin(); file != end; file++) {
7958 if (aslist != NULL) {
7964 for (
int j = 0; j < as->
num_table; j++) {
7976 (*file)->airportspec = NULL;
7980 if (airporttilespec != NULL) {
7982 free(airporttilespec[i]);
7984 free(airporttilespec);
7985 airporttilespec = NULL;
7993 const GRFFile *
const *end = _grf_files.
End();
7994 for (
GRFFile **file = _grf_files.
Begin(); file != end; file++) {
8000 if (industryspec != NULL) {
8003 if (ind == NULL)
continue;
8017 industryspec = NULL;
8020 if (indtspec == NULL)
continue;
8033 const GRFFile *
const *end = _grf_files.
End();
8034 for (
GRFFile **file = _grf_files.
Begin(); file != end; file++) {
8035 ObjectSpec **&objectspec = (*file)->objectspec;
8036 if (objectspec == NULL)
continue;
8038 free(objectspec[i]);
8049 const GRFFile *
const *end = _grf_files.
End();
8050 for (
GRFFile **file = _grf_files.
Begin(); file != end; file++) {
8076 CleanUpGRFTownNames();
8118 ObjectClass::Reset();
8123 StationClass::Reset();
8127 AirportClass::Reset();
8150 _loaded_newgrf_features.
has_2CC =
false;
8157 _grf_id_overrides.clear();
8159 InitializeSoundPool();
8207 if (newfile != NULL) {
8213 newfile =
new GRFFile(config);
8231 for (
Price i = PR_BEGIN; i < PR_END; i++) {
8255 free(this->filename);
8265 'PASS',
'COAL',
'MAIL',
'LVST',
'GOOD',
'GRAI',
'WHEA',
'MAIZ',
'WOOD',
8266 'IORE',
'STEL',
'VALU',
'GOLD',
'DIAM',
'PAPR',
'FOOD',
'FRUT',
'CORE',
8267 'WATR',
'SUGR',
'TOYS',
'BATT',
'SWET',
'TOFF',
'COLA',
'CTCD',
'BUBL',
8271 static const CargoLabel _default_refitmasks_road[] = {
8274 static const CargoLabel _default_refitmasks_ships[] = {
8275 'COAL',
'MAIL',
'LVST',
'GOOD',
'GRAI',
'WHEA',
'MAIZ',
'WOOD',
'IORE',
8276 'STEL',
'VALU',
'GOLD',
'DIAM',
'PAPR',
'FOOD',
'FRUT',
'CORE',
'WATR',
8277 'RUBR',
'SUGR',
'TOYS',
'BATT',
'SWET',
'TOFF',
'COLA',
'CTCD',
'BUBL',
8281 static const CargoLabel _default_refitmasks_aircraft[] = {
8282 'PASS',
'MAIL',
'GOOD',
'VALU',
'GOLD',
'DIAM',
'FOOD',
'FRUT',
'SUGR',
8283 'TOYS',
'BATT',
'SWET',
'TOFF',
'COLA',
'CTCD',
'BUBL',
'PLST',
'FZDR',
8286 static const CargoLabel *
const _default_refitmasks[] = {
8288 _default_refitmasks_road,
8289 _default_refitmasks_ships,
8290 _default_refitmasks_aircraft,
8301 FOR_ALL_ENGINES(e) {
8304 bool only_defaultcargo;
8309 uint32 not_mask = 0;
8310 uint32 xor_mask = ei->refit_mask;
8316 if (_gted[engine].cargo_allowed != 0) {
8319 FOR_ALL_CARGOSPECS(cs) {
8325 ei->refit_mask = ((mask & ~not_mask) ^ xor_mask) &
_cargo_mask;
8331 uint32 xor_mask = 0;
8336 for (uint i = 0;; i++) {
8337 if (cl[i] == 0)
break;
8349 only_defaultcargo = (ei->refit_mask == 0);
8363 if (ei->cargo_type ==
CT_INVALID && ei->refit_mask != 0) {
8365 const uint8 *cargo_map_for_first_refittable = NULL;
8368 if (file == NULL) file = e->
GetGRF();
8369 if (file != NULL && file->grf_version >= 8 && file->
cargo_list.
Length() != 0) {
8370 cargo_map_for_first_refittable = file->
cargo_map;
8374 if (cargo_map_for_first_refittable != NULL) {
8376 byte best_local_slot = 0xFF;
8378 FOR_EACH_SET_CARGO_ID(cargo_type, ei->refit_mask) {
8379 byte local_slot = cargo_map_for_first_refittable[cargo_type];
8380 if (local_slot < best_local_slot) {
8381 best_local_slot = local_slot;
8382 ei->cargo_type = cargo_type;
8404 for (uint i = 0; i < CF_END; i++) {
8417 FOR_ALL_ENGINES(e) {
8418 if (e->
GetGRF() == NULL) {
8421 e->info.
string_id = STR_NEWGRF_INVALID_ENGINE;
8454 default: NOT_REACHED();
8468 cs->
quantifier = STR_NEWGRF_INVALID_CARGO_QUANTITY;
8469 cs->
abbrev = STR_NEWGRF_INVALID_CARGO_ABBREV;
8493 if (filename != NULL)
DEBUG(grf, 1,
"FinaliseHouseArray: %s defines house %d as multitile, but no suitable tiles follow. Disabling house.", filename, hs->
grf_prop.
local_id);
8503 if (filename != NULL)
DEBUG(grf, 1,
"FinaliseHouseArray: %s defines multitile house %d with non-zero population on additional tiles. Disabling house.", filename, hs->
grf_prop.
local_id);
8511 DEBUG(grf, 1,
"FinaliseHouseArray: %s defines house %d with different house size then it's substitute type. Disabling house.", filename, hs->
grf_prop.
local_id);
8518 if (filename != NULL)
DEBUG(grf, 1,
"FinaliseHouseArray: %s defines house %d without a size but marked it as available. Disabling house.", filename, hs->
grf_prop.
local_id);
8537 if (hs == NULL || !hs->
enabled)
continue;
8542 if (min_year == 0)
return;
8546 if (hs == NULL || !hs->
enabled)
continue;
8569 const GRFFile *
const *end = _grf_files.
End();
8570 for (
GRFFile **file = _grf_files.
Begin(); file != end; file++) {
8571 HouseSpec **&housespec = (*file)->housespec;
8572 if (housespec == NULL)
continue;
8577 if (hs == NULL)
continue;
8579 const HouseSpec *next1 = (i + 1 < NUM_HOUSES_PER_GRF ? housespec[i + 1] : NULL);
8580 const HouseSpec *next2 = (i + 2 < NUM_HOUSES_PER_GRF ? housespec[i + 2] : NULL);
8581 const HouseSpec *next3 = (i + 3 < NUM_HOUSES_PER_GRF ? housespec[i + 3] : NULL);
8583 if (!
IsHouseSpecValid(hs, next1, next2, next3, (*file)->filename))
continue;
8591 const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : NULL);
8592 const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : NULL);
8593 const HouseSpec *next3 = (i + 3 < NUM_HOUSES ? HouseSpec::Get(i + 3) : NULL);
8632 const GRFFile *
const *end = _grf_files.
End();
8633 for (
GRFFile **file = _grf_files.
Begin(); file != end; file++) {
8636 if (industryspec != NULL) {
8640 if (indsp != NULL && indsp->
enabled) {
8646 if (strid != STR_UNDEFINED) indsp->
name = strid;
8649 if (strid != STR_UNDEFINED) indsp->
closure_text = strid;
8664 if (strid != STR_UNDEFINED) indsp->
station_name = strid;
8673 if (indtspec != NULL) {
8676 if (indtsp != NULL) {
8677 _industile_mngr.SetEntitySpec(indtsp);
8686 for (uint i = 0; i < 3; i++) {
8691 indsp->
name = STR_NEWGRF_INVALID_INDUSTRYTYPE;
8703 const GRFFile *
const *end = _grf_files.
End();
8704 for (
GRFFile **file = _grf_files.
Begin(); file != end; file++) {
8705 ObjectSpec **&objectspec = (*file)->objectspec;
8706 if (objectspec != NULL) {
8708 if (objectspec[i] != NULL && objectspec[i]->grf_prop.grffile != NULL && objectspec[i]->
enabled) {
8723 const GRFFile *
const *end = _grf_files.
End();
8724 for (
GRFFile **file = _grf_files.
Begin(); file != end; file++) {
8725 AirportSpec **&airportspec = (*file)->airportspec;
8726 if (airportspec != NULL) {
8728 if (airportspec[i] != NULL && airportspec[i]->enabled) {
8729 _airport_mngr.SetEntitySpec(airportspec[i]);
8735 if (airporttilespec != NULL) {
8737 if (airporttilespec[i] != NULL && airporttilespec[i]->enabled) {
8738 _airporttile_mngr.SetEntitySpec(airporttilespec[i]);
8751 static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage)
8765 static const SpecialSpriteHandler handlers[][GLS_END] = {
8766 { NULL, SafeChangeInfo, NULL, NULL, ReserveChangeInfo, FeatureChangeInfo, },
8767 { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
8768 { NULL, NULL, NULL, NULL, NULL, NewSpriteGroup, },
8769 { NULL,
GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, },
8770 { NULL, NULL, NULL, NULL, NULL, FeatureNewName, },
8771 { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, },
8772 { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, },
8773 { NULL, NULL, NULL, NULL, SkipIf, SkipIf, },
8774 { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, GRFInfo, },
8775 { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, },
8776 { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, },
8777 { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, },
8778 { NULL, NULL, NULL, GRFComment, NULL, GRFComment, },
8780 { NULL, SafeGRFInhibit, NULL, GRFInhibit, GRFInhibit, GRFInhibit, },
8783 { SkipAct11,
GRFUnsafe, SkipAct11, GRFSound, SkipAct11, GRFSound, },
8791 GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.find(location);
8792 if (it == _grf_line_to_action6_sprite_override.end()) {
8798 buf = _grf_line_to_action6_sprite_override[location];
8799 grfmsg(7,
"DecodeSpecialSprite: Using preloaded pseudo sprite data");
8809 byte action = bufp->ReadByte();
8811 if (action == 0xFF) {
8812 grfmsg(2,
"DecodeSpecialSprite: Unexpected data block, skipping");
8813 }
else if (action == 0xFE) {
8814 grfmsg(2,
"DecodeSpecialSprite: Unexpected import block, skipping");
8815 }
else if (action >=
lengthof(handlers)) {
8816 grfmsg(7,
"DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
8817 }
else if (handlers[action][stage] == NULL) {
8818 grfmsg(7,
"DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage);
8820 grfmsg(7,
"DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage);
8821 handlers[action][stage](bufp);
8824 grfmsg(1,
"DecodeSpecialSprite: Tried to read past end of pseudo-sprite data");
8831 extern const byte
_grf_cont_v2_sig[8] = {
'G',
'R',
'F', 0x82, 0x0D, 0x0A, 0x1A, 0x0A};
8844 for (uint i = 0; i <
lengthof(_grf_cont_v2_sig); i++) {
8845 if (
FioReadByte() != _grf_cont_v2_sig[i])
return 0;
8865 const char *filename = config->
filename;
8876 if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
8878 if (_cur.
grffile == NULL)
usererror(
"File '%s' lost in cache.\n", filename);
8884 DEBUG(grf, 0,
"'%s' is not loaded as the maximum number of file slots has been reached", filename);
8886 config->
error =
new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
8896 DEBUG(grf, 2,
"LoadNewGRFFile: Reading NewGRF-file '%s'", filename);
8900 DEBUG(grf, 7,
"LoadNewGRFFile: Custom .grf has invalid format");
8904 if (stage == GLS_INIT || stage == GLS_ACTIVATION) {
8916 if (compression != 0) {
8917 DEBUG(grf, 7,
"LoadNewGRFFile: Unsupported compression format");
8929 DEBUG(grf, 7,
"LoadNewGRFFile: Custom .grf has invalid format");
8943 DecodeSpecialSprite(buf.
Allocate(num), num, stage);
8954 grfmsg(0,
"LoadNewGRFFile: Unexpected sprite, disabling");
8955 DisableGrf(STR_NEWGRF_ERROR_UNEXPECTED_SPRITE);
9020 static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT);
9023 int num_grfs = _grf_files.
Length();
9024 int *grf_overrides =
AllocaM(
int, num_grfs);
9025 for (
int i = 0; i < num_grfs; i++) {
9026 grf_overrides[i] = -1;
9028 GRFFile *source = _grf_files[i];
9029 uint32
override = _grf_id_overrides[source->grfid];
9030 if (
override == 0)
continue;
9033 if (dest == NULL)
continue;
9035 grf_overrides[i] = _grf_files.
FindIndex(dest);
9036 assert(grf_overrides[i] >= 0);
9040 for (
int i = 0; i < num_grfs; i++) {
9041 if (grf_overrides[i] < 0 || grf_overrides[i] >= i)
continue;
9042 GRFFile *source = _grf_files[i];
9043 GRFFile *dest = _grf_files[grf_overrides[i]];
9049 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9052 DEBUG(grf, 3,
"'%s' overrides price base multiplier %d of '%s'", source->filename, p, dest->filename);
9058 for (
int i = num_grfs - 1; i >= 0; i--) {
9059 if (grf_overrides[i] < 0 || grf_overrides[i] <= i)
continue;
9060 GRFFile *source = _grf_files[i];
9061 GRFFile *dest = _grf_files[grf_overrides[i]];
9067 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9070 DEBUG(grf, 3,
"Price base multiplier %d from '%s' propagated to '%s'", p, source->filename, dest->filename);
9076 for (
int i = 0; i < num_grfs; i++) {
9077 if (grf_overrides[i] < 0)
continue;
9078 GRFFile *source = _grf_files[i];
9079 GRFFile *dest = _grf_files[grf_overrides[i]];
9085 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9086 if (!
HasBit(features, _price_base_specs[p].grf_feature))
continue;
9088 DEBUG(grf, 3,
"Price base multiplier %d from '%s' propagated to '%s'", p, dest->filename, source->filename);
9095 const GRFFile *
const *end = _grf_files.
End();
9096 for (
GRFFile **file = _grf_files.
Begin(); file != end; file++) {
9097 if ((*file)->grf_version >= 8)
continue;
9098 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
9099 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9101 if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9104 price_base_multipliers[p] = price_base_multipliers[fallback_price];
9110 for (
GRFFile **file = _grf_files.
Begin(); file != end; file++) {
9111 PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers;
9112 for (
Price p = PR_BEGIN; p < PR_END; p++) {
9113 if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) {
9115 price_base_multipliers[p] = 0;
9120 DEBUG(grf, 3,
"'%s' sets global price base multiplier %d", (*file)->filename, p);
9122 price_base_multipliers[p] = 0;
9124 DEBUG(grf, 3,
"'%s' sets local price base multiplier %d", (*file)->filename, p);
9139 _string_to_grf_mapping.
Clear();
9142 for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) {
9145 _grf_line_to_action6_sprite_override.clear();
9196 FOR_ALL_ENGINES_OF_TYPE(e,
VEH_ROAD) {
9209 e->u.rail.railtype = railtype;
9219 _grm_sprites.clear();
9228 void LoadNewGRF(uint load_index, uint file_index, uint num_baseset)
9268 for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
9275 if (stage == GLS_RESERVE) {
9276 static const uint32 overrides[][2] = {
9277 { 0x44442202, 0x44440111 },
9278 { 0x6D620402, 0x6D620401 },
9279 { 0x4D656f20, 0x4D656F17 },
9281 for (
size_t i = 0; i <
lengthof(overrides); i++) {
9286 uint slot = file_index;
9287 uint num_non_static = 0;
9296 DEBUG(grf, 0,
"NewGRF file is missing '%s'; disabling", c->
filename);
9305 DEBUG(grf, 0,
"'%s' is not loaded as the maximum number of non-static GRFs has been reached", c->
filename);
9307 c->
error =
new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED);
9313 if (stage == GLS_RESERVE) {
9315 }
else if (stage == GLS_ACTIVATION) {
9320 DEBUG(sprite, 2,
"LoadNewGRF: Currently %i sprites are loaded", _cur.
spriteid);