diff --git a/openttd.h b/openttd.h index 26f45f2191..4e2119fbe1 100644 --- a/openttd.h +++ b/openttd.h @@ -1,4 +1,5 @@ /* $Id$ */ +/** @file openttd.h */ #ifndef OPENTTD_H #define OPENTTD_H @@ -71,8 +72,8 @@ typedef byte PlayerID; typedef byte OrderID; typedef byte CargoID; typedef uint16 StringID; -typedef uint32 SpriteID; -typedef uint32 PalSpriteID; +typedef uint32 SpriteID; //! The number of a sprite, without mapping bits and colortables +typedef uint32 PalSpriteID; //! The number of a sprite plus all the mapping bits and colortables typedef uint32 CursorID; typedef uint16 EngineID; //! All enginenumbers should be of this type typedef uint16 UnitID; //! All unitnumber stuff is of this type (or anyway, should be) diff --git a/rail.h b/rail.h index 8632fe368b..96203e5ab7 100644 --- a/rail.h +++ b/rail.h @@ -201,6 +201,11 @@ typedef struct RailtypeInfo { * @note: Something more flexible might be desirable in the future. */ SpriteID total_offset; + + /** + * Bridge offset + */ + SpriteID bridge_offset; } RailtypeInfo; extern const RailtypeInfo _railtypes[RAILTYPE_END]; @@ -592,5 +597,5 @@ static inline bool IsCompatibleRail(RailType enginetype, RailType tiletype) void DrawTrackBits(TileInfo *ti, TrackBits track, bool earth, bool snow, bool flat); void DrawTrainDepotSprite(int x, int y, int image, RailType railtype); void DrawDefaultWaypointSprite(int x, int y, RailType railtype); - #endif /* RAIL_H */ + diff --git a/railtypes.h b/railtypes.h index bb1b6a10cd..be097383cc 100644 --- a/railtypes.h +++ b/railtypes.h @@ -41,6 +41,9 @@ const RailtypeInfo _railtypes[] = { /* main offset */ 0, + + /* bridge offset */ + 0, }, /** Monorail */ @@ -77,6 +80,9 @@ const RailtypeInfo _railtypes[] = { /* main offset */ 82, + + /* bridge offset */ + 16, }, /** Maglev */ @@ -113,6 +119,9 @@ const RailtypeInfo _railtypes[] = { /* main offset */ 164, + + /* bridge offset */ + 24, }, }; diff --git a/tunnelbridge_cmd.c b/tunnelbridge_cmd.c index dec5e6a3c0..b5bcfe3d53 100644 --- a/tunnelbridge_cmd.c +++ b/tunnelbridge_cmd.c @@ -968,8 +968,8 @@ extern const byte _road_sloped_sprites[14]; static void DrawBridgePillars(const TileInfo *ti, int x, int y, int z) { - const uint32 *b; - uint32 image; + const PalSpriteID *b; + PalSpriteID image; int piece; b = _bridge_poles_table[GetBridgeType(ti->tile)]; @@ -1030,11 +1030,27 @@ uint GetBridgeFoundation(uint tileh, byte direction) { return 0; } +/** + * Draws a tunnel of bridge tile. + * For tunnels, this is rather simple, as you only needa draw the entrance. + * Bridges are a bit more complex. base_offset is where the sprite selection comes into play + * and it works a bit like a bitmask.

For bridge heads: + *

+ * For middle parts: + * + * Please note that in this code, "roads" are treated as railtype 1, whilst the real railtypes are 0, 2 and 3 + */ static void DrawTile_TunnelBridge(TileInfo *ti) { uint32 image; - uint tmp; - const uint32 *b; + const PalSpriteID *b; bool ice = _m[ti->tile].m4 & 0x80; // draw tunnel? @@ -1053,19 +1069,24 @@ static void DrawTile_TunnelBridge(TileInfo *ti) AddSortableSpriteToDraw(image+1, ti->x + 15, ti->y + 15, 1, 1, 8, (byte)ti->z); // draw bridge? } else if ((byte)ti->map5 & 0x80) { - // get type of track on the bridge. - tmp = _m[ti->tile].m3; - if (ti->map5 & 0x40) tmp >>= 4; - tmp &= 0xF; + RailType rt; + int base_offset; - // 0 = rail bridge - // 1 = road bridge - // 2 = monorail bridge - // 3 = maglev bridge + if (HASBIT(ti->map5, 1)) { /* This is a road bridge */ + base_offset = 8; + } else { /* Rail bridge */ + if (HASBIT(ti->map5, 6)) { /* The bits we need depend on the fact whether it is a bridge head or not */ + rt = GB(_m[ti->tile].m3, 4, 3); + } else { + rt = GB(_m[ti->tile].m3, 0, 3); + } - // add direction and fix stuff. - if (tmp != 0) tmp++; - tmp = (ti->map5&3) + (tmp*2); + base_offset = GetRailTypeInfo(rt)->bridge_offset; + assert(base_offset != 8); /* This one is used for roads */ + } + + /* as the lower 3 bits are used for other stuff, make sure they are clear */ + assert( (base_offset & 0x07) == 0x00); if (!(ti->map5 & 0x40)) { // bridge ramps @@ -1077,14 +1098,14 @@ static void DrawTile_TunnelBridge(TileInfo *ti) if (ti->tileh != 0) image = SPR_RAIL_TRACK_Y + _track_sloped_sprites[ti->tileh - 1]; } - // bridge ending. - 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" ? - if (ti->map5 & 0x20) b += 2; // which side + /* Cope for the direction of the bridge */ + if (HASBIT(ti->map5, 0)) base_offset++; - image = *b; + if (ti->map5 & 0x20) base_offset += 2; // which side + if (ti->tileh == 0) base_offset += 4; // sloped bridge head + + /* Table number 6 always refers to the bridge heads for any bridge type */ + image = GetBridgeSpriteTable(GetBridgeType(ti->tile), 6)[base_offset]; if (!ice) { DrawClearLandTile(ti, 3); @@ -1101,6 +1122,7 @@ static void DrawTile_TunnelBridge(TileInfo *ti) int x,y; image = GB(ti->map5, 3, 2); // type of stuff under bridge (only defined for 0,1) + /** @todo So why do we even WASTE that one bit?! (map5, bit 4) */ assert(image <= 1); if (!(ti->map5 & 0x20)) { @@ -1134,16 +1156,22 @@ static void DrawTile_TunnelBridge(TileInfo *ti) // road image = SPR_ROAD_Y + (ti->map5 & 1); if (ti->tileh != 0) image = _road_sloped_sprites[ti->tileh - 1] + 0x53F; - if (ice) image += 19; // ice? + if (ice) image += 19; } DrawGroundSprite(image); } + + /* Cope for the direction of the bridge */ + if (HASBIT(ti->map5, 0)) base_offset += 4; + + /* base_offset needs to be 0 due to the structure of the sprite table see table/bridge_land.h */ + assert( (base_offset & 0x03) == 0x00); // get bridge sprites - b = GetBridgeSpriteTable(GetBridgeType(ti->tile), GetBridgePiece(ti->tile)) + tmp * 4; + b = GetBridgeSpriteTable(GetBridgeType(ti->tile), GetBridgePiece(ti->tile)) + base_offset; z = GetBridgeHeight(ti) + 5; - // draw rail + // draw rail or road component image = b[0]; if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image); AddSortableSpriteToDraw(image, ti->x, ti->y, (ti->map5&1)?11:16, (ti->map5&1)?16:11, 1, z); @@ -1153,7 +1181,7 @@ static void DrawTile_TunnelBridge(TileInfo *ti) image = b[1]; if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image); - // draw roof + // draw roof, the component of the bridge which is logically between the vehicle and the camera if (ti->map5&1) { x += 12; if (image & SPRITE_MASK) AddSortableSpriteToDraw(image, x,y, 1, 16, 0x28, z);