summaryrefslogtreecommitdiff
path: root/src/newgrf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/newgrf.cpp')
-rw-r--r--src/newgrf.cpp104
1 files changed, 77 insertions, 27 deletions
diff --git a/src/newgrf.cpp b/src/newgrf.cpp
index 3be403a67..5a0d9098b 100644
--- a/src/newgrf.cpp
+++ b/src/newgrf.cpp
@@ -61,7 +61,6 @@
static int _skip_sprites; // XXX
static uint _file_index; // XXX
-SpriteID _signal_base;
SpriteID _coast_base;
static GRFFile *_cur_grffile;
@@ -3241,6 +3240,34 @@ static void FeatureNewName(byte *buf, int len)
}
}
+/**
+ * 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)
{
@@ -3252,50 +3279,52 @@ static void GraphicsNew(byte *buf, int len)
/* TODO */
SpriteID replace = 0;
- const SpriteID *index_tbl = NULL;
if (!check_length(len, 2, "GraphicsNew")) return;
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
- switch (num) {
- case 74: replace = SPR_SLOPES_BASE; break;
- case 90: index_tbl = _slopes_action05_90; break;
- default:
- grfmsg(1, "GraphicsNew: Foundation graphics sprite count must be 74 or 90, skipping");
- return;
+ 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; 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;
}
@@ -3303,7 +3332,7 @@ static void GraphicsNew(byte *buf, int len)
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;
}
@@ -3311,13 +3340,15 @@ static void GraphicsNew(byte *buf, int len)
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");
@@ -3327,8 +3358,12 @@ static void GraphicsNew(byte *buf, int len)
_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;
}
@@ -3336,13 +3371,33 @@ static void GraphicsNew(byte *buf, int len)
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);
@@ -3350,12 +3405,6 @@ static void GraphicsNew(byte *buf, int len)
return;
}
- if (index_tbl != NULL) {
- grfmsg(2, "GraphicsNew: Loading %u sprites of type 0x%02X at indexed SpriteIDs", num, type);
- LoadSpritesIndexed(_file_index, &_nfo_line, index_tbl);
- return;
- }
-
if (replace == 0) {
grfmsg(2, "GraphicsNew: Loading %u sprites of type 0x%02X at SpriteID 0x%04X", num, type, _cur_spriteid);
} else {
@@ -3366,6 +3415,8 @@ static void GraphicsNew(byte *buf, int len)
LoadNextSprite(replace == 0 ? _cur_spriteid++ : replace++, _file_index, _nfo_line);
_nfo_line++;
}
+
+ _skip_sprites = skip_num;
}
/* Action 0x05 (SKIP) */
@@ -5028,7 +5079,6 @@ static void ResetNewGRFData()
_loaded_newgrf_features.has_newhouses = false;
_loaded_newgrf_features.has_newindustries = false;
_loaded_newgrf_features.has_newwater = false;
- _signal_base = 0;
_coast_base = 0;
InitializeSoundPool();