# HG changeset patch # User celestar # Date 2005-07-29 21:36:02 # Node ID 8ada8e8f788da0108da767a0b5c879735ce8f024 # Parent e57ed01defe137f6ede261017b51096d4b93e4a0 (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. diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -670,6 +670,7 @@ C_SOURCES += queue.c 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 diff --git a/rail.h b/rail.h --- a/rail.h +++ b/rail.h @@ -139,6 +139,30 @@ typedef enum SignalStates { 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 @@ static inline TransportType GetCrossingT } /** + * 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 TransportType GetCrossingT */ 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 diff --git a/rail_cmd.c b/rail_cmd.c --- a/rail_cmd.c +++ b/rail_cmd.c @@ -1359,87 +1359,11 @@ static void DrawSpecialBuilding(uint32 i 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 @@ static void DrawTile_Track(TileInfo *ti) 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 @@ static void DrawTile_Track(TileInfo *ti) (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 @@ static void DrawTile_Track(TileInfo *ti) 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) { diff --git a/railtypes.c b/railtypes.c 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), + }, +}; +