--- a/src/newgrf.cpp Thu Nov 22 23:01:41 2007 +0000
+++ b/src/newgrf.cpp Fri Nov 23 16:59:30 2007 +0000
@@ -45,6 +45,9 @@
#include "newgrf_commons.h"
#include "newgrf_townname.h"
#include "newgrf_industries.h"
+#include "table/landscape_sprite.h"
+#include "gfxinit.h"
+#include "fios.h"
/* TTDPatch extended GRF format codec
* (c) Petr Baudis 2004 (GPL'd)
@@ -58,7 +61,6 @@
static int _skip_sprites; // XXX
static uint _file_index; // XXX
-SpriteID _signal_base;
SpriteID _coast_base;
static GRFFile *_cur_grffile;
@@ -246,6 +248,17 @@
*/
StringID MapGRFStringID(uint32 grfid, StringID str)
{
+ /* StringID table for TextIDs 0x4E->0x6D */
+ static StringID units_volume[] = {
+ STR_NOTHING, STR_PASSENGERS, STR_TONS, STR_BAGS,
+ STR_LITERS, STR_ITEMS, STR_CRATES, STR_TONS,
+ STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
+ STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
+ STR_TONS, STR_TONS, STR_BAGS, STR_LITERS,
+ STR_TONS, STR_LITERS, STR_TONS, STR_NOTHING,
+ STR_BAGS, STR_LITERS, STR_TONS, STR_NOTHING,
+ STR_TONS, STR_NOTHING, STR_LITERS, STR_NOTHING
+ };
/* 0xD0 and 0xDC stand for all the TextIDs in the range
* of 0xD000 (misc graphics texts) and 0xDC00 (misc persistent texts).
* These strings are unique to each grf file, and thus require to be used with the
@@ -257,7 +270,7 @@
/* We have some changes in our cargo strings, resulting in some missing. */
TEXID_TO_STRINGID(0x000E, 0x002D, STR_000E);
TEXID_TO_STRINGID(0x002E, 0x004D, STR_002E);
- TEXID_TO_STRINGID(0x004E, 0x006D, STR_QUANTITY_NOTHING);
+ if (str >= 0x004E && str <= 0x006D) str = units_volume[str - 0x004E];
TEXID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING);
TEXID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING);
@@ -415,7 +428,7 @@
case 0x15: { // Cargo type
uint8 ctype = grf_load_byte(&buf);
- if (ctype < NUM_CARGO && HASBIT(_cargo_mask, ctype)) {
+ if (ctype < NUM_CARGO && HasBit(_cargo_mask, ctype)) {
rvi->cargo_type = ctype;
} else {
rvi->cargo_type = CT_INVALID;
@@ -495,6 +508,12 @@
rvi->tractive_effort = grf_load_byte(&buf);
break;
+ case 0x20: // Air drag
+ /** @todo Air drag for trains. */
+ grf_load_byte(&buf);
+ ret = true;
+ break;
+
case 0x21: // Shorter vehicle
rvi->shorten_factor = grf_load_byte(&buf);
break;
@@ -528,7 +547,7 @@
case 0x27: // Miscellaneous flags
ei->misc_flags = grf_load_byte(&buf);
- _loaded_newgrf_features.has_2CC |= HASBIT(ei->misc_flags, EF_USES_2CC);
+ _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
break;
case 0x28: // Cargo classes allowed
@@ -543,12 +562,6 @@
ei->base_intro = grf_load_dword(&buf);
break;
- case 0x20: // Air drag
- /** @todo Air drag for trains. */
- grf_load_byte(&buf);
- ret = true;
- break;
-
default:
ret = true;
break;
@@ -602,7 +615,7 @@
case 0x10: { // Cargo type
uint8 cargo = grf_load_byte(&buf);
- if (cargo < NUM_CARGO && HASBIT(_cargo_mask, cargo)) {
+ if (cargo < NUM_CARGO && HasBit(_cargo_mask, cargo)) {
rvi->cargo_type = cargo;
} else {
rvi->cargo_type = CT_INVALID;
@@ -636,6 +649,13 @@
ei->callbackmask = grf_load_byte(&buf);
break;
+ case 0x18: // Tractive effort
+ case 0x19: // Air drag
+ /** @todo Tractive effort and air drag for road vehicles. */
+ grf_load_byte(&buf);
+ ret = true;
+ break;
+
case 0x1A: // Refit cost
ei->refit_cost = grf_load_byte(&buf);
break;
@@ -646,7 +666,7 @@
case 0x1C: // Miscellaneous flags
ei->misc_flags = grf_load_byte(&buf);
- _loaded_newgrf_features.has_2CC |= HASBIT(ei->misc_flags, EF_USES_2CC);
+ _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
break;
case 0x1D: // Cargo classes allowed
@@ -661,13 +681,6 @@
ei->base_intro = grf_load_dword(&buf);
break;
- case 0x18: // Tractive effort
- case 0x19: // Air drag
- /** @todo Tractive effort and air drag for road vehicles. */
- grf_load_byte(&buf);
- ret = true;
- break;
-
default:
ret = true;
break;
@@ -714,7 +727,7 @@
case 0x0C: { // Cargo type
uint8 cargo = grf_load_byte(&buf);
- if (cargo < NUM_CARGO && HASBIT(_cargo_mask, cargo)) {
+ if (cargo < NUM_CARGO && HasBit(_cargo_mask, cargo)) {
svi->cargo_type = cargo;
} else {
svi->cargo_type = CT_INVALID;
@@ -746,13 +759,20 @@
ei->refit_cost = grf_load_byte(&buf);
break;
+ case 0x14: // Ocean speed fraction
+ case 0x15: // Canal speed fraction
+ /** @todo Speed fractions for ships on oceans and canals */
+ grf_load_byte(&buf);
+ ret = true;
+ break;
+
case 0x16: // Retire vehicle early
ei->retire_early = grf_load_byte(&buf);
break;
case 0x17: // Miscellaneous flags
ei->misc_flags = grf_load_byte(&buf);
- _loaded_newgrf_features.has_2CC |= HASBIT(ei->misc_flags, EF_USES_2CC);
+ _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
break;
case 0x18: // Cargo classes allowed
@@ -767,13 +787,6 @@
ei->base_intro = grf_load_dword(&buf);
break;
- case 0x14: // Ocean speed fraction
- case 0x15: // Canal speed fraction
- /** @todo Speed fractions for ships on oceans and canals */
- grf_load_byte(&buf);
- ret = true;
- break;
-
default:
ret = true;
break;
@@ -863,7 +876,7 @@
case 0x17: // Miscellaneous flags
ei->misc_flags = grf_load_byte(&buf);
- _loaded_newgrf_features.has_2CC |= HASBIT(ei->misc_flags, EF_USES_2CC);
+ _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC);
break;
case 0x18: // Cargo classes allowed
@@ -935,9 +948,9 @@
dts->ground_sprite = grf_load_word(&buf);
dts->ground_pal = grf_load_word(&buf);
if (dts->ground_sprite == 0) continue;
- if (HASBIT(dts->ground_pal, 15)) {
- CLRBIT(dts->ground_pal, 15);
- SETBIT(dts->ground_sprite, SPRITE_MODIFIER_USE_OFFSET);
+ if (HasBit(dts->ground_pal, 15)) {
+ ClrBit(dts->ground_pal, 15);
+ SetBit(dts->ground_sprite, SPRITE_MODIFIER_USE_OFFSET);
}
while (buf < *bufp + len) {
@@ -958,18 +971,18 @@
dtss->pal = grf_load_word(&buf);
/* Remap flags as ours collide */
- if (HASBIT(dtss->pal, 15)) {
- CLRBIT(dtss->pal, 15);
- SETBIT(dtss->image, SPRITE_MODIFIER_USE_OFFSET);
+ if (HasBit(dtss->pal, 15)) {
+ ClrBit(dtss->pal, 15);
+ SetBit(dtss->image, SPRITE_MODIFIER_USE_OFFSET);
}
- if (HASBIT(dtss->image, 15)) {
- CLRBIT(dtss->image, 15);
- SETBIT(dtss->image, PALETTE_MODIFIER_COLOR);
+ if (HasBit(dtss->image, 15)) {
+ ClrBit(dtss->image, 15);
+ SetBit(dtss->image, PALETTE_MODIFIER_COLOR);
}
- if (HASBIT(dtss->image, 14)) {
- CLRBIT(dtss->image, 14);
- SETBIT(dtss->image, PALETTE_MODIFIER_TRANSPARENT);
+ if (HasBit(dtss->image, 14)) {
+ ClrBit(dtss->image, 14);
+ SetBit(dtss->image, PALETTE_MODIFIER_TRANSPARENT);
}
}
}
@@ -1162,12 +1175,12 @@
SpriteID image = grf_load_word(&buf);
SpriteID pal = grf_load_word(&buf);
- if (HASBIT(pal, 15)) {
- SETBIT(image, PALETTE_MODIFIER_TRANSPARENT);
+ if (HasBit(pal, 15)) {
+ SetBit(image, PALETTE_MODIFIER_TRANSPARENT);
}
/* Clear old color modifer bit */
- CLRBIT(image, 15);
+ ClrBit(image, 15);
bridge->sprite_table[tableid][sprite].sprite = image;
bridge->sprite_table[tableid][sprite].pal = pal;
@@ -1180,7 +1193,7 @@
break;
case 0x0F: // Long format year of availability (year since year 0)
- bridge->avail_year = clamp(grf_load_dword(&buf), MIN_YEAR, MAX_YEAR);
+ bridge->avail_year = Clamp(grf_load_dword(&buf), MIN_YEAR, MAX_YEAR);
break;
default:
@@ -1333,7 +1346,7 @@
continue;
}
- _house_mngr.Add(hid + i, override);
+ _house_mngr.Add(hid + i, _cur_grffile->grfid, override);
} break;
case 0x16: // Periodic refresh multiplier
@@ -1357,7 +1370,7 @@
break;
case 0x1B: // Animation speed
- housespec->animation_speed = clamp(grf_load_byte(&buf), 2, 16);
+ housespec->animation_speed = Clamp(grf_load_byte(&buf), 2, 16);
break;
case 0x1C: // Class of the building type
@@ -1392,6 +1405,12 @@
housespec->minimum_life = grf_load_byte(&buf);
break;
+ case 0x20: { // @todo Cargo acceptance watch list
+ byte count = grf_load_byte(&buf);
+ for (byte j = 0; j < count; j++) grf_load_byte(&buf);
+ ret = true;
+ } break;
+
default:
ret = true;
break;
@@ -1420,11 +1439,21 @@
}
} break;
- case 0x09: // Cargo translation table
- /* This is loaded during the initialisation stage, so just skip it here. */
- /* Each entry is 4 bytes. */
- buf += 4;
- break;
+ case 0x09: { // Cargo translation table
+ if (gvid != 0) {
+ if (i == 0) grfmsg(1, "InitChangeInfo: Cargo translation table must start at zero");
+ /* Skip data */
+ buf += 4;
+ break;
+ }
+ if (i == 0) {
+ free(_cur_grffile->cargo_list);
+ _cur_grffile->cargo_max = numinfo;
+ _cur_grffile->cargo_list = MallocT<CargoLabel>(numinfo);
+ }
+ CargoLabel cl = grf_load_dword(&buf);
+ _cur_grffile->cargo_list[i] = BSWAP32(cl);
+ } break;
case 0x0A: { // Currency display names
uint curidx = GetNewgrfCurrencyIdConverted(gvid + i);
@@ -1543,9 +1572,9 @@
cs->bitnum = grf_load_byte(&buf);
if (cs->IsValid()) {
cs->grfid = _cur_grffile->grfid;
- SETBIT(_cargo_mask, cid + i);
+ SetBit(_cargo_mask, cid + i);
} else {
- CLRBIT(_cargo_mask, cid + i);
+ ClrBit(_cargo_mask, cid + i);
}
break;
@@ -1755,14 +1784,14 @@
return false;
}
- _industile_mngr.Add(indtid + i, ovrid);
+ _industile_mngr.Add(indtid + i, _cur_grffile->grfid, ovrid);
} break;
case 0x0A: // Tile acceptance
case 0x0B:
case 0x0C: {
uint16 acctp = grf_load_word(&buf);
- tsp->accepts_cargo[prop - 0x0A] = GetCargoTranslation(GB(acctp, 0, 8), _cur_grffile);
+ tsp->accepts_cargo[prop - 0x0A] = GB(acctp, 0, 8);
tsp->acceptance[prop - 0x0A] = GB(acctp, 8, 8);
} break;
@@ -1868,7 +1897,7 @@
return false;
}
indsp->grf_prop.override = ovrid;
- _industry_mngr.Add(indid + i, ovrid);
+ _industry_mngr.Add(indid + i, _cur_grffile->grfid, ovrid);
} break;
case 0x0A: { // Set industry layout(s)
@@ -1936,7 +1965,7 @@
}
/* Install final layout construction in the industry spec */
indsp->table = tile_table;
- SETBIT(indsp->cleanup_flag, 1);
+ SetBit(indsp->cleanup_flag, 1);
free(itt);
} break;
@@ -1962,13 +1991,13 @@
case 0x10: // Production cargo types
for (byte j = 0; j < 2; j++) {
- indsp->produced_cargo[j] = GetCargoTranslation(grf_load_byte(&buf), _cur_grffile);
+ indsp->produced_cargo[j] = grf_load_byte(&buf);
}
break;
case 0x11: // Acceptance cargo types
for (byte j = 0; j < 3; j++) {
- indsp->accepts_cargo[j] = GetCargoTranslation(grf_load_byte(&buf), _cur_grffile);
+ indsp->accepts_cargo[j] = grf_load_byte(&buf);
}
grf_load_byte(&buf); // Unnused, eat it up
break;
@@ -1988,7 +2017,7 @@
for (uint8 j = 0; j < indsp->number_of_sounds; j++) sounds[j] = grf_load_byte(&buf);
indsp->random_sounds = sounds;
- SETBIT(indsp->cleanup_flag, 0);
+ SetBit(indsp->cleanup_flag, 0);
} break;
case 0x16: // Conflicting industry types
@@ -2058,7 +2087,7 @@
* 4 for defining new train station sets
* B num-props how many properties to change per vehicle/station
* B num-info how many vehicles/stations to change
- * B id ID of first vehicle/station to change, if num-info is
+ * E id ID of first vehicle/station to change, if num-info is
* greater than one, this one and the following
* vehicles/stations will be changed
* B property what property to change, depends on the feature
@@ -2074,7 +2103,7 @@
/* GSF_CANAL */ NULL,
/* GSF_BRIDGE */ BridgeChangeInfo,
/* GSF_TOWNHOUSE */ TownHouseChangeInfo,
- /* GSF_GLOBALVAR */ GlobalVarChangeInfo,
+ /* GSF_GLOBALVAR */ NULL, /* Global variables are handled during reservation */
/* GSF_INDUSTRYTILES */IndustrytilesChangeInfo,
/* GSF_INDUSTRIES */ IndustriesChangeInfo,
/* GSF_CARGOS */ NULL, /* Cargo is handled during reservation */
@@ -2086,7 +2115,7 @@
uint8 feature = grf_load_byte(&buf);
uint8 numprops = grf_load_byte(&buf);
uint numinfo = grf_load_byte(&buf);
- uint engine = grf_load_byte(&buf);
+ uint engine = grf_load_extended(&buf);
grfmsg(6, "FeatureChangeInfo: feature %d, %d properties, to apply to %d+%d",
feature, numprops, engine, numinfo);
@@ -2173,8 +2202,8 @@
buf++;
uint8 feature = grf_load_byte(&buf);
uint8 numprops = grf_load_byte(&buf);
- grf_load_byte(&buf);
- grf_load_byte(&buf);
+ grf_load_byte(&buf); // num-info
+ grf_load_extended(&buf); // id
if (feature == GSF_BRIDGE && numprops == 1) {
uint8 prop = grf_load_byte(&buf);
@@ -2183,51 +2212,12 @@
if (prop == 0x0D) return;
}
- SETBIT(_cur_grfconfig->flags, GCF_UNSAFE);
+ SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
/* Skip remainder of GRF */
_skip_sprites = -1;
}
-/* Action 0x00 (GLS_INIT) */
-static void InitChangeInfo(byte *buf, int len)
-{
- byte *bufend = buf + len;
-
- if (!check_length(len, 6, "InitChangeInfo")) return;
- buf++;
- uint8 feature = grf_load_byte(&buf);
- uint8 numprops = grf_load_byte(&buf);
- uint8 numinfo = grf_load_byte(&buf);
- uint8 index = grf_load_byte(&buf);
-
- while (numprops-- && buf < bufend) {
- uint8 prop = grf_load_byte(&buf);
-
- switch (feature) {
- case GSF_GLOBALVAR:
- switch (prop) {
- case 0x09: // Cargo Translation Table
- if (index != 0) {
- grfmsg(1, "InitChangeInfo: Cargo translation table must start at zero");
- return;
- }
-
- free(_cur_grffile->cargo_list);
- _cur_grffile->cargo_max = numinfo;
- _cur_grffile->cargo_list = MallocT<CargoLabel>(numinfo);
-
- for (uint i = 0; i < numinfo; i++) {
- CargoLabel cl = grf_load_dword(&buf);
- _cur_grffile->cargo_list[i] = BSWAP32(cl);
- }
- break;
- }
- break;
- }
- }
-}
-
/* Action 0x00 (GLS_RESERVE) */
static void ReserveChangeInfo(byte *buf, int len)
{
@@ -2237,18 +2227,27 @@
buf++;
uint8 feature = grf_load_byte(&buf);
- if (feature != GSF_CARGOS) return;
+ if (feature != GSF_CARGOS && feature != GSF_GLOBALVAR) return;
uint8 numprops = grf_load_byte(&buf);
uint8 numinfo = grf_load_byte(&buf);
- uint8 index = grf_load_byte(&buf);
+ uint8 index = grf_load_extended(&buf);
while (numprops-- && buf < bufend) {
uint8 prop = grf_load_byte(&buf);
-
- if (CargoChangeInfo(index, numinfo, prop, &buf, bufend - buf)) {
- grfmsg(2, "ReserveChangeInfo: Ignoring property 0x%02X (not implemented)", prop);
+ bool ignoring = false;
+
+ switch (feature) {
+ default: NOT_REACHED();
+ case GSF_CARGOS:
+ ignoring = CargoChangeInfo(index, numinfo, prop, &buf, bufend - buf);
+ break;
+ case GSF_GLOBALVAR:
+ ignoring = GlobalVarChangeInfo(index, numinfo, prop, &buf, bufend - buf);
+ break;
}
+
+ if (ignoring) grfmsg(2, "ReserveChangeInfo: Ignoring property 0x%02X (not implemented)", prop);
}
}
@@ -2345,7 +2344,7 @@
* defined spritegroup. */
static const SpriteGroup* GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
{
- if (HASBIT(groupid, 15)) return NewCallBackResultSpriteGroup(groupid);
+ if (HasBit(groupid, 15)) return NewCallBackResultSpriteGroup(groupid);
if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid);
@@ -2358,7 +2357,7 @@
/* Helper function to either create a callback or a result sprite group. */
static const SpriteGroup* CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid, uint16 num_sprites)
{
- if (HASBIT(spriteid, 15)) return NewCallBackResultSpriteGroup(spriteid);
+ if (HasBit(spriteid, 15)) return NewCallBackResultSpriteGroup(spriteid);
if (spriteid >= _cur_grffile->spriteset_numsets) {
grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid, max %u", setid, type, spriteid, _cur_grffile->spriteset_numsets);
@@ -2434,7 +2433,7 @@
group = AllocateSpriteGroup();
group->type = SGT_DETERMINISTIC;
- group->g.determ.var_scope = HASBIT(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
+ group->g.determ.var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
switch (GB(type, 2, 2)) {
default: NOT_REACHED();
@@ -2483,7 +2482,7 @@
}
/* Continue reading var adjusts while bit 5 is set. */
- } while (HASBIT(varadjust, 5));
+ } while (HasBit(varadjust, 5));
group->g.determ.num_ranges = grf_load_byte(&buf);
if (group->g.determ.num_ranges > 0) group->g.determ.ranges = CallocT<DeterministicSpriteGroupRange>(group->g.determ.num_ranges);
@@ -2508,11 +2507,11 @@
group = AllocateSpriteGroup();
group->type = SGT_RANDOMIZED;
- group->g.random.var_scope = HASBIT(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
+ group->g.random.var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
uint8 triggers = grf_load_byte(&buf);
group->g.random.triggers = GB(triggers, 0, 7);
- group->g.random.cmp_mode = HASBIT(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
+ group->g.random.cmp_mode = HasBit(triggers, 7) ? RSG_CMP_ALL : RSG_CMP_ANY;
group->g.random.lowest_randbit = grf_load_byte(&buf);
group->g.random.num_groups = grf_load_byte(&buf);
group->g.random.groups = CallocT<const SpriteGroup*>(group->g.random.num_groups);
@@ -2592,24 +2591,24 @@
group->g.layout.dts->ground_sprite = grf_load_word(&buf);
group->g.layout.dts->ground_pal = grf_load_word(&buf);
/* Remap transparent/colour modifier bits */
- if (HASBIT(group->g.layout.dts->ground_sprite, 14)) {
- CLRBIT(group->g.layout.dts->ground_sprite, 14);
- SETBIT(group->g.layout.dts->ground_sprite, PALETTE_MODIFIER_TRANSPARENT);
+ if (HasBit(group->g.layout.dts->ground_sprite, 14)) {
+ ClrBit(group->g.layout.dts->ground_sprite, 14);
+ SetBit(group->g.layout.dts->ground_sprite, PALETTE_MODIFIER_TRANSPARENT);
}
- if (HASBIT(group->g.layout.dts->ground_sprite, 15)) {
- CLRBIT(group->g.layout.dts->ground_sprite, 15);
- SETBIT(group->g.layout.dts->ground_sprite, PALETTE_MODIFIER_COLOR);
+ if (HasBit(group->g.layout.dts->ground_sprite, 15)) {
+ ClrBit(group->g.layout.dts->ground_sprite, 15);
+ SetBit(group->g.layout.dts->ground_sprite, PALETTE_MODIFIER_COLOR);
}
- if (HASBIT(group->g.layout.dts->ground_pal, 14)) {
- CLRBIT(group->g.layout.dts->ground_pal, 14);
- SETBIT(group->g.layout.dts->ground_sprite, SPRITE_MODIFIER_OPAQUE);
+ if (HasBit(group->g.layout.dts->ground_pal, 14)) {
+ ClrBit(group->g.layout.dts->ground_pal, 14);
+ SetBit(group->g.layout.dts->ground_sprite, SPRITE_MODIFIER_OPAQUE);
}
- if (HASBIT(group->g.layout.dts->ground_pal, 15)) {
+ if (HasBit(group->g.layout.dts->ground_pal, 15)) {
/* Bit 31 set means this is a custom sprite, so rewrite it to the
* last spriteset defined. */
SpriteID sprite = _cur_grffile->spriteset_start + GB(group->g.layout.dts->ground_sprite, 0, 14) * sprites;
SB(group->g.layout.dts->ground_sprite, 0, SPRITE_WIDTH, sprite);
- CLRBIT(group->g.layout.dts->ground_pal, 15);
+ ClrBit(group->g.layout.dts->ground_pal, 15);
}
group->g.layout.dts->seq = CallocT<DrawTileSeqStruct>(num_sprites + 1);
@@ -2622,24 +2621,24 @@
seq->delta_x = grf_load_byte(&buf);
seq->delta_y = grf_load_byte(&buf);
- if (HASBIT(seq->image, 14)) {
- CLRBIT(seq->image, 14);
- SETBIT(seq->image, PALETTE_MODIFIER_TRANSPARENT);
+ if (HasBit(seq->image, 14)) {
+ ClrBit(seq->image, 14);
+ SetBit(seq->image, PALETTE_MODIFIER_TRANSPARENT);
}
- if (HASBIT(seq->image, 15)) {
- CLRBIT(seq->image, 15);
- SETBIT(seq->image, PALETTE_MODIFIER_COLOR);
+ if (HasBit(seq->image, 15)) {
+ ClrBit(seq->image, 15);
+ SetBit(seq->image, PALETTE_MODIFIER_COLOR);
}
- if (HASBIT(seq->pal, 14)) {
- CLRBIT(seq->pal, 14);
- SETBIT(seq->image, SPRITE_MODIFIER_OPAQUE);
+ if (HasBit(seq->pal, 14)) {
+ ClrBit(seq->pal, 14);
+ SetBit(seq->image, SPRITE_MODIFIER_OPAQUE);
}
- if (HASBIT(seq->pal, 15)) {
+ if (HasBit(seq->pal, 15)) {
/* Bit 31 set means this is a custom sprite, so rewrite it to the
* last spriteset defined. */
SpriteID sprite = _cur_grffile->spriteset_start + GB(seq->image, 0, 14) * sprites;
SB(seq->image, 0, SPRITE_WIDTH, sprite);
- CLRBIT(seq->pal, 15);
+ ClrBit(seq->pal, 15);
}
if (type > 0) {
@@ -3122,10 +3121,10 @@
uint8 feature = grf_load_byte(&buf);
uint8 lang = grf_load_byte(&buf);
uint8 num = grf_load_byte(&buf);
- bool generic = HASBIT(lang, 7);
+ bool generic = HasBit(lang, 7);
uint16 id = generic ? grf_load_word(&buf) : grf_load_byte(&buf);
- CLRBIT(lang, 7);
+ ClrBit(lang, 7);
if (feature <= GSF_AIRCRAFT && id < _vehcounts[feature]) {
id += _vehshifts[feature];
@@ -3221,6 +3220,34 @@
}
}
+/**
+ * Sanitize incoming sprite offsets for Action 5 graphics replacements.
+ * @param num the number of sprites to load.
+ * @param offset offset from the base.
+ * @param max_sprites the maximum number of sprites that can be loaded in this action 5.
+ * @param name used for error warnings.
+ * @return the number of sprites that is going to be skipped
+ */
+static uint16 SanitizeSpriteOffset(uint16& num, uint16 offset, int max_sprites, const char *name)
+{
+
+ if (offset >= max_sprites) {
+ grfmsg(1, "GraphicsNew: %s sprite offset must be less than %i, skipping", name, max_sprites);
+ uint orig_num = num;
+ num = 0;
+ return orig_num;
+ }
+
+ if (offset + num > max_sprites) {
+ grfmsg(4, "GraphicsNew: %s sprite overflow, truncating...", name);
+ uint orig_num = num;
+ num = max(max_sprites - offset, 0);
+ return orig_num - num;
+ }
+
+ return 0;
+}
+
/* Action 0x05 */
static void GraphicsNew(byte *buf, int len)
{
@@ -3237,42 +3264,47 @@
buf++;
uint8 type = grf_load_byte(&buf);
uint16 num = grf_load_extended(&buf);
+ uint16 skip_num = 0;
+ uint16 offset = HasBit(type, 7) ? grf_load_extended(&buf) : 0;
+ ClrBit(type, 7); // Clear the high bit as that only indicates whether there is an offset.
switch (type) {
case 0x04: // Signal graphics
- if (num != 112 && num != 240) {
- grfmsg(1, "GraphicsNew: Signal graphics sprite count must be 112 or 240, skipping");
+ if (num != PRESIGNAL_SPRITE_COUNT && num != PRESIGNAL_AND_SEMAPHORE_SPRITE_COUNT && num != PRESIGNAL_SEMAPHORE_AND_PBS_SPRITE_COUNT) {
+ grfmsg(1, "GraphicsNew: Signal graphics sprite count must be 48, 112 or 240, skipping");
return;
}
- _signal_base = _cur_spriteid;
+ replace = SPR_SIGNALS_BASE;
break;
case 0x05: // Catenary graphics
- if (num != 48) {
+ if (num != ELRAIL_SPRITE_COUNT) {
grfmsg(1, "GraphicsNew: Catenary graphics sprite count must be 48, skipping");
return;
}
- replace = SPR_ELRAIL_BASE + 3;
+ replace = SPR_ELRAIL_BASE;
break;
case 0x06: // Foundations
- if (num != 74) {
- grfmsg(1, "GraphicsNew: Foundation graphics sprite count must be 74, skipping");
+ if (num != NORMAL_FOUNDATION_SPRITE_COUNT && num != NORMAL_AND_HALFTILE_FOUNDATION_SPRITE_COUNT) {
+ grfmsg(1, "GraphicsNew: Foundation graphics sprite count must be 74 or 90, skipping");
return;
}
- replace = SPR_SLOPES_BASE;
+ replace = SPR_SLOPES_BASE; break;
break;
+ /* case 0x07: // TTDP GUI sprites. Not used by OTTD. */
+
case 0x08: // Canal graphics
- if (num != 65) {
+ if (num != CANALS_SPRITE_COUNT) {
grfmsg(1, "GraphicsNew: Canal graphics sprite count must be 65, skipping");
return;
}
- replace = SPR_CANALS_BASE + 5;
+ replace = SPR_CANALS_BASE;
break;
case 0x09: // One way graphics
- if (num != 6) {
+ if (num != ONEWAY_SPRITE_COUNT) {
grfmsg(1, "GraphicsNew: One way road graphics sprite count must be 6, skipping");
return;
}
@@ -3280,7 +3312,7 @@
break;
case 0x0A: // 2CC colour maps
- if (num != 256) {
+ if (num != TWOCCMAP_SPRITE_COUNT) {
grfmsg(1, "GraphicsNew: 2CC colour maps sprite count must be 256, skipping");
return;
}
@@ -3288,23 +3320,30 @@
break;
case 0x0B: // tramways
- if (num != 113) {
+ if (num != TRAMWAY_SPRITE_COUNT) {
grfmsg(1, "GraphicsNew: Tramway graphics sprite count must be 113, skipping");
return;
}
replace = SPR_TRAMWAY_BASE;
break;
+ /* case 0x0C: // Snowy temperate trees. Not yet used by OTTD. */
+
case 0x0D: // Coast graphics
if (num != 16) {
grfmsg(1, "GraphicsNew: Coast graphics sprite count must be 16, skipping");
return;
}
_coast_base = _cur_spriteid;
+ _loaded_newgrf_features.has_newwater = true;
break;
+ /* case 0x0E: // New Signals. Not yet used by OTTD. */
+
+ /* case 0x0F: // Tracks for marking sloped rail. Not yet used by OTTD. */
+
case 0x10: // New airport sprites
- if (num != 15) {
+ if (num != AIRPORTX_SPRITE_COUNT) {
grfmsg(1, "GraphicsNew: Airport graphics sprite count must be 15, skipping");
return;
}
@@ -3312,13 +3351,33 @@
break;
case 0x11: // Road stop sprites
- if (num != 8) {
+ if (num != ROADSTOP_SPRITE_COUNT) {
grfmsg(1, "GraphicsNew: Road stop graphics sprite count must be 8, skipping");
return;
}
replace = SPR_ROADSTOP_BASE;
break;
+ /* case 0x12: // Aqueduct sprites. Not yet used by OTTD. */
+
+ case 0x13: // Autorail sprites
+ if (num != AUTORAIL_SPRITE_COUNT) {
+ grfmsg(1, "GraphicsNew: Autorail graphics sprite count must be 55, skipping");
+ return;
+ }
+ replace = SPR_AUTORAIL_BASE;
+ break;
+
+ case 0x14: // Flag sprites
+ skip_num = SanitizeSpriteOffset(num, offset, FLAGS_SPRITE_COUNT, "Flag graphics");
+ replace = SPR_FLAGS_BASE + offset;
+ break;
+
+ case 0x15: // OpenTTD GUI sprites
+ skip_num = SanitizeSpriteOffset(num, offset, OPENTTD_SPRITE_COUNT, "OpenTTD graphics");
+ replace = SPR_OPENTTD_BASE + offset;
+ break;
+
default:
grfmsg(2, "GraphicsNew: Custom graphics (type 0x%02X) sprite block of length %u (unimplemented, ignoring)",
type, num);
@@ -3336,6 +3395,8 @@
LoadNextSprite(replace == 0 ? _cur_spriteid++ : replace++, _file_index, _nfo_line);
_nfo_line++;
}
+
+ _skip_sprites = skip_num;
}
/* Action 0x05 (SKIP) */
@@ -3357,7 +3418,7 @@
{
switch (param) {
case 0x81: // current year
- return clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
+ return Clamp(_cur_year, ORIGINAL_BASE_YEAR, ORIGINAL_MAX_YEAR) - ORIGINAL_BASE_YEAR;
case 0x83: // current climate, 0=temp, 1=arctic, 2=trop, 3=toyland
return _opt.landscape;
@@ -3365,9 +3426,9 @@
case 0x84: { // GRF loading stage
uint32 res = 0;
- if (_cur_stage > GLS_INIT) SETBIT(res, 0);
- if (_cur_stage == GLS_RESERVE) SETBIT(res, 8);
- if (_cur_stage == GLS_ACTIVATION) SETBIT(res, 9);
+ if (_cur_stage > GLS_INIT) SetBit(res, 0);
+ if (_cur_stage == GLS_RESERVE) SetBit(res, 8);
+ if (_cur_stage == GLS_ACTIVATION) SetBit(res, 9);
return res;
}
@@ -3413,6 +3474,11 @@
case 0x9E: // Miscellaneous GRF features
return _misc_grf_features;
+ case 0xA1: { // OpenTTD version
+ extern uint32 _openttd_newgrf_version;
+ return _openttd_newgrf_version;
+ }
+
default:
/* GRF Parameter */
if (param < 0x80) return _cur_grffile->param[param];
@@ -3476,7 +3542,7 @@
/* Bit 7 of param_size indicates we should add to the original value
* instead of replacing it. */
- add_value = HASBIT(param_size, 7);
+ add_value = HasBit(param_size, 7);
param_size = GB(param_size, 0, 7);
/* Where to apply the data to within the pseudo sprite data. */
@@ -3553,7 +3619,14 @@
grfmsg(7, "SkipIf: Test condtype %d, param 0x%08X, condval 0x%08X", condtype, param_val, cond_val);
- if (param == 0x88) {
+ /*
+ * Parameter (variable in specs) 0x88 can only have GRF ID checking
+ * conditions, except conditions 0x0B and 0x0C (cargo availability)
+ * as those ignore the parameter. So, when the condition type is
+ * either of those, the specific variable 0x88 code is skipped, so
+ * the "general" code for the cargo availability conditions kicks in.
+ */
+ if (param == 0x88 && condtype != 0x0B && condtype != 0x0C) {
/* GRF ID checks */
const GRFConfig *c = GetGRFConfig(cond_val);
@@ -3564,51 +3637,51 @@
}
switch (condtype) {
- /* Tests 6 to 10 are only for param 0x88, GRFID checks */
- case 6: // Is GRFID active?
+ /* Tests 0x06 to 0x0A are only for param 0x88, GRFID checks */
+ case 0x06: // Is GRFID active?
result = c->status == GCS_ACTIVATED;
break;
- case 7: // Is GRFID non-active?
+ case 0x07: // Is GRFID non-active?
result = c->status != GCS_ACTIVATED;
break;
- case 8: // GRFID is not but will be active?
+ case 0x08: // GRFID is not but will be active?
result = c->status == GCS_INITIALISED;
break;
- case 9: // GRFID is or will be active?
+ case 0x09: // GRFID is or will be active?
result = c->status == GCS_ACTIVATED || c->status == GCS_INITIALISED;
break;
- case 10: // GRFID is not nor will be active
+ case 0x0A: // GRFID is not nor will be active
/* This is the only condtype that doesn't get ignored if the GRFID is not found */
result = c == NULL || c->flags == GCS_DISABLED || c->status == GCS_NOT_FOUND;
break;
- default: grfmsg(1, "SkipIf: Unsupported GRF test %d. Ignoring", condtype); return;
+ default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return;
}
} else {
/* Parameter or variable tests */
switch (condtype) {
- case 0: result = !!(param_val & (1 << cond_val));
- break;
- case 1: result = !(param_val & (1 << cond_val));
- break;
- case 2: result = (param_val & mask) == cond_val;
- break;
- case 3: result = (param_val & mask) != cond_val;
- break;
- case 4: result = (param_val & mask) < cond_val;
- break;
- case 5: result = (param_val & mask) > cond_val;
- break;
- case 11: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
- break;
- case 12: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
- break;
-
- default: grfmsg(1, "SkipIf: Unsupported test %d. Ignoring", condtype); return;
+ case 0x00: result = !!(param_val & (1 << cond_val));
+ break;
+ case 0x01: result = !(param_val & (1 << cond_val));
+ break;
+ case 0x02: result = (param_val & mask) == cond_val;
+ break;
+ case 0x03: result = (param_val & mask) != cond_val;
+ break;
+ case 0x04: result = (param_val & mask) < cond_val;
+ break;
+ case 0x05: result = (param_val & mask) > cond_val;
+ break;
+ case 0x0B: result = GetCargoIDByLabel(BSWAP32(cond_val)) == CT_INVALID;
+ break;
+ case 0x0C: result = GetCargoIDByLabel(BSWAP32(cond_val)) != CT_INVALID;
+ break;
+
+ default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return;
}
}
@@ -3670,7 +3743,7 @@
_cur_grfconfig->grfid = grfid;
/* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
- if (GB(grfid, 24, 8) == 0xFF) SETBIT(_cur_grfconfig->flags, GCF_SYSTEM);
+ if (GB(grfid, 24, 8) == 0xFF) SetBit(_cur_grfconfig->flags, GCF_SYSTEM);
len -= 6;
const char *name = grf_load_string(&buf, len);
@@ -3779,7 +3852,8 @@
STR_NEWGRF_ERROR_UNSET_SWITCH,
STR_NEWGRF_ERROR_INVALID_PARAMETER,
STR_NEWGRF_ERROR_LOAD_BEFORE,
- STR_NEWGRF_ERROR_LOAD_AFTER
+ STR_NEWGRF_ERROR_LOAD_AFTER,
+ STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER,
};
static const StringID sevstr[] = {
@@ -3805,11 +3879,11 @@
/* Skip the error until the activation stage unless bit 7 of the severity
* is set. */
- if (!HASBIT(severity, 7) && _cur_stage == GLS_INIT) {
+ if (!HasBit(severity, 7) && _cur_stage == GLS_INIT) {
grfmsg(7, "GRFLoadError: Skipping non-fatal GRFLoadError in stage %d", _cur_stage);
return;
}
- CLRBIT(severity, 7);
+ ClrBit(severity, 7);
if (severity >= lengthof(sevstr)) {
grfmsg(7, "GRFLoadError: Invalid severity id %d. Setting to 2 (non-fatal error).", severity);
@@ -3893,7 +3967,7 @@
* reserved, it would be marked unsafe anyway. GRM for (e.g. bridge)
* sprites is considered safe. */
- SETBIT(_cur_grfconfig->flags, GCF_UNSAFE);
+ SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
/* Skip remainder of GRF */
_skip_sprites = -1;
@@ -4010,7 +4084,7 @@
* - it has been set to any value in the newgrf(w).cfg parameter list
* - it OR A PARAMETER WITH HIGHER NUMBER has been set to any value by
* an earlier action D */
- if (HASBIT(oper, 7)) {
+ if (HasBit(oper, 7)) {
if (target < 0x80 && target < _cur_grffile->param_end) {
grfmsg(7, "ParamSet: Param %u already defined, skipping", target);
return;
@@ -4248,7 +4322,7 @@
/* GRF is unsafe it if tries to deactivate other GRFs */
if (grfid != _cur_grfconfig->grfid) {
- SETBIT(_cur_grfconfig->flags, GCF_UNSAFE);
+ SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
/* Skip remainder of GRF */
_skip_sprites = -1;
@@ -4304,9 +4378,9 @@
len--;
grfmsg(6, "FeatureTownName: definition 0x%02X", id & 0x7F);
- if (HASBIT(id, 7)) {
+ if (HasBit(id, 7)) {
/* Final definition */
- CLRBIT(id, 7);
+ ClrBit(id, 7);
bool new_scheme = _cur_grffile->grf_version >= 7;
if (!check_length(len, 1, "FeatureTownName: lang_id")) return;
@@ -4315,7 +4389,7 @@
byte nb_gen = townname->nb_gen;
do {
- CLRBIT(lang, 7);
+ ClrBit(lang, 7);
if (!check_length(len, 1, "FeatureTownName: style name")) return;
const char *name = grf_load_string(&buf, len);
@@ -4356,7 +4430,7 @@
byte prob = grf_load_byte(&buf);
len--;
- if (HASBIT(prob, 7)) {
+ if (HasBit(prob, 7)) {
byte ref_id = grf_load_byte(&buf);
len--;
@@ -4671,7 +4745,7 @@
/* Used during safety scan on unsafe actions */
static void GRFUnsafe(byte *buf, int len)
{
- SETBIT(_cur_grfconfig->flags, GCF_UNSAFE);
+ SetBit(_cur_grfconfig->flags, GCF_UNSAFE);
/* Skip remainder of GRF */
_skip_sprites = -1;
@@ -4828,12 +4902,12 @@
if (ind != NULL) {
/* We need to remove the sounds array */
- if (HASBIT(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
+ if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
free((void*)ind->random_sounds);
}
/* We need to remove the tiles layouts */
- if (HASBIT(ind->cleanup_flag, CLEAN_TILELSAYOUT) && ind->table != NULL) {
+ if (HasBit(ind->cleanup_flag, CLEAN_TILELSAYOUT) && ind->table != NULL) {
for (int j = 0; j < ind->num_table; j++) {
/* remove the individual layouts */
if (ind->table[j] != NULL) {
@@ -4887,7 +4961,7 @@
static void ResetNewGRFErrors()
{
for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
- if (!HASBIT(c->flags, GCF_COPY) && c->error != NULL) {
+ if (!HasBit(c->flags, GCF_COPY) && c->error != NULL) {
free(c->error->custom_message);
free(c->error->data);
free(c->error);
@@ -4984,8 +5058,7 @@
_loaded_newgrf_features.has_2CC = false;
_loaded_newgrf_features.has_newhouses = false;
_loaded_newgrf_features.has_newindustries = false;
-
- _signal_base = 0;
+ _loaded_newgrf_features.has_newwater = false;
_coast_base = 0;
InitializeSoundPool();
@@ -5112,12 +5185,12 @@
/* Apply cargo translation table to the refit mask */
uint num_cargo = min(32, file->cargo_max);
for (uint i = 0; i < num_cargo; i++) {
- if (!HASBIT(_engine_info[engine].refit_mask, i)) continue;
+ if (!HasBit(_engine_info[engine].refit_mask, i)) continue;
CargoID c = GetCargoIDByLabel(file->cargo_list[i]);
if (c == CT_INVALID) continue;
- SETBIT(xor_mask, c);
+ SetBit(xor_mask, c);
}
} else {
/* No cargo table, so use the cargo bitnum values */
@@ -5125,7 +5198,7 @@
const CargoSpec *cs = GetCargo(c);
if (!cs->IsValid()) continue;
- if (HASBIT(_engine_info[engine].refit_mask, cs->bitnum)) SETBIT(xor_mask, c);
+ if (HasBit(_engine_info[engine].refit_mask, cs->bitnum)) SetBit(xor_mask, c);
}
}
}
@@ -5134,8 +5207,8 @@
/* Build up the list of cargo types from the set cargo classes. */
for (CargoID i = 0; i < NUM_CARGO; i++) {
const CargoSpec *cs = GetCargo(i);
- if (cargo_allowed[engine] & cs->classes) SETBIT(mask, i);
- if (cargo_disallowed[engine] & cs->classes) SETBIT(not_mask, i);
+ if (cargo_allowed[engine] & cs->classes) SetBit(mask, i);
+ if (cargo_disallowed[engine] & cs->classes) SetBit(not_mask, i);
}
} else {
/* Don't apply default refit mask to wagons or engines with no capacity */
@@ -5152,7 +5225,7 @@
CargoID cargo = GetCargoIDByLabel(cl[i]);
if (cargo == CT_INVALID) continue;
- SETBIT(xor_mask, cargo);
+ SetBit(xor_mask, cargo);
}
}
}
@@ -5250,6 +5323,15 @@
strid = GetGRFStringID(indsp->grf_prop.grffile->grfid, indsp->new_industry_text);
if (strid != STR_UNDEFINED) indsp->new_industry_text = strid;
+ for (byte j = 0; j < 2; j++) {
+ CargoID c = GetCargoTranslation(indsp->produced_cargo[j], indsp->grf_prop.grffile);
+ indsp->produced_cargo[j] = c;
+ }
+ for (byte j = 0; j < 3; j++) {
+ CargoID c = GetCargoTranslation(indsp->accepts_cargo[j], indsp->grf_prop.grffile);
+ indsp->accepts_cargo[j] = c;
+ }
+
_industry_mngr.SetEntitySpec(indsp);
_loaded_newgrf_features.has_newindustries = true;
}
@@ -5260,6 +5342,10 @@
for (int i = 0; i < NUM_INDUSTRYTILES; i++) {
IndustryTileSpec *indtsp = file->indtspec[i];
if (indtsp != NULL) {
+ for (byte j = 0; j < 3; j++) {
+ CargoID c = GetCargoTranslation(indtsp->accepts_cargo[j], indtsp->grf_prop.grffile);
+ indtsp->accepts_cargo[j] = c;
+ }
_industile_mngr.SetEntitySpec(indtsp);
}
}
@@ -5316,7 +5402,7 @@
* is not in memory and scanning the file every time would be too expensive.
* In other stages we skip action 0x10 since it's already dealt with. */
static const SpecialSpriteHandler handlers[][GLS_END] = {
- /* 0x00 */ { NULL, SafeChangeInfo, NULL, InitChangeInfo, ReserveChangeInfo, FeatureChangeInfo, },
+ /* 0x00 */ { NULL, SafeChangeInfo, NULL, NULL, ReserveChangeInfo, FeatureChangeInfo, },
/* 0x01 */ { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, },
/* 0x02 */ { NULL, NULL, NULL, NULL, NULL, NewSpriteGroup, },
/* 0x03 */ { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, },
@@ -5362,7 +5448,7 @@
grfmsg(7, "DecodeSpecialSprite: Handling data block in stage %d", stage);
GRFDataBlock(buf, num);
} else if (action == 0xFE) {
- grfmsg(7, "DecodeSpecialSprite: andling import block in stage %d", stage);
+ grfmsg(7, "DecodeSpecialSprite: Handling import block in stage %d", stage);
GRFImportBlock(buf, num);
} else if (action >= lengthof(handlers)) {
grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action);
@@ -5394,7 +5480,16 @@
_cur_grffile = GetFileByFilename(filename);
if (_cur_grffile == NULL) error("File '%s' lost in cache.\n", filename);
if (stage == GLS_RESERVE && config->status != GCS_INITIALISED) return;
- if (stage == GLS_ACTIVATION && config->status != GCS_INITIALISED) return;
+ if (stage == GLS_ACTIVATION && !HasBit(config->flags, GCF_RESERVED)) return;
+ }
+
+ if (file_index > LAST_GRF_SLOT) {
+ DEBUG(grf, 0, "'%s' is not loaded as the maximum number of GRFs has been reached", filename);
+ config->status = GCS_DISABLED;
+ config->error = CallocT<GRFError>(1);
+ config->error->severity = STR_NEWGRF_ERROR_MSG_FATAL;
+ config->error->message = STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED;
+ return;
}
FioOpenFile(file_index, filename);
@@ -5504,30 +5599,27 @@
/* Load newgrf sprites
* in each loading stage, (try to) open each file specified in the config
* and load information from it. */
- for (GrfLoadingStage stage = GLS_LABELSCAN; stage < GLS_ACTIVATION; stage++) {
+ for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) {
uint slot = file_index;
_cur_stage = stage;
_cur_spriteid = load_index;
for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue;
- if (stage > GLS_INIT && HASBIT(c->flags, GCF_INIT_ONLY)) continue;
+ if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue;
/* @todo usererror() */
if (!FioCheckFileExists(c->filename)) error("NewGRF file is missing '%s'", c->filename);
if (stage == GLS_LABELSCAN) InitNewGRFFile(c, _cur_spriteid);
- LoadNewGRFFile(c, slot, stage);
+ LoadNewGRFFile(c, slot++, stage);
if (stage == GLS_RESERVE) {
- if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED;
- _cur_stage = GLS_ACTIVATION;
- LoadNewGRFFile(c, slot++, GLS_ACTIVATION);
- _cur_stage = stage;
+ SetBit(c->flags, GCF_RESERVED);
+ } else if (stage == GLS_ACTIVATION) {
+ ClrBit(c->flags, GCF_RESERVED);
ClearTemporaryNewGRFData();
BuildCargoTranslationMap();
DEBUG(sprite, 2, "LoadNewGRF: Currently %i sprites are loaded", _cur_spriteid);
- } else {
- slot++;
}
}
}
@@ -5538,5 +5630,5 @@
bool HasGrfMiscBit(GrfMiscBit bit)
{
- return HASBIT(_misc_grf_features, bit);
+ return HasBit(_misc_grf_features, bit);
}