summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/rail.h24
-rw-r--r--src/rail_cmd.cpp167
2 files changed, 109 insertions, 82 deletions
diff --git a/src/rail.h b/src/rail.h
index 90952f5ea..539a162b8 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 d44eaa166..d7a25d8bb 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);
-}
-static void DrawTrackFence_NW_SE(const TileInfo *ti, SpriteID base_image)
-{
- DrawTrackFence_NW(ti, base_image);
- DrawTrackFence_SE(ti, base_image);
-}
-
-static void DrawTrackFence_NE(const TileInfo *ti, SpriteID base_image)
-{
- 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);
-}
+/** 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_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);
-}
+/** 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_SW(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)
{
- 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;