From 74e61a180630aeccd3da64da218f59bebfc4cc6d Mon Sep 17 00:00:00 2001 From: frosch Date: Sun, 26 Jul 2015 12:28:34 +0000 Subject: [PATCH] (svn r27343) -Feature [FS#6315]: [NewGRF] Allow railtype NewGRF to define separate sprites for the fences on either track side. --- src/rail.h | 24 ++++--- src/rail_cmd.cpp | 167 ++++++++++++++++++++++++++--------------------- 2 files changed, 109 insertions(+), 82 deletions(-) diff --git a/src/rail.h b/src/rail.h index 90952f5ea4..539a162b8e 100644 --- a/src/rail.h +++ b/src/rail.h @@ -89,14 +89,22 @@ enum RailTrackBridgeOffset { * the sprites in the original data files. */ enum RailFenceOffset { - RFO_FLAT_X, - RFO_FLAT_Y, - RFO_FLAT_VERT, - RFO_FLAT_HORZ, - RFO_SLOPE_SW, - RFO_SLOPE_SE, - RFO_SLOPE_NE, - RFO_SLOPE_NW, + RFO_FLAT_X_NW, //!< Slope FLAT, Track X, Fence NW + RFO_FLAT_Y_NE, //!< Slope FLAT, Track Y, Fence NE + RFO_FLAT_LEFT, //!< Slope FLAT, Track LEFT, Fence E + RFO_FLAT_UPPER, //!< Slope FLAT, Track UPPER, Fence S + RFO_SLOPE_SW_NW, //!< Slope SW, Track X, Fence NW + RFO_SLOPE_SE_NE, //!< Slope SE, Track Y, Fence NE + RFO_SLOPE_NE_NW, //!< Slope NE, Track X, Fence NW + RFO_SLOPE_NW_NE, //!< Slope NW, Track Y, Fence NE + RFO_FLAT_X_SE, //!< Slope FLAT, Track X, Fence SE + RFO_FLAT_Y_SW, //!< Slope FLAT, Track Y, Fence SW + RFO_FLAT_RIGHT, //!< Slope FLAT, Track RIGHT, Fence W + RFO_FLAT_LOWER, //!< Slope FLAT, Track LOWER, Fence N + RFO_SLOPE_SW_SE, //!< Slope SW, Track X, Fence SE + RFO_SLOPE_SE_SW, //!< Slope SE, Track Y, Fence SW + RFO_SLOPE_NE_SE, //!< Slope NE, Track X, Fence SE + RFO_SLOPE_NW_SW, //!< Slope NW, Track Y, Fence SW }; /** List of rail type labels. */ diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index d44eaa1660..d7a25d8bb1 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -1874,109 +1874,128 @@ static void DrawSingleSignal(TileIndex tile, const RailtypeInfo *rti, Track trac static uint32 _drawtile_track_palette; -static void DrawTrackFence_NW(const TileInfo *ti, SpriteID base_image) -{ - RailFenceOffset rfo = RFO_FLAT_X; - if (ti->tileh & SLOPE_NW) rfo = (ti->tileh & SLOPE_W) ? RFO_SLOPE_SW : RFO_SLOPE_NE; - AddSortableSpriteToDraw(base_image + rfo, _drawtile_track_palette, - ti->x, ti->y + 1, 16, 1, 4, ti->z); -} -static void DrawTrackFence_SE(const TileInfo *ti, SpriteID base_image) -{ - RailFenceOffset rfo = RFO_FLAT_X; - if (ti->tileh & SLOPE_SE) rfo = (ti->tileh & SLOPE_S) ? RFO_SLOPE_SW : RFO_SLOPE_NE; - AddSortableSpriteToDraw(base_image + rfo, _drawtile_track_palette, - ti->x, ti->y + TILE_SIZE - 1, 16, 1, 4, ti->z); -} +/** Offsets for drawing fences */ +struct FenceOffset { + Corner height_ref; //!< Corner to use height offset from. + int x_offs; //!< Bounding box X offset. + int y_offs; //!< Bounding box Y offset. + int x_size; //!< Bounding box X size. + int y_size; //!< Bounding box Y size. +}; -static void DrawTrackFence_NW_SE(const TileInfo *ti, SpriteID base_image) -{ - DrawTrackFence_NW(ti, base_image); - DrawTrackFence_SE(ti, base_image); -} +/** Offsets for drawing fences */ +static FenceOffset _fence_offsets[] = { + { CORNER_INVALID, 0, 1, 16, 1 }, // RFO_FLAT_X_NW + { CORNER_INVALID, 1, 0, 1, 16 }, // RFO_FLAT_Y_NE + { CORNER_W, 8, 8, 1, 1 }, // RFO_FLAT_LEFT + { CORNER_N, 8, 8, 1, 1 }, // RFO_FLAT_UPPER + { CORNER_INVALID, 0, 1, 16, 1 }, // RFO_SLOPE_SW_NW + { CORNER_INVALID, 1, 0, 1, 16 }, // RFO_SLOPE_SE_NE + { CORNER_INVALID, 0, 1, 16, 1 }, // RFO_SLOPE_NE_NW + { CORNER_INVALID, 1, 0, 1, 16 }, // RFO_SLOPE_NW_NE + { CORNER_INVALID, 0, 15, 16, 1 }, // RFO_FLAT_X_SE + { CORNER_INVALID, 15, 0, 1, 16 }, // RFO_FLAT_Y_SW + { CORNER_E, 8, 8, 1, 1 }, // RFO_FLAT_RIGHT + { CORNER_S, 8, 8, 1, 1 }, // RFO_FLAT_LOWER + { CORNER_INVALID, 0, 15, 16, 1 }, // RFO_SLOPE_SW_SE + { CORNER_INVALID, 15, 0, 1, 16 }, // RFO_SLOPE_SE_SW + { CORNER_INVALID, 0, 15, 16, 1 }, // RFO_SLOPE_NE_SE + { CORNER_INVALID, 15, 0, 1, 16 }, // RFO_SLOPE_NW_SW +}; -static void DrawTrackFence_NE(const TileInfo *ti, SpriteID base_image) +/** + * Draw a track fence. + * @param ti Tile drawing information. + * @param base_image First fence sprite. + * @param num_sprites Number of fence sprites. + * @param rfo Fence to draw. + */ +static void DrawTrackFence(const TileInfo *ti, SpriteID base_image, uint num_sprites, RailFenceOffset rfo) { - RailFenceOffset rfo = RFO_FLAT_Y; - if (ti->tileh & SLOPE_NE) rfo = (ti->tileh & SLOPE_E) ? RFO_SLOPE_SE : RFO_SLOPE_NW; - AddSortableSpriteToDraw(base_image + rfo, _drawtile_track_palette, - ti->x + 1, ti->y, 1, 16, 4, ti->z); -} - -static void DrawTrackFence_SW(const TileInfo *ti, SpriteID base_image) -{ - RailFenceOffset rfo = RFO_FLAT_Y; - if (ti->tileh & SLOPE_SW) rfo = (ti->tileh & SLOPE_S) ? RFO_SLOPE_SE : RFO_SLOPE_NW; - AddSortableSpriteToDraw(base_image + rfo, _drawtile_track_palette, - ti->x + TILE_SIZE - 1, ti->y, 1, 16, 4, ti->z); -} - -static void DrawTrackFence_NE_SW(const TileInfo *ti, SpriteID base_image) -{ - DrawTrackFence_NE(ti, base_image); - DrawTrackFence_SW(ti, base_image); + int z = ti->z; + if (_fence_offsets[rfo].height_ref != CORNER_INVALID) { + z += GetSlopePixelZInCorner(RemoveHalftileSlope(ti->tileh), _fence_offsets[rfo].height_ref); + } + AddSortableSpriteToDraw(base_image + (rfo % num_sprites), _drawtile_track_palette, + ti->x + _fence_offsets[rfo].x_offs, + ti->y + _fence_offsets[rfo].y_offs, + _fence_offsets[rfo].x_size, + _fence_offsets[rfo].y_size, + 4, z); } /** - * Draw fence at eastern side of track. + * Draw fence at NW border matching the tile slope. */ -static void DrawTrackFence_NS_1(const TileInfo *ti, SpriteID base_image) +static void DrawTrackFence_NW(const TileInfo *ti, SpriteID base_image, uint num_sprites) { - int z = ti->z + GetSlopePixelZInCorner(RemoveHalftileSlope(ti->tileh), CORNER_W); - AddSortableSpriteToDraw(base_image + RFO_FLAT_VERT, _drawtile_track_palette, - ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z); + RailFenceOffset rfo = RFO_FLAT_X_NW; + if (ti->tileh & SLOPE_NW) rfo = (ti->tileh & SLOPE_W) ? RFO_SLOPE_SW_NW : RFO_SLOPE_NE_NW; + DrawTrackFence(ti, base_image, num_sprites, rfo); } /** - * Draw fence at western side of track. + * Draw fence at SE border matching the tile slope. */ -static void DrawTrackFence_NS_2(const TileInfo *ti, SpriteID base_image) +static void DrawTrackFence_SE(const TileInfo *ti, SpriteID base_image, uint num_sprites) { - int z = ti->z + GetSlopePixelZInCorner(RemoveHalftileSlope(ti->tileh), CORNER_E); - AddSortableSpriteToDraw(base_image + RFO_FLAT_VERT, _drawtile_track_palette, - ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z); + RailFenceOffset rfo = RFO_FLAT_X_SE; + if (ti->tileh & SLOPE_SE) rfo = (ti->tileh & SLOPE_S) ? RFO_SLOPE_SW_SE : RFO_SLOPE_NE_SE; + DrawTrackFence(ti, base_image, num_sprites, rfo); } /** - * Draw fence at southern side of track. + * Draw fence at NE border matching the tile slope. */ -static void DrawTrackFence_WE_1(const TileInfo *ti, SpriteID base_image) +static void DrawTrackFence_NE(const TileInfo *ti, SpriteID base_image, uint num_sprites) { - int z = ti->z + GetSlopePixelZInCorner(RemoveHalftileSlope(ti->tileh), CORNER_N); - AddSortableSpriteToDraw(base_image + RFO_FLAT_HORZ, _drawtile_track_palette, - ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z); + RailFenceOffset rfo = RFO_FLAT_Y_NE; + if (ti->tileh & SLOPE_NE) rfo = (ti->tileh & SLOPE_E) ? RFO_SLOPE_SE_NE : RFO_SLOPE_NW_NE; + DrawTrackFence(ti, base_image, num_sprites, rfo); } /** - * Draw fence at northern side of track. + * Draw fence at SW border matching the tile slope. */ -static void DrawTrackFence_WE_2(const TileInfo *ti, SpriteID base_image) +static void DrawTrackFence_SW(const TileInfo *ti, SpriteID base_image, uint num_sprites) { - int z = ti->z + GetSlopePixelZInCorner(RemoveHalftileSlope(ti->tileh), CORNER_S); - AddSortableSpriteToDraw(base_image + RFO_FLAT_HORZ, _drawtile_track_palette, - ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z); + RailFenceOffset rfo = RFO_FLAT_Y_SW; + if (ti->tileh & SLOPE_SW) rfo = (ti->tileh & SLOPE_S) ? RFO_SLOPE_SE_SW : RFO_SLOPE_NW_SW; + DrawTrackFence(ti, base_image, num_sprites, rfo); } - +/** + * Draw track fences. + * @param ti Tile drawing information. + * @param rti Rail type information. + */ static void DrawTrackDetails(const TileInfo *ti, const RailtypeInfo *rti) { /* Base sprite for track fences. * Note: Halftile slopes only have fences on the upper part. */ + uint num_sprites = 0; SpriteID base_image = GetCustomRailSprite(rti, ti->tile, RTSG_FENCES, IsHalftileSlope(ti->tileh) ? TCX_UPPER_HALFTILE : TCX_NORMAL); - if (base_image == 0) base_image = SPR_TRACK_FENCE_FLAT_X; + if (base_image == 0) { + base_image = SPR_TRACK_FENCE_FLAT_X; + num_sprites = 8; + } + + assert(num_sprites > 0); switch (GetRailGroundType(ti->tile)) { - case RAIL_GROUND_FENCE_NW: DrawTrackFence_NW(ti, base_image); break; - case RAIL_GROUND_FENCE_SE: DrawTrackFence_SE(ti, base_image); break; - case RAIL_GROUND_FENCE_SENW: DrawTrackFence_NW_SE(ti, base_image); break; - case RAIL_GROUND_FENCE_NE: DrawTrackFence_NE(ti, base_image); break; - case RAIL_GROUND_FENCE_SW: DrawTrackFence_SW(ti, base_image); break; - case RAIL_GROUND_FENCE_NESW: DrawTrackFence_NE_SW(ti, base_image); break; - case RAIL_GROUND_FENCE_VERT1: DrawTrackFence_NS_1(ti, base_image); break; - case RAIL_GROUND_FENCE_VERT2: DrawTrackFence_NS_2(ti, base_image); break; - case RAIL_GROUND_FENCE_HORIZ1: DrawTrackFence_WE_1(ti, base_image); break; - case RAIL_GROUND_FENCE_HORIZ2: DrawTrackFence_WE_2(ti, base_image); break; + case RAIL_GROUND_FENCE_NW: DrawTrackFence_NW(ti, base_image, num_sprites); break; + case RAIL_GROUND_FENCE_SE: DrawTrackFence_SE(ti, base_image, num_sprites); break; + case RAIL_GROUND_FENCE_SENW: DrawTrackFence_NW(ti, base_image, num_sprites); + DrawTrackFence_SE(ti, base_image, num_sprites); break; + case RAIL_GROUND_FENCE_NE: DrawTrackFence_NE(ti, base_image, num_sprites); break; + case RAIL_GROUND_FENCE_SW: DrawTrackFence_SW(ti, base_image, num_sprites); break; + case RAIL_GROUND_FENCE_NESW: DrawTrackFence_NE(ti, base_image, num_sprites); + DrawTrackFence_SW(ti, base_image, num_sprites); break; + case RAIL_GROUND_FENCE_VERT1: DrawTrackFence(ti, base_image, num_sprites, RFO_FLAT_LEFT); break; + case RAIL_GROUND_FENCE_VERT2: DrawTrackFence(ti, base_image, num_sprites, RFO_FLAT_RIGHT); break; + case RAIL_GROUND_FENCE_HORIZ1: DrawTrackFence(ti, base_image, num_sprites, RFO_FLAT_UPPER); break; + case RAIL_GROUND_FENCE_HORIZ2: DrawTrackFence(ti, base_image, num_sprites, RFO_FLAT_LOWER); break; case RAIL_GROUND_WATER: { Corner track_corner; if (IsHalftileSlope(ti->tileh)) { @@ -1987,10 +2006,10 @@ static void DrawTrackDetails(const TileInfo *ti, const RailtypeInfo *rti) track_corner = OppositeCorner(GetHighestSlopeCorner(ComplementSlope(ti->tileh))); } switch (track_corner) { - case CORNER_W: DrawTrackFence_NS_1(ti, base_image); break; - case CORNER_S: DrawTrackFence_WE_2(ti, base_image); break; - case CORNER_E: DrawTrackFence_NS_2(ti, base_image); break; - case CORNER_N: DrawTrackFence_WE_1(ti, base_image); break; + case CORNER_W: DrawTrackFence(ti, base_image, num_sprites, RFO_FLAT_LEFT); break; + case CORNER_S: DrawTrackFence(ti, base_image, num_sprites, RFO_FLAT_LOWER); break; + case CORNER_E: DrawTrackFence(ti, base_image, num_sprites, RFO_FLAT_RIGHT); break; + case CORNER_N: DrawTrackFence(ti, base_image, num_sprites, RFO_FLAT_UPPER); break; default: NOT_REACHED(); } break;