spritecache.c
changeset 184 dbeaaaf8b2bb
parent 182 1641047f1d9f
child 361 ad7a042ee0eb
--- a/spritecache.c	Wed Sep 08 17:44:29 2004 +0000
+++ b/spritecache.c	Wed Sep 08 18:05:49 2004 +0000
@@ -52,7 +52,7 @@
 	"TRG1R.GRF",
 	"TRGIR.GRF",
 	"signalsw.grf", //0x1320 - 0x1405 inclusive
-//	"openttd.grf",	//0x1406 - 
+//	"openttd.grf",	//0x1406 -
 	NULL
 };
 
@@ -93,7 +93,7 @@
 			_skip_sprites--;
 		deaf = 1;
 	}
-	
+
 	type = FioReadByte();
 	if (type == 0xFF) {
 		/* We need to really skip only special sprites in the deaf
@@ -108,7 +108,7 @@
 		}
 		return;
 	}
-	
+
 	_cur_sprite.info = type;
 #ifdef WANT_SPRITESIZES
 	_cur_sprite.height = FioReadByte();
@@ -146,7 +146,7 @@
 	byte *rel;
 	int8 i;
 	int j, dist;
-	
+
 	type = FioReadByte();
 	/* We've decoded special sprites when reading headers. */
 	if (type != 0xFF) {
@@ -173,7 +173,7 @@
 			dist = -(((i&7)<<8)|FioReadByte());
 			i = -(i >> 3);
 			num -= i;
-			
+
 			rel = &dest[dist];
 			while (i--)
 				*dest++ = *rel++;
@@ -209,7 +209,7 @@
 
 #if defined(WANT_NEW_LRU)
 	_sprite_lru_new[load_index] = 0;
-#else	
+#else
 	_sprite_lru[load_index] = 0xFFFF;
 	_sprite_lru_cur[load_index] = 0;
 #endif
@@ -282,7 +282,7 @@
 			} while (++start <= end);
 		}
 	}
-}	
+}
 
 typedef size_t CDECL fread_t(void*,size_t,size_t,FILE*);
 
@@ -398,20 +398,20 @@
 	byte *s, *t;
 	size_t size, sizeb, cur_size;
 	int i;
-	
+
 	DEBUG(spritecache, 2) ("compacting sprite cache, inuse=%d", GetSpriteCacheUsage());
 
 	s = _spritecache_ptr;
-	
+
 	while (true) {
 		size = S_DATA(s);
-		
+
 		// Only look for free blocks.
 		if (size & S_FREE_MASK) {
 			size -= S_FREE_MASK;
 			// Since free blocks are automatically coalesced, this should hold true.
 			assert(!(S_DATA(s+size) & S_FREE_MASK));
-			
+
 			// If the next block is the sentinel block, we can safely return
 			if ( (sizeb=S_DATA(s + size)) == 0)
 				break;
@@ -427,13 +427,13 @@
 				// Offset the sprite pointer by the size of the free block
 				_sprite_ptr[i] -= size;
 
-				// Move the memory 
+				// Move the memory
 				memcpy_overlapping(s+S_HDRSIZE, s+S_HDRSIZE+size, sizeb - S_HDRSIZE );
 
 				// What we just did had the effect of swapping the allocated block with the free block, so we need to update
 				//  the block pointers. First update the allocated one. It is in use.
 				S_DATA(s) = sizeb;
-							
+
 				// Then coalesce the free ones that follow.
 				s += sizeb;
 				while ((cur_size = S_DATA(s+size)) & S_FREE_MASK)
@@ -485,7 +485,7 @@
 #endif
 				_sprite_lru[i] < cur_lru)
 					continue;
-		
+
 		// Found a sprite with a higher LRU value, then remember it.
 		if (_sprite_lru[i] != cur_lru) {
 			cur_lru = _sprite_lru[i];
@@ -551,7 +551,7 @@
 			// Now s points at a free block.
 			// The block is exactly the size we need?
 			if (cur_size != mem_req) {
-				
+
 				// No.. is it too small?
 				if (cur_size < mem_req + S_HDRSIZE)
 					break;
@@ -567,7 +567,7 @@
 
 			FioSeekToFile(_sprite_file_pos[sprite]);
 			ReadSprite(_sprite_size[sprite], s);
-			
+
 			// Patch the height to compensate for a TTD bug?
 			if (sprite == 142) { s[1] = 10; }
 
@@ -580,7 +580,7 @@
 			DeleteEntryFromSpriteCache();
 			goto restart;
 		}
-		
+
 		s += cur_size;
 	}
 }
@@ -628,7 +628,7 @@
 }
 #endif
 
-byte *GetSpritePtr(uint sprite) 
+byte *GetSpritePtr(uint sprite)
 {
 	byte *p;
 
@@ -650,7 +650,7 @@
 	p = _sprite_ptr[sprite];
 	if (p == NULL)
 		p = LoadSpriteToMem(sprite);  // No, need to load it.
-	return p;	
+	return p;
 }
 
 byte _sprite_page_to_load = 0xFF;
@@ -680,9 +680,18 @@
 {
 	int i,j;
 
-	/* load initial sprites */
+	/*
+	 * Note for developers:
+	 *   Keep in mind that when you add a LoadGrfIndexed in the 'if'-section below
+	 *   that you should also add the corresponding FioOpenFile to the 'else'-section
+	 *   below.
+	 */
+
+	// Try to load the sprites from cache
 	if (!HandleCachedSpriteHeaders(_cached_filenames[_opt.landscape], true)) {
-		
+		// We do not have the sprites in cache yet, or cache is disabled
+		// So just load all files from disk..
+
 		int load_index = 0;
 		for(i=0; _filename_list[i] != NULL; i++) {
 			load_index += LoadGrfFile(_filename_list[i], load_index, (byte)i);
@@ -690,38 +699,48 @@
 
 		LoadGrfIndexed("openttd.grf", _openttd_grf_indexes, i++);
 
-		{
-			int l;
-			if ((l=_sprite_page_to_load) != 0)
-				LoadGrfIndexed(_landscape_filenames[l-1], _landscape_spriteindexes[l-1], i++); 
-		}
-		
+		if (_sprite_page_to_load != 0)
+			LoadGrfIndexed(_landscape_filenames[_sprite_page_to_load-1], _landscape_spriteindexes[_sprite_page_to_load-1], i++);
+
 		LoadGrfIndexed("trkfoundw.grf", _slopes_spriteindexes[_opt.landscape], i++);
 
 		load_index = SPR_CANALS_BASE;
 		load_index += LoadGrfFile("canalsw.grf", load_index, i++);
-		/* XXX: Only for debugging. Will be more generic. */
 
-		load_index = SPR_OPENTTD_BASE + OPENTTD_SPRITES_COUNT+1;
+		load_index = SPR_OPENTTD_BASE + OPENTTD_SPRITES_COUNT + 1;
 
 		for(j=0; j!=lengthof(_newgrf_files) && _newgrf_files[j]; j++)
 			load_index += LoadGrfFile(_newgrf_files[j], load_index, i++);
 
-//		load_index += LoadGrfFile("arcticseto.grf", load_index, i++);
-//		load_index += LoadGrfFile("tempsetpo.grf", load_index, i++);
-//		load_index += LoadGrfFile("newshipso.grf", load_index, i++);
-		//load_index += LoadGrfFile("brseto.grf", load_index, i++);
-
+		// If needed, save the cache to file
 		HandleCachedSpriteHeaders(_cached_filenames[_opt.landscape], false);
 	} else {
+		// We have sprites cached. We just loaded the cached files
+		//  now we only have to open a file-pointer to all the original grf-files
+		// This is very important. Not all sprites are in the cache. So sometimes
+		//  the game needs to load the sprite from disk. When the file is not
+		//  open it can not read. So all files that are in the 'if'-section
+		//  above should also be in this 'else'-section.
+		//
+		// NOTE: the order of the files must be identical as in the section above!!
+
 		for(i=0; _filename_list[i] != NULL; i++)
-			FioOpenFile(i,_filename_list[i]); 
-		
-		FioOpenFile(i, "openttd.grf");
-		FioOpenFile(i+1, "canalsw.grf");
-		
+			FioOpenFile(i,_filename_list[i]);
+
+		FioOpenFile(i++, "openttd.grf");
+
 		if (_sprite_page_to_load != 0)
-			FioOpenFile(i+2, _landscape_filenames[_sprite_page_to_load-1]);
+			FioOpenFile(i++, _landscape_filenames[_sprite_page_to_load-1]);
+
+		FioOpenFile(i++, "trkfoundw.grf");
+		FioOpenFile(i++, "canalsw.grf");
+
+		// FIXME: if a user changes his newgrf's, the cached-sprites gets
+		//  invalid. We should have some kind of check for this.
+		// The best solution for this is to delete the cached-sprites.. but how
+		//  do we detect it?
+		for(j=0; j!=lengthof(_newgrf_files) && _newgrf_files[j]; j++)
+			FioOpenFile(i++, _newgrf_files[j]);
 	}
 
 	_compact_cache_counter = 0;
@@ -744,7 +763,7 @@
 
 void GfxLoadSprites() {
 	static byte *_sprite_mem;
-	
+
 	// Need to reload the sprites only if the landscape changed
 	if (_sprite_page_to_load != _opt.landscape) {
 		_sprite_page_to_load = _opt.landscape;
@@ -793,4 +812,4 @@
 */
 	return sd;
 }
- 
+