(svn r554) -newgrf: Keep track of GRF files. Remember them all in a linked list, this already enables tests for an already loaded GRF file in SkipIf(). Patch by octo, heavily re-hammered by pasky
authordarkvater
Fri, 12 Nov 2004 22:28:19 +0000
changeset 366 9d2630b8b4de
parent 365 5752af05ed75
child 367 d0d895bd4972
(svn r554) -newgrf: Keep track of GRF files. Remember them all in a linked list, this already enables tests for an already loaded GRF file in SkipIf(). Patch by octo, heavily re-hammered by pasky
grfspecial.c
spritecache.c
--- a/grfspecial.c	Fri Nov 12 21:51:34 2004 +0000
+++ b/grfspecial.c	Fri Nov 12 22:28:19 2004 +0000
@@ -20,7 +20,15 @@
 extern int _replace_sprites_count[16];
 extern int _replace_sprites_offset[16];
 
-static const char *_cur_grffile;
+struct GRFFile {
+	char *filename;
+	uint32 grfid;
+	uint16 flags;
+	uint16 sprite_offset;
+	struct GRFFile *next;
+};
+
+static struct GRFFile *_cur_grffile, *_first_grffile;
 static int _cur_spriteid;
 
 static int32 _paramlist[0x7f];
@@ -56,7 +64,7 @@
 	va_start(va, str);
 	vsprintf(buf, str, va);
 	va_end(va);
-	DEBUG(grf, 2) ("[%s][%s] %s", _cur_grffile, severitystr[severity], buf);
+	DEBUG(grf, 2) ("[%s][%s] %s", _cur_grffile->filename, severitystr[severity], buf);
 }
 
 
@@ -96,6 +104,32 @@
 }
 
 
+static struct GRFFile *GetFileByGRFID(uint32 grfid)
+{
+	struct GRFFile *file;
+
+	file = _first_grffile;
+	while ((file != NULL) && (file->grfid != grfid))
+		file = file->next;
+
+	return file;
+}
+
+#if 0
+/* Will be used very soon. */
+static struct GRFFile *GetFileByFilename(char *filename)
+{
+	struct GRFFile *file;
+
+	file = _first_grffile;
+	while ((file != NULL) && strcmp(file->filename, filename))
+		file = retval->next;
+
+	return file;
+}
+#endif
+
+
 typedef bool (*VCI_Handler)(uint engine, int numinfo, int prop, byte **buf, int len);
 
 #define FOR_EACH_ENGINE for (i = 0; i < numinfo; i++)
@@ -909,6 +943,12 @@
 		case 0x86:
 			param_val = _opt.road_side << 4;
 			break;
+		case 0x88: {
+			struct GRFFile *file;
+
+			file = GetFileByGRFID(cond_val);
+			param_val = (file != NULL);
+		}	break;
 		default:
 			if (param >= 0x80) {
 				/* In-game variable. */
@@ -934,6 +974,10 @@
 			break;
 		case 5: result = (param_val > cond_val);
 			break;
+		case 6: result = param_val; /* GRFID is active (only for param-num=88) */
+			break;
+		case 7: result = !param_val; /* GRFID is not active (only for param-num=88) */
+			break;
 		default:
 			grfmsg(GMS_WARN, "Unsupported test %d. Ignoring.", condtype);
 			return;
@@ -965,17 +1009,22 @@
 	 * S info          string describing the set, and e.g. author and copyright */
 	/* TODO: Check version. (We should have own versioning done somehow.) */
 	uint8 version;
-	uint32 grfid; /* this is de facto big endian - grf_load_dword() unsuitable */
+	uint32 grfid;
 	char *name;
 	char *info;
 
 	check_length(len, 9, "GRFInfo");
 	version = buf[1];
+	/* this is de facto big endian - grf_load_dword() unsuitable */
 	grfid = buf[2] << 24 | buf[3] << 16 | buf[4] << 8 | buf[5];
 	name = buf + 6;
 	info = name + strlen(name) + 1;
+
+	_cur_grffile->grfid = grfid;
+	_cur_grffile->flags |= 0x0001; /* set active flag */
+
 	DEBUG(grf, 1) ("[%s] Loaded GRFv%d set %08lx - %s:\n%s\n",
-	               _cur_grffile, version, grfid, name, info);
+	               _cur_grffile->filename, version, grfid, name, info);
 }
 
 static void SpriteReplace(byte *buf, int len)
@@ -1203,6 +1252,29 @@
 		| (1 << 0x17);		/* newstartyear */
 }
 
+void InitNewGRFFile(const char *filename, int sprite_offset) {
+	struct GRFFile *newfile;
+
+	newfile = malloc(sizeof(struct GRFFile));
+
+	if (newfile == NULL)
+		error ("Out of memory");
+
+	newfile->filename = strdup(filename);
+	newfile->grfid = 0;
+	newfile->flags = 0x0000;
+	newfile->sprite_offset = sprite_offset;
+	newfile->next = NULL;
+
+	if (_first_grffile == NULL) {
+		_cur_grffile = newfile;
+		_first_grffile = newfile;
+	} else {
+		_cur_grffile->next = newfile;
+		_cur_grffile = newfile;
+	}
+}
+
 
 /* Here we perform initial decoding of some special sprites (as are they
  * described at http://www.ttdpatch.net/src/newgrf.txt, but this is only a very
@@ -1211,7 +1283,7 @@
  * a crafted invalid GRF file. We should tell that to the user somehow, or
  * better make this more robust in the future. */
 
-void DecodeSpecialSprite(const char *filename, int num, int spriteid)
+void DecodeSpecialSprite(int num, int spriteid)
 {
 #define NUM_ACTIONS 0xF
 	static const SpecialSpriteHandler handlers[NUM_ACTIONS] = {
@@ -1243,7 +1315,6 @@
 		initialized = 1;
 	}
 
-	_cur_grffile = filename;
 	_cur_spriteid = spriteid;
 
 	for (i = 0; i != num; i++)
--- a/spritecache.c	Fri Nov 12 21:51:34 2004 +0000
+++ b/spritecache.c	Fri Nov 12 22:28:19 2004 +0000
@@ -19,7 +19,6 @@
 int _replace_sprites_count[16];
 int _replace_sprites_offset[16];
 
-static const char *_cur_grffile;
 static int _skip_specials;
 static SpriteHdr _cur_sprite;
 
@@ -85,7 +84,8 @@
 
 static void CompactSpriteCache();
 
-void DecodeSpecialSprite(const char *filename, int num, int load_index);
+void InitNewGRFFile(const char *filename, int sprite_offset);
+void DecodeSpecialSprite(int num, int load_index);
 
 static void ReadSpriteHeaderSkipData(int num, int load_index)
 {
@@ -110,7 +110,7 @@
 		if (_skip_specials || deaf) {
 			FioSkipBytes(num);
 		} else {
-			DecodeSpecialSprite(_cur_grffile, num, load_index);
+			DecodeSpecialSprite(num, load_index);
 		}
 		return;
 	}
@@ -281,14 +281,13 @@
 	int load_index_org = load_index;
 
 	FioOpenFile(file_index, filename);
-	_cur_grffile = filename;
 
 	/* Thou shalt use LoadNewGrfFile() if thou loadeth a GRF file that
 	 * might contain some special sprites. */
 	_skip_specials = 1;
 	_skip_sprites = 0;
 
-	DEBUG(spritecache, 2) ("Reading grf-file ``%s''", _cur_grffile);
+	DEBUG(spritecache, 2) ("Reading grf-file ``%s''", filename);
 
  	if(file_index==0 && !_ignore_wrong_grf)
  		if(!CheckGrfFile())
@@ -312,12 +311,11 @@
 	int i;
 	
 	FioOpenFile(file_index, filename);
-	_cur_grffile = filename;
 	_skip_specials = 0;
 	_skip_sprites = 0;
 
 	DEBUG(spritecache, 2) ("Reading newgrf-file ``%s'' [offset: %u]",
-			_cur_grffile, load_index);
+			filename, load_index);
 
 	{
 		int length;
@@ -360,11 +358,10 @@
 	int start;
 
 	FioOpenFile(file_index, filename);
-	_cur_grffile = filename;
 	_skip_specials = 1;
 	_skip_sprites = 0;
 
-	DEBUG(spritecache, 2) ("Reading indexed grf-file ``%s''", _cur_grffile);
+	DEBUG(spritecache, 2) ("Reading indexed grf-file ``%s''", filename);
 
 	for(;(start=*index_tbl++) != 0xffff;) {
 		int end = *index_tbl++;
@@ -808,8 +805,10 @@
 
 		load_index = SPR_OPENTTD_BASE + OPENTTD_SPRITES_COUNT + 1;
 
-		for(j=0; j!=lengthof(_newgrf_files) && _newgrf_files[j]; j++)
+		for(j = 0; j != lengthof(_newgrf_files) && _newgrf_files[j]; j++) {
+			InitNewGRFFile(_newgrf_files[j], load_index);
 			load_index += LoadNewGrfFile(_newgrf_files[j], load_index, i++);
+		}
 
 		// If needed, save the cache to file
 		HandleCachedSpriteHeaders(_cached_filenames[_opt.landscape], false);
@@ -823,7 +822,7 @@
 		//
 		// NOTE: the order of the files must be identical as in the section above!!
 
-		for(i=0; _filename_list[i] != NULL; i++)
+		for(i = 0; _filename_list[i] != NULL; i++)
 			FioOpenFile(i,_filename_list[i]);
 
 		FioOpenFile(i++, "openttd.grf");