Changeset - r14477:752d803ed3be
[Not reviewed]
master
0 12 2
peter1138 - 14 years ago 2010-02-07 22:22:54
peter1138@openttd.org
(svn r19056) -Add: [NewGRF] Action 3/2/1 (i.e. new graphics) support for rail types. (To be documented...)
14 files changed with 608 insertions and 55 deletions:
0 comments (0 inline, 0 general)
source.list
Show inline comments
 
@@ -206,6 +206,7 @@ newgrf_house.h
 
newgrf_industries.h
 
newgrf_industrytiles.h
 
newgrf_properties.h
 
newgrf_railtype.h
 
newgrf_sound.h
 
newgrf_spritegroup.h
 
newgrf_station.h
 
@@ -745,6 +746,7 @@ newgrf_generic.cpp
 
newgrf_house.cpp
 
newgrf_industries.cpp
 
newgrf_industrytiles.cpp
 
newgrf_railtype.cpp
 
newgrf_sound.cpp
 
newgrf_spritegroup.cpp
 
newgrf_station.cpp
src/elrail.cpp
Show inline comments
 
@@ -64,6 +64,8 @@
 
#include "elrail_func.h"
 
#include "engine_base.h"
 
#include "company_base.h"
 
#include "rail.h"
 
#include "newgrf_railtype.h"
 

	
 
#include "table/sprites.h"
 
#include "table/elrail_data.h"
 
@@ -165,7 +167,9 @@ static TrackBits MaskWireBits(TileIndex 
 
 */
 
static inline SpriteID GetWireBase(TileIndex tile)
 
{
 
	return SPR_WIRE_BASE;
 
	const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(tile));
 
	SpriteID wires = GetCustomRailSprite(rti, tile, RTSG_WIRES);
 
	return wires == 0 ? SPR_WIRE_BASE : wires;
 
}
 

	
 
/**
 
@@ -173,7 +177,9 @@ static inline SpriteID GetWireBase(TileI
 
 */
 
static inline SpriteID GetPylonBase(TileIndex tile)
 
{
 
	return SPR_PYLON_BASE;
 
	const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(tile));
 
	SpriteID pylons = GetCustomRailSprite(rti, tile, RTSG_PYLONS);
 
	return pylons == 0 ? SPR_PYLON_BASE : pylons;
 
}
 

	
 
/** Corrects the tileh for certain tile types. Returns an effective tileh for the track on the tile.
src/newgrf.cpp
Show inline comments
 
@@ -3037,6 +3037,7 @@ static void NewSpriteGroup(ByteReader *b
 
				case GSF_STATION:
 
				case GSF_CANAL:
 
				case GSF_CARGOS:
 
				case GSF_RAILTYPES:
 
				{
 
					byte sprites     = _cur_grffile->spriteset_numents;
 
					byte num_loaded  = type;
 
@@ -3519,6 +3520,35 @@ static void CargoMapSpriteGroup(ByteRead
 
	}
 
}
 

	
 
static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount)
 
{
 
	uint8 *railtypes = AllocaM(uint8, idcount);
 
	for (uint i = 0; i < idcount; i++) {
 
		railtypes[i] = _cur_grffile->railtype_map[buf->ReadByte()];
 
	}
 

	
 
	uint8 cidcount = buf->ReadByte();
 
	for (uint c = 0; c < cidcount; c++) {
 
		uint8 ctype = buf->ReadByte();
 
		uint16 groupid = buf->ReadWord();
 
		if (!IsValidGroupID(groupid, "RailTypeMapSpriteGroup")) continue;
 

	
 
		if (ctype >= RTSG_END) continue;
 

	
 
		extern RailtypeInfo _railtypes[RAILTYPE_END];
 
		for (uint i = 0; i < idcount; i++) {
 
			if (railtypes[i] != INVALID_RAILTYPE) {
 
				RailtypeInfo *rti = &_railtypes[railtypes[i]];
 

	
 
				rti->group[ctype] = _cur_grffile->spritegroups[groupid];
 
			}
 
		}
 
	}
 

	
 
	/* Railtypes do not use the default group. */
 
	buf->ReadWord();
 
}
 

	
 

	
 
/* Action 0x03 */
 
static void FeatureMapSpriteGroup(ByteReader *buf)
 
@@ -3594,6 +3624,10 @@ static void FeatureMapSpriteGroup(ByteRe
 
			CargoMapSpriteGroup(buf, idcount);
 
			return;
 

	
 
		case GSF_RAILTYPES:
 
			RailTypeMapSpriteGroup(buf, idcount);
 
			break;
 

	
 
		default:
 
			grfmsg(1, "FeatureMapSpriteGroup: Unsupported feature %d, skipping", feature);
 
			return;
 
@@ -6446,6 +6480,9 @@ static void AfterLoadGRFs()
 
	/* Load old shore sprites in new position, if they were replaced by ActionA */
 
	ActivateOldShore();
 

	
 
	/* Set up custom rail types */
 
	InitRailTypes();
 

	
 
	Engine *e;
 
	FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
 
		if (_gted[e->index].rv_max_speed != 0) {
src/newgrf_railtype.cpp
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file newgrf_railtype.cpp NewGRF handling of rail types. */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "variables.h"
 
#include "debug.h"
 
#include "strings_type.h"
 
#include "rail.h"
 
#include "road_map.h"
 
#include "newgrf.h"
 
#include "newgrf_callbacks.h"
 
#include "newgrf_commons.h"
 
#include "newgrf_railtype.h"
 
#include "newgrf_spritegroup.h"
 

	
 
static uint32 RailTypeGetRandomBits(const ResolverObject *object)
 
{
 
	return 0;
 
}
 

	
 
static uint32 RailTypeGetTriggers(const ResolverObject *object)
 
{
 
	return 0;
 
}
 

	
 
static void RailTypeSetTriggers(const ResolverObject *object, int triggers)
 
{
 
}
 

	
 
static uint32 RailTypeGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
 
{
 
	TileIndex tile = object->u.routes.tile;
 

	
 
	if (tile == INVALID_TILE) {
 
		switch (variable) {
 
			case 0x40: return 0;
 
			case 0x41: return 0;
 
			case 0x42: return 0;
 
		}
 
	}
 

	
 
	switch (variable) {
 
		case 0x40: return GetTerrainType(tile);
 
		case 0x41: return 0;
 
		case 0x42: return IsLevelCrossingTile(tile) && IsCrossingBarred(tile);
 
	}
 

	
 
	DEBUG(grf, 1, "Unhandled rail type tile property 0x%X", variable);
 

	
 
	*available = false;
 
	return UINT_MAX;
 
}
 

	
 
static const SpriteGroup *RailTypeResolveReal(const ResolverObject *object, const RealSpriteGroup *group)
 
{
 
	if (group->num_loading > 0) return group->loading[0];
 
	if (group->num_loaded  > 0) return group->loaded[0];
 
	return NULL;
 
}
 

	
 
static inline void NewRailTypeResolver(ResolverObject *res, TileIndex tile)
 
{
 
	res->GetRandomBits = &RailTypeGetRandomBits;
 
	res->GetTriggers   = &RailTypeGetTriggers;
 
	res->SetTriggers   = &RailTypeSetTriggers;
 
	res->GetVariable   = &RailTypeGetVariable;
 
	res->ResolveReal   = &RailTypeResolveReal;
 

	
 
	res->u.routes.tile = tile;
 

	
 
	res->callback        = CBID_NO_CALLBACK;
 
	res->callback_param1 = 0;
 
	res->callback_param2 = 0;
 
	res->last_value      = 0;
 
	res->trigger         = 0;
 
	res->reseed          = 0;
 
	res->count           = 0;
 
}
 

	
 
SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSpriteGroup rtsg)
 
{
 
	assert(rtsg < RTSG_END);
 

	
 
	if (rti->group[rtsg] == NULL) return 0;
 

	
 
	const SpriteGroup *group;
 
	ResolverObject object;
 

	
 
	NewRailTypeResolver(&object, tile);
 

	
 
	group = SpriteGroup::Resolve(rti->group[rtsg], &object);
 
	if (group == NULL || group->GetNumResults() == 0) return 0;
 

	
 
	return group->GetResult();
 
}
 

	
 
uint8 GetReverseRailTypeTranslation(RailType railtype, const GRFFile *grffile)
 
{
 
	/* No rail type table present, return rail type as-is */
 
	if (grffile->railtype_max == 0) return railtype;
 

	
 
	/* Look for a matching rail type label in the table */
 
	RailTypeLabel label = GetRailTypeInfo(railtype)->label;
 
	for (uint i = 0; i < grffile->railtype_max; i++) {
 
		if (label == grffile->railtype_list[i]) return i;
 
	}
 

	
 
	/* If not found, return as invalid */
 
	return 0xFF;
 
}
src/newgrf_railtype.h
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
#ifndef NEWGRF_RAILTYPE_H
 
#define NEWGRF_RAILTYPE_H
 

	
 
#include "rail.h"
 

	
 
SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSpriteGroup rtsg);
 

	
 
uint8 GetReverseRailTypeTranslation(RailType railtype, const GRFFile *grffile);
 

	
 
#endif /* NEWGRF_RAILTYPE_H */
src/newgrf_spritegroup.h
Show inline comments
 
@@ -339,6 +339,9 @@ struct ResolverObject {
 
			uint8 count;
 
			uint8 station_size;
 
		} generic;
 
		struct {
 
			TileIndex tile;
 
		} routes;
 
	} u;
 

	
 
	uint32 (*GetRandomBits)(const struct ResolverObject*);
src/newgrf_station.cpp
Show inline comments
 
@@ -20,6 +20,7 @@
 
#include "newgrf_station.h"
 
#include "newgrf_spritegroup.h"
 
#include "newgrf_sound.h"
 
#include "newgrf_railtype.h"
 
#include "town.h"
 
#include "newgrf_town.h"
 
#include "date_func.h"
 
@@ -442,7 +443,7 @@ static uint32 StationGetVariable(const R
 
			if (!HasBit(_svc.valid, 1)) { _svc.v41 = GetPlatformInfoHelper(tile, true,  false, false); SetBit(_svc.valid, 1); }
 
			return _svc.v41;
 

	
 
		case 0x42: return GetTerrainType(tile) | (GetRailType(tile) << 8);
 
		case 0x42: return GetTerrainType(tile) | (GetReverseRailTypeTranslation(GetRailType(tile), object->u.station.statspec->grffile) << 8);
 
		case 0x43: return st->owner; // Station owner
 
		case 0x44: return HasStationReservation(tile) ? 7 : 4; // PBS status
 
		case 0x45:
src/rail.h
Show inline comments
 
@@ -30,6 +30,54 @@ enum RailTypeFlags {
 
};
 
DECLARE_ENUM_AS_BIT_SET(RailTypeFlags);
 

	
 
struct SpriteGroup;
 

	
 
enum RailTypeSpriteGroup {
 
	RTSG_CURSORS,     ///< Cursor and toolbar icon images
 
	RTSG_OVERLAY,     ///< Images for overlaying track
 
	RTSG_GROUND,      ///< Main group of ground images
 
	RTSG_TUNNEL,      ///< Main group of ground images for snow or desert
 
	RTSG_WIRES,       ///< Catenary wires
 
	RTSG_PYLONS,      ///< Catenary pylons
 
	RTSG_BRIDGE,      ///< Bridge surface images
 
	RTSG_CROSSING,    ///< Level crossing overlay images
 
	RTSG_DEPOT,       ///< Depot images
 
	RTSG_FENCES,      ///< Fence images
 
	RTSG_END,
 
};
 

	
 
/**
 
 * Offsets for sprites within an overlay/underlay set.
 
 * These are the same for overlay and underlay sprites.
 
 */
 
enum RailTrackOffset {
 
	RTO_X,            ///< Piece of rail in X direction
 
	RTO_Y,            ///< Piece of rail in Y direction
 
	RTO_N,            ///< Piece of rail in northern corner
 
	RTO_S,            ///< Piece of rail in southern corner
 
	RTO_E,            ///< Piece of rail in eastern corner
 
	RTO_W,            ///< Piece of rail in western corner
 
	RTO_SLOPE_NE,     ///< Piece of rail on slope with north-east raised
 
	RTO_SLOPE_SE,     ///< Piece of rail on slope with south-east raised
 
	RTO_SLOPE_SW,     ///< Piece of rail on slope with south-west raised
 
	RTO_SLOPE_NW,     ///< Piece of rail on slope with north-west raised
 
	RTO_CROSSING_XY,  ///< Crossing of X and Y rail, with ballast
 
	RTO_JUNCTION_SW,  ///< Ballast for junction 'pointing' SW
 
	RTO_JUNCTION_NE,  ///< Ballast for junction 'pointing' NE
 
	RTO_JUNCTION_SE,  ///< Ballast for junction 'pointing' SE
 
	RTO_JUNCTION_NW,  ///< Ballast for junction 'pointing' NW
 
	RTO_JUNCTION_NSEW,///< Ballast for full junction
 
};
 

	
 
/**
 
 * Offsets for spries within a bridge surface overlay set.
 
 */
 
enum RailTrackBridgeOffset {
 
	RTBO_X,     ///< Piece of rail in X direction
 
	RTBO_Y,     ///< Piece of rail in Y direction
 
	RTBO_SLOPE, ///< Sloped rail pieces, in order NE, SE, SW, NW
 
};
 

	
 
/** Offsets from base sprite for fence sprites. These are in the order of
 
 *  the sprites in the original data files.
 
 */
 
@@ -154,6 +202,16 @@ struct RailtypeInfo {
 
	 * Unique 32 bit rail type identifier
 
	 */
 
	RailTypeLabel label;
 

	
 
	/**
 
	 * Sprite groups for resolving sprites
 
	 */
 
	const SpriteGroup *group[RTSG_END];
 

	
 
	inline bool UsesOverlay() const
 
	{
 
		return this->group[RTSG_GROUND] != NULL;
 
	}
 
};
 

	
 

	
 
@@ -287,6 +345,11 @@ RailType GetRailTypeByLabel(RailTypeLabe
 
void ResetRailTypes();
 

	
 
/**
 
 * Resolve sprites of custom rail types
 
 */
 
void InitRailTypes();
 

	
 
/**
 
 * Allocate a new rail type label
 
 */
 
RailType AllocateRailType(RailTypeLabel label);
src/rail_cmd.cpp
Show inline comments
 
@@ -19,6 +19,8 @@
 
#include "pathfinder/yapf/yapf_cache.h"
 
#include "newgrf_engine.h"
 
#include "landscape_type.h"
 
#include "newgrf_railtype.h"
 
#include "newgrf_commons.h"
 
#include "train.h"
 
#include "variables.h"
 
#include "autoslope.h"
 
@@ -52,6 +54,37 @@ void ResetRailTypes()
 
	memcpy(_railtypes, _original_railtypes, sizeof(_original_railtypes));
 
}
 

	
 
void ResolveRailTypeGUISprites(RailtypeInfo *rti)
 
{
 
	SpriteID cursors_base = GetCustomRailSprite(rti, INVALID_TILE, RTSG_CURSORS);
 
	if (cursors_base != 0) {
 
		rti->gui_sprites.build_ns_rail = cursors_base +  0;
 
		rti->gui_sprites.build_x_rail  = cursors_base +  1;
 
		rti->gui_sprites.build_ew_rail = cursors_base +  2;
 
		rti->gui_sprites.build_y_rail  = cursors_base +  3;
 
		rti->gui_sprites.auto_rail     = cursors_base +  4;
 
		rti->gui_sprites.build_depot   = cursors_base +  5;
 
		rti->gui_sprites.build_tunnel  = cursors_base +  6;
 
		rti->gui_sprites.convert_rail  = cursors_base +  7;
 
		rti->cursor.rail_ns   = cursors_base +  8;
 
		rti->cursor.rail_swne = cursors_base +  9;
 
		rti->cursor.rail_ew   = cursors_base + 10;
 
		rti->cursor.rail_nwse = cursors_base + 11;
 
		rti->cursor.autorail  = cursors_base + 12;
 
		rti->cursor.depot     = cursors_base + 13;
 
		rti->cursor.tunnel    = cursors_base + 14;
 
		rti->cursor.convert   = cursors_base + 15;
 
	}
 
}
 

	
 
void InitRailTypes()
 
{
 
	for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
 
		RailtypeInfo *rti = &_railtypes[rt];
 
		ResolveRailTypeGUISprites(rti);
 
	}
 
}
 

	
 
RailType AllocateRailType(RailTypeLabel label)
 
{
 
	for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
 
@@ -1709,10 +1742,11 @@ static void DrawTrackFence_WE_2(const Ti
 
}
 

	
 

	
 
static void DrawTrackDetails(const TileInfo *ti)
 
static void DrawTrackDetails(const TileInfo *ti, const RailtypeInfo *rti)
 
{
 
	/* Base sprite for track fences. */
 
	SpriteID base_image = SPR_TRACK_FENCE_FLAT_X;
 
	SpriteID base_image = GetCustomRailSprite(rti, ti->tile, RTSG_FENCES);
 
	if (base_image == 0) base_image = SPR_TRACK_FENCE_FLAT_X;
 

	
 
	switch (GetRailGroundType(ti->tile)) {
 
		case RAIL_GROUND_FENCE_NW:     DrawTrackFence_NW(ti, base_image);    break;
 
@@ -1747,6 +1781,162 @@ static void DrawTrackDetails(const TileI
 
	}
 
}
 

	
 
/* SubSprite for drawing the track halftile of 'three-corners-raised'-sloped rail sprites. */
 
static const int INF = 1000; // big number compared to tilesprite size
 
static const SubSprite _halftile_sub_sprite[4] = {
 
	{ -INF    , -INF  , 32 - 33, INF     }, // CORNER_W, clip 33 pixels from right
 
	{ -INF    ,  0 + 7, INF    , INF     }, // CORNER_S, clip 7 pixels from top
 
	{ -31 + 33, -INF  , INF    , INF     }, // CORNER_E, clip 33 pixels from left
 
	{ -INF    , -INF  , INF    , 30 - 23 }  // CORNER_N, clip 23 pixels from bottom
 
};
 

	
 
static inline void DrawTrackSprite(SpriteID sprite, PaletteID pal, const TileInfo *ti, Slope s)
 
{
 
	DrawGroundSprite(sprite, pal, NULL, 0, (ti->tileh & s) ? -8 : 0);
 
}
 

	
 
static void DrawTrackBitsOverlay(TileInfo *ti, TrackBits track, const RailtypeInfo *rti)
 
{
 
	RailGroundType rgt = GetRailGroundType(ti->tile);
 
	Foundation f = GetRailFoundation(ti->tileh, track);
 
	Corner halftile_corner = CORNER_INVALID;
 

	
 
	if (IsNonContinuousFoundation(f)) {
 
		/* Save halftile corner */
 
		halftile_corner = (f == FOUNDATION_STEEP_BOTH ? GetHighestSlopeCorner(ti->tileh) : GetHalftileFoundationCorner(f));
 
		/* Draw lower part first */
 
		track &= ~CornerToTrackBits(halftile_corner);
 
		f = (f == FOUNDATION_STEEP_BOTH ? FOUNDATION_STEEP_LOWER : FOUNDATION_NONE);
 
	}
 

	
 
	DrawFoundation(ti, f);
 
	/* DrawFoundation modifies ti */
 

	
 
	/* Draw ground */
 
	if (track == TRACK_BIT_NONE && rgt == RAIL_GROUND_WATER) {
 
		if (IsSteepSlope(ti->tileh)) {
 
			DrawShoreTile(ti->tileh);
 
		} else {
 
			DrawGroundSprite(SPR_FLAT_WATER_TILE, PAL_NONE);
 
		}
 
	} else {
 
		SpriteID image;
 

	
 
		switch (rgt) {
 
			case RAIL_GROUND_BARREN:     image = SPR_FLAT_BARE_LAND;  break;
 
			case RAIL_GROUND_ICE_DESERT: image = SPR_FLAT_SNOW_DESERT_TILE; break;
 
			default:                     image = SPR_FLAT_GRASS_TILE; break;
 
		}
 

	
 
		image += _tileh_to_sprite[ti->tileh];
 

	
 
		DrawGroundSprite(image, PAL_NONE);
 
	}
 

	
 
	SpriteID overlay = GetCustomRailSprite(rti, ti->tile, RTSG_OVERLAY);
 
	SpriteID ground = GetCustomRailSprite(rti, ti->tile, RTSG_GROUND);
 
	TrackBits pbs = _settings_client.gui.show_track_reservation ? GetRailReservationTrackBits(ti->tile) : TRACK_BIT_NONE;
 

	
 
	if (track == TRACK_BIT_NONE) {
 
		/* Half-tile foundation, no track here? */
 
	} else if (ti->tileh == SLOPE_NW && track == TRACK_BIT_Y) {
 
		DrawGroundSprite(ground + RTO_SLOPE_NW, PAL_NONE);
 
		if (pbs != TRACK_BIT_NONE) DrawGroundSprite(overlay + 9, PALETTE_CRASH);
 
	} else if (ti->tileh == SLOPE_NE && track == TRACK_BIT_X) {
 
		DrawGroundSprite(ground + RTO_SLOPE_NE, PAL_NONE);
 
		if (pbs != TRACK_BIT_NONE) DrawGroundSprite(overlay + 6, PALETTE_CRASH);
 
	} else if (ti->tileh == SLOPE_SE && track == TRACK_BIT_Y) {
 
		DrawGroundSprite(ground + RTO_SLOPE_SE, PAL_NONE);
 
		if (pbs != TRACK_BIT_NONE) DrawGroundSprite(overlay + 7, PALETTE_CRASH);
 
	} else if (ti->tileh == SLOPE_SW && track == TRACK_BIT_X) {
 
		DrawGroundSprite(ground + RTO_SLOPE_SW, PAL_NONE);
 
		if (pbs != TRACK_BIT_NONE) DrawGroundSprite(overlay + 8, PALETTE_CRASH);
 
	} else {
 
		switch (track) {
 
			/* Draw single ground sprite when not overlapping. No track overlay
 
			 * is necessary for these sprites. */
 
			case TRACK_BIT_X:     DrawGroundSprite(ground + RTO_X, PAL_NONE); break;
 
			case TRACK_BIT_Y:     DrawGroundSprite(ground + RTO_Y, PAL_NONE); break;
 
			case TRACK_BIT_UPPER: DrawTrackSprite(ground + RTO_N, PAL_NONE, ti, SLOPE_N); break;
 
			case TRACK_BIT_LOWER: DrawTrackSprite(ground + RTO_S, PAL_NONE, ti, SLOPE_S); break;
 
			case TRACK_BIT_RIGHT: DrawTrackSprite(ground + RTO_E, PAL_NONE, ti, SLOPE_E); break;
 
			case TRACK_BIT_LEFT:  DrawTrackSprite(ground + RTO_W, PAL_NONE, ti, SLOPE_W); break;
 
			case TRACK_BIT_CROSS: DrawGroundSprite(ground + RTO_CROSSING_XY, PAL_NONE); break;
 
			case TRACK_BIT_HORZ:  DrawTrackSprite(ground + RTO_N, PAL_NONE, ti, SLOPE_N);
 
			                      DrawTrackSprite(ground + RTO_S, PAL_NONE, ti, SLOPE_S); break;
 
			case TRACK_BIT_VERT:  DrawTrackSprite(ground + RTO_E, PAL_NONE, ti, SLOPE_E);
 
			                      DrawTrackSprite(ground + RTO_W, PAL_NONE, ti, SLOPE_W); break;
 

	
 
			default:
 
				/* We're drawing a junction tile */
 
				if ((track & TRACK_BIT_3WAY_NE) == 0) {
 
					DrawGroundSprite(ground + RTO_JUNCTION_SW, PAL_NONE);
 
				} else if ((track & TRACK_BIT_3WAY_SW) == 0) {
 
					DrawGroundSprite(ground + RTO_JUNCTION_NE, PAL_NONE);
 
				} else if ((track & TRACK_BIT_3WAY_NW) == 0) {
 
					DrawGroundSprite(ground + RTO_JUNCTION_SE, PAL_NONE);
 
				} else if ((track & TRACK_BIT_3WAY_SE) == 0) {
 
					DrawGroundSprite(ground + RTO_JUNCTION_NW, PAL_NONE);
 
				} else {
 
					DrawGroundSprite(ground + RTO_JUNCTION_NSEW, PAL_NONE);
 
				}
 

	
 
				/* Mask out PBS bits as we shall draw them afterwards anyway. */
 
				track &= ~pbs;
 

	
 
				/* Draw regular track bits */
 
				if (track & TRACK_BIT_X)     DrawGroundSprite(overlay + RTO_X, PAL_NONE);
 
				if (track & TRACK_BIT_Y)     DrawGroundSprite(overlay + RTO_Y, PAL_NONE);
 
				if (track & TRACK_BIT_UPPER) DrawGroundSprite(overlay + RTO_N, PAL_NONE);
 
				if (track & TRACK_BIT_LOWER) DrawGroundSprite(overlay + RTO_S, PAL_NONE);
 
				if (track & TRACK_BIT_RIGHT) DrawGroundSprite(overlay + RTO_E, PAL_NONE);
 
				if (track & TRACK_BIT_LEFT)  DrawGroundSprite(overlay + RTO_W, PAL_NONE);
 
		}
 

	
 
		/* Draw reserved track bits */
 
		if (pbs & TRACK_BIT_X)     DrawGroundSprite(overlay + RTO_X, PALETTE_CRASH);
 
		if (pbs & TRACK_BIT_Y)     DrawGroundSprite(overlay + RTO_Y, PALETTE_CRASH);
 
		if (pbs & TRACK_BIT_UPPER) DrawTrackSprite(overlay + RTO_N, PALETTE_CRASH, ti, SLOPE_N);
 
		if (pbs & TRACK_BIT_LOWER) DrawTrackSprite(overlay + RTO_S, PALETTE_CRASH, ti, SLOPE_S);
 
		if (pbs & TRACK_BIT_RIGHT) DrawTrackSprite(overlay + RTO_E, PALETTE_CRASH, ti, SLOPE_E);
 
		if (pbs & TRACK_BIT_LEFT)  DrawTrackSprite(overlay + RTO_W, PALETTE_CRASH, ti, SLOPE_W);
 
	}
 

	
 
	if (IsValidCorner(halftile_corner)) {
 
		DrawFoundation(ti, HalftileFoundation(halftile_corner));
 

	
 
		/* Draw higher halftile-overlay: Use the sloped sprites with three corners raised. They probably best fit the lightning. */
 
		Slope fake_slope = SlopeWithThreeCornersRaised(OppositeCorner(halftile_corner));
 

	
 
		SpriteID image;
 
		switch (rgt) {
 
			case RAIL_GROUND_BARREN:     image = SPR_FLAT_BARE_LAND;  break;
 
			case RAIL_GROUND_ICE_DESERT:
 
			case RAIL_GROUND_HALF_SNOW:  image = SPR_FLAT_SNOW_DESERT_TILE; break;
 
			default:                     image = SPR_FLAT_GRASS_TILE; break;
 
		}
 

	
 
		image += _tileh_to_sprite[fake_slope];
 

	
 
		DrawGroundSprite(image, PAL_NONE, &(_halftile_sub_sprite[halftile_corner]));
 

	
 
		track = CornerToTrackBits(halftile_corner);
 

	
 
		int offset;
 
		switch (track) {
 
			default: NOT_REACHED();
 
			case TRACK_BIT_UPPER: offset = RTO_N; break;
 
			case TRACK_BIT_LOWER: offset = RTO_S; break;
 
			case TRACK_BIT_RIGHT: offset = RTO_E; break;
 
			case TRACK_BIT_LEFT:  offset = RTO_W; break;
 
		}
 

	
 
		DrawTrackSprite(ground + offset, PAL_NONE, ti, fake_slope);
 
		if (HasReservedTracks(ti->tile, track)) {
 
			DrawTrackSprite(overlay + offset, PALETTE_CRASH, ti, fake_slope);
 
		}
 
	}
 
}
 

	
 
/**
 
 * Draw ground sprite and track bits
 
@@ -1755,16 +1945,13 @@ static void DrawTrackDetails(const TileI
 
 */
 
static void DrawTrackBits(TileInfo *ti, TrackBits track)
 
{
 
	/* SubSprite for drawing the track halftile of 'three-corners-raised'-sloped rail sprites. */
 
	static const int INF = 1000; // big number compared to tilesprite size
 
	static const SubSprite _halftile_sub_sprite[4] = {
 
		{ -INF    , -INF  , 32 - 33, INF     }, // CORNER_W, clip 33 pixels from right
 
		{ -INF    ,  0 + 7, INF    , INF     }, // CORNER_S, clip 7 pixels from top
 
		{ -31 + 33, -INF  , INF    , INF     }, // CORNER_E, clip 33 pixels from left
 
		{ -INF    , -INF  , INF    , 30 - 23 }  // CORNER_N, clip 23 pixels from bottom
 
	};
 

	
 
	const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
 

	
 
	if (rti->UsesOverlay()) {
 
		DrawTrackBitsOverlay(ti, track, rti);
 
		return;
 
	}
 

	
 
	RailGroundType rgt = GetRailGroundType(ti->tile);
 
	Foundation f = GetRailFoundation(ti->tileh, track);
 
	Corner halftile_corner = CORNER_INVALID;
 
@@ -1960,7 +2147,7 @@ static void DrawTile_Track(TileInfo *ti)
 

	
 
		DrawTrackBits(ti, rails);
 

	
 
		if (HasBit(_display_opt, DO_FULL_DETAIL)) DrawTrackDetails(ti);
 
		if (HasBit(_display_opt, DO_FULL_DETAIL)) DrawTrackDetails(ti, rti);
 

	
 
		if (HasCatenaryDrawn(GetRailType(ti->tile))) DrawCatenary(ti);
 

	
 
@@ -1969,6 +2156,7 @@ static void DrawTile_Track(TileInfo *ti)
 
		/* draw depot */
 
		const DrawTileSprites *dts;
 
		PaletteID pal = PAL_NONE;
 
		SpriteID relocation;
 

	
 
		if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
 

	
 
@@ -1979,8 +2167,12 @@ static void DrawTile_Track(TileInfo *ti)
 
			dts = &_depot_gfx_table[GetRailDepotDirection(ti->tile)];
 
		}
 

	
 
		image = dts->ground.sprite;
 
		if (image != SPR_FLAT_GRASS_TILE) image += rti->total_offset;
 
		if (rti->UsesOverlay()) {
 
			image = SPR_FLAT_GRASS_TILE;
 
		} else {
 
			image = dts->ground.sprite;
 
			if (image != SPR_FLAT_GRASS_TILE) image += rti->total_offset;
 
		}
 

	
 
		/* adjust ground tile for desert
 
		 * don't adjust for snow, because snow in depots looks weird */
 
@@ -1994,19 +2186,43 @@ static void DrawTile_Track(TileInfo *ti)
 

	
 
		DrawGroundSprite(image, GroundSpritePaletteTransform(image, pal, _drawtile_track_palette));
 

	
 
		/* PBS debugging, draw reserved tracks darker */
 
		if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && HasDepotReservation(ti->tile)) {
 
		if (rti->UsesOverlay()) {
 
			SpriteID ground = GetCustomRailSprite(rti, ti->tile, RTSG_GROUND);
 

	
 
			switch (GetRailDepotDirection(ti->tile)) {
 
				case DIAGDIR_SW: DrawGroundSprite(rti->base_sprites.single_x, PALETTE_CRASH); break;
 
				case DIAGDIR_SE: DrawGroundSprite(rti->base_sprites.single_y, PALETTE_CRASH); break;
 
				case DIAGDIR_SW: DrawGroundSprite(ground + RTO_X, PAL_NONE); break;
 
				case DIAGDIR_SE: DrawGroundSprite(ground + RTO_Y, PAL_NONE); break;
 
				default: break;
 
			}
 

	
 
			if (_settings_client.gui.show_track_reservation && HasDepotReservation(ti->tile)) {
 
				SpriteID overlay = GetCustomRailSprite(rti, ti->tile, RTSG_OVERLAY);
 

	
 
				switch (GetRailDepotDirection(ti->tile)) {
 
					case DIAGDIR_SW: DrawGroundSprite(overlay + RTO_X, PALETTE_CRASH); break;
 
					case DIAGDIR_SE: DrawGroundSprite(overlay + RTO_Y, PALETTE_CRASH); break;
 
					default: break;
 
				}
 
			}
 

	
 
			relocation  = GetCustomRailSprite(rti, ti->tile, RTSG_DEPOT);
 
			relocation -= SPR_RAIL_DEPOT_SE_1;
 
		} else {
 
			/* PBS debugging, draw reserved tracks darker */
 
			if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && HasDepotReservation(ti->tile)) {
 
				switch (GetRailDepotDirection(ti->tile)) {
 
					case DIAGDIR_SW: DrawGroundSprite(rti->base_sprites.single_y, PALETTE_CRASH); break;
 
					case DIAGDIR_SE: DrawGroundSprite(rti->base_sprites.single_x, PALETTE_CRASH); break;
 
					default: break;
 
				}
 
			}
 

	
 
			relocation = rti->total_offset;
 
		}
 

	
 
		if (HasCatenaryDrawn(GetRailType(ti->tile))) DrawCatenary(ti);
 

	
 
		/* No NewGRF depots, so no relocation */
 
		DrawRailTileSeq(ti, dts, TO_BUILDINGS, rti->total_offset, 0, _drawtile_track_palette);
 
		DrawRailTileSeq(ti, dts, TO_BUILDINGS, relocation, 0, _drawtile_track_palette);
 
	}
 
	DrawBridgeMiddle(ti);
 
}
src/road_cmd.cpp
Show inline comments
 
@@ -35,6 +35,7 @@
 
#include "town.h"
 
#include "company_base.h"
 
#include "core/random_func.hpp"
 
#include "newgrf_railtype.h"
 

	
 
#include "table/strings.h"
 

	
 
@@ -1164,7 +1165,36 @@ static void DrawTile_Road(TileInfo *ti)
 
		case ROAD_TILE_CROSSING: {
 
			if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
 

	
 
			SpriteID image = GetRailTypeInfo(GetRailType(ti->tile))->base_sprites.crossing;
 
			const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
 

	
 
			if (rti->UsesOverlay()) {
 
				Axis axis = GetCrossingRailAxis(ti->tile);
 
				SpriteID road = SPR_ROAD_Y + axis;
 
				PaletteID pal = PAL_NONE;
 

	
 
				Roadside roadside = GetRoadside(ti->tile);
 

	
 
				if (AlwaysDrawUnpavedRoads(ti->tile, roadside)) {
 
					road += 19;
 
				} else {
 
					switch (roadside) {
 
						case ROADSIDE_BARREN: pal = PALETTE_TO_BARE_LAND; break;
 
						case ROADSIDE_GRASS:  break;
 
						default:              road -= 19; break; // Paved
 
					}
 
				}
 

	
 
				DrawGroundSprite(road, pal);
 

	
 
				SpriteID rail = GetCustomRailSprite(rti, ti->tile, RTSG_CROSSING) + axis;
 
				DrawGroundSprite(rail, PAL_NONE);
 
				DrawRailTileSeq(ti, &_crossing_layout, TO_CATENARY, rail, 0, PAL_NONE);
 

	
 
				if (HasCatenaryDrawn(GetRailType(ti->tile))) DrawCatenary(ti);
 
				break;
 
			}
 

	
 
			SpriteID image = rti->base_sprites.crossing;
 
			PaletteID pal = PAL_NONE;
 

	
 
			if (GetCrossingRoadAxis(ti->tile) == AXIS_X) image++;
src/station_cmd.cpp
Show inline comments
 
@@ -39,6 +39,7 @@
 
#include "elrail_func.h"
 
#include "station_base.h"
 
#include "roadstop_base.h"
 
#include "newgrf_railtype.h"
 
#include "waypoint_base.h"
 
#include "waypoint_func.h"
 
#include "pbs.h"
 
@@ -2303,12 +2304,13 @@ static void DrawTile_Station(TileInfo *t
 
	RoadTypes roadtypes;
 
	int32 total_offset;
 
	int32 custom_ground_offset;
 
	const RailtypeInfo *rti = NULL;
 
	uint32 relocation = 0;
 
	const BaseStation *st = NULL;
 
	const StationSpec *statspec = NULL;
 

	
 
	if (HasStationRail(ti->tile)) {
 
		const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
 
		rti = GetRailTypeInfo(GetRailType(ti->tile));
 
		roadtypes = ROADTYPES_NONE;
 
		total_offset = rti->total_offset;
 
		custom_ground_offset = rti->custom_ground_offset;
 
@@ -2446,18 +2448,29 @@ static void DrawTile_Station(TileInfo *t
 
	} else {
 
		SpriteID image = t->ground.sprite;
 
		PaletteID pal  = t->ground.pal;
 
		if (HasBit(image, SPRITE_MODIFIER_CUSTOM_SPRITE)) {
 
			image += GetCustomStationGroundRelocation(statspec, st, ti->tile);
 
			image += custom_ground_offset;
 
		if (rti != NULL && rti->UsesOverlay() && (image == SPR_RAIL_TRACK_X || image == SPR_RAIL_TRACK_Y)) {
 
			SpriteID ground = GetCustomRailSprite(rti, ti->tile, RTSG_GROUND);
 
			DrawGroundSprite(SPR_FLAT_GRASS_TILE, PAL_NONE);
 
			DrawGroundSprite(ground + (image == SPR_RAIL_TRACK_X ? RTO_X : RTO_Y), PAL_NONE);
 

	
 
			if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && HasStationReservation(ti->tile)) {
 
				SpriteID overlay = GetCustomRailSprite(rti, ti->tile, RTSG_OVERLAY);
 
				DrawGroundSprite(overlay + (image == SPR_RAIL_TRACK_X ? RTO_X : RTO_Y), PALETTE_CRASH);
 
			}
 
		} else {
 
			image += total_offset;
 
		}
 
		DrawGroundSprite(image, GroundSpritePaletteTransform(image, pal, palette));
 

	
 
		/* PBS debugging, draw reserved tracks darker */
 
		if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && HasStationRail(ti->tile) && HasStationReservation(ti->tile)) {
 
			const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
 
			DrawGroundSprite(GetRailStationAxis(ti->tile) == AXIS_X ? rti->base_sprites.single_x : rti->base_sprites.single_y, PALETTE_CRASH);
 
			if (HasBit(image, SPRITE_MODIFIER_CUSTOM_SPRITE)) {
 
				image += GetCustomStationGroundRelocation(statspec, st, ti->tile);
 
				image += custom_ground_offset;
 
			} else {
 
				image += total_offset;
 
			}
 
			DrawGroundSprite(image, GroundSpritePaletteTransform(image, pal, palette));
 

	
 
			/* PBS debugging, draw reserved tracks darker */
 
			if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && HasStationRail(ti->tile) && HasStationReservation(ti->tile)) {
 
				const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
 
				DrawGroundSprite(GetRailStationAxis(ti->tile) == AXIS_X ? rti->base_sprites.single_x : rti->base_sprites.single_y, PALETTE_CRASH);
 
			}
 
		}
 
	}
 

	
 
@@ -2482,14 +2495,21 @@ void StationPickerDrawSprite(int x, int 
 
	int32 total_offset = 0;
 
	PaletteID pal = COMPANY_SPRITE_COLOUR(_local_company);
 
	const DrawTileSprites *t = &_station_display_datas[st][image];
 
	const RailtypeInfo *rti = NULL;
 

	
 
	if (railtype != INVALID_RAILTYPE) {
 
		const RailtypeInfo *rti = GetRailTypeInfo(railtype);
 
		rti = GetRailTypeInfo(railtype);
 
		total_offset = rti->total_offset;
 
	}
 

	
 
	SpriteID img = t->ground.sprite;
 
	DrawSprite(img + total_offset, HasBit(img, PALETTE_MODIFIER_COLOUR) ? pal : PAL_NONE, x, y);
 
	if ((img == SPR_RAIL_TRACK_X || img == SPR_RAIL_TRACK_Y) && rti->UsesOverlay()) {
 
		SpriteID ground = GetCustomRailSprite(rti, INVALID_TILE, RTSG_GROUND);
 
		DrawSprite(SPR_FLAT_GRASS_TILE, PAL_NONE, x, y);
 
		DrawSprite(ground + (img == SPR_RAIL_TRACK_X ? RTO_X : RTO_Y), PAL_NONE, x, y);
 
	} else {
 
		DrawSprite(img + total_offset, HasBit(img, PALETTE_MODIFIER_COLOUR) ? pal : PAL_NONE, x, y);
 
	}
 

	
 
	if (roadtype == ROADTYPE_TRAM) {
 
		DrawSprite(SPR_TRAMWAY_TRAM + (t->ground.sprite == SPR_ROAD_PAVED_STRAIGHT_X ? 1 : 0), PAL_NONE, x, y);
src/table/railtypes.h
Show inline comments
 
@@ -89,6 +89,8 @@ static const RailtypeInfo _original_rail
 

	
 
		/* rail type label */
 
		'RAIL',
 

	
 
		{ NULL },
 
	},
 

	
 
	/** Electrified railway */
 
@@ -167,6 +169,8 @@ static const RailtypeInfo _original_rail
 

	
 
		/* rail type label */
 
		'ELRL',
 

	
 
		{ NULL },
 
	},
 

	
 
	/** Monorail */
 
@@ -241,6 +245,8 @@ static const RailtypeInfo _original_rail
 

	
 
		/* rail type label */
 
		'MONO',
 

	
 
		{ NULL },
 
	},
 

	
 
	/** Maglev */
 
@@ -315,6 +321,8 @@ static const RailtypeInfo _original_rail
 

	
 
		/* rail type label */
 
		'MGLV',
 

	
 
		{ NULL },
 
	},
 
};
 

	
src/table/road_land.h
Show inline comments
 
@@ -70,6 +70,20 @@ static const DrawTileSprites _tram_depot
 
	{ {0xA4A, PAL_NONE}, _tram_depot_NW }
 
};
 

	
 
/* Sprite layout for level crossings. The SpriteIDs are actually offsets
 
 * from the base SpriteID returned from the NewGRF sprite resolver. */
 
static const DrawTileSeqStruct _crossing_layout_ALL[] = {
 
	TILE_SEQ_LINE(2, PAL_NONE,  0,  0, 3, 3)
 
	TILE_SEQ_LINE(4, PAL_NONE,  0, 13, 3, 3)
 
	TILE_SEQ_LINE(6, PAL_NONE, 13,  0, 3, 3)
 
	TILE_SEQ_LINE(8, PAL_NONE, 13, 13, 3, 3)
 
	TILE_SEQ_END()
 
};
 

	
 
static const DrawTileSprites _crossing_layout = {
 
	{0, PAL_NONE}, _crossing_layout_ALL
 
};
 

	
 
#undef TILE_SEQ_LINE
 
#undef TILE_SEQ_END
 

	
src/tunnelbridge_cmd.cpp
Show inline comments
 
@@ -40,6 +40,7 @@
 
#include "pbs.h"
 
#include "company_base.h"
 
#include "engine_base.h"
 
#include "newgrf_railtype.h"
 

	
 
#include "table/sprites.h"
 
#include "table/strings.h"
 
@@ -930,14 +931,22 @@ static void DrawTile_TunnelBridge(TileIn
 
					AddSortableSpriteToDraw(SPR_TRAMWAY_TUNNEL_WIRES + tunnelbridge_direction, PAL_NONE, ti->x, ti->y, BB_data[10], BB_data[11], TILE_HEIGHT, ti->z, IsTransparencySet(TO_CATENARY), BB_data[8], BB_data[9], BB_Z_SEPARATOR);
 
				}
 
			}
 
		} else if (HasCatenaryDrawn(GetRailType(ti->tile))) {
 
			/* Maybe draw pylons on the entry side */
 
			DrawCatenary(ti);
 
		} else {
 
			const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
 
			if (rti->UsesOverlay()) {
 
				SpriteID surface = GetCustomRailSprite(rti, ti->tile, RTSG_TUNNEL);
 
				if (surface != 0) DrawGroundSprite(surface + tunnelbridge_direction, PAL_NONE);
 
			}
 

	
 
			catenary = true;
 
			StartSpriteCombine();
 
			/* Draw wire above the ramp */
 
			DrawCatenaryOnTunnel(ti);
 
			if (HasCatenaryDrawn(GetRailType(ti->tile))) {
 
				/* Maybe draw pylons on the entry side */
 
				DrawCatenary(ti);
 

	
 
				catenary = true;
 
				StartSpriteCombine();
 
				/* Draw wire above the ramp */
 
				DrawCatenaryOnTunnel(ti);
 
			}
 
		}
 

	
 
		AddSortableSpriteToDraw(image + 1, PAL_NONE, ti->x + TILE_SIZE - 1, ti->y + TILE_SIZE - 1, BB_data[0], BB_data[1], TILE_HEIGHT, ti->z, false, BB_data[2], BB_data[3], BB_Z_SEPARATOR);
 
@@ -995,15 +1004,6 @@ static void DrawTile_TunnelBridge(TileIn
 
		/* Bridge heads are drawn solid no matter how invisibility/transparency is set */
 
		AddSortableSpriteToDraw(psid->sprite, psid->pal, ti->x, ti->y, 16, 16, ti->tileh == SLOPE_FLAT ? 0 : 8, ti->z);
 

	
 
		if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && transport_type == TRANSPORT_RAIL && HasTunnelBridgeReservation(ti->tile)) {
 
			const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
 
			if (HasBridgeFlatRamp(ti->tileh, DiagDirToAxis(tunnelbridge_direction))) {
 
				AddSortableSpriteToDraw(DiagDirToAxis(tunnelbridge_direction) == AXIS_X ? rti->base_sprites.single_x : rti->base_sprites.single_y, PALETTE_CRASH, ti->x, ti->y, 16, 16, 0, ti->z + 8);
 
			} else {
 
				AddSortableSpriteToDraw(rti->base_sprites.single_sloped + tunnelbridge_direction, PALETTE_CRASH, ti->x, ti->y, 16, 16, 8, ti->z);
 
			}
 
		}
 

	
 
		if (transport_type == TRANSPORT_ROAD) {
 
			RoadTypes rts = GetRoadTypes(ti->tile);
 

	
 
@@ -1021,6 +1021,26 @@ static void DrawTile_TunnelBridge(TileIn
 
			}
 
			EndSpriteCombine();
 
		} else if (transport_type == TRANSPORT_RAIL) {
 
			const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
 
			if (rti->UsesOverlay()) {
 
				SpriteID surface = GetCustomRailSprite(rti, ti->tile, RTSG_BRIDGE);
 
				if (surface != 0) {
 
					if (HasBridgeFlatRamp(ti->tileh, DiagDirToAxis(tunnelbridge_direction))) {
 
						AddSortableSpriteToDraw(surface + ((DiagDirToAxis(tunnelbridge_direction) == AXIS_X) ? RTBO_X : RTBO_Y), PAL_NONE, ti->x, ti->y, 16, 16, 0, ti->z + 8);
 
					} else {
 
						AddSortableSpriteToDraw(surface + RTBO_SLOPE + tunnelbridge_direction, PAL_NONE, ti->x, ti->y, 16, 16, 8, ti->z);
 
					}
 
				}
 
				/* Don't fallback to non-overlay sprite -- the spec states that
 
				 * if an overlay is present then the bridge surface must be
 
				 * present. */
 
			} else if (_game_mode != GM_MENU &&_settings_client.gui.show_track_reservation && HasTunnelBridgeReservation(ti->tile)) {
 
				if (HasBridgeFlatRamp(ti->tileh, DiagDirToAxis(tunnelbridge_direction))) {
 
					AddSortableSpriteToDraw(DiagDirToAxis(tunnelbridge_direction) == AXIS_X ? rti->base_sprites.single_x : rti->base_sprites.single_y, PALETTE_CRASH, ti->x, ti->y, 16, 16, 0, ti->z + 8);
 
				} else {
 
					AddSortableSpriteToDraw(rti->base_sprites.single_sloped + tunnelbridge_direction, PALETTE_CRASH, ti->x, ti->y, 16, 16, 8, ti->z);
 
				}
 
			}
 
			EndSpriteCombine();
 
			if (HasCatenaryDrawn(GetRailType(ti->tile))) {
 
				DrawCatenary(ti);
 
@@ -1128,7 +1148,7 @@ void DrawBridgeMiddle(const TileInfo *ti
 
	AddSortableSpriteToDraw(SPR_EMPTY_BOUNDING_BOX, PAL_NONE, x, y, 16, 16, 1, bridge_z - TILE_HEIGHT + BB_Z_SEPARATOR);
 

	
 
	/* Draw Trambits as SpriteCombine */
 
	if (transport_type == TRANSPORT_ROAD) StartSpriteCombine();
 
	if (transport_type == TRANSPORT_ROAD || transport_type == TRANSPORT_RAIL) StartSpriteCombine();
 

	
 
	/* Draw floor and far part of bridge*/
 
	if (!IsInvisibilitySet(TO_BRIDGES)) {
 
@@ -1152,6 +1172,15 @@ void DrawBridgeMiddle(const TileInfo *ti
 
			StartSpriteCombine();
 
		}
 
	} else if (transport_type == TRANSPORT_RAIL) {
 
		const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(rampsouth));
 
		if (rti->UsesOverlay()) {
 
			SpriteID surface = GetCustomRailSprite(rti, ti->tile, RTSG_BRIDGE);
 
			if (surface != 0) {
 
				AddSortableSpriteToDraw(surface + axis, PAL_NONE, x, y, 16, 16, 0, bridge_z, IsTransparencySet(TO_BRIDGES));
 
			}
 
		}
 
		EndSpriteCombine();
 

	
 
		if (HasCatenaryDrawn(GetRailType(rampsouth))) {
 
			DrawCatenaryOnBridge(ti);
 
		}
0 comments (0 inline, 0 general)