changeset 2233:1631045675f5 draft

(svn r2753) -Codechange: Introduced a new struct "RailtypeInfo" to store rail type specific information. Begun populating it with a bunch of sprites, more to come later. This should result in cleaner, more compact code which allows easy introduction of new railtypes.
author celestar <celestar@openttd.org>
date Fri, 29 Jul 2005 21:36:02 +0000
parents 0a3ef10e1a34
children a5e44c6e40dd
files Makefile rail.h rail_cmd.c railtypes.c
diffstat 4 files changed, 116 insertions(+), 101 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile
+++ b/Makefile
@@ -670,6 +670,7 @@
 C_SOURCES += rail.c
 C_SOURCES += rail_cmd.c
 C_SOURCES += rail_gui.c
+C_SOURCES += railtypes.c
 C_SOURCES += rev.c
 C_SOURCES += road_cmd.c
 C_SOURCES += road_gui.c
--- a/rail.h
+++ b/rail.h
@@ -139,6 +139,30 @@
 	SIGNAL_STATE_GREEN = 1,
 } SignalState;
 
+/** This struct contains all the info that is needed to draw and construct tracks.
+ */
+typedef struct RailtypeInfo {
+	struct {
+		SpriteID track_y;      ///< single piece of rail in Y direction, with ground
+		SpriteID track_ns;     ///< two pieces of rail in North and South corner (East-West direction)
+		SpriteID ground;       ///< ground sprite for a 3-way switch
+		SpriteID single_y;     ///< single piece of rail in Y direction, without ground
+		SpriteID single_x;     ///< single piece of rail in X direction
+		SpriteID single_n;     ///< single piece of rail in the northern corner
+		SpriteID single_s;     ///< single piece of rail in the southern corner
+		SpriteID single_e;     ///< single piece of rail in the eastern corner
+		SpriteID single_w;     ///< single piece of rail in the western corner
+	} base_sprites;
+
+	/** sprite number difference between a piece of track on a snowy ground and the corresponding one on normal ground */
+	SpriteID snow_offset;
+
+	/** bitmask to the OTHER railtypes that can be used by an engine of THIS railtype */
+	byte compatible_railtypes;
+} RailtypeInfo;
+
+RailtypeInfo railtypes[RAILTYPE_END];
+
 // these are the maximums used for updating signal blocks, and checking if a depot is in a pbs block
 enum {
 	NUM_SSD_ENTRY = 256, // max amount of blocks
@@ -500,6 +524,17 @@
 }
 
 /**
+ * Returns a pointer to the Railtype information for a given railtype
+ * @param railtype the rail type which the information is requested for
+ * @return The pointer to the RailtypeInfo
+ */
+static inline RailtypeInfo *GetRailTypeInfo(RailType railtype)
+{
+	assert(railtype < RAILTYPE_END);
+	return &railtypes[railtype];
+}
+
+/**
  * Checks if an engine of the given RailType can drive on a tile with a given
  * RailType. This would normally just be an equality check, but for electric
  * rails (which also support non-electric engines).
@@ -509,13 +544,7 @@
  */
 static inline bool IsCompatibleRail(RailType enginetype, RailType tiletype)
 {
-	static const bool EquivRailTypes[RAILTYPE_END][RAILTYPE_END] = {
-	{ true, false, false },
-	{ false, true, false },
-	{ false, false, true },
-	};
-
-	return EquivRailTypes[enginetype][tiletype];
+	return HASBIT(GetRailTypeInfo(enginetype)->compatible_railtypes, tiletype);
 }
 
 #endif // RAIL_H
--- a/rail_cmd.c
+++ b/rail_cmd.c
@@ -1359,87 +1359,11 @@
 	AddSortableSpriteToDraw(image, ti->x + x, ti->y + y, xsize, ysize, zsize, ti->z + z);
 }
 
-/* Arrangement of the sprites
- *  1) Single track in Y direction
- *  2) Northern and southern trackbits set
- *  3) "Basis" for 3-way switch
- *  4) Single rail in Y direction without ground sprite
- *  5) as above, X direction
- *  6) as above, nortern track
- *  7) as above, southern track
- *  8) as above, eastern track
- *  9) as above, western track
- * 10) the offset of the snow sprites
- */
-static SpriteID RailSpriteIDs[] = {
-	SPR_RAIL_TRACK_Y,
-	SPR_RAIL_TRACK_N_S,
-	SPR_RAIL_TRACK_BASE,
-	SPR_RAIL_SINGLE_Y,
-	SPR_RAIL_SINGLE_X,
-	SPR_RAIL_SINGLE_NORTH,
-	SPR_RAIL_SINGLE_SOUTH,
-	SPR_RAIL_SINGLE_EAST,
-	SPR_RAIL_SINGLE_WEST,
-	SPR_RAIL_SNOW_OFFSET,
-};
-
-static SpriteID MonoSpriteIDs[] = {
-	SPR_MONO_TRACK_Y,
-	SPR_MONO_TRACK_N_S,
-	SPR_MONO_TRACK_BASE,
-	SPR_MONO_SINGLE_Y,
-	SPR_MONO_SINGLE_X,
-	SPR_MONO_SINGLE_NORTH,
-	SPR_MONO_SINGLE_SOUTH,
-	SPR_MONO_SINGLE_EAST,
-	SPR_MONO_SINGLE_WEST,
-	SPR_MONO_SNOW_OFFSET,
-};
-
-static SpriteID MaglevSpriteIDs[] = {
-	SPR_MGLV_TRACK_Y,
-	SPR_MGLV_TRACK_N_S,
-	SPR_MGLV_TRACK_BASE,
-	SPR_MGLV_SINGLE_Y,
-	SPR_MGLV_SINGLE_X,
-	SPR_MGLV_SINGLE_NORTH,
-	SPR_MGLV_SINGLE_SOUTH,
-	SPR_MGLV_SINGLE_EAST,
-	SPR_MGLV_SINGLE_WEST,
-	SPR_MGLV_SNOW_OFFSET,
-};
-
-/** Sprite reference enum */
-enum {
-	TRACK_Y,
-	TRACK_N_S,
-	TRACK_BASE,
-	SINGLE_Y,
-	SINGLE_X,
-	SINGLE_NORTH,
-	SINGLE_SOUTH,
-	SINGLE_EAST,
-	SINGLE_WEST,
-	SNOW_OFFSET,
-};
-
-/** Contains the pointers to the arrays *SpriteIDs.
-  * There, all the Sprites are recorded that the
-  * Track Draw system requireds. Note: Pointer arrangement
-  * must match the tracktype number
-  */
-static SpriteID *TrackSpriteIDs[RAILTYPE_END] = {
-	RailSpriteIDs,
-	MonoSpriteIDs,
-	MaglevSpriteIDs
-};
-
 static void DrawTile_Track(TileInfo *ti)
 {
 	uint32 tracktype_offs;
 	byte m5;
-	SpriteID *TrackSet = TrackSpriteIDs[GetRailType(ti->tile)];
+	const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
 	uint32 image;	//XXX ok why the hell is SpriteID 16 bit when all the drawing routines need 32?
 
 	_drawtile_track_palette = SPRITE_PALETTE(PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile)));
@@ -1455,7 +1379,7 @@
 		special = false;
 
 		// select the sprite to use based on the map5 byte.
-		(image = TrackSet[TRACK_Y], m5 == TRACK_BIT_DIAG2) ||
+		(image = rti->base_sprites.track_y, m5 == TRACK_BIT_DIAG2) ||
 		(image++,				m5 == TRACK_BIT_DIAG1) ||
 		(image++,				m5 == TRACK_BIT_UPPER) ||
 		(image++,				m5 == TRACK_BIT_LOWER) ||
@@ -1463,12 +1387,12 @@
 		(image++,				m5 == TRACK_BIT_LEFT) ||
 		(image++,				m5 == (TRACK_BIT_DIAG1|TRACK_BIT_DIAG2)) ||
 
-		(image = TrackSet[TRACK_N_S], m5 == (TRACK_BIT_UPPER|TRACK_BIT_LOWER)) ||
+		(image = rti->base_sprites.track_ns, m5 == (TRACK_BIT_UPPER|TRACK_BIT_LOWER)) ||
 		(image++,				m5 == (TRACK_BIT_LEFT|TRACK_BIT_RIGHT)) ||
 
 		(special=true, false) ||
 
-		(image = TrackSet[TRACK_BASE], !(m5 & (TRACK_BIT_RIGHT|TRACK_BIT_UPPER|TRACK_BIT_DIAG1))) ||
+		(image = rti->base_sprites.ground, !(m5 & (TRACK_BIT_RIGHT|TRACK_BIT_UPPER|TRACK_BIT_DIAG1))) ||
 		(image++,				!(m5 & (TRACK_BIT_LEFT|TRACK_BIT_LOWER|TRACK_BIT_DIAG1))) ||
 		(image++,				!(m5 & (TRACK_BIT_LEFT|TRACK_BIT_UPPER|TRACK_BIT_DIAG2))) ||
 		(image++,				!(m5 & (TRACK_BIT_RIGHT|TRACK_BIT_LOWER|TRACK_BIT_DIAG2))) ||
@@ -1479,34 +1403,34 @@
 			if (f) DrawFoundation(ti, f);
 
 			// default sloped sprites..
-			if (ti->tileh != 0) image = _track_sloped_sprites[ti->tileh - 1] + TrackSet[TRACK_Y];
+			if (ti->tileh != 0) image = _track_sloped_sprites[ti->tileh - 1] + rti->base_sprites.track_y;
 		}
 
 		if ((_m[ti->tile].m2 & RAIL_MAP2LO_GROUND_MASK)==RAIL_GROUND_BROWN) {
 			image = (image & SPRITE_MASK) | PALETTE_TO_BARE_LAND; // use a brown palette
 		 } else if ((_m[ti->tile].m2 & RAIL_MAP2LO_GROUND_MASK)==RAIL_GROUND_ICE_DESERT) {
-			image += TrackSet[SNOW_OFFSET];
+			image += rti->snow_offset;
 		}
 
 		DrawGroundSprite(image);
 
 		if (special) {
-			if (m5 & TRACK_BIT_DIAG1) DrawGroundSprite(TrackSet[SINGLE_Y]);
-			if (m5 & TRACK_BIT_DIAG2) DrawGroundSprite(TrackSet[SINGLE_X]);
-			if (m5 & TRACK_BIT_UPPER) DrawGroundSprite(TrackSet[SINGLE_NORTH]);
-			if (m5 & TRACK_BIT_LOWER) DrawGroundSprite(TrackSet[SINGLE_SOUTH]);
-			if (m5 & TRACK_BIT_LEFT)  DrawGroundSprite(TrackSet[SINGLE_WEST]);
-			if (m5 & TRACK_BIT_RIGHT) DrawGroundSprite(TrackSet[SINGLE_EAST]);
+			if (m5 & TRACK_BIT_DIAG1) DrawGroundSprite(rti->base_sprites.single_y);
+			if (m5 & TRACK_BIT_DIAG2) DrawGroundSprite(rti->base_sprites.single_x);
+			if (m5 & TRACK_BIT_UPPER) DrawGroundSprite(rti->base_sprites.single_n);
+			if (m5 & TRACK_BIT_LOWER) DrawGroundSprite(rti->base_sprites.single_s);
+			if (m5 & TRACK_BIT_LEFT)  DrawGroundSprite(rti->base_sprites.single_w);
+			if (m5 & TRACK_BIT_RIGHT) DrawGroundSprite(rti->base_sprites.single_e);
 		}
 
 		if (_debug_pbs_level >= 1) {
 			byte pbs = PBSTileReserved(ti->tile);
-			if (pbs & TRACK_BIT_DIAG1) DrawGroundSprite(TrackSet[SINGLE_Y] | PALETTE_CRASH);
-			if (pbs & TRACK_BIT_DIAG2) DrawGroundSprite(TrackSet[SINGLE_X] | PALETTE_CRASH);
-			if (pbs & TRACK_BIT_UPPER) DrawGroundSprite(TrackSet[SINGLE_NORTH] | PALETTE_CRASH);
-			if (pbs & TRACK_BIT_LOWER) DrawGroundSprite(TrackSet[SINGLE_SOUTH] | PALETTE_CRASH);
-			if (pbs & TRACK_BIT_LEFT)  DrawGroundSprite(TrackSet[SINGLE_WEST] | PALETTE_CRASH);
-			if (pbs & TRACK_BIT_RIGHT) DrawGroundSprite(TrackSet[SINGLE_EAST] | PALETTE_CRASH);
+			if (pbs & TRACK_BIT_DIAG1) DrawGroundSprite(rti->base_sprites.single_y | PALETTE_CRASH);
+			if (pbs & TRACK_BIT_DIAG2) DrawGroundSprite(rti->base_sprites.single_x | PALETTE_CRASH);
+			if (pbs & TRACK_BIT_UPPER) DrawGroundSprite(rti->base_sprites.single_n | PALETTE_CRASH);
+			if (pbs & TRACK_BIT_LOWER) DrawGroundSprite(rti->base_sprites.single_s | PALETTE_CRASH);
+			if (pbs & TRACK_BIT_LEFT)  DrawGroundSprite(rti->base_sprites.single_w | PALETTE_CRASH);
+			if (pbs & TRACK_BIT_RIGHT) DrawGroundSprite(rti->base_sprites.single_e | PALETTE_CRASH);
 		}
 
 		if (_display_opt & DO_FULL_DETAIL) {
new file mode 100644
--- /dev/null
+++ b/railtypes.c
@@ -0,0 +1,61 @@
+/* $Id: */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "rail.h"
+#include "table/sprites.h"
+
+/** @file railtypes.c
+ * All the railtype-specific information is stored here.
+ */
+
+/** Global Railtype definition
+ */
+RailtypeInfo railtypes[RAILTYPE_END] = {
+	{
+		{
+			SPR_RAIL_TRACK_Y,
+			SPR_RAIL_TRACK_N_S,
+			SPR_RAIL_TRACK_BASE,
+			SPR_RAIL_SINGLE_Y,
+			SPR_RAIL_SINGLE_X,
+			SPR_RAIL_SINGLE_NORTH,
+			SPR_RAIL_SINGLE_SOUTH,
+			SPR_RAIL_SINGLE_EAST,
+			SPR_RAIL_SINGLE_WEST
+		},
+		SPR_RAIL_SNOW_OFFSET,
+		(1 << RAILTYPE_RAIL),
+	},
+	{
+		{
+			SPR_MONO_TRACK_Y,
+			SPR_MONO_TRACK_N_S,
+			SPR_MONO_TRACK_BASE,
+			SPR_MONO_SINGLE_Y,
+			SPR_MONO_SINGLE_X,
+			SPR_MONO_SINGLE_NORTH,
+			SPR_MONO_SINGLE_SOUTH,
+			SPR_MONO_SINGLE_EAST,
+			SPR_MONO_SINGLE_WEST
+		},
+		SPR_MONO_SNOW_OFFSET,
+		(1 << RAILTYPE_MONO),
+	},
+	{
+		{
+			SPR_MGLV_TRACK_Y,
+			SPR_MGLV_TRACK_N_S,
+			SPR_MGLV_TRACK_BASE,
+			SPR_MGLV_SINGLE_Y,
+			SPR_MGLV_SINGLE_X,
+			SPR_MGLV_SINGLE_NORTH,
+			SPR_MGLV_SINGLE_SOUTH,
+			SPR_MGLV_SINGLE_EAST,
+			SPR_MGLV_SINGLE_WEST
+		},
+		SPR_MGLV_SNOW_OFFSET,
+		(1 << RAILTYPE_MAGLEV),
+	},
+};
+