Changeset - r22170:e59c2f7a1876
[Not reviewed]
master
0 2 0
frosch - 9 years ago 2015-07-26 12:28:34
frosch@openttd.org
(svn r27343) -Feature [FS#6315]: [NewGRF] Allow railtype NewGRF to define separate sprites for the fences on either track side.
2 files changed with 112 insertions and 85 deletions:
0 comments (0 inline, 0 general)
src/rail.h
Show inline comments
 
@@ -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. */
src/rail_cmd.cpp
Show inline comments
 
@@ -1874,109 +1874,128 @@ static void DrawSingleSignal(TileIndex t
 
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)
 

	
 
/** 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.
 
};
 

	
 
/** 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
 
};
 

	
 
/**
 
 * 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_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);
 
}
 

	
 
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 TileI
 
				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;
0 comments (0 inline, 0 general)