changeset 6869:d3c5269fa036 draft

(svn r10109) -Fix [FS#838]: some NewGRFs use the same (unused in the "current" climate) sprite IDs. Normally this gives some artefacts, but when one NewGRF expects it to be a sprite and another NewGRF overwrites it with a non-sprite nasty things happen (drawing a non-sprite crashes OTTD).
author rubidium <rubidium@openttd.org>
date Tue, 12 Jun 2007 09:40:50 +0000
parents c0bb9eee78b1
children 3b117aea3e1b
files src/spritecache.cpp src/spritecache.h
diffstat 2 files changed, 20 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/spritecache.cpp
+++ b/src/spritecache.cpp
@@ -118,7 +118,7 @@
 
 void* AllocSprite(size_t);
 
-static void* ReadSprite(SpriteCache *sc, SpriteID id)
+static void* ReadSprite(SpriteCache *sc, SpriteID id, bool real_sprite)
 {
 	uint32 file_pos = sc->file_pos;
 
@@ -139,6 +139,14 @@
 	byte type = FioReadByte();
 	/* Type 0xFF indicates either a colormap or some other non-sprite info */
 	if (type == 0xFF) {
+		if (real_sprite) {
+			static byte warning_level = 0;
+			DEBUG(sprite, warning_level, "Tried to load non sprite #%d as a real sprite. Probable cause: NewGRF interference", id);
+			warning_level = 6;
+			if (id == SPR_IMG_QUERY) error("Uhm, would you be so kind not to load a NewGRF that makes the 'query' sprite a non- sprite?");
+			return (void*)GetSprite(SPR_IMG_QUERY);
+		}
+
 		byte *dest = (byte *)AllocSprite(num);
 
 		sc->ptr = dest;
@@ -186,6 +194,12 @@
 		return sc->ptr;
 	}
 
+	if (!real_sprite) {
+		static byte warning_level = 0;
+		DEBUG(sprite, warning_level, "Tried to load real sprite #%d as a non sprite. Probable cause: NewGRF interference", id);
+		warning_level = 6;
+	}
+
 	SpriteLoaderGrf sprite_loader;
 	SpriteLoader::Sprite sprite;
 
@@ -403,7 +417,7 @@
 }
 
 
-const void *GetRawSprite(SpriteID sprite)
+const void *GetRawSprite(SpriteID sprite, bool real_sprite)
 {
 	SpriteCache *sc;
 	void* p;
@@ -418,7 +432,7 @@
 	p = sc->ptr;
 
 	/* Load the sprite, if it is not loaded, yet */
-	if (p == NULL) p = ReadSprite(sc, sprite);
+	if (p == NULL) p = ReadSprite(sc, sprite, real_sprite);
 	return p;
 }
 
--- a/src/spritecache.h
+++ b/src/spritecache.h
@@ -15,17 +15,17 @@
 
 extern uint _sprite_cache_size;
 
-const void *GetRawSprite(SpriteID sprite);
+const void *GetRawSprite(SpriteID sprite, bool real_sprite);
 bool SpriteExists(SpriteID sprite);
 
 static inline const Sprite *GetSprite(SpriteID sprite)
 {
-	return (Sprite*)GetRawSprite(sprite);
+	return (Sprite*)GetRawSprite(sprite, true);
 }
 
 static inline const byte *GetNonSprite(SpriteID sprite)
 {
-	return (byte*)GetRawSprite(sprite);
+	return (byte*)GetRawSprite(sprite, false);
 }
 
 void GfxInitSpriteMem();