(svn r549) -newgrf: Support for action 0xd (change a parameter (sorta variable for the GRF scripts)). Based on patch by octo, heavy changes by pasky.
authordarkvater
Fri, 12 Nov 2004 18:47:19 +0000
changeset 361 ad7a042ee0eb
parent 360 ff657281ae48
child 362 bd9bc9c072ba
(svn r549) -newgrf: Support for action 0xd (change a parameter (sorta variable for the GRF scripts)). Based on patch by octo, heavy changes by pasky.
grfspecial.c
spritecache.c
--- a/grfspecial.c	Fri Nov 12 18:43:12 2004 +0000
+++ b/grfspecial.c	Fri Nov 12 18:47:19 2004 +0000
@@ -17,6 +17,8 @@
  * served as subject to the initial testing of this codec. */
 
 extern int _skip_sprites;
+extern int _replace_sprites_count[16];
+extern int _replace_sprites_offset[16];
 
 static const char *_cur_grffile;
 static int _cur_spriteid;
@@ -927,7 +929,6 @@
 
 	numsprites = grf_load_byte(&buf);
 	grfmsg(GMS_NOTICE, "Skipping %d sprites, test was true.", numsprites);
-
 	_skip_sprites = numsprites;
 	if (_skip_sprites == 0) {
 		/* Zero means there are no sprites to skip, so
@@ -969,7 +970,30 @@
 	 * Each set:
 	 * B num-sprites   How many sprites are in this set
 	 * W first-sprite  First sprite number to replace */
-	/* TODO */
+	uint8 num_sets;
+	int i;
+
+	buf++; /* skip action byte */
+	num_sets = grf_load_byte(&buf);
+
+	if (num_sets > 16) {
+		grfmsg(GMS_ERROR, "SpriteReplace: Too many sets (%d), taking only the first 16!", num_sets);
+	}
+	
+	for (i = 0; i < 16; i++) {
+		if (i < num_sets) {
+			uint8 num_sprites = grf_load_byte(&buf);
+			uint16 first_sprite = grf_load_word(&buf);
+
+			_replace_sprites_count[i] = num_sprites;
+			_replace_sprites_offset[i] = first_sprite;
+			grfmsg(GMS_NOTICE, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
+					i, num_sprites, first_sprite);
+		} else {
+			_replace_sprites_count[i] = 0;
+			_replace_sprites_offset[i] = 0;
+		}
+	}
 }
 
 static void GRFError(byte *buf, int len)
--- a/spritecache.c	Fri Nov 12 18:43:12 2004 +0000
+++ b/spritecache.c	Fri Nov 12 18:47:19 2004 +0000
@@ -13,12 +13,17 @@
 //#define WANT_LOCKED
 
 
+/* These are used in grfspecial.c: */
+
 int _skip_sprites = 0;
+int _replace_sprites_count[16];
+int _replace_sprites_offset[16];
 
 static const char *_cur_grffile;
 static int _skip_specials;
 static SpriteHdr _cur_sprite;
 
+
 static byte *_sprite_ptr[NUM_SPRITES];
 static uint16 _sprite_size[NUM_SPRITES];
 static uint32 _sprite_file_pos[NUM_SPRITES];
@@ -185,15 +190,46 @@
 static bool LoadNextSprite(int load_index, byte file_index)
 {
 	uint16 size;
+	uint32 file_pos;
 
-	if ( (size = FioReadWord()) == 0)
+	if ((size = FioReadWord()) == 0)
 		return false;
 
-	_sprite_size[load_index] = size;
-	_sprite_file_pos[load_index] = FioGetPos() | (file_index << 24);
+	file_pos = FioGetPos() | (file_index << 24);
 
 	ReadSpriteHeaderSkipData(size, load_index);
 
+	if ((_replace_sprites_count[0] > 0) && (_cur_sprite.info != 0xFF)) {
+		int count = _replace_sprites_count[0];
+		int offset = _replace_sprites_offset[0];
+
+		_replace_sprites_offset[0]++;
+		_replace_sprites_count[0]--;
+		
+		if ((offset + count) <= NUM_SPRITES) {
+			load_index = offset;
+		} else {
+			DEBUG(spritecache, 1) ("Sprites to be replaced are out of range: %x+%x",
+					count, offset);
+			_replace_sprites_offset[0] = 0;
+			_replace_sprites_count[0] = 0;
+		}
+
+		if (_replace_sprites_count[0] == 0) {
+			int i;
+
+			for (i = 0; i < 15; i++) {
+				_replace_sprites_count[i] = _replace_sprites_count[i + 1];
+				_replace_sprites_offset[i] = _replace_sprites_offset[i + 1];
+			}
+			_replace_sprites_count[i] = 0;
+			_replace_sprites_offset[i] = 0;
+		}
+	}
+
+	_sprite_size[load_index] = size;
+	_sprite_file_pos[load_index] = file_pos;
+
 #ifdef WANT_SPRITESIZES
 	_sprite_xsize[load_index] = _cur_sprite.width;
 	_sprite_ysize[load_index] = _cur_sprite.height;
@@ -259,7 +295,10 @@
 		}
 	}
 
-	_skip_sprites = 0; // clean up
+	/* Clean up. */
+	_skip_sprites = 0;
+	memset(_replace_sprites_count, 0, 16 * sizeof(*_replace_sprites_count));
+	memset(_replace_sprites_offset, 0, 16 * sizeof(*_replace_sprites_offset));
 
 	return load_index - load_index_org;
 }