(svn r3004) -Feature, NewGRF: Support loading of bridge attributes and tables from GRF. Currently drawing tall pillars uses old data.
authorpeter1138
Sat, 01 Oct 2005 17:38:48 +0000
changeset 2478 16b05f1de6bb
parent 2477 d454d5152386
child 2479 eb73083a5f5f
(svn r3004) -Feature, NewGRF: Support loading of bridge attributes and tables from GRF. Currently drawing tall pillars uses old data.
bridge.h
newgrf.c
tunnelbridge_cmd.c
--- a/bridge.h	Sat Oct 01 12:43:34 2005 +0000
+++ b/bridge.h	Sat Oct 01 17:38:48 2005 +0000
@@ -15,8 +15,11 @@
 	uint16 speed;        ///< maximum travel speed
 	PalSpriteID sprite;  ///< the sprite which is used in the GUI (possibly with a recolor sprite)
 	StringID material;   ///< the string that contains the bridge description
+	PalSpriteID **sprite_table; ///< table of sprites for drawing the bridge
+	byte flags;          ///< bit 0 set: disable drawing of far pillars.
 } Bridge;
 
-extern const Bridge _bridge[MAX_BRIDGES];
+extern const Bridge orig_bridge[MAX_BRIDGES];
+Bridge _bridge[MAX_BRIDGES];
 
 #endif /* BRIDGE_H */
--- a/newgrf.c	Sat Oct 01 12:43:34 2005 +0000
+++ b/newgrf.c	Sat Oct 01 17:38:48 2005 +0000
@@ -15,6 +15,7 @@
 #include "sprite.h"
 #include "newgrf.h"
 #include "variables.h"
+#include "bridge.h"
 
 /* TTDPatch extended GRF format codec
  * (c) Petr Baudis 2004 (GPL'd)
@@ -974,6 +975,82 @@
 	return ret;
 }
 
+static bool BridgeChangeInfo(uint brid, int numinfo, int prop, byte **bufp, int len)
+{
+	byte *buf = *bufp;
+	int i;
+	int ret = 0;
+
+	switch (prop) {
+		case 0x08: /* Year of availability */
+			FOR_EACH_OBJECT {
+				_bridge[brid + i].avail_year = grf_load_byte(&buf);
+			}
+			break;
+
+		case 0x09: /* Minimum length */
+			FOR_EACH_OBJECT {
+				_bridge[brid + i].min_length = grf_load_byte(&buf);
+			}
+			break;
+
+		case 0x0A: /* Maximum length */
+			FOR_EACH_OBJECT {
+				_bridge[brid + i].max_length = grf_load_byte(&buf);
+			}
+			break;
+
+		case 0x0B: /* Cost factor */
+			FOR_EACH_OBJECT {
+				_bridge[brid + i].price = grf_load_byte(&buf);
+			}
+			break;
+
+		case 0x0C: /* Maximum speed */
+			FOR_EACH_OBJECT {
+				_bridge[brid + i].speed = grf_load_word(&buf);
+			}
+			break;
+
+		case 0x0D: /* Bridge sprite tables */
+			FOR_EACH_OBJECT {
+				Bridge *bridge = &_bridge[brid + i];
+				byte tableid = grf_load_byte(&buf);
+				byte numtables = grf_load_byte(&buf);
+				byte table, sprite;
+
+				if (bridge->sprite_table == NULL) {
+					/* Allocate memory for sprite table pointers and set to NULL */
+					bridge->sprite_table = malloc(7 * sizeof(*bridge->sprite_table));
+					for (table = 0; table < 7; table++)
+						bridge->sprite_table[table] = NULL;
+				}
+
+				for (table = tableid; table < tableid + numtables; table++) {
+					assert(table < 7);
+					if (bridge->sprite_table[table] == NULL) {
+						bridge->sprite_table[table] = malloc(32 * sizeof(**bridge->sprite_table));
+					}
+
+					for (sprite = 0; sprite < 32; sprite++)
+						bridge->sprite_table[table][sprite] = grf_load_dword(&buf);
+				}
+			}
+			break;
+
+		case 0x0E: /* Flags; bit 0 - disable far pillars */
+			FOR_EACH_OBJECT {
+				_bridge[brid + i].flags = grf_load_byte(&buf);
+			}
+			break;
+
+		default:
+			ret = 1;
+	}
+
+	*bufp = buf;
+	return ret;
+}
 
 /* Action 0x00 */
 static void VehicleChangeInfo(byte *buf, int len)
@@ -1001,7 +1078,7 @@
 		/* GSF_AIRCRAFT */ AircraftVehicleChangeInfo,
 		/* GSF_STATION */  StationChangeInfo,
 		/* GSF_CANAL */    NULL,
-		/* GSF_BRIDGE */   NULL,
+		/* GSF_BRIDGE */   BridgeChangeInfo,
 		/* GSF_TOWNHOUSE */NULL,
 	};
 
@@ -2181,12 +2258,28 @@
  */
 static void ResetNewGRFData(void)
 {
+	int i;
+
 	// Copy/reset original engine info data
 	memcpy(&_engine_info, &orig_engine_info, sizeof(orig_engine_info));
 	memcpy(&_rail_vehicle_info, &orig_rail_vehicle_info, sizeof(orig_rail_vehicle_info));
 	memcpy(&_ship_vehicle_info, &orig_ship_vehicle_info, sizeof(orig_ship_vehicle_info));
 	memcpy(&_aircraft_vehicle_info, &orig_aircraft_vehicle_info, sizeof(orig_aircraft_vehicle_info));
 	memcpy(&_road_vehicle_info, &orig_road_vehicle_info, sizeof(orig_road_vehicle_info));
+
+	// Copy/reset original bridge info data
+	// First, free sprite table data
+	for (i = 0; i < MAX_BRIDGES; i++) {
+		if (_bridge[i].sprite_table != NULL) {
+			byte j;
+			for (j = 0; j < 7; j++) {
+				if (_bridge[i].sprite_table[j] != NULL)
+					free(_bridge[i].sprite_table[j]);
+			}
+			free(_bridge[i].sprite_table);
+		}
+	}
+	memcpy(&_bridge, &orig_bridge, sizeof(_bridge));
 }
 
 static void InitNewGRFFile(const char* filename, int sprite_offset)
--- a/tunnelbridge_cmd.c	Sat Oct 01 12:43:34 2005 +0000
+++ b/tunnelbridge_cmd.c	Sat Oct 01 17:38:48 2005 +0000
@@ -31,7 +31,7 @@
 
 extern void DrawCanalWater(TileIndex tile);
 
-const Bridge _bridge[] = {
+const Bridge orig_bridge[] = {
 /*
 	   year of availablity
 	   |  minimum length
@@ -40,19 +40,19 @@
 	   |  |   |    |    maximum speed
 	   |  |   |    |    |  sprite to use in GUI                string with description
 	   |  |   |    |    |  |                                   |                            */
-	{  0, 0, 16,  80,  32, 0xA24                             , STR_5012_WOODEN              },
-	{  0, 0,  2, 112,  48, 0xA26 | PALETTE_TO_STRUCT_RED     , STR_5013_CONCRETE            },
-	{ 10, 0,  5, 144,  64, 0xA25                             , STR_500F_GIRDER_STEEL        },
-	{  0, 2, 10, 168,  80, 0xA22 | PALETTE_TO_STRUCT_CONCRETE, STR_5011_SUSPENSION_CONCRETE },
-	{ 10, 3, 16, 185,  96, 0xA22                             , STR_500E_SUSPENSION_STEEL    },
-	{ 10, 3, 16, 192, 112, 0xA22 | PALETTE_TO_STRUCT_YELLOW  , STR_500E_SUSPENSION_STEEL	},
-	{ 10, 3,  7, 224, 160, 0xA23                             , STR_5010_CANTILEVER_STEEL    },
-	{ 10, 3,  8, 232, 208, 0xA23 | PALETTE_TO_STRUCT_BROWN   , STR_5010_CANTILEVER_STEEL    },
-	{ 10, 3,  9, 248, 240, 0xA23 | PALETTE_TO_STRUCT_RED     , STR_5010_CANTILEVER_STEEL    },
-	{ 10, 0,  2, 240, 256, 0xA27                             , STR_500F_GIRDER_STEEL        },
-	{ 75, 2, 16, 255, 320, 0xA28                             , STR_5014_TUBULAR_STEEL       },
-	{ 85, 2, 32, 380, 512, 0xA28 | PALETTE_TO_STRUCT_YELLOW  , STR_5014_TUBULAR_STEEL       },
-	{ 90, 2, 32, 510, 608, 0xA28 | PALETTE_TO_STRUCT_GREY    , STR_BRIDGE_TUBULAR_SILICON   }
+	{  0, 0, 16,  80,  32, 0xA24                             , STR_5012_WOODEN             , NULL, 0 },
+	{  0, 0,  2, 112,  48, 0xA26 | PALETTE_TO_STRUCT_RED     , STR_5013_CONCRETE           , NULL, 0 },
+	{ 10, 0,  5, 144,  64, 0xA25                             , STR_500F_GIRDER_STEEL       , NULL, 0 },
+	{  0, 2, 10, 168,  80, 0xA22 | PALETTE_TO_STRUCT_CONCRETE, STR_5011_SUSPENSION_CONCRETE, NULL, 0 },
+	{ 10, 3, 16, 185,  96, 0xA22                             , STR_500E_SUSPENSION_STEEL   , NULL, 0 },
+	{ 10, 3, 16, 192, 112, 0xA22 | PALETTE_TO_STRUCT_YELLOW  , STR_500E_SUSPENSION_STEEL   , NULL, 0 },
+	{ 10, 3,  7, 224, 160, 0xA23                             , STR_5010_CANTILEVER_STEEL   , NULL, 0 },
+	{ 10, 3,  8, 232, 208, 0xA23 | PALETTE_TO_STRUCT_BROWN   , STR_5010_CANTILEVER_STEEL   , NULL, 0 },
+	{ 10, 3,  9, 248, 240, 0xA23 | PALETTE_TO_STRUCT_RED     , STR_5010_CANTILEVER_STEEL   , NULL, 0 },
+	{ 10, 0,  2, 240, 256, 0xA27                             , STR_500F_GIRDER_STEEL       , NULL, 0 },
+	{ 75, 2, 16, 255, 320, 0xA28                             , STR_5014_TUBULAR_STEEL      , NULL, 0 },
+	{ 85, 2, 32, 380, 512, 0xA28 | PALETTE_TO_STRUCT_YELLOW  , STR_5014_TUBULAR_STEEL      , NULL, 0 },
+	{ 90, 2, 32, 510, 608, 0xA28 | PALETTE_TO_STRUCT_GREY    , STR_BRIDGE_TUBULAR_SILICON  , NULL, 0 }
 };
 
 // calculate the price factor for building a long bridge.
@@ -78,6 +78,17 @@
 	BRIDGE_NO_FOUNDATION = 1 << 0 | 1 << 3 | 1 << 6 | 1 << 9 | 1 << 12,
 };
 
+static inline const PalSpriteID *GetBridgeSpriteTable(int index, byte table)
+{
+	const Bridge *bridge = &_bridge[index];
+	assert(table < 7);
+	if (bridge->sprite_table == NULL || bridge->sprite_table[table] == NULL) {
+		return _bridge_sprite_table[index][table];
+	} else {
+		return bridge->sprite_table[table];
+	}
+}
+
 /**
  * Determines which piece of a bridge is contained in the current tile
  * @param tile The tile to analyze
@@ -1067,7 +1078,7 @@
 			}
 
 			// bridge ending.
-			b = _bridge_sprite_table[GB(_m[ti->tile].m2, 4, 4)][6];
+			b = GetBridgeSpriteTable(GetBridgeType(ti->tile), 6);
 			b += (tmp&(3<<1))*4; /* actually ((tmp>>2)&3)*8 */
 			b += (tmp&1); // direction
 			if (ti->tileh == 0) b += 4; // sloped "entrance" ?
@@ -1128,7 +1139,7 @@
 				DrawGroundSprite(image);
 			}
 			// get bridge sprites
-			b = _bridge_sprite_table[GB(_m[ti->tile].m2, 4, 4)][GB(_m[ti->tile].m2, 0, 4)] + tmp * 4;
+			b = GetBridgeSpriteTable(GetBridgeType(ti->tile), GetBridgePiece(ti->tile)) + tmp * 4;
 
 			z = GetBridgeHeight(ti) + 5;