Changeset - r4549:76b9213799ac
[Not reviewed]
master
0 59 0
rubidium - 18 years ago 2006-09-04 20:40:33
rubidium@openttd.org
(svn r6381) -Cleanup: make the '/* */' comments that span multiple lines more uniform.
-Cleanup: whitespace alignment of a few tables.
59 files changed with 694 insertions and 700 deletions:
0 comments (0 inline, 0 general)
aircraft_cmd.c
Show inline comments
 
@@ -506,25 +506,25 @@ int32 CmdSendAircraftToHangar(TileIndex 
 
	}
 

	
 
	if (!IsValidVehicleID(p1)) return CMD_ERROR;
 

	
 
	v = GetVehicle(p1);
 

	
 
	if (v->type != VEH_Aircraft || !CheckOwnership(v->owner) || IsAircraftInHangar(v)) return CMD_ERROR;
 

	
 
	if (v->current_order.type == OT_GOTO_DEPOT && !(p2 & DEPOT_LOCATE_HANGAR)) {
 
		if (!!(p2 & DEPOT_SERVICE) == HASBIT(v->current_order.flags, OFB_HALT_IN_DEPOT)) {
 
			/* We called with a different DEPOT_SERVICE setting.
 
			 * Now we change the setting to apply the new one and let the vehicle head for the same hangar.
 
			 * Note: the if is (true for requesting service == true for ordered to stop in hangar)          */
 
			 * Note: the if is (true for requesting service == true for ordered to stop in hangar) */
 
			if (flags & DC_EXEC) {
 
				TOGGLEBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
 
				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
 
			}
 
			return 0;
 
		}
 

	
 
		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of hangar orders
 
		if (flags & DC_EXEC) {
 
			if (v->current_order.flags & OF_UNLOAD) v->cur_order_index++;
 
			v->current_order.type = OT_DUMMY;
 
			v->current_order.flags = 0;
 
@@ -1906,33 +1906,33 @@ static uint GetNumTerminals(const Airpor
 

	
 
	for (i = Airport->terminals[0]; i > 0; i--) num += Airport->terminals[i];
 

	
 
	return num;
 
}
 

	
 
static bool AirportFindFreeTerminal(Vehicle *v, const AirportFTAClass *Airport)
 
{
 
	AirportFTA *temp;
 
	Station *st;
 

	
 
	/* example of more terminalgroups
 
		{0,HANGAR,NOTHING_block,1}, {0,255,TERM_GROUP1_block,0}, {0,255,TERM_GROUP2_ENTER_block,1}, {0,0,N,1},
 
		Heading 255 denotes a group. We see 2 groups here:
 
		1. group 0 -- TERM_GROUP1_block (check block)
 
		2. group 1 -- TERM_GROUP2_ENTER_block (check block)
 
		First in line is checked first, group 0. If the block (TERM_GROUP1_block) is free, it
 
		looks at the corresponding terminals of that group. If no free ones are found, other
 
		possible groups are checked (in this case group 1, since that is after group 0). If that
 
		fails, then attempt fails and plane waits
 
	*/
 
	 * {0,HANGAR,NOTHING_block,1}, {0,255,TERM_GROUP1_block,0}, {0,255,TERM_GROUP2_ENTER_block,1}, {0,0,N,1},
 
	 * Heading 255 denotes a group. We see 2 groups here:
 
	 * 1. group 0 -- TERM_GROUP1_block (check block)
 
	 * 2. group 1 -- TERM_GROUP2_ENTER_block (check block)
 
	 * First in line is checked first, group 0. If the block (TERM_GROUP1_block) is free, it
 
	 * looks at the corresponding terminals of that group. If no free ones are found, other
 
	 * possible groups are checked (in this case group 1, since that is after group 0). If that
 
	 * fails, then attempt fails and plane waits
 
	 */
 
	if (Airport->terminals[0] > 1) {
 
		st = GetStation(v->u.air.targetairport);
 
		temp = Airport->layout[v->u.air.pos].next_in_chain;
 
		while (temp != NULL) {
 
			if (temp->heading == 255) {
 
				if (!HASBITS(st->airport_flags, temp->block)) {
 
					int target_group;
 
					int i;
 
					int group_start = 0;
 
					int group_end;
 

	
 
					//read which group do we want to go to?
depot.h
Show inline comments
 
/* $Id$ */
 

	
 
#ifndef DEPOT_H
 
#define DEPOT_H
 

	
 
/** @file depot.h Header files for depots (not hangars)
 
  * @see depot.c */
 
 *  @see depot.c */
 

	
 
#include "direction.h"
 
#include "pool.h"
 
#include "tile.h"
 
#include "variables.h"
 

	
 
struct Depot {
 
	TileIndex xy;
 
	TownID town_index;
 
	DepotID index;
 
};
 

	
economy.c
Show inline comments
 
@@ -237,26 +237,26 @@ int UpdateCompanyRatingAndValue(Player *
 

	
 
	InvalidateWindow(WC_PERFORMANCE_DETAIL, 0);
 
	return score;
 
}
 

	
 
// use OWNER_SPECTATOR as new_player to delete the player.
 
void ChangeOwnershipOfPlayerItems(PlayerID old_player, PlayerID new_player)
 
{
 
	PlayerID old = _current_player;
 
	_current_player = old_player;
 

	
 
	/* Temporarily increase the player's money, to be sure that
 
	* removing his/her property doesn't fail because of lack of money.
 
	* Not too drastically though, because it could overflow */
 
	 * removing his/her property doesn't fail because of lack of money.
 
	 * Not too drastically though, because it could overflow */
 
	if (new_player == OWNER_SPECTATOR) {
 
		GetPlayer(old_player)->money64 = MAX_UVALUE(uint64) >>2; // jackpot ;p
 
		UpdatePlayerMoney32(GetPlayer(old_player));
 
	}
 

	
 
	if (new_player == OWNER_SPECTATOR) {
 
		Subsidy *s;
 

	
 
		for (s = _subsidies; s != endof(_subsidies); s++) {
 
			if (s->cargo_type != CT_INVALID && s->age >= 12) {
 
				if (GetStation(s->to)->owner == old_player) s->cargo_type = CT_INVALID;
 
			}
elrail.c
Show inline comments
 
/* $Id$ */
 
/** @file elrail.c
 
  This file deals with displaying wires and pylons for electric railways.
 
<h2>Basics</h2>
 

	
 
<h3>Tile Types</h3>
 

	
 
We have two different types of tiles in the drawing code:
 
Normal Railway Tiles (NRTs) which can have more than one track on it, and
 
Special Railways tiles (SRTs) which have only one track (like crossings, depots
 
stations, etc).
 

	
 
<h3>Location Categories</h3>
 

	
 
All tiles are categorized into three location groups (TLG):
 
Group 0: Tiles with both an even X coordinate and an even Y coordinate
 
Group 1: Tiles with an even X and an odd Y coordinate
 
Group 2: Tiles with an odd X and an even Y coordinate
 
Group 3: Tiles with both an odd X and Y coordnate.
 

	
 
<h3>Pylon Points</h3>
 
<h4>Control Points</h4>
 
A Pylon Control Point (PCP) is a position where a wire (or rather two)
 
is mounted onto a pylon.
 
Each NRT does contain 4 PCPs which are bitmapped to a byte
 
variable and are represented by the DiagDirection enum
 

	
 
Each track ends on two PCPs and thus requires one pylon on each end. However,
 
there is one exception: Straight-and-level tracks only have one pylon every
 
other tile.
 

	
 
Now on each edge there are two PCPs: One from each adjacent tile. Both PCPs
 
are merged using an OR operation (i. e. if one tile needs a PCP at the postion
 
in question, both tiles get it).
 

	
 
<h4>Position Points</h4>
 
A Pylon Position Point (PPP) is a position where a pylon is located on the
 
ground.  Each PCP owns 8 in (45 degree steps) PPPs that are located around
 
it. PPPs are represented using the Direction enum. Each track bit has PPPs
 
that are impossible (because the pylon would be situated on the track) and
 
some that are preferred (because the pylon would be rectangular to the track).
 

	
 
<img src="../../elrail_tile.png">
 
<img src="../../elrail_track.png">
 

	
 
  */
 
 * This file deals with displaying wires and pylons for electric railways.
 
 * <h2>Basics</h2>
 
 *
 
 * <h3>Tile Types</h3>
 
 *
 
 * We have two different types of tiles in the drawing code:
 
 * Normal Railway Tiles (NRTs) which can have more than one track on it, and
 
 * Special Railways tiles (SRTs) which have only one track (like crossings, depots
 
 * stations, etc).
 
 *
 
 * <h3>Location Categories</h3>
 
 *
 
 * All tiles are categorized into three location groups (TLG):
 
 * Group 0: Tiles with both an even X coordinate and an even Y coordinate
 
 * Group 1: Tiles with an even X and an odd Y coordinate
 
 * Group 2: Tiles with an odd X and an even Y coordinate
 
 * Group 3: Tiles with both an odd X and Y coordnate.
 
 *
 
 * <h3>Pylon Points</h3>
 
 * <h4>Control Points</h4>
 
 * A Pylon Control Point (PCP) is a position where a wire (or rather two)
 
 * is mounted onto a pylon.
 
 * Each NRT does contain 4 PCPs which are bitmapped to a byte
 
 * variable and are represented by the DiagDirection enum
 
 *
 
 * Each track ends on two PCPs and thus requires one pylon on each end. However,
 
 * there is one exception: Straight-and-level tracks only have one pylon every
 
 * other tile.
 
 *
 
 * Now on each edge there are two PCPs: One from each adjacent tile. Both PCPs
 
 * are merged using an OR operation (i. e. if one tile needs a PCP at the postion
 
 * in question, both tiles get it).
 
 *
 
 * <h4>Position Points</h4>
 
 * A Pylon Position Point (PPP) is a position where a pylon is located on the
 
 * ground.  Each PCP owns 8 in (45 degree steps) PPPs that are located around
 
 * it. PPPs are represented using the Direction enum. Each track bit has PPPs
 
 * that are impossible (because the pylon would be situated on the track) and
 
 * some that are preferred (because the pylon would be rectangular to the track).
 
 *
 
 * <img src="../../elrail_tile.png">
 
 * <img src="../../elrail_track.png">
 
 *
 
 */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "station_map.h"
 
#include "tile.h"
 
#include "viewport.h"
 
#include "functions.h" /* We should REALLY get rid of this goddamn file, as it is butt-ugly */
 
#include "variables.h" /* ... same here */
 
#include "rail.h"
 
#include "debug.h"
 
#include "tunnel_map.h"
 
#include "road_map.h"
 
#include "bridge_map.h"
 
#include "bridge.h"
 
#include "rail_map.h"
 
#include "table/sprites.h"
 
#include "table/elrail_data.h"
 

	
 
static inline TLG GetTLG(TileIndex t)
 
{
 
	return (HASBIT(TileX(t), 0) << 1) + HASBIT(TileY(t), 0);
 
}
 

	
 
/** Finds which Rail Bits are present on a given tile. For bridge tiles,
 
  * returns track bits under the bridge
 
  */
 
 * returns track bits under the bridge
 
 */
 
static TrackBits GetRailTrackBitsUniversal(TileIndex t, byte *override)
 
{
 
	switch (GetTileType(t)) {
 
		case MP_RAILWAY:
 
			if (GetRailType(t) != RAILTYPE_ELECTRIC) return 0;
 
			switch (GetRailTileType(t)) {
 
				case RAIL_TILE_NORMAL: case RAIL_TILE_SIGNALS:
 
					return GetTrackBits(t);
 
				case RAIL_TILE_DEPOT_WAYPOINT:
 
					if (GetRailTileSubtype(t) == RAIL_SUBTYPE_WAYPOINT) return GetRailWaypointBits(t);
 
				default:
 
					return 0;
 
@@ -114,113 +114,113 @@ static TrackBits GetRailTrackBitsUnivers
 
		case MP_STATION:
 
			if (!IsRailwayStation(t)) return 0;
 
			if (GetRailType(t) != RAILTYPE_ELECTRIC) return 0;
 
			if (!IsStationTileElectrifiable(t)) return 0;
 
			return TrackToTrackBits(GetRailStationTrack(t));
 

	
 
		default:
 
			return 0;
 
	}
 
}
 

	
 
/** Corrects the tileh for certain tile types. Returns an effective tileh for the track on the tile.
 
  * @param tile The tile to analyse
 
  * @param *tileh the tileh
 
  */
 
 * @param tile The tile to analyse
 
 * @param *tileh the tileh
 
 */
 
static void AdjustTileh(TileIndex tile, Slope *tileh)
 
{
 
	if (IsTileType(tile, MP_TUNNELBRIDGE)) {
 
		if (IsTunnel(tile)) {
 
			*tileh = SLOPE_FLAT;
 
		} else {
 
			if (IsBridgeRamp(tile)) {
 
				if (*tileh != SLOPE_FLAT) {
 
					*tileh = SLOPE_FLAT;
 
				} else {
 
					switch (GetBridgeRampDirection(tile)) {
 
						case DIAGDIR_NE: *tileh = SLOPE_NE; break;
 
						case DIAGDIR_SE: *tileh = SLOPE_SE; break;
 
						case DIAGDIR_SW: *tileh = SLOPE_SW; break;
 
						case DIAGDIR_NW: *tileh = SLOPE_NW; break;
 
						default: break;
 
					}
 
				}
 
			}
 
		}
 
	}
 
}
 

	
 
/** Draws wires and, if required, pylons on a given tile
 
  * @param ti The Tileinfo to draw the tile for
 
  */
 
 * @param ti The Tileinfo to draw the tile for
 
 */
 
static void DrawCatenaryRailway(const TileInfo *ti)
 
{
 
	/* Pylons are placed on a tile edge, so we need to take into account
 
	   the track configuration of 2 adjacent tiles. trackconfig[0] stores the
 
	   current tile (home tile) while [1] holds the neighbour */
 
	 * the track configuration of 2 adjacent tiles. trackconfig[0] stores the
 
	 * current tile (home tile) while [1] holds the neighbour */
 
	TrackBits trackconfig[TS_END];
 
	bool isflat[TS_END];
 
	/* Note that ti->tileh has already been adjusted for Foundations */
 
	Slope tileh[TS_END] = { ti->tileh, SLOPE_FLAT };
 

	
 
	TLG tlg = GetTLG(ti->tile);
 
	byte PCPstatus = 0;
 
	byte OverridePCP = 0;
 
	byte PPPpreferred[DIAGDIR_END];
 
	byte PPPallowed[DIAGDIR_END];
 
	DiagDirection i;
 
	Track t;
 

	
 
	/* Find which rail bits are present, and select the override points.
 
	   We don't draw a pylon:
 
	   1) INSIDE a tunnel (we wouldn't see it anyway)
 
	   2) on the "far" end of a bridge head (the one that connects to bridge middle),
 
	      because that one is drawn on the bridge. Exception is for length 0 bridges
 
	      which have no middle tiles */
 
	 * We don't draw a pylon:
 
	 * 1) INSIDE a tunnel (we wouldn't see it anyway)
 
	 * 2) on the "far" end of a bridge head (the one that connects to bridge middle),
 
	 *    because that one is drawn on the bridge. Exception is for length 0 bridges
 
	 *    which have no middle tiles */
 
	trackconfig[TS_HOME] = GetRailTrackBitsUniversal(ti->tile, &OverridePCP);
 
	/* If a track bit is present that is not in the main direction, the track is level */
 
	isflat[TS_HOME] = trackconfig[TS_HOME] & (TRACK_BIT_HORZ | TRACK_BIT_VERT);
 

	
 
	AdjustTileh(ti->tile, &tileh[TS_HOME]);
 

	
 
	for (i = DIAGDIR_NE; i < DIAGDIR_END; i++) {
 
		TileIndex neighbour = ti->tile + TileOffsByDir(i);
 
		uint foundation = 0;
 
		int k;
 

	
 
		/* Here's one of the main headaches. GetTileSlope does not correct for possibly
 
		   existing foundataions, so we do have to do that manually later on.*/
 
		 * existing foundataions, so we do have to do that manually later on.*/
 
		tileh[TS_NEIGHBOUR] = GetTileSlope(neighbour, NULL);
 
		trackconfig[TS_NEIGHBOUR] = GetRailTrackBitsUniversal(neighbour, NULL);
 
		if (IsTunnelTile(neighbour) && i != GetTunnelDirection(neighbour)) trackconfig[TS_NEIGHBOUR] = 0;
 
		isflat[TS_NEIGHBOUR] = trackconfig[TS_NEIGHBOUR] & (TRACK_BIT_HORZ | TRACK_BIT_VERT);
 

	
 
		PPPpreferred[i] = 0xFF; /* We start with preferring everything (end-of-line in any direction) */
 
		PPPallowed[i] = AllowedPPPonPCP[i];
 

	
 
		/* We cycle through all the existing tracks at a PCP and see what
 
		   PPPs we want to have, or may not have at all */
 
		 * PPPs we want to have, or may not have at all */
 
		for (k = 0; k < NUM_TRACKS_AT_PCP; k++) {
 
			/* Next to us, we have a bridge head, don't worry about that one, if it shows away from us */
 
			if (TrackSourceTile[i][k] == TS_NEIGHBOUR &&
 
			    IsBridgeTile(neighbour) && IsBridgeRamp(neighbour) &&
 
			    GetBridgeRampDirection(neighbour) == ReverseDiagDir(i)) {
 
				continue;
 
			}
 

	
 
			/* We check whether the track in question (k) is present in the tile
 
			   (TrackSourceTile) */
 
			 * (TrackSourceTile) */
 
			if (HASBIT(trackconfig[TrackSourceTile[i][k]], TracksAtPCP[i][k])) {
 
				/* track found, if track is in the neighbour tile, adjust the number
 
				   of the PCP for preferred/allowed determination*/
 
				 * of the PCP for preferred/allowed determination*/
 
				DiagDirection PCPpos = (TrackSourceTile[i][k] == TS_HOME) ? i : ReverseDiagDir(i);
 
				SETBIT(PCPstatus, i); /* This PCP is in use */
 

	
 
				PPPpreferred[i] &= PreferredPPPofTrackAtPCP[TracksAtPCP[i][k]][PCPpos];
 
				PPPallowed[i] &= ~DisallowedPPPofTrackAtPCP[TracksAtPCP[i][k]][PCPpos];
 
			}
 
		}
 

	
 
		/* Deactivate all PPPs if PCP is not used */
 
		PPPpreferred[i] *= HASBIT(PCPstatus, i);
 
		PPPallowed[i] *= HASBIT(PCPstatus, i);
 

	
 
@@ -235,35 +235,35 @@ static void DrawCatenaryRailway(const Ti
 

	
 
		if (foundation != 0) {
 
			if (foundation < 15) {
 
				tileh[TS_NEIGHBOUR] = SLOPE_FLAT;
 
			} else {
 
				tileh[TS_NEIGHBOUR] = _inclined_tileh[foundation - 15];
 
			}
 
		}
 

	
 
		AdjustTileh(neighbour, &tileh[TS_NEIGHBOUR]);
 

	
 
		/* If we have a straight (and level) track, we want a pylon only every 2 tiles
 
		   Delete the PCP if this is the case. */
 
		 * Delete the PCP if this is the case. */
 
		/* Level means that the slope is the same, or the track is flat */
 
		if (tileh[TS_HOME] == tileh[TS_NEIGHBOUR] || (isflat[TS_HOME] && isflat[TS_NEIGHBOUR])) {
 
			for (k = 0; k < NUM_IGNORE_GROUPS; k++)
 
				if (PPPpreferred[i] == IgnoredPCP[k][tlg][i]) CLRBIT(PCPstatus, i);
 
		}
 

	
 
		/* Now decide where we draw our pylons. First try the preferred PPPs, but they may not exist.
 
		   In that case, we try the any of the allowed ones. if they don't exist either, don't draw
 
		   anything. Note that the preferred PPPs still contain the end-of-line markers.
 
		   Remove those (simply by ANDing with allowed, since these markers are never allowed) */
 
		 * In that case, we try the any of the allowed ones. if they don't exist either, don't draw
 
		 * anything. Note that the preferred PPPs still contain the end-of-line markers.
 
		 * Remove those (simply by ANDing with allowed, since these markers are never allowed) */
 
		if ((PPPallowed[i] & PPPpreferred[i]) != 0) PPPallowed[i] &= PPPpreferred[i];
 

	
 
		if (PPPallowed[i] != 0 && HASBIT(PCPstatus, i) && !HASBIT(OverridePCP, i)) {
 
			for (k = 0; k < DIR_END; k++) {
 
				byte temp = PPPorder[i][GetTLG(ti->tile)][k];
 

	
 
				if (HASBIT(PPPallowed[i], temp)) {
 
					uint x  = ti->x + x_pcp_offsets[i] + x_ppp_offsets[temp];
 
					uint y  = ti->y + y_pcp_offsets[i] + y_ppp_offsets[temp];
 

	
 
					/* Don't build the pylon if it would be outside the tile */
 
					if (!HASBIT(OwnedPPPonPCP[i], temp)) {
engine.c
Show inline comments
 
@@ -182,28 +182,28 @@ void StartupEngines(void)
 
			CalcEngineReliability(e);
 
		}
 

	
 
		e->lifelength = ei->lifelength + _patches.extend_vehicle_life;
 

	
 
		// prevent certain engines from ever appearing.
 
		if (!HASBIT(ei->climates, _opt.landscape)) {
 
			e->flags |= ENGINE_AVAILABLE;
 
			e->player_avail = 0;
 
		}
 

	
 
		/* This sets up type for the engine
 
		   It is needed if you want to ask the engine what type it is
 
		   It should hopefully be the same as when you ask a vehicle what it is
 
		   but using this, you can ask what type an engine number is
 
		   even if it is not a vehicle (yet)*/
 
		 * It is needed if you want to ask the engine what type it is
 
		 * It should hopefully be the same as when you ask a vehicle what it is
 
		 * but using this, you can ask what type an engine number is
 
		 * even if it is not a vehicle (yet)*/
 
	}
 

	
 
	AdjustAvailAircraft();
 
}
 

	
 
static void AcceptEnginePreview(Engine *e, PlayerID player)
 
{
 
	Player *p = GetPlayer(player);
 

	
 
	assert(e->railtype < RAILTYPE_END);
 
	SETBIT(e->player_avail, player);
 
	SETBIT(p->avail_railtypes, e->railtype);
engine.h
Show inline comments
 
/* $Id$ */
 

	
 
#ifndef ENGINE_H
 
#define ENGINE_H
 

	
 
/** @file engine.h
 
  */
 
/** @file engine.h */
 

	
 
#include "pool.h"
 

	
 
typedef struct RailVehicleInfo {
 
	byte image_index;
 
	byte flags; /* 1=multihead engine, 2=wagon */
 
	byte base_cost;
 
	uint16 max_speed;
 
	uint16 power;
 
	uint16 weight;
 
	byte running_cost_base;
 
	byte running_cost_class;
 
@@ -62,26 +61,26 @@ typedef struct AircraftVehicleInfo {
 

	
 
typedef struct RoadVehicleInfo {
 
	byte image_index;
 
	byte base_cost;
 
	byte running_cost;
 
	byte sfx;
 
	byte max_speed;
 
	byte capacity;
 
	CargoID cargo_type;
 
} RoadVehicleInfo;
 

	
 
/** Information about a vehicle
 
  * @see table/engines.h
 
  */
 
 *  @see table/engines.h
 
 */
 
typedef struct EngineInfo {
 
	Date base_intro;
 
	byte unk2;              ///< Carriages have the highest bit set in this one
 
	Year lifelength;
 
	Year base_life;
 
	byte railtype:4;
 
	byte climates:4;
 
	uint32 refit_mask;
 
	byte refit_cost;
 
	byte misc_flags;
 
	byte callbackmask;
 
} EngineInfo;
heightmap.c
Show inline comments
 
@@ -112,25 +112,25 @@ static bool ReadHeightmapPNG(char *filen
 

	
 
	info_ptr = png_create_info_struct(png_ptr);
 
	if (info_ptr == NULL || setjmp(png_jmpbuf(png_ptr))) {
 
		ShowErrorMessage(STR_PNGMAP_ERR_MISC, STR_PNGMAP_ERROR, 0, 0);
 
		fclose(fp);
 
		png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
 
		return false;
 
	}
 

	
 
	png_init_io(png_ptr, fp);
 

	
 
	/* Allocate memory and read image, without alpha or 16-bit samples
 
	* (result is either 8-bit indexed/grayscale or 24-bit RGB) */
 
	 * (result is either 8-bit indexed/grayscale or 24-bit RGB) */
 
	png_set_packing(png_ptr);
 
	png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_PACKING | PNG_TRANSFORM_STRIP_ALPHA | PNG_TRANSFORM_STRIP_16, NULL);
 

	
 
	/* Maps of wrong color-depth are not used.
 
	 * (this should have been taken care of by stripping alpha and 16-bit samples on load) */
 
	if ((info_ptr->channels != 1) && (info_ptr->channels != 3) && (info_ptr->bit_depth != 8)) {
 
		ShowErrorMessage(STR_PNGMAP_ERR_IMAGE_TYPE, STR_PNGMAP_ERROR, 0, 0);
 
		fclose(fp);
 
		png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
 
		return false;
 
	}
 

	
news_gui.c
Show inline comments
 
@@ -8,36 +8,36 @@
 
#include "table/strings.h"
 
#include "window.h"
 
#include "gui.h"
 
#include "viewport.h"
 
#include "gfx.h"
 
#include "news.h"
 
#include "vehicle.h"
 
#include "sound.h"
 
#include "variables.h"
 
#include "date.h"
 

	
 
/* News system
 
News system is realized as a FIFO queue (in an array)
 
The positions in the queue can't be rearranged, we only access
 
the array elements through pointers to the elements. Once the
 
array is full, the oldest entry (_oldest_news) is being overwritten
 
by the newest (_latest news).
 

	
 
oldest                   current   lastest
 
 |                          |         |
 
[O------------F-------------C---------L           ]
 
              |
 
           forced
 
*/
 
 * News system is realized as a FIFO queue (in an array)
 
 * The positions in the queue can't be rearranged, we only access
 
 * the array elements through pointers to the elements. Once the
 
 * array is full, the oldest entry (_oldest_news) is being overwritten
 
 * by the newest (_latest news).
 
 *
 
 * oldest                   current   lastest
 
 *  |                          |         |
 
 * [O------------F-------------C---------L           ]
 
 *               |
 
 *            forced
 
 */
 

	
 
#define MAX_NEWS 30
 

	
 
#define INVALID_NEWS 255
 

	
 
static NewsItem _news_items[MAX_NEWS];
 
static byte _current_news = INVALID_NEWS; // points to news item that should be shown next
 
static byte _oldest_news = 0;    // points to first item in fifo queue
 
static byte _latest_news = INVALID_NEWS;  // points to last item in fifo queue
 
/* if the message being shown was forced by the user, its index is stored in
 
 * _forced_news. forced_news is INVALID_NEWS otherwise.
 
 * (Users can force messages through history or "last message") */
 
@@ -515,25 +515,25 @@ void ShowLastNewsMessage(void)
 
{
 
	if (_forced_news == INVALID_NEWS) {
 
		ShowNewsMessage(_current_news);
 
	} else if (_forced_news != 0) {
 
		ShowNewsMessage(_forced_news - 1);
 
	} else {
 
		ShowNewsMessage(_total_news != MAX_NEWS ? _latest_news : MAX_NEWS - 1);
 
	}
 
}
 

	
 

	
 
/* return news by number, with 0 being the most
 
recent news. Returns INVALID_NEWS if end of queue reached. */
 
 * recent news. Returns INVALID_NEWS if end of queue reached. */
 
static byte getNews(byte i)
 
{
 
	if (i >= _total_news) return INVALID_NEWS;
 

	
 
	if (_latest_news < i) {
 
		i = _latest_news + MAX_NEWS - i;
 
	} else {
 
		i = _latest_news - i;
 
	}
 

	
 
	i %= MAX_NEWS;
 
	return i;
oldloader.c
Show inline comments
 
@@ -1510,25 +1510,25 @@ static bool LoadOldMain(LoadgameState *l
 
		_m[i].m4 = _old_map3[i * 2 + 1];
 
	}
 

	
 
	for (i = 0; i < OLD_MAP_SIZE; i ++) {
 
		if (IsTileType(i, MP_RAILWAY)) {
 
			/* We save presignals different from TTDPatch, convert them */
 
			if (GetRailTileType(i) == RAIL_TILE_SIGNALS) {
 
				/* This byte is always zero in TTD for this type of tile */
 
				if (_m[i].m4) /* Convert the presignals to our own format */
 
					_m[i].m4 = (_m[i].m4 >> 1) & 7;
 
			}
 
			/* TTDPatch stores PBS things in L6 and all elsewhere; so we'll just
 
			* clear it for ourselves and let OTTD's rebuild PBS itself */
 
			 * clear it for ourselves and let OTTD's rebuild PBS itself */
 
			_m[i].m4 &= 0xF; /* Only keep the lower four bits; upper four is PBS */
 
		}
 
	}
 

	
 
	/* Fix the game to be compatible with OpenTTD */
 
	FixOldTowns();
 
	FixOldStations();
 
	FixOldVehicles();
 

	
 
	AddTypeToEngines();
 

	
 
	/* We have a new difficulty setting */
openttd.c
Show inline comments
 
@@ -1059,31 +1059,31 @@ static void CheckIsPlayerActive(void)
 
}
 

	
 
// since savegame version 4.1, exclusive transport rights are stored at towns
 
static void UpdateExclusiveRights(void)
 
{
 
	Town *t;
 

	
 
	FOR_ALL_TOWNS(t) {
 
		t->exclusivity = (byte)-1;
 
	}
 

	
 
	/* FIXME old exclusive rights status is not being imported (stored in s->blocked_months_obsolete)
 
			could be implemented this way:
 
			1.) Go through all stations
 
					Build an array town_blocked[ town_id ][ player_id ]
 
				 that stores if at least one station in that town is blocked for a player
 
			2.) Go through that array, if you find a town that is not blocked for
 
					one player, but for all others, then give him exclusivity.
 
	*/
 
	 *   could be implemented this way:
 
	 * 1.) Go through all stations
 
	 *     Build an array town_blocked[ town_id ][ player_id ]
 
	 *     that stores if at least one station in that town is blocked for a player
 
	 * 2.) Go through that array, if you find a town that is not blocked for
 
	 *     one player, but for all others, then give him exclusivity.
 
	 */
 
}
 

	
 
static const byte convert_currency[] = {
 
	 0,  1, 12,  8,  3,
 
	10, 14, 19,  4,  5,
 
	 9, 11, 13,  6, 17,
 
	16, 22, 21,  7, 15,
 
	18,  2, 20, };
 

	
 
// since savegame version 4.2 the currencies are arranged differently
 
static void UpdateCurrencies(void)
 
{
order.h
Show inline comments
 
/* $Id$ */
 

	
 
/** @file order.h
 
  */
 
/** @file order.h */
 

	
 
#ifndef ORDER_H
 
#define ORDER_H
 

	
 
#include "macros.h"
 
#include "pool.h"
 

	
 
enum {
 
	INVALID_ORDER = 0xFFFF,
 
};
 

	
 
/* Order types */
order_cmd.c
Show inline comments
 
@@ -808,27 +808,27 @@ void RestoreVehicleOrders(const Vehicle*
 
	if (bak->name[0] != 0) {
 
		_cmd_text = bak->name;
 
		DoCommandP(0, v->index, 0, NULL, CMD_NAME_VEHICLE);
 
	}
 

	
 
	/* If we had shared orders, recover that */
 
	if (bak->clone != INVALID_VEHICLE) {
 
		DoCommandP(0, v->index | (bak->clone << 16), 0, NULL, CMD_CLONE_ORDER);
 
		return;
 
	}
 

	
 
	/* CMD_NO_TEST_IF_IN_NETWORK is used here, because CMD_INSERT_ORDER checks if the
 
	    order number is one more than the current amount of orders, and because
 
	    in network the commands are queued before send, the second insert always
 
	    fails in test mode. By bypassing the test-mode, that no longer is a problem. */
 
	 *  order number is one more than the current amount of orders, and because
 
	 *  in network the commands are queued before send, the second insert always
 
	 *  fails in test mode. By bypassing the test-mode, that no longer is a problem. */
 
	for (i = 0; bak->order[i].type != OT_NOTHING; i++) {
 
		if (!DoCommandP(0, v->index + (i << 16), PackOrder(&bak->order[i]), NULL, CMD_INSERT_ORDER | CMD_NO_TEST_IF_IN_NETWORK))
 
			break;
 
	}
 

	
 
	/* Restore vehicle order-index and service interval */
 
	DoCommandP(0, v->index, bak->orderindex | (bak->service_interval << 16) , NULL, CMD_RESTORE_ORDER_INDEX);
 
}
 

	
 
/** Restore the current order-index of a vehicle and sets service-interval.
 
 * @param tile unused
 
 * @param p1 the ID of the vehicle
 
@@ -1046,28 +1046,28 @@ void DeleteVehicleOrders(Vehicle *v)
 
		if (v->prev_shared != NULL) {
 
			v->prev_shared->next_shared = v->next_shared;
 
			u = v->prev_shared;
 
		}
 
		if (v->next_shared != NULL) {
 
			v->next_shared->prev_shared = v->prev_shared;
 
			u = v->next_shared;
 
		}
 
		v->prev_shared = NULL;
 
		v->next_shared = NULL;
 

	
 
		/* We only need to update this-one, because if there is a third
 
		    vehicle which shares the same order-list, nothing will change. If
 
		    this is the last vehicle, the last line of the order-window
 
		    will change from Shared order list, to Order list, so it needs
 
		    an update */
 
		 *  vehicle which shares the same order-list, nothing will change. If
 
		 *  this is the last vehicle, the last line of the order-window
 
		 *  will change from Shared order list, to Order list, so it needs
 
		 *  an update */
 
		InvalidateVehicleOrder(u);
 
		return;
 
	}
 

	
 
	/* Remove the orders */
 
	cur = v->orders;
 
	v->orders = NULL;
 
	v->num_orders = 0;
 

	
 
		while (cur != NULL) {
 
		next = cur->next;
 
		DeleteOrder(cur);
 
@@ -1166,26 +1166,26 @@ static void Load_ORDR(void)
 

	
 
			for (i = 0; i < len; ++i) {
 
				if (!AddBlockIfNeeded(&_order_pool, i))
 
					error("Orders: failed loading savegame: too many orders");
 

	
 
				AssignOrder(GetOrder(i), UnpackOrder(orders[i]));
 
			}
 
		}
 

	
 
		/* Update all the next pointer */
 
		for (i = 1; i < len; ++i) {
 
			/* The orders were built like this:
 
			     Vehicle one had order[0], and as long as order++.type was not
 
			     OT_NOTHING, it was part of the order-list of that vehicle */
 
			 *   Vehicle one had order[0], and as long as order++.type was not
 
			 *   OT_NOTHING, it was part of the order-list of that vehicle */
 
			if (GetOrder(i)->type != OT_NOTHING)
 
				GetOrder(i - 1)->next = GetOrder(i);
 
		}
 
	} else {
 
		int index;
 

	
 
		while ((index = SlIterateArray()) != -1) {
 
			Order *order;
 

	
 
			if (!AddBlockIfNeeded(&_order_pool, index))
 
				error("Orders: failed loading savegame: too many orders");
 

	
player.h
Show inline comments
 
@@ -220,26 +220,25 @@ static inline Player* GetPlayer(PlayerID
 
	assert(i < lengthof(_players));
 
	return &_players[i];
 
}
 

	
 
static inline bool IsLocalPlayer(void)
 
{
 
	return _local_player == _current_player;
 
}
 

	
 
void DeletePlayerWindows(PlayerID pi);
 
byte GetPlayerRailtypes(PlayerID p);
 

	
 
/** Finds out if a Player has a certain railtype available
 
  */
 
/** Finds out if a Player has a certain railtype available */
 
static inline bool HasRailtypeAvail(const Player *p, RailType Railtype)
 
{
 
	return HASBIT(p->avail_railtypes, Railtype);
 
}
 

	
 
/* Validate functions for rail building */
 
static inline bool ValParamRailtype(uint32 rail) { return HASBIT(GetPlayer(_current_player)->avail_railtypes, rail);}
 

	
 
/** Returns the "best" railtype a player can build.
 
 * As the AI doesn't know what the BEST one is, we have our own priority list
 
 * here. When adding new railtypes, modify this function
 
 * @param p the player "in action"
players.c
Show inline comments
 
/* $Id$ */
 

	
 
/** @file players.c
 
  * @todo Cleanup the messy DrawPlayerFace function asap
 
  */
 
 * @todo Cleanup the messy DrawPlayerFace function asap
 
 */
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "engine.h"
 
#include "functions.h"
 
#include "string.h"
 
#include "strings.h"
 
#include "table/strings.h"
 
#include "table/sprites.h"
 
#include "map.h"
 
#include "player.h"
 
#include "town.h"
 
#include "vehicle.h"
rail.h
Show inline comments
 
@@ -73,46 +73,46 @@ static inline TrackBits TrackToTrackBits
 
{
 
	return (TrackBits)(1 << track);
 
}
 

	
 

	
 
static inline TrackBits AxisToTrackBits(Axis a)
 
{
 
	return TrackToTrackBits(AxisToTrack(a));
 
}
 

	
 

	
 
/** These are a combination of tracks and directions. Values are 0-5 in one
 
direction (corresponding to the Track enum) and 8-13 in the other direction. */
 
 * direction (corresponding to the Track enum) and 8-13 in the other direction. */
 
typedef enum Trackdirs {
 
	TRACKDIR_X_NE     =  0,
 
	TRACKDIR_Y_SE     =  1,
 
	TRACKDIR_UPPER_E  =  2,
 
	TRACKDIR_LOWER_E  =  3,
 
	TRACKDIR_LEFT_S   =  4,
 
	TRACKDIR_RIGHT_S  =  5,
 
	/* Note the two missing values here. This enables trackdir -> track
 
	 * conversion by doing (trackdir & 7) */
 
	TRACKDIR_X_SW     =  8,
 
	TRACKDIR_Y_NW     =  9,
 
	TRACKDIR_UPPER_W  = 10,
 
	TRACKDIR_LOWER_W  = 11,
 
	TRACKDIR_LEFT_N   = 12,
 
	TRACKDIR_RIGHT_N  = 13,
 
	TRACKDIR_END,
 
	INVALID_TRACKDIR  = 0xFF,
 
} Trackdir;
 

	
 
/** These are a combination of tracks and directions. Values are 0-5 in one
 
direction (corresponding to the Track enum) and 8-13 in the other direction. */
 
 * direction (corresponding to the Track enum) and 8-13 in the other direction. */
 
typedef enum TrackdirBits {
 
	TRACKDIR_BIT_NONE     = 0x0000,
 
	TRACKDIR_BIT_X_NE     = 0x0001,
 
	TRACKDIR_BIT_Y_SE     = 0x0002,
 
	TRACKDIR_BIT_UPPER_E  = 0x0004,
 
	TRACKDIR_BIT_LOWER_E  = 0x0008,
 
	TRACKDIR_BIT_LEFT_S   = 0x0010,
 
	TRACKDIR_BIT_RIGHT_S  = 0x0020,
 
	/* Again, note the two missing values here. This enables trackdir -> track conversion by doing (trackdir & 0xFF) */
 
	TRACKDIR_BIT_X_SW     = 0x0100,
 
	TRACKDIR_BIT_Y_NW     = 0x0200,
 
	TRACKDIR_BIT_UPPER_W  = 0x0400,
rail_cmd.c
Show inline comments
 
@@ -577,31 +577,30 @@ int32 CmdBuildTrainDepot(TileIndex tile,
 
	int32 cost, ret;
 
	Slope tileh;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	if (!EnsureNoVehicle(tile)) return CMD_ERROR;
 
	/* check railtype and valid direction for depot (0 through 3), 4 in total */
 
	if (!ValParamRailtype(p1) || p2 > 3) return CMD_ERROR;
 

	
 
	tileh = GetTileSlope(tile, NULL);
 

	
 
	/* Prohibit construction if
 
		The tile is non-flat AND
 
		1) The AI is "old-school"
 
		2) build-on-slopes is disabled
 
		3) the tile is steep i.e. spans two height levels
 
		4) the exit points in the wrong direction
 

	
 
	*/
 
	 * The tile is non-flat AND
 
	 * 1) The AI is "old-school"
 
	 * 2) build-on-slopes is disabled
 
	 * 3) the tile is steep i.e. spans two height levels
 
	 * 4) the exit points in the wrong direction
 
	 */
 

	
 
	if (tileh != SLOPE_FLAT && (
 
				_is_old_ai_player ||
 
				!_patches.build_on_slopes ||
 
				IsSteepSlope(tileh) ||
 
				!CanBuildDepotByTileh(p2, tileh)
 
			)) {
 
		return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
 
	}
 

	
 
	ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
	if (CmdFailed(ret)) return CMD_ERROR;
 
@@ -744,49 +743,49 @@ static int32 CmdSignalTrackHelper(TileIn
 
	byte semaphores = (HASBIT(p2, 3) ? 8 : 0);
 
	byte signal_density = (p2 >> 24);
 

	
 
	if (p1 >= MapSize()) return CMD_ERROR;
 
	end_tile = p1;
 
	if (signal_density == 0 || signal_density > 20) return CMD_ERROR;
 

	
 
	if (!IsTileType(tile, MP_RAILWAY)) return CMD_ERROR;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	/* for vertical/horizontal tracks, double the given signals density
 
	* since the original amount will be too dense (shorter tracks) */
 
	 * since the original amount will be too dense (shorter tracks) */
 
	if (!IsDiagonalTrack(track)) signal_density *= 2;
 

	
 
	if (CmdFailed(ValidateAutoDrag(&trackdir, tile, end_tile))) return CMD_ERROR;
 

	
 
	track = TrackdirToTrack(trackdir); /* trackdir might have changed, keep track in sync */
 

	
 
	// copy the signal-style of the first rail-piece if existing
 
	if (HasSignals(tile)) {
 
		signals = _m[tile].m3 & SignalOnTrack(track);
 
		if (signals == 0) signals = SignalOnTrack(track); /* Can this actually occur? */
 

	
 
		// copy signal/semaphores style (independent of CTRL)
 
		semaphores = (GetSignalVariant(tile) == SIG_ELECTRIC ? 0 : 8);
 
	} else { // no signals exist, drag a two-way signal stretch
 
		signals = SignalOnTrack(track);
 
	}
 

	
 
	/* signal_ctr         - amount of tiles already processed
 
	 * signals_density    - patch setting to put signal on every Nth tile (double space on |, -- tracks)
 
	 **********
 
	 * trackdir   - trackdir to build with autorail
 
	 * semaphores - semaphores or signals
 
	 * signals    - is there a signal/semaphore on the first tile, copy its style (two-way/single-way)
 
	                and convert all others to semaphore/signal
 
	 *              and convert all others to semaphore/signal
 
	 * mode       - 1 remove signals, 0 build signals */
 
	signal_ctr = total_cost = 0;
 
	for (;;) {
 
		// only build/remove signals with the specified density
 
		if (signal_ctr % signal_density == 0) {
 
			ret = DoCommand(tile, TrackdirToTrack(trackdir) | semaphores, signals, flags, (mode == 1) ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS);
 

	
 
			/* Abort placement for any other error than NOT_SUITABLE_TRACK
 
			 * This includes vehicles on track, competitor's tracks, etc. */
 
			if (CmdFailed(ret)) {
 
				if (_error_message != STR_1005_NO_SUITABLE_RAILROAD_TRACK && mode != 1) return CMD_ERROR;
 
				_error_message = INVALID_STRING_ID;
roadveh_cmd.c
Show inline comments
 
@@ -377,26 +377,26 @@ int32 CmdSendRoadVehToDepot(TileIndex ti
 
	v = GetVehicle(p1);
 

	
 
	if (v->type != VEH_Road || !CheckOwnership(v->owner)) return CMD_ERROR;
 

	
 
	if (v->vehstatus & VS_CRASHED) return CMD_ERROR;
 

	
 
	if (IsRoadVehInDepot(v)) return CMD_ERROR;
 

	
 
	/* If the current orders are already goto-depot */
 
	if (v->current_order.type == OT_GOTO_DEPOT) {
 
		if (!!(p2 & DEPOT_SERVICE) == HASBIT(v->current_order.flags, OFB_HALT_IN_DEPOT)) {
 
			/* We called with a different DEPOT_SERVICE setting.
 
			* Now we change the setting to apply the new one and let the vehicle head for the same depot.
 
			* Note: the if is (true for requesting service == true for ordered to stop in depot)          */
 
			 * Now we change the setting to apply the new one and let the vehicle head for the same depot.
 
			 * Note: the if is (true for requesting service == true for ordered to stop in depot) */
 
			if (flags & DC_EXEC) {
 
				TOGGLEBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
 
				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
 
			}
 
			return 0;
 
		}
 

	
 
		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
 
		if (flags & DC_EXEC) {
 
			/* If the orders to 'goto depot' are in the orders list (forced servicing),
 
			 * then skip to the next order; effectively cancelling this forced service */
 
			if (HASBIT(v->current_order.flags, OFB_PART_OF_ORDERS))
saveload.c
Show inline comments
 
@@ -679,28 +679,28 @@ bool SlObjectMember(void *ptr, const Sav
 
				SlWriteUint16(ReferenceToInt(*(void**)ptr, conv));
 
			} else {
 
				*(void**)ptr = IntToReference(SlReadUint16(), conv);
 
			}
 
			break;
 
		case SL_ARR: SlArray(ptr, sld->length, conv); break;
 
		case SL_STR: SlString(ptr, sld->length, conv); break;
 
		default: NOT_REACHED();
 
		}
 
		break;
 

	
 
	/* SL_WRITEBYTE translates a value of a variable to another one upon
 
		* saving or loading.
 
		* XXX - variable renaming abuse
 
		* game_value: the value of the variable ingame is abused by sld->version_from
 
		* file_value: the value of the variable in the savegame is abused by sld->version_to */
 
   * saving or loading.
 
   * XXX - variable renaming abuse
 
   * game_value: the value of the variable ingame is abused by sld->version_from
 
   * file_value: the value of the variable in the savegame is abused by sld->version_to */
 
	case SL_WRITEBYTE:
 
		if (_sl.save) {
 
			SlWriteByte(sld->version_to);
 
		} else {
 
			*(byte*)ptr = sld->version_from;
 
		}
 
		break;
 

	
 
	/* SL_INCLUDE loads common code for a type
 
	 * XXX - variable renaming abuse
 
	 * include_index: common code to include from _desc_includes[], abused by sld->version_from */
 
	case SL_INCLUDE:
 
@@ -1597,25 +1597,25 @@ SaveOrLoadResult SaveOrLoad(const char *
 
		}
 

	
 
		/* Old maps were hardcoded to 256x256 and thus did not contain
 
		 * any mapsize information. Pre-initialize to 256x256 to not to
 
		 * confuse old games */
 
		InitializeGame(IG_DATE_RESET, 256, 256);
 

	
 
		SlLoadChunks();
 
		fmt->uninit_read();
 
		fclose(_sl.fh);
 

	
 
		/* After loading fix up savegame for any internal changes that
 
		* might've occured since then. If it fails, load back the old game */
 
		 * might've occured since then. If it fails, load back the old game */
 
		if (!AfterLoadGame()) return SL_REINIT;
 
	}
 

	
 
	return SL_OK;
 
}
 

	
 
/** Do a save when exiting the game (patch option) _patches.autosave_on_exit */
 
void DoExitSave(void)
 
{
 
	char buf[200];
 
	snprintf(buf, sizeof(buf), "%s%sexit.sav", _path.autosave_dir, PATHSEP);
 
	SaveOrLoad(buf, SL_SAVE);
settings.c
Show inline comments
 
@@ -759,25 +759,25 @@ static void ini_save_settings(IniFile *i
 
			s = sdb->name;
 
			group = group_def;
 
		}
 

	
 
		item = ini_getitem(group, s, true);
 
		ptr = ini_get_variable(sld, object);
 

	
 
		if (item->value != NULL) {
 
			// check if the value is the same as the old value
 
			const void *p = string_to_val(sdb, item->value);
 

	
 
			/* The main type of a variable/setting is in bytes 8-15
 
			* The subtype (what kind of numbers do we have there) is in 0-7 */
 
			 * The subtype (what kind of numbers do we have there) is in 0-7 */
 
			switch (sdb->cmd) {
 
			case SDT_BOOLX:
 
			case SDT_NUMX:
 
			case SDT_ONEOFMANY:
 
			case SDT_MANYOFMANY:
 
				switch (GetVarMemType(sld->conv)) {
 
				case SLE_VAR_BL:
 
				case SLE_VAR_I8:
 
				case SLE_VAR_U8:
 
					if (*(byte*)ptr == (byte)(unsigned long)p) continue;
 
					break;
 
				case SLE_VAR_I16:
settings_gui.c
Show inline comments
 
@@ -319,43 +319,43 @@ static const GameSettingData _game_setti
 
	{  0,   1,  1, STR_6836_OFF},
 
	{  0,   2,  1, STR_6839_PERMISSIVE},
 
};
 

	
 
static inline bool GetBitAndShift(uint32 *b)
 
{
 
	uint32 x = *b;
 
	*b >>= 1;
 
	return HASBIT(x, 0);
 
}
 

	
 
/*
 
	A: competitors
 
	B: start time in months / 3
 
	C: town count (2 = high, 0 = low)
 
	D: industry count (3 = high, 0 = none)
 
	E: inital loan / 1000 (in GBP)
 
	F: interest rate
 
	G: running costs (0 = low, 2 = high)
 
	H: construction speed of competitors (0 = very slow, 4 = very fast)
 
	I: intelligence (0-2)
 
	J: breakdowns(0 = off, 2 = normal)
 
	K: subsidy multiplier (0 = 1.5, 3 = 4.0)
 
	L: construction cost (0-2)
 
	M: terrain type (0 = very flat, 3 = mountainous)
 
	N: amount of water (0 = very low, 3 = high)
 
	O: economy (0 = steady, 1 = fluctuating)
 
	P: Train reversing (0 = end of line + stations, 1 = end of line)
 
	Q: disasters
 
	R: area restructuring (0 = permissive, 2 = hostile)
 
*/
 
 * A: competitors
 
 * B: start time in months / 3
 
 * C: town count (2 = high, 0 = low)
 
 * D: industry count (3 = high, 0 = none)
 
 * E: inital loan / 1000 (in GBP)
 
 * F: interest rate
 
 * G: running costs (0 = low, 2 = high)
 
 * H: construction speed of competitors (0 = very slow, 4 = very fast)
 
 * I: intelligence (0-2)
 
 * J: breakdowns (0 = off, 2 = normal)
 
 * K: subsidy multiplier (0 = 1.5, 3 = 4.0)
 
 * L: construction cost (0-2)
 
 * M: terrain type (0 = very flat, 3 = mountainous)
 
 * N: amount of water (0 = very low, 3 = high)
 
 * O: economy (0 = steady, 1 = fluctuating)
 
 * P: Train reversing (0 = end of line + stations, 1 = end of line)
 
 * Q: disasters
 
 * R: area restructuring (0 = permissive, 2 = hostile)
 
 */
 
static const int16 _default_game_diff[3][GAME_DIFFICULTY_NUM] = { /*
 
	 A, B, C, D,   E, F, G, H, I, J, K, L, M, N, O, P, Q, R*/
 
	{2, 2, 1, 3, 300, 2, 0, 2, 0, 1, 2, 0, 1, 0, 0, 0, 0, 0}, //easy
 
	{4, 1, 1, 2, 150, 3, 1, 3, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1}, //medium
 
	{7, 0, 2, 2, 100, 4, 1, 3, 2, 2, 0, 2, 3, 2, 1, 1, 1, 2}, //hard
 
};
 

	
 
void SetDifficultyLevel(int mode, GameOptions *gm_opt)
 
{
 
	int i;
 
	assert(mode <= 3);
 

	
 
@@ -978,37 +978,38 @@ static void NewgrfWndProc(Window *w, Win
 

	
 
			_sel_grffile = _first_grffile;
 
			// get selected grf-file
 
			while (y-- != 0) _sel_grffile = _sel_grffile->next;
 

	
 
			SetWindowDirty(w);
 
		} break;
 
		case 9: /* Cancel button */
 
			DeleteWindowById(WC_GAME_OPTIONS, 0);
 
			break;
 
		} break;
 

	
 
/* Parameter edit box not used yet
 
#if 0 /* Parameter edit box not used yet */
 
	case WE_TIMEOUT:
 
		WP(w,def_d).data_2 = 0;
 
		SetWindowDirty(w);
 
		break;
 

	
 
	case WE_ON_EDIT_TEXT: {
 
		if (*e->edittext.str) {
 
			SetWindowDirty(w);
 
		}
 
		break;
 
	}
 
*/
 
#endif
 

	
 
	case WE_DESTROY:
 
		_sel_grffile = NULL;
 
		DeleteWindowById(WC_QUERY_STRING, 0);
 
		break;
 
	}
 
}
 

	
 
static const Widget _newgrf_widgets[] = {
 
{   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,                    STR_018B_CLOSE_WINDOW},
 
{    WWT_CAPTION,   RESIZE_NONE,    14,    11,   279,     0,    13, STR_NEWGRF_SETTINGS_CAPTION, STR_018C_WINDOW_TITLE_DRAG_THIS},
 
{      WWT_PANEL,   RESIZE_NONE,    14,     0,   279,   183,   276, 0x0,                         STR_NULL},
 

	
smallmap_gui.c
Show inline comments
 
@@ -221,26 +221,26 @@ static const uint16 * const _legend_tabl
 
		d[0] |= GB(val, 24, 8);
 
		d[1] |= GB(val, 16, 8);
 
		d[2] |= GB(val,  8, 8);
 
		d[3] |= GB(val,  0, 8);
 
#	elif defined(TTD_LITTLE_ENDIAN)
 
		d[0] |= GB(val,  0, 8);
 
		d[1] |= GB(val,  8, 8);
 
		d[2] |= GB(val, 16, 8);
 
		d[3] |= GB(val, 24, 8);
 
#	endif
 
	}
 
#else
 
#	define WRITE_PIXELS(dst, val)		*(uint32*)(dst) = (val);
 
#	define WRITE_PIXELS_OR(dst,val)	*(uint32*)(dst) |= (val);
 
#	define WRITE_PIXELS(dst, val)   *(uint32*)(dst) = (val);
 
#	define WRITE_PIXELS_OR(dst,val) *(uint32*)(dst) |= (val);
 
#endif
 

	
 
#define MKCOLOR(x) TO_LE32X(x)
 

	
 
/* Height encodings; 16 levels XXX - needs updating for more/finer heights! */
 
static const uint32 _map_height_bits[16] = {
 
	MKCOLOR(0x5A5A5A5A),
 
	MKCOLOR(0x5A5B5A5B),
 
	MKCOLOR(0x5B5B5B5B),
 
	MKCOLOR(0x5B5C5B5C),
 
	MKCOLOR(0x5C5C5C5C),
 
	MKCOLOR(0x5C5D5C5D),
station_cmd.c
Show inline comments
 
/* $Id$ */
 

	
 
/** @file station_cmd.c
 
  */
 
/** @file station_cmd.c */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "debug.h"
 
#include "functions.h"
 
#include "station_map.h"
 
#include "table/sprites.h"
 
#include "table/strings.h"
 
#include "map.h"
 
#include "tile.h"
 
#include "station.h"
 
#include "gfx.h"
 
@@ -160,25 +159,25 @@ RoadStop *AllocateRoadStop(void)
 

	
 
			return rs;
 
		}
 
	}
 

	
 
	/* Check if we can add a block to the pool */
 
	if (AddBlockToPool(&_roadstop_pool)) return AllocateRoadStop();
 

	
 
	return NULL;
 
}
 

	
 
/* Calculate the radius of the station. Basicly it is the biggest
 
    radius that is available within the station */
 
 *  radius that is available within the station */
 
static uint FindCatchmentRadius(const Station* st)
 
{
 
	uint ret = 0;
 

	
 
	if (st->bus_stops != NULL)   ret = max(ret, CA_BUS);
 
	if (st->truck_stops != NULL) ret = max(ret, CA_TRUCK);
 
	if (st->train_tile) ret = max(ret, CA_TRAIN);
 
	if (st->dock_tile)  ret = max(ret, CA_DOCK);
 

	
 
	if (st->airport_tile) {
 
		switch (st->airport_type) {
 
			case AT_OILRIG:        ret = max(ret, CA_AIR_OILPAD);   break;
 
@@ -774,31 +773,31 @@ int32 CheckFlatLandBelow(TileIndex tile,
 

	
 
	Slope tileh;
 
	uint z;
 
	int allowed_z = -1;
 
	int flat_z;
 

	
 
	BEGIN_TILE_LOOP(tile_cur, w, h, tile)
 
		if (!EnsureNoVehicle(tile_cur)) return CMD_ERROR;
 

	
 
		tileh = GetTileSlope(tile_cur, &z);
 

	
 
		/* Prohibit building if
 
			1) The tile is "steep" (i.e. stretches two height levels)
 
			-OR-
 
			2) The tile is non-flat if
 
				a) the player building is an "old-school" AI
 
				-OR-
 
				b) the build_on_slopes switch is disabled
 
		*/
 
		 *   1) The tile is "steep" (i.e. stretches two height levels)
 
		 * -OR-
 
		 *   2) The tile is non-flat if
 
		 *     a) the player building is an "old-school" AI
 
		 *   -OR-
 
		 *     b) the build_on_slopes switch is disabled
 
		 */
 
		if (IsSteepSlope(tileh) ||
 
				((_is_old_ai_player || !_patches.build_on_slopes) && tileh != SLOPE_FLAT)) {
 
			return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
 
		}
 

	
 
		flat_z = z;
 
		if (tileh != SLOPE_FLAT) {
 
			// need to check so the entrance to the station is not pointing at a slope.
 
			if ((invalid_dirs&1 && !(tileh & SLOPE_NE) && (uint)w_cur == w) ||
 
					(invalid_dirs&2 && !(tileh & SLOPE_SE) && h_cur == 1) ||
 
					(invalid_dirs&4 && !(tileh & SLOPE_SW) && w_cur == 1) ||
 
					(invalid_dirs&8 && !(tileh & SLOPE_NW) && (uint)h_cur == h)) {
 
@@ -1243,29 +1242,29 @@ uint GetStationPlatforms(const Station *
 

	
 
	// find ending tile
 
	t = tile;
 
	do {
 
		t += delta;
 
		len++;
 
	} while (TileBelongsToRailStation(st, t) && GetRailStationAxis(t) == axis);
 

	
 
	return len - 1;
 
}
 

	
 
/** Determines the REMAINING length of a platform, starting at (and including)
 
  * the given tile.
 
  * @param tile the tile from which to start searching. Must be a railway station tile
 
  * @param dir The direction in which to search.
 
  * @return The platform length
 
  */
 
 * the given tile.
 
 * @param tile the tile from which to start searching. Must be a railway station tile
 
 * @param dir The direction in which to search.
 
 * @return The platform length
 
 */
 
uint GetPlatformLength(TileIndex tile, DiagDirection dir)
 
{
 
	TileIndex start_tile = tile;
 
	uint length = 0;
 
	assert(IsRailwayStationTile(tile));
 
	assert(dir < DIAGDIR_END);
 

	
 
	do {
 
		length ++;
 
		tile += TileOffsByDir(dir);
 
	} while (IsCompatibleTrainStationTile(tile, start_tile));
 

	
 
@@ -1344,41 +1343,41 @@ int32 DoConvertStationRail(TileIndex til
 
	if (GetRailType(tile) == totype) return CMD_ERROR;
 

	
 
	if (exec) {
 
		SetRailType(tile, totype);
 
		MarkTileDirtyByTile(tile);
 
		YapfNotifyTrackLayoutChange(tile, GetRailStationTrack(tile));
 
	}
 

	
 
	return _price.build_rail >> 1;
 
}
 

	
 
/** Heavy wizardry used to add a roadstop to a station.
 
  * To understand the function, lets first look at what is passed around,
 
  * especially the last two parameters. CmdBuildRoadStop allocates a road
 
  * stop and needs to put that stop into the linked list of road stops.
 
  * It (CmdBuildRoadStop) has a **currstop pointer which points to element
 
  * in the linked list of stops (each element in this list being a pointer
 
  * in itself, hence the double pointer). We (FindRoadStopSpot) need to
 
  * modify this pointer (**currstop) thus we need to pass by reference,
 
  * obtaining a triple pointer (***currstop). When finished, **currstop
 
  * in CmdBuildRoadStop will contain the address of the pointer which will
 
  * then point into the global roadstop array. *prev (in CmdBuildRoadStop)
 
  * is the pointer tino the global roadstop array which has *currstop in
 
  * its ->next element.
 
  * @param[in] truck_station Determines whether a stop is RS_BUS or RS_TRUCK
 
  * @param[in] station The station to do the whole procedure for
 
  * @param[out] currstop See the detailed function description
 
  * @param prev See the detailed function description
 
  */
 
 * To understand the function, lets first look at what is passed around,
 
 * especially the last two parameters. CmdBuildRoadStop allocates a road
 
 * stop and needs to put that stop into the linked list of road stops.
 
 * It (CmdBuildRoadStop) has a **currstop pointer which points to element
 
 * in the linked list of stops (each element in this list being a pointer
 
 * in itself, hence the double pointer). We (FindRoadStopSpot) need to
 
 * modify this pointer (**currstop) thus we need to pass by reference,
 
 * obtaining a triple pointer (***currstop). When finished, **currstop
 
 * in CmdBuildRoadStop will contain the address of the pointer which will
 
 * then point into the global roadstop array. *prev (in CmdBuildRoadStop)
 
 * is the pointer tino the global roadstop array which has *currstop in
 
 * its ->next element.
 
 * @param[in] truck_station Determines whether a stop is RS_BUS or RS_TRUCK
 
 * @param[in] station The station to do the whole procedure for
 
 * @param[out] currstop See the detailed function description
 
 * @param prev See the detailed function description
 
 */
 
static void FindRoadStopSpot(bool truck_station, Station* st, RoadStop*** currstop, RoadStop** prev)
 
{
 
	RoadStop **primary_stop = (truck_station) ? &st->truck_stops : &st->bus_stops;
 
	assert(*prev == NULL);
 

	
 
	if (*primary_stop == NULL) {
 
		//we have no roadstop of the type yet, so write a "primary stop"
 
		*currstop = primary_stop;
 
	} else {
 
		//there are stops already, so append to the end of the list
 
		*prev = *primary_stop;
 
		*currstop = &(*primary_stop)->next;
 
@@ -2358,30 +2357,30 @@ void DestroyRoadStop(RoadStop* rs)
 
			if (v->type == VEH_Road && v->u.road.slot == rs) {
 
				ClearSlot(v);
 
			}
 
		}
 
	}
 
	assert(rs->num_vehicles == 0);
 

	
 
	if (rs->prev != NULL) rs->prev->next = rs->next;
 
	if (rs->next != NULL) rs->next->prev = rs->prev;
 
}
 

	
 
/**
 
  * Clean up a station by clearing vehicle orders and invalidating windows.
 
  * Aircraft-Hangar orders need special treatment here, as the hangars are
 
  * actually part of a station (tiletype is STATION), but the order type
 
  * is OT_GOTO_DEPOT.
 
  * @param st Station to be deleted
 
  */
 
 * Clean up a station by clearing vehicle orders and invalidating windows.
 
 * Aircraft-Hangar orders need special treatment here, as the hangars are
 
 * actually part of a station (tiletype is STATION), but the order type
 
 * is OT_GOTO_DEPOT.
 
 * @param st Station to be deleted
 
 */
 
void DestroyStation(Station *st)
 
{
 
	StationID index;
 

	
 
	index = st->index;
 

	
 
	DeleteName(st->string_id);
 
	MarkStationDirty(st);
 
	RebuildStationLists();
 
	InvalidateWindowClasses(WC_STATION_LIST);
 

	
 
	DeleteWindowById(WC_STATION_VIEW, index);
station_gui.c
Show inline comments
 
@@ -238,25 +238,25 @@ static void SortStationsList(plstations_
 
}
 

	
 
static void PlayerStationsWndProc(Window *w, WindowEvent *e)
 
{
 
	const PlayerID owner = w->window_number;
 
	static byte facilities = FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK;
 
	static uint16 cargo_filter = 0x1FFF;
 
	plstations_d *sl = &WP(w, plstations_d);
 

	
 
	switch (e->event) {
 
	case WE_PAINT: {
 
		/* Set up cargo click-states. Toggle the all-vehicle and all-cargo types button
 
		* depending on if all types are clicked or not */
 
		 * depending on if all types are clicked or not */
 
		SB(w->click_state, 6, 5, facilities);
 
		SB(w->click_state, 26, 1, facilities == (FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_BUS_STOP | FACIL_AIRPORT | FACIL_DOCK));
 
		SB(w->click_state, 12, NUM_CARGO + 1, cargo_filter);
 
		SB(w->click_state, 27, 1, cargo_filter == 0x1FFF);
 

	
 
		BuildStationsList(sl, owner, facilities, cargo_filter);
 
		SortStationsList(sl);
 

	
 
		SetVScrollCount(w, sl->list_length);
 

	
 
		/* draw widgets, with player's name in the caption */
 
		{
table/autorail.h
Show inline comments
 
/* $Id$ */
 

	
 
/* Rail selection types (directions):
 
 / \    / \    / \    / \   / \   / \
 
/  /\  /\  \  /===\  /   \ /|  \ /  |\
 
\/  /  \  \/  \   /  \===/ \|  / \  |/
 
 \ /    \ /    \ /    \ /   \ /   \ /
 
  0      1      2      3     4     5
 
*/
 
 *  / \    / \    / \    / \   / \   / \
 
 * /  /\  /\  \  /===\  /   \ /|  \ /  |\
 
 * \/  /  \  \/  \   /  \===/ \|  / \  |/
 
 *  \ /    \ /    \ /    \ /   \ /   \ /
 
 *   0      1      2      3     4     5
 
 */
 

	
 
// mark invalid tiles red
 
#define RED(c) c | PALETTE_SEL_TILE_RED
 

	
 
// table maps each of the six rail directions and tileh combinations to a sprite
 
// invalid entries are required to make sure that this array can be quickly accessed
 
static const int _AutorailTilehSprite[][6] = {
 
// type   0        1        2        3        4        5
 
	{       0,       8,      16,      25,      34,      42 }, // tileh = 0
 
	{       5,      13, RED(22), RED(31),      35,      42 }, // tileh = 1
 
	{       5,      10,      16,      26, RED(38), RED(46) }, // tileh = 2
 
	{       5,       9, RED(23),      26,      35, RED(46) }, // tileh = 3
table/bridge_land.h
Show inline comments
 
/* $Id$ */
 

	
 
/** @file bridge_land.h This file contains all the sprites for bridges
 
  * It consists of a number of arrays.
 
  * <ul><li>_bridge_sprite_table_n_m. Defines all the sprites of a bridge besides the pylons.
 
  * n defines the number of the bridge type, m the number of the section. the highest m for
 
  * each bridge set defines the heads.<br>
 
  * Sprites for middle secionts are arranged in groups of four, the elements are:
 
  * <ol><li>Element containing the track. This element is logically behind the vehicle.</li>
 
  * <li>Element containing the structure that is logically between the vehicle and the camera</li>
 
  * <li>Element containing the pylons.</li></ol>
 
  * First group is for railway in X direction, second for railway in Y direction, two groups each follow for road, monorail and maglev<p>
 
  * <br>Elements for heads are arranged in groups of eight:
 
  * <ol><li>X direction, north end, flat</li>
 
  * <li>Y direction, north end, flat</li>
 
  * <li>X direction, south end, flat</li>
 
  * <li>Y direction, south end, flat</li>
 
  * <li>X direction, north end, sloped</li>
 
  * <li>Y direction, north end, sloped</li>
 
  * <li>X direction, south end, sloped</li>
 
  * <li>Y direction, south end, sloped</li></ol>
 
  * This is repeated 4 times, for rail, road, monorail, maglev</li>
 
  * </ul>
 
  */
 
 * It consists of a number of arrays.
 
 * <ul><li>_bridge_sprite_table_n_m. Defines all the sprites of a bridge besides the pylons.
 
 * n defines the number of the bridge type, m the number of the section. the highest m for
 
 * each bridge set defines the heads.<br>
 
 * Sprites for middle secionts are arranged in groups of four, the elements are:
 
 * <ol><li>Element containing the track. This element is logically behind the vehicle.</li>
 
 * <li>Element containing the structure that is logically between the vehicle and the camera</li>
 
 * <li>Element containing the pylons.</li></ol>
 
 * First group is for railway in X direction, second for railway in Y direction, two groups each follow for road, monorail and maglev<p>
 
 * <br>Elements for heads are arranged in groups of eight:
 
 * <ol><li>X direction, north end, flat</li>
 
 * <li>Y direction, north end, flat</li>
 
 * <li>X direction, south end, flat</li>
 
 * <li>Y direction, south end, flat</li>
 
 * <li>X direction, north end, sloped</li>
 
 * <li>Y direction, north end, sloped</li>
 
 * <li>X direction, south end, sloped</li>
 
 * <li>Y direction, south end, sloped</li></ol>
 
 * This is repeated 4 times, for rail, road, monorail, maglev</li>
 
 * </ul>
 
 */
 

	
 
static const PalSpriteID _bridge_sprite_table_2_0[] = {
 
	    0x9C3,     0x9C7,     0x9C9,       0x0,     0x9C4,     0x9C8,     0x9CA,       0x0,
 
	    0x9C5,     0x9C7,     0x9C9,       0x0,     0x9C6,     0x9C8,     0x9CA,       0x0,
 
	   0x10E4,     0x9C7,     0x9C9,       0x0,    0x10E5,     0x9C8,     0x9CA,       0x0,
 
	   0x110C,     0x9C7,     0x9C9,       0x0,    0x110D,     0x9C8,     0x9CA,       0x0,
 
};
 

	
 
static const PalSpriteID _bridge_sprite_table_2_1[] = {
 
	    0x986,     0x988,     0x985,     0x987,     0x98A,     0x98C,     0x989,     0x98B,
 
	0x98E | PALETTE_TO_STRUCT_WHITE, 0x990 | PALETTE_TO_STRUCT_WHITE, 0x98D | PALETTE_TO_STRUCT_WHITE, 0x98F | PALETTE_TO_STRUCT_WHITE, 0x992 | PALETTE_TO_STRUCT_WHITE, 0x994 | PALETTE_TO_STRUCT_WHITE, 0x991 | PALETTE_TO_STRUCT_WHITE, 0x993 | PALETTE_TO_STRUCT_WHITE,
 
	0x10E7 | PALETTE_TO_STRUCT_WHITE, 0x10E9 | PALETTE_TO_STRUCT_WHITE, 0x10E6 | PALETTE_TO_STRUCT_WHITE, 0x10E8 | PALETTE_TO_STRUCT_WHITE, 0x10EB | PALETTE_TO_STRUCT_WHITE, 0x10ED | PALETTE_TO_STRUCT_WHITE, 0x10EA | PALETTE_TO_STRUCT_WHITE, 0x10EC | PALETTE_TO_STRUCT_WHITE,
table/elrail_data.h
Show inline comments
 
/* $Id */
 
/** @file elrail_data.h Stores all the data for overhead wire and pylon drawing.
 
  @see elrail.c */
 
 *  @see elrail.c */
 

	
 
#ifndef ELRAIL_DATA_H
 
#define ELRAIL_DATA_H
 

	
 
/** Tile Location group.
 
  This defines whether the X and or Y coordinate of a tile is even */
 
 * This defines whether the X and or Y coordinate of a tile is even */
 
typedef enum TLG {
 
	XEVEN_YEVEN = 0,
 
	XEVEN_YODD  = 1,
 
	XODD_YEVEN  = 2,
 
	XODD_YODD   = 3,
 
	TLG_END
 
} TLG;
 

	
 
/** When determining the pylon configuration on the edge, two tiles are taken
 
  into account: the tile being drawn itself (the home tile, the one in
 
  ti->tile), and the neighbouring tile */
 
 * into account: the tile being drawn itself (the home tile, the one in
 
 * ti->tile), and the neighbouring tile */
 
typedef enum {
 
	TS_HOME      = 0,
 
	TS_NEIGHBOUR = 1,
 

	
 
	TS_END
 
} TileSource;
 

	
 
enum {
 
	NUM_TRACKS_AT_PCP = 6
 
};
 

	
 
/** Which PPPs are possible at all on a given PCP */
 
static byte AllowedPPPonPCP[DIAGDIR_END] = {
 
	1 << DIR_N | 1 << DIR_E  | 1 << DIR_SE | 1 << DIR_S | 1 << DIR_W  | 1 << DIR_NW,
 
	1 << DIR_N | 1 << DIR_NE | 1 << DIR_E  | 1 << DIR_S | 1 << DIR_SW | 1 << DIR_W,
 
	1 << DIR_N | 1 << DIR_E  | 1 << DIR_SE | 1 << DIR_S | 1 << DIR_W  | 1 << DIR_NW,
 
	1 << DIR_N | 1 << DIR_NE | 1 << DIR_E  | 1 << DIR_S | 1 << DIR_SW | 1 << DIR_W,
 
};
 

	
 
/** Which of the PPPs are inside the tile. For the two PPPs on the tile border
 
  the following system is used: if you rotate the PCP so that it is in the
 
  north, the eastern PPP belongs to the tile. */
 
 * the following system is used: if you rotate the PCP so that it is in the
 
 * north, the eastern PPP belongs to the tile. */
 
static byte OwnedPPPonPCP[DIAGDIR_END] = {
 
	1 << DIR_SE | 1 << DIR_S  | 1 << DIR_SW | 1 << DIR_W,
 
	1 << DIR_N  | 1 << DIR_SW | 1 << DIR_W  | 1 << DIR_NW,
 
	1 << DIR_N  | 1 << DIR_NE | 1 << DIR_E  | 1 << DIR_NW,
 
	1 << DIR_NE | 1 << DIR_E  | 1 << DIR_SE | 1 << DIR_S
 
};
 

	
 
/** Maps a track bit onto two PCP positions */
 
static const DiagDirection PCPpositions[TRACK_END][2] = {
 
	{DIAGDIR_NE, DIAGDIR_SW}, /* X */
 
	{DIAGDIR_SE, DIAGDIR_NW}, /* Y */
 
	{DIAGDIR_NW, DIAGDIR_NE}, /* UPPER */
 
	{DIAGDIR_SE, DIAGDIR_SW}, /* LOWER */
 
	{DIAGDIR_SW, DIAGDIR_NW}, /* LEFT */
 
	{DIAGDIR_NE, DIAGDIR_SE}, /* RIGHT */
 
};
 

	
 
#define PCP_NOT_ON_TRACK 0xFF
 
/** Preferred points of each trackbit. Those are the ones perpendicular to the
 
  track, plus the point in extension of the track (to mark end-of-track). PCPs
 
  which are not on either end of the track are fully preferred.
 
  @see PCPpositions */
 
 * track, plus the point in extension of the track (to mark end-of-track). PCPs
 
 * which are not on either end of the track are fully preferred.
 
 * @see PCPpositions */
 
static byte PreferredPPPofTrackAtPCP[TRACK_END][DIAGDIR_END] = {
 
	{    /* X */
 
		1 << DIR_NE | 1 << DIR_SE | 1 << DIR_NW, /* NE */
 
		PCP_NOT_ON_TRACK,                        /* SE */
 
		1 << DIR_SE | 1 << DIR_SW | 1 << DIR_NW, /* SW */
 
		PCP_NOT_ON_TRACK                         /* NE */
 
	}, { /* Y */
 
		PCP_NOT_ON_TRACK,
 
		1 << DIR_NE | 1 << DIR_SE | 1 << DIR_SW,
 
		PCP_NOT_ON_TRACK,
 
		1 << DIR_SW | 1 << DIR_NW | 1 << DIR_NE
 
	}, { /* UPPER */
 
@@ -92,26 +92,26 @@ static byte PreferredPPPofTrackAtPCP[TRA
 
		1 << DIR_N | 1 << DIR_E | 1 << DIR_W,
 
		1 << DIR_S | 1 << DIR_E | 1 << DIR_W,
 
		PCP_NOT_ON_TRACK,
 
		PCP_NOT_ON_TRACK
 
	}
 
};
 
#undef PCP_NOT_ON_TRACK
 

	
 

	
 
#define NUM_IGNORE_GROUPS 3
 
#define IGNORE_NONE 0xFF
 
/** In case we have a staight line, we place pylon only every two tiles,
 
  so there are certain tiles which we ignore. A straight line is found if
 
  we have exactly two PPPs. */
 
 * so there are certain tiles which we ignore. A straight line is found if
 
 * we have exactly two PPPs. */
 
static byte IgnoredPCP[NUM_IGNORE_GROUPS][TLG_END][DIAGDIR_END] = {
 
	{   /* Ignore group 1, X and Y tracks */
 
		{     /* X even, Y even */
 
			IGNORE_NONE,
 
			1 << DIR_NE | 1 << DIR_SW,
 
			1 << DIR_NW | 1 << DIR_SE,
 
			IGNORE_NONE
 
		}, { /* X even, Y odd  */
 
			IGNORE_NONE,
 
			IGNORE_NONE,
 
			1 << DIR_NW | 1 << DIR_SE,
 
			1 << DIR_NE | 1 << DIR_SW
 
@@ -187,25 +187,25 @@ static byte DisallowedPPPofTrackAtPCP[TR
 
	{1 << DIR_S | 1 << DIR_N,  1 << DIR_S | 1 << DIR_N,  0,           0,         }, /* RIGHT */
 
};
 

	
 
/* This array stores which track bits can meet at a tile edge */
 
static const Track TracksAtPCP[DIAGDIR_END][NUM_TRACKS_AT_PCP] = {
 
	{TRACK_X, TRACK_X, TRACK_UPPER, TRACK_LOWER, TRACK_LEFT, TRACK_RIGHT},
 
	{TRACK_Y, TRACK_Y, TRACK_UPPER, TRACK_LOWER, TRACK_LEFT, TRACK_RIGHT},
 
	{TRACK_X, TRACK_X, TRACK_UPPER, TRACK_LOWER, TRACK_LEFT, TRACK_RIGHT},
 
	{TRACK_Y, TRACK_Y, TRACK_UPPER, TRACK_LOWER, TRACK_LEFT, TRACK_RIGHT},
 
};
 

	
 
/* takes each of the 6 track bits from the array above and
 
   assigns it to the home tile or neighbour tile */
 
 * assigns it to the home tile or neighbour tile */
 
static const TileSource TrackSourceTile[DIAGDIR_END][NUM_TRACKS_AT_PCP] = {
 
	{TS_HOME, TS_NEIGHBOUR, TS_HOME     , TS_NEIGHBOUR, TS_NEIGHBOUR, TS_HOME     },
 
	{TS_HOME, TS_NEIGHBOUR, TS_NEIGHBOUR, TS_HOME     , TS_NEIGHBOUR, TS_HOME     },
 
	{TS_HOME, TS_NEIGHBOUR, TS_NEIGHBOUR, TS_HOME     , TS_HOME     , TS_NEIGHBOUR},
 
	{TS_HOME, TS_NEIGHBOUR, TS_HOME     , TS_NEIGHBOUR, TS_HOME     , TS_NEIGHBOUR},
 
};
 

	
 
/* Several PPPs maybe exist, here they are sorted in order of preference. */
 
static const Direction PPPorder[DIAGDIR_END][TLG_END][DIR_END] = {    /*  X  -  Y  */
 
	{   /* PCP 0 */
 
		{DIR_NE, DIR_NW, DIR_SE, DIR_SW, DIR_N, DIR_E, DIR_S, DIR_W}, /* evn - evn */
 
		{DIR_NE, DIR_SE, DIR_SW, DIR_NW, DIR_S, DIR_W, DIR_N, DIR_E}, /* evn - odd */
 
@@ -223,26 +223,26 @@ static const Direction PPPorder[DIAGDIR_
 
		{DIR_SW, DIR_SE, DIR_NE, DIR_NW, DIR_S, DIR_W, DIR_N, DIR_E}, /* odd - odd */
 
	}, {/* PCP 3 */
 
		{DIR_NE, DIR_NW, DIR_SE, DIR_SW, DIR_N, DIR_W, DIR_S, DIR_E}, /* evn - evn */
 
		{DIR_NE, DIR_SE, DIR_SW, DIR_NW, DIR_S, DIR_E, DIR_N, DIR_W}, /* evn - odd */
 
		{DIR_SW, DIR_NW, DIR_NE, DIR_SE, DIR_S, DIR_E, DIR_N, DIR_W}, /* odd - evn */
 
		{DIR_SW, DIR_SE, DIR_NE, DIR_NW, DIR_N, DIR_W, DIR_S, DIR_E}, /* odd - odd */
 
	}
 
};
 
/* Geometric placement of the PCP relative to the tile origin */
 
static const int8 x_pcp_offsets[DIAGDIR_END] = {0,  8, 15, 8};
 
static const int8 y_pcp_offsets[DIAGDIR_END] = {8, 15,  8, 0};
 
/* Geometric placement of the PPP relative to the PCP*/
 
static const int8 x_ppp_offsets[DIR_END] = {-3, -4, -3,  0, +3, +4, +3,  0};
 
static const int8 y_ppp_offsets[DIR_END] = {-3,  0, +3, +4, +3,  0, -3, -4};
 
static const int8 x_ppp_offsets[DIR_END] = {-3, -4, -3,  0,  3,  4,  3,  0};
 
static const int8 y_ppp_offsets[DIR_END] = {-3,  0,  3,  4,  3,  0, -3, -4};
 
/* The type of pylon to draw at each PPP */
 
static const SpriteID pylons_normal[] = {
 
	SPR_PYLON_EW_N,
 
	SPR_PYLON_Y_NE,
 
	SPR_PYLON_NS_E,
 
	SPR_PYLON_X_SE,
 
	SPR_PYLON_EW_S,
 
	SPR_PYLON_Y_SW,
 
	SPR_PYLON_NS_W,
 
	SPR_PYLON_X_NW
 
};
 

	
 
@@ -332,34 +332,34 @@ static const SortableSpriteStruct Catena
 
	{ SPR_WIRE_EW_E,          8,  0,  8,  8,  1, ELRAIL_ELEVATION }, //!32: UPPER trackbit wire, pylon on both ends
 
	{ SPR_WIRE_EW_E,         16,  8,  8,  8,  1, ELRAIL_ELEVATION }  //!33: LOWER trackbit wire, pylon on both ends
 
};
 

	
 
static const SortableSpriteStruct CatenarySpriteData_Depot[] = {
 
	{ SPR_WIRE_DEPOT_NE,      0,  8,  8,  1,  1, ELRAIL_ELEVATION }, //! Wire for NE depot exit
 
	{ SPR_WIRE_DEPOT_SE,      8,  0,  1,  8,  1, ELRAIL_ELEVATION }, //! Wire for SE depot exit
 
	{ SPR_WIRE_DEPOT_SW,      0,  8,  8,  1,  1, ELRAIL_ELEVATION }, //! Wire for SW depot exit
 
	{ SPR_WIRE_DEPOT_NW,      8,  0,  1,  8,  1, ELRAIL_ELEVATION }  //! Wire for NW depot exit
 
};
 

	
 
/** Refers to a certain element of the catenary.
 
  * Identifiers for Wires:
 
  * <ol><li>Direction of the wire</li>
 
  * <li>Slope of the tile for diagonals, placement inside the track for horiz/vertical pieces</li>
 
  * <li>Place where a pylon shoule be</li></ol>
 
  * Identifiers for Pylons:
 
  * <ol><li>Direction of the wire</li>
 
  * <li>Slope of the tile</li>
 
  * <li>Position of the Pylon relative to the track</li>
 
  * <li>Position of the Pylon inside the tile</li></ol>
 
  */
 
 * Identifiers for Wires:
 
 * <ol><li>Direction of the wire</li>
 
 * <li>Slope of the tile for diagonals, placement inside the track for horiz/vertical pieces</li>
 
 * <li>Place where a pylon shoule be</li></ol>
 
 * Identifiers for Pylons:
 
 * <ol><li>Direction of the wire</li>
 
 * <li>Slope of the tile</li>
 
 * <li>Position of the Pylon relative to the track</li>
 
 * <li>Position of the Pylon inside the tile</li></ol>
 
 */
 
typedef enum {
 
	WIRE_X_FLAT_SW,
 
	WIRE_X_FLAT_NE,
 
	WIRE_X_FLAT_BOTH,
 

	
 
	WIRE_X_UP_SW,
 
	WIRE_X_UP_NE,
 
	WIRE_X_UP_BOTH,
 

	
 
	WIRE_X_DOWN_SW,
 
	WIRE_X_DOWN_NE,
 
	WIRE_X_DOWN_BOTH,
 
@@ -389,29 +389,29 @@ typedef enum {
 
	WIRE_EW_S_BOTH,
 

	
 
	WIRE_EW_N_W,
 
	WIRE_EW_S_W,
 

	
 
	WIRE_EW_N_E,
 
	WIRE_EW_S_E,
 

	
 
	INVALID_CATENARY = 0xFF
 
} CatenarySprite;
 

	
 
/* Selects a Wire (with white and grey ends) depending on whether:
 
   a) none (should never happen)
 
   b) the first
 
   c) the second
 
   d) both
 
   PCP exists.*/
 
 * a) none (should never happen)
 
 * b) the first
 
 * c) the second
 
 * d) both
 
 * PCP exists.*/
 
static const CatenarySprite Wires[5][TRACK_END][4] = {
 
	{ /* Tileh == 0 */
 
		{INVALID_CATENARY, WIRE_X_FLAT_NE,   WIRE_X_FLAT_SW,   WIRE_X_FLAT_BOTH},
 
		{INVALID_CATENARY, WIRE_Y_FLAT_SE,   WIRE_Y_FLAT_NW,   WIRE_Y_FLAT_BOTH},
 
		{INVALID_CATENARY, WIRE_EW_N_W,      WIRE_EW_N_E,      WIRE_EW_N_BOTH},
 
		{INVALID_CATENARY, WIRE_EW_S_E,      WIRE_EW_S_W,      WIRE_EW_S_BOTH},
 
		{INVALID_CATENARY, WIRE_NS_W_S,      WIRE_NS_W_N,      WIRE_NS_W_BOTH},
 
		{INVALID_CATENARY, WIRE_NS_E_N,      WIRE_NS_E_S,      WIRE_NS_E_BOTH},
 
	}, { /* Tileh == 3 */
 
		{INVALID_CATENARY, WIRE_X_UP_NE,     WIRE_X_UP_SW,     WIRE_X_UP_BOTH},
 
		{INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
 
		{INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY, INVALID_CATENARY},
table/engines.h
Show inline comments
 
/* $Id$ */
 

	
 
#ifndef ENGINES_H
 
#define ENGINES_H
 

	
 
/** @file table/engines.h
 
  * This file contains all the data for vehicles
 
  */
 
 *  This file contains all the data for vehicles
 
 */
 

	
 
#include "../sound.h"
 

	
 
/** Writes the properties of a vehicle into the EngineInfo struct.
 
  * @see EngineInfo
 
  * @param a Introduction date
 
  * @param e Rail Type of the vehicle
 
  * @param f Bitmask of the climates
 
  */
 
 * @see EngineInfo
 
 * @param a Introduction date
 
 * @param e Rail Type of the vehicle
 
 * @param f Bitmask of the climates
 
 */
 
#define MK(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, b, c, d, e, f, 0, 8, 0, 0 }
 
/** Writes the properties of a train carriage into the EngineInfo struct.
 
  * @see EngineInfo
 
  * @param a Introduction date
 
  * @param e Rail Type of the vehicle
 
  * @param f Bitmask of the climates
 
  * @note the 0x80 in parameter b sets the "is carriage bit"
 
  */
 
 * @see EngineInfo
 
 * @param a Introduction date
 
 * @param e Rail Type of the vehicle
 
 * @param f Bitmask of the climates
 
 * @note the 0x80 in parameter b sets the "is carriage bit"
 
 */
 
#define MW(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, b | 0x80, c, d, e, f, 0, 8, 0, 0 }
 

	
 
// Rail types
 
// R = Conventional railway
 
// E = Electrified railway
 
// M = Monorail
 
// L = MagLev
 
#define R 0
 
#define E 1
 
#define M 2
 
#define L 3
 
// Climates
table/sprites.h
Show inline comments
 
/* $Id$ */
 

	
 
#ifndef SPRITES_H
 
#define SPRITES_H
 

	
 
/** @file sprites.h
 
	This file contails all sprite-related enums and defines. These consist mainly of
 
	the sprite numbers and a bunch of masks and macros to handle sprites and to get
 
	rid of all the magic numbers in the code.
 

	
 
@NOTE:
 
	ALL SPRITE NUMBERS BELOW 5126 are in the main files
 
	SPR_CANALS_BASE is in canalsw.grf
 
	SPR_SLOPES_BASE is in trkfoundw.grf
 
	SPR_OPENTTD_BASE is in openttd.grf
 

	
 
	All elements which consist of two elements should
 
	have the same name and then suffixes
 
		_GROUND and _BUILD for building-type sprites
 
		_REAR and _FRONT for transport-type sprites (tiles where vehicles are on)
 
	These sprites are split because of the Z order of the elements
 
		(like some parts of a bridge are behind the vehicle, while others are before)
 

	
 

	
 
	All sprites which are described here are referenced only one to a handful of times
 
	throughout the code. When introducing new sprite enums, use meaningful names.
 
	Don't be lazy and typing, and only use abbrevations when their meaning is clear or
 
	the length of the enum would get out of hand. In that case EXPLAIN THE ABBREVATION
 
	IN THIS FILE, and perhaps add some comments in the code where it is used.
 
	Now, don't whine about this being too much typing work if the enums are like
 
	30 characters in length. If your editor doen't help you simplifying your work,
 
	get a proper editor. If your Operating Systems don't have any decent editors,
 
	get a proper Operating System.
 

	
 
	@todo Split the "Sprites" enum into smaller chunks and document them
 
*/
 
 * This file contails all sprite-related enums and defines. These consist mainly of
 
 * the sprite numbers and a bunch of masks and macros to handle sprites and to get
 
 * rid of all the magic numbers in the code.
 
 *
 
 * @NOTE:
 
 * ALL SPRITE NUMBERS BELOW 5126 are in the main files
 
 * SPR_CANALS_BASE is in canalsw.grf
 
 * SPR_SLOPES_BASE is in trkfoundw.grf
 
 * SPR_OPENTTD_BASE is in openttd.grf
 
 *
 
 * All elements which consist of two elements should
 
 * have the same name and then suffixes
 
 *   _GROUND and _BUILD for building-type sprites
 
 *   _REAR and _FRONT for transport-type sprites (tiles where vehicles are on)
 
 * These sprites are split because of the Z order of the elements
 
 *  (like some parts of a bridge are behind the vehicle, while others are before)
 
 *
 
 *
 
 * All sprites which are described here are referenced only one to a handful of times
 
 * throughout the code. When introducing new sprite enums, use meaningful names.
 
 * Don't be lazy and typing, and only use abbrevations when their meaning is clear or
 
 * the length of the enum would get out of hand. In that case EXPLAIN THE ABBREVATION
 
 * IN THIS FILE, and perhaps add some comments in the code where it is used.
 
 * Now, don't whine about this being too much typing work if the enums are like
 
 * 30 characters in length. If your editor doen't help you simplifying your work,
 
 * get a proper editor. If your Operating Systems don't have any decent editors,
 
 * get a proper Operating System.
 
 *
 
 * @todo Split the "Sprites" enum into smaller chunks and document them
 
 */
 

	
 

	
 
enum Sprites {
 
	SPR_SELECT_TILE  = 752,
 
	SPR_DOT          = 774, // corner marker for lower/raise land
 
	SPR_DOT_SMALL    = 4078,
 
	SPR_WHITE_POINT  = 4079,
 

	
 
	/* ASCII */
 
	SPR_ASCII_SPACE       = 2,
 
	SPR_ASCII_SPACE_SMALL = 226,
 
	SPR_ASCII_SPACE_BIG   = 450,
 
@@ -217,26 +217,26 @@ enum Sprites {
 
	OFFSET_TILEH_4              = 13,
 
	OFFSET_TILEH_6              = 21,
 
	OFFSET_TILEH_7              = 17,
 
	OFFSET_TILEH_8              = 12,
 
	OFFSET_TILEH_9              = 23,
 
	OFFSET_TILEH_11             = 18,
 
	OFFSET_TILEH_12             = 20,
 
	OFFSET_TILEH_13             = 19,
 
	OFFSET_TILEH_14             = 16,
 

	
 
	/* Elrail stuff */
 
	/* Wires. First identifier is the direction of the track, second is the required placement of the pylon.
 
	   "short" denotes a wire that requires a pylon on each end. Third identifier is the direction of the slope
 
	   (in positive coordinate direction) */
 
	 * "short" denotes a wire that requires a pylon on each end. Third identifier is the direction of the slope
 
	 * (in positive coordinate direction) */
 
	SPR_WIRE_X_SHORT = SPR_ELRAIL_BASE + 3,
 
	SPR_WIRE_Y_SHORT = SPR_ELRAIL_BASE + 4,
 
	SPR_WIRE_EW_SHORT = SPR_ELRAIL_BASE + 5,
 
	SPR_WIRE_NS_SHORT = SPR_ELRAIL_BASE + 6,
 
	SPR_WIRE_X_SHORT_DOWN = SPR_ELRAIL_BASE + 7,
 
	SPR_WIRE_Y_SHORT_UP = SPR_ELRAIL_BASE + 8,
 
	SPR_WIRE_X_SHORT_UP = SPR_ELRAIL_BASE + 9,
 
	SPR_WIRE_Y_SHORT_DOWN = SPR_ELRAIL_BASE + 10,
 

	
 
	SPR_WIRE_X_SW = SPR_ELRAIL_BASE + 11,
 
	SPR_WIRE_Y_SE = SPR_ELRAIL_BASE + 12,
 
	SPR_WIRE_EW_E = SPR_ELRAIL_BASE + 13,
 
@@ -552,37 +552,36 @@ enum Sprites {
 
	SPR_BTSGA_ROAD_Y_REAR       = 2502,
 
	SPR_BTSGA_X_FRONT           = 2503,
 
	SPR_BTSGA_Y_FRONT           = 2504,
 
	SPR_BTSGA_X_PILLAR          = 2505,
 
	SPR_BTSGA_Y_PILLAR          = 2606,
 
	SPR_BTSGA_MONO_X_REAR       = 4324,
 
	SPR_BTSGA_MONO_Y_REAR       = 4325,
 
	SPR_BTSGA_MGLV_X_REAR       = 4364,
 
	SPR_BTSGA_MGLV_Y_REAR       = 4365,
 

	
 
	/* BTSUS == Suspension bridge */
 
	/* TILE_* denotes the different tiles a suspension bridge
 
		can have
 
		TILE_A and TILE_B are the "beginnings" and "ends" of the
 
			suspension system. they have small rectangluar endcaps
 
		TILE_C and TILE_D look almost identical to TILE_A and
 
			TILE_B, but they do not have the "endcaps". They form the
 
			middle part
 
		TILE_E is a condensed configuration of two pillars. while they
 
			are usually 2 pillars apart, they only have 1 pillar separation
 
			here
 
		TILE_F is an extended configuration of pillars. they are
 
			plugged in when pillars should be 3 tiles apart
 

	
 
	*/
 
	 * can have
 
	 * TILE_A and TILE_B are the "beginnings" and "ends" of the
 
	 *   suspension system. they have small rectangluar endcaps
 
	 * TILE_C and TILE_D look almost identical to TILE_A and
 
	 *   TILE_B, but they do not have the "endcaps". They form the
 
	 *   middle part
 
	 * TILE_E is a condensed configuration of two pillars. while they
 
	 *   are usually 2 pillars apart, they only have 1 pillar separation
 
	 *   here
 
	 * TILE_F is an extended configuration of pillars. they are
 
	 *   plugged in when pillars should be 3 tiles apart
 
	 */
 
	SPR_BTSUS_ROAD_Y_REAR_TILE_A  = 2453,
 
	SPR_BTSUS_ROAD_Y_REAR_TILE_B  = 2454,
 
	SPR_BTSUS_Y_FRONT_TILE_A      = 2455,
 
	SPR_BTSUS_Y_FRONT_TILE_B      = 2456,
 
	SPR_BTSUS_ROAD_Y_REAR_TILE_D  = 2457,
 
	SPR_BTSUS_ROAD_Y_REAR_TILE_C  = 2458,
 
	SPR_BTSUS_Y_FRONT_TILE_D      = 2459,
 
	SPR_BTSUS_Y_FRONT_TILE_C      = 2460,
 
	SPR_BTSUS_ROAD_X_REAR_TILE_A  = 2461,
 
	SPR_BTSUS_ROAD_X_REAR_TILE_B  = 2462,
 
	SPR_BTSUS_X_FRONT_TILE_A      = 2463,
 
	SPR_BTSUS_X_FRONT_TILE_B      = 2464,
 
@@ -704,28 +703,28 @@ enum Sprites {
 
	SPR_BTGIR_ROAD_Y        = 2556,
 
	SPR_BTGIR_X_FRONT       = 2557,
 
	SPR_BTGIR_Y_FRONT       = 2558,
 
	SPR_BTGIR_X_PILLAR      = 2505,
 
	SPR_BTGIR_Y_PILLAR      = 2506,
 
	SPR_BTGIR_MONO_X        = 4362,
 
	SPR_BTGIR_MONO_Y        = 4363,
 
	SPR_BTGIR_MGLV_X        = 4402,
 
	SPR_BTGIR_MGLV_Y        = 4403,
 

	
 
	/* tubular bridges */
 
	/* tubular bridges have 3 kinds of tiles:
 
			a start tile (with only half a tube on the far side, marked _BEG
 
			a middle tile (full tunnel), marked _MID
 
			and an end tile (half a tube on the near side, maked _END
 
	*/
 
	 *  a start tile (with only half a tube on the far side, marked _BEG
 
	 *  a middle tile (full tunnel), marked _MID
 
	 *  and an end tile (half a tube on the near side, maked _END
 
	 */
 
	SPR_BTTUB_X_FRONT_BEG       = 2559,
 
	SPR_BTTUB_X_FRONT_MID       = 2660,
 
	SPR_BTTUB_X_FRONT_END       = 2561,
 
	SPR_BTTUB_Y_FRONT_END       = 2562,
 
	SPR_BTTUB_Y_FRONT_MID       = 2563,
 
	SPR_BTTUB_Y_FRONT_BEG       = 2564,
 
	SPR_BTTUB_X_RAIL_REAR_BEG   = 2569,
 
	SPR_BTTUB_X_RAIL_REAR_MID   = 2570,
 
	SPR_BTTUB_X_RAIL_REAR_END   = 2571,
 

	
 

	
 
	/* ramps (for all bridges except wood and tubular?)*/
table/town_land.h
Show inline comments
 
/* $Id$ */
 

	
 
/** @file town_land.h
 
 */
 
/** @file town_land.h */
 

	
 
enum {
 
	HOUSE_TEMP_CHURCH    = 0x03,
 
	HOUSE_STADIUM        = 0x14,
 
	HOUSE_MODERN_STADIUM = 0x20,
 
	HOUSE_ARCT_CHURCH    = 0x3c,
 
	HOUSE_SNOW_CHURCH    = 0x3d,
 
	HOUSE_TROP_CHURCH    = 0x53,
 
	HOUSE_TOY_CHURCH     = 0x5b,
 

	
 
	HOUSE_MAX            = 110
 
};
 

	
 
/** Writes the data into the Town Tile Drawing Struct
 
  * @param s1 The first sprite of the building, mostly the ground sprite
 
  * @param s2 The second sprite of the building.
 
  * @param sx The x-position of the sprite within the tile
 
  * @param xy the y-position of the sprite within the tile
 
  * @param w the width of the sprite
 
  * @param h the height of the sprite
 
  * @param dz the virtual height of the sprite
 
  * @param p set to 1 if a lift is present
 
  * @see DrawTownTileStruct
 
  */
 
 * @param s1 The first sprite of the building, mostly the ground sprite
 
 * @param s2 The second sprite of the building.
 
 * @param sx The x-position of the sprite within the tile
 
 * @param xy the y-position of the sprite within the tile
 
 * @param w the width of the sprite
 
 * @param h the height of the sprite
 
 * @param dz the virtual height of the sprite
 
 * @param p set to 1 if a lift is present
 
 * @see DrawTownTileStruct
 
 */
 
#define M(s1, s2, sx, sy, w, h, dz, p) {s1, s2, sx, sy, w - 1, h - 1, dz, p}
 

	
 
static const DrawBuildingsTileStruct _town_draw_tile_data[] = {
 
	M( 0xf54,  0x58d,  0,  0, 14, 14,   8, 0),
 
	M( 0xf54,  0x58e,  0,  0, 14, 14,  60, 0),
 
	M( 0xf54,  0x58f,  0,  0, 14, 14,  60, 0),
 
	M( 0x590,  0x58f,  0,  0, 14, 14,  60, 0),
 
	M( 0xf54,  0x58d,  0,  0, 14, 14,   8, 0),
 
	M( 0xf54,  0x58e,  0,  0, 14, 14,  60, 0),
 
	M( 0xf54,  0x591,  0,  0, 14, 14,  60, 0),
 
	M( 0x590,  0x591,  0,  0, 14, 14,  60, 0),
 
	M( 0xf54,  0x58d | PALETTE_TO_STRUCT_WHITE,  0,  0, 14, 14,   8, 0),
 
@@ -1919,38 +1918,38 @@ static const uint16 _housetype_flags[] =
 
	0x2007, 0x0807, 0x6018, 0x0818, 0x2018, 0x0818, 0x6018, 0x0818,
 
	0x2001, 0x0801, 0x201E, 0x081E, 0x200F, 0x080F, 0x2007, 0x0807,
 
	0x201C, 0x081C, 0x201C, 0x0000, 0x081C, 0x0000, 0x601C, 0x081C,
 
	0x2018, 0x0818, 0x201C, 0x0000, 0x081C, 0x0000, 0x401E, 0x401E,
 
	0x401E, 0x4001, 0x401C, 0x400E, 0x401E, 0x401C, 0x401C, 0x4018,
 
	0x4000, 0x401C, 0x4018, 0x801F, 0x801F, 0x8003, 0x800F, 0x800F,
 
	0x800F, 0x800F, 0x801C, 0x801F, 0x0000, 0x801C, 0x8001, 0x8001,
 
	0x801C, 0x801C, 0x801C, 0x801C, 0x801F, 0x801F,
 
};
 
assert_compile(lengthof(_housetype_flags) == HOUSE_MAX);
 

	
 
static const byte _housetype_extra_flags[] = {
 
	 0, 0, 0, 0,32,32, 0, 8,
 
	 0, 0, 0, 0, 0, 0, 0, 0,
 
	 0, 0, 0, 0,16, 0, 0, 0,
 
	 0, 0, 0, 0, 0, 0, 0, 0,
 
	16, 0, 0, 0, 0, 0, 0, 0,
 
	16, 0, 0, 0, 0, 0, 0, 0,
 
	 0, 0, 0, 0, 0, 0, 0, 0,
 
	 0, 0, 0, 0, 0, 0, 0, 0,
 
	 0, 0, 8, 0, 8, 0, 0, 0,
 
	 0, 0, 4, 0, 4, 0, 0, 0,
 
	 0, 0, 0, 0, 0, 0, 0, 4,
 
	 0, 0, 0, 0, 0, 0, 0, 0,
 
	 0, 0, 0, 8, 0, 0, 0, 0,
 
	 0, 0, 0, 0, 0, 0,
 
	 0,  0,  0,  0, 32, 32,  0,  8,
 
	 0,  0,  0,  0,  0,  0,  0,  0,
 
	 0,  0,  0,  0, 16,  0,  0,  0,
 
	 0,  0,  0,  0,  0,  0,  0,  0,
 
	16,  0,  0,  0,  0,  0,  0,  0,
 
	16,  0,  0,  0,  0,  0,  0,  0,
 
	 0,  0,  0,  0,  0,  0,  0,  0,
 
	 0,  0,  0,  0,  0,  0,  0,  0,
 
	 0,  0,  8,  0,  8,  0,  0,  0,
 
	 0,  0,  4,  0,  4,  0,  0,  0,
 
	 0,  0,  0,  0,  0,  0,  0,  4,
 
	 0,  0,  0,  0,  0,  0,  0,  0,
 
	 0,  0,  0,  8,  0,  0,  0,  0,
 
	 0,  0,  0,  0,  0,  0,
 
};
 
assert_compile(lengthof(_housetype_extra_flags) == HOUSE_MAX);
 

	
 
static const byte _housetype_population[] = {
 
	187,  85,  40,   5, 220, 220,  30, 140,
 
	  0,   0,   0,   0,   0, 150,  95,  95,
 
	 95, 130,   6, 110,  65,   0,   0,   0,
 
	 15,  12,  13, 100, 170, 100, 180,  35,
 
	 65,   0,   0,   0, 140,  15,  15,  35,
 
	180,   0,   0,   0,  80,  80,  16,  16,
 
	 14,  14, 135, 135, 170, 170, 210, 210,
 
	 10,  10,  25,  25,   6,   6,  17,  17,
 
@@ -2128,38 +2127,38 @@ static const HousetypeYear _housetype_ye
 
	{    0, MAX_YEAR },
 
	{    0, MAX_YEAR },
 
	{    0, MAX_YEAR },
 
	{    0, MAX_YEAR },
 
	{    0, MAX_YEAR },
 
	{    0, MAX_YEAR },
 
	{    0, MAX_YEAR },
 
	{    0, MAX_YEAR },
 
};
 
assert_compile(lengthof(_housetype_years) == HOUSE_MAX);
 

	
 
static const byte _housetype_cargo_passengers[] = {
 
	8, 8, 8, 2, 10,10,4, 6,
 
	6, 2, 2, 2, 2, 8, 6, 6,
 
	6, 10,6, 6, 4, 4, 4, 4,
 
	3, 3, 3, 7, 8, 6, 8, 8,
 
	4, 4, 4, 4, 8, 3, 3, 8,
 
	8, 8, 8, 8, 5, 5, 3, 3,
 
	3, 3, 8, 8, 9, 9,10, 10,
 
	2, 2, 3, 3, 2, 2, 3, 3,
 
	6, 6, 6, 6, 6, 6, 7, 7,
 
	9, 9, 7, 7, 7, 7, 3, 3,
 
	3, 3, 6, 2, 3, 6, 6, 8,
 
	8, 6, 8, 2, 6, 3, 3, 3,
 
	3, 3, 8, 4, 4, 8, 3, 3,
 
	8, 8, 8, 4, 3, 3,
 
	8,  8,  8,  2, 10, 10,  4,  6,
 
	6,  2,  2,  2,  2,  8,  6,  6,
 
	6, 10,  6,  6,  4,  4,  4,  4,
 
	3,  3,  3,  7,  8,  6,  8,  8,
 
	4,  4,  4,  4,  8,  3,  3,  8,
 
	8,  8,  8,  8,  5,  5,  3,  3,
 
	3,  3,  8,  8,  9,  9, 10, 10,
 
	2,  2,  3,  3,  2,  2,  3,  3,
 
	6,  6,  6,  6,  6,  6,  7,  7,
 
	9,  9,  7,  7,  7,  7,  3,  3,
 
	3,  3,  6,  2,  3,  6,  6,  8,
 
	8,  6,  8,  2,  6,  3,  3,  3,
 
	3,  3,  8,  4,  4,  8,  3,  3,
 
	8,  8,  8,  4,  3,  3,
 
};
 
assert_compile(lengthof(_housetype_cargo_passengers) == HOUSE_MAX);
 

	
 
static const byte _housetype_cargo_mail[] = {
 
	 3, 3, 3, 0, 4, 4, 1, 1,
 
	 1, 0, 0, 0, 0, 2, 2, 2,
 
	 2, 3, 3, 2, 0, 0, 0, 0,
 
	 1, 1, 1, 2, 3, 2, 3, 2,
 
	 0, 0, 0, 0, 3, 1, 1, 2,
 
	 2, 2, 2, 2, 2, 2, 1, 1,
 
	 1, 1, 3, 3, 3, 3, 3, 3,
 
	 1, 1, 1, 1, 0, 0, 1, 1,
tgp.c
Show inline comments
 
@@ -496,43 +496,43 @@ static void HeightMapAdjustWaterLevel(am
 
		*h = (height_t)(((int)h_max_new) * (*h - h_water_level) / (h_max - h_water_level)) + I2H(1);
 
		/* Make sure all values are in the proper range (0..h_max_new) */
 
		if (*h < 0) *h = I2H(0);
 
		if (*h >= h_max_new) *h = h_max_new - 1;
 
	}
 

	
 
	free(hist_buf);
 
}
 

	
 
static double perlin_coast_noise_2D(const double x, const double y, const double p, const int prime);
 

	
 
/**
 
* This routine sculpts in from the edge a random amount, again a Perlin
 
* sequence, to avoid the rigid flat-edge slopes that were present before. The
 
* Perlin noise map doesnt know where we are going to slice across, and so we
 
* often cut straight through high terrain. the smoothing routine makes it
 
* legal, gradually increasing up from the edge to the original terrain height.
 
* By cutting parts of this away, it gives a far more irregular edge to the
 
* map-edge. Sometimes it works beautifully with the existing sea & lakes, and
 
* creates a very realistic coastline. Other times the variation is less, and
 
* the map-edge shows its cliff-like roots.
 
*
 
* This routine may be extended to randomly sculpt the height of the terrain
 
* near the edge. This will have the coast edge at low level (1-3), rising in
 
* smoothed steps inland to about 15 tiles in. This should make it look as
 
* though the map has been built for the map size, rather than a slice through
 
* a larger map.
 
*
 
* Please note that all the small numbers; 53, 101, 167, etc. are small primes
 
* to help give the perlin noise a bit more of a random feel.
 
*/
 
 * This routine sculpts in from the edge a random amount, again a Perlin
 
 * sequence, to avoid the rigid flat-edge slopes that were present before. The
 
 * Perlin noise map doesnt know where we are going to slice across, and so we
 
 * often cut straight through high terrain. the smoothing routine makes it
 
 * legal, gradually increasing up from the edge to the original terrain height.
 
 * By cutting parts of this away, it gives a far more irregular edge to the
 
 * map-edge. Sometimes it works beautifully with the existing sea & lakes, and
 
 * creates a very realistic coastline. Other times the variation is less, and
 
 * the map-edge shows its cliff-like roots.
 
 *
 
 * This routine may be extended to randomly sculpt the height of the terrain
 
 * near the edge. This will have the coast edge at low level (1-3), rising in
 
 * smoothed steps inland to about 15 tiles in. This should make it look as
 
 * though the map has been built for the map size, rather than a slice through
 
 * a larger map.
 
 *
 
 * Please note that all the small numbers; 53, 101, 167, etc. are small primes
 
 * to help give the perlin noise a bit more of a random feel.
 
 */
 
static void HeightMapCoastLines(void)
 
{
 
	int smallest_size = min(_patches.map_x, _patches.map_y);
 
	const int margin = 4;
 
	uint y, x;
 
	uint max_x;
 
	uint max_y;
 

	
 
	/* Lower to sea level */
 
	for (y = 0; y <= _height_map.size_y; y++) {
 
		/* Top right */
 
		max_x = myabs((perlin_coast_noise_2D(_height_map.size_y - y, y, 0.9, 53) + 0.25) * 5 + (perlin_coast_noise_2D(y, y, 0.35, 179) + 1) * 12);
 
@@ -617,30 +617,30 @@ static void HeightMapSmoothCoasts(void)
 
	for (x = 0; x < _height_map.size_x; x++) {
 
		HeightMapSmoothCoastInDirection(x, 0, 0, 1);
 
		HeightMapSmoothCoastInDirection(x, _height_map.size_y - 1, 0, -1);
 
	}
 
	/* First Smooth NE and SW coasts (x close to 0 and x close to size_x) */
 
	for (y = 0; y < _height_map.size_y; y++) {
 
		HeightMapSmoothCoastInDirection(0, y, 1, 0);
 
		HeightMapSmoothCoastInDirection(_height_map.size_x - 1, y, -1, 0);
 
	}
 
}
 

	
 
/**
 
* This routine provides the essential cleanup necessary before OTTD can
 
* display the terrain. When generated, the terrain heights can jump more than
 
* one level between tiles. This routine smooths out those differences so that
 
* the most it can change is one level. When OTTD can support cliffs, this
 
* routine may not be necessary.
 
*/
 
 * This routine provides the essential cleanup necessary before OTTD can
 
 * display the terrain. When generated, the terrain heights can jump more than
 
 * one level between tiles. This routine smooths out those differences so that
 
 * the most it can change is one level. When OTTD can support cliffs, this
 
 * routine may not be necessary.
 
 */
 
static void HeightMapSmoothSlopes(height_t dh_max)
 
{
 
	int x, y;
 
	for (y = 1; y <= (int)_height_map.size_y; y++) {
 
		for (x = 1; x <= (int)_height_map.size_x; x++) {
 
			height_t h_max = min(HeightMapXY(x - 1, y), HeightMapXY(x, y - 1)) + dh_max;
 
			if (HeightMapXY(x, y) > h_max) HeightMapXY(x, y) = h_max;
 
		}
 
	}
 
	for (y = _height_map.size_y - 1; y >= 0; y--) {
 
		for (x = _height_map.size_x - 1; x >= 0; x--) {
 
			height_t h_max = min(HeightMapXY(x + 1, y), HeightMapXY(x, y + 1)) + dh_max;
town_cmd.c
Show inline comments
 
@@ -729,25 +729,25 @@ static int GrowTownAtRoad(Town *t, TileI
 

	
 
		// Select a random bit from the blockmask, walk a step
 
		// and continue the search from there.
 
		do block = Random() & 3; while (!HASBIT(mask,block));
 
		tile += ToTileIndexDiff(_roadblock_tileadd[block]);
 

	
 
		if (IsTileType(tile, MP_STREET)) {
 
			/* Don't allow building over roads of other cities */
 
			if (IsTileOwner(tile, OWNER_TOWN) && GetTownByTile(tile) != t) {
 
				_grow_town_result = -1;
 
			} else if (_game_mode == GM_EDITOR) {
 
				/* If we are in the SE, and this road-piece has no town owner yet, it just found an
 
				*  owner :) (happy happy happy road now) */
 
				 * owner :) (happy happy happy road now) */
 
				SetTileOwner(tile, OWNER_TOWN);
 
				SetTownIndex(tile, t->index);
 
			}
 
		}
 

	
 
		// Max number of times is checked.
 
	} while (--_grow_town_result >= 0);
 

	
 
	return (_grow_town_result == -2);
 
}
 

	
 
// Generate a random road block
train_cmd.c
Show inline comments
 
@@ -1334,26 +1334,26 @@ int32 CmdSellRailWagon(TileIndex tile, u
 
				}
 
			}
 

	
 
			/* 2. We are selling the first engine, some special action might be required
 
			 * here, so take attention */
 
			if ((flags & DC_EXEC) && v == first) {
 
				new_f = GetNextVehicle(first);
 

	
 
				/* 2.1 If the first wagon is sold, update the first-> pointers to NULL */
 
				for (tmp = first; tmp != NULL; tmp = tmp->next) tmp->first = NULL;
 

	
 
				/* 2.2 If there are wagons present after the deleted front engine, check
 
					* if the second wagon (which will be first) is an engine. If it is one,
 
					* promote it as a new train, retaining the unitnumber, orders */
 
         * if the second wagon (which will be first) is an engine. If it is one,
 
         * promote it as a new train, retaining the unitnumber, orders */
 
				if (new_f != NULL) {
 
					if (IsTrainEngine(new_f)) {
 
						switch_engine = true;
 
						/* Copy important data from the front engine */
 
						new_f->unitnumber = first->unitnumber;
 
						new_f->current_order = first->current_order;
 
						new_f->cur_order_index = first->cur_order_index;
 
						new_f->orders = first->orders;
 
						if (first->prev_shared != NULL) {
 
							first->prev_shared->next_shared = new_f;
 
							new_f->prev_shared = first->prev_shared;
 
						}
 
@@ -1893,27 +1893,27 @@ static TrainFindDepotData FindClosestTra
 
	} else if (_patches.new_pathfinding_all) {
 
		NPFFoundTargetData ftd;
 
		Vehicle* last = GetLastVehicleInChain(v);
 
		Trackdir trackdir = GetVehicleTrackdir(v);
 
		Trackdir trackdir_rev = ReverseTrackdir(GetVehicleTrackdir(last));
 

	
 
		assert (trackdir != INVALID_TRACKDIR);
 
		ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, last->tile, trackdir_rev, TRANSPORT_RAIL, v->owner, v->u.rail.compatible_railtypes, NPF_INFINITE_PENALTY);
 
		if (ftd.best_bird_dist == 0) {
 
			/* Found target */
 
			tfdd.tile = ftd.node.tile;
 
			/* Our caller expects a number of tiles, so we just approximate that
 
			* number by this. It might not be completely what we want, but it will
 
			* work for now :-) We can possibly change this when the old pathfinder
 
			* is removed. */
 
			 * number by this. It might not be completely what we want, but it will
 
			 * work for now :-) We can possibly change this when the old pathfinder
 
			 * is removed. */
 
			tfdd.best_length = ftd.best_path_dist / NPF_TILE_LENGTH;
 
			if (NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE)) tfdd.reverse = true;
 
		}
 
	} else {
 
		// search in the forward direction first.
 
		DiagDirection i;
 

	
 
		i = DirToDiagDir(v->direction);
 
		if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[i]) {
 
			i = ChangeDiagDir(i, DIAGDIRDIFF_90LEFT);
 
		}
 
		NewTrainPathfind(tile, 0, v->u.rail.compatible_railtypes, i, (NTPEnumProc*)NtpCallbFindDepot, &tfdd);
 
@@ -1951,26 +1951,26 @@ int32 CmdSendTrainToDepot(TileIndex tile
 

	
 
	if (!IsValidVehicleID(p1)) return CMD_ERROR;
 

	
 
	v = GetVehicle(p1);
 

	
 
	if (v->type != VEH_Train || !CheckOwnership(v->owner)) return CMD_ERROR;
 

	
 
	if (v->vehstatus & VS_CRASHED) return CMD_ERROR;
 

	
 
	if (v->current_order.type == OT_GOTO_DEPOT) {
 
		if (!!(p2 & DEPOT_SERVICE) == HASBIT(v->current_order.flags, OFB_HALT_IN_DEPOT)) {
 
			/* We called with a different DEPOT_SERVICE setting.
 
			* Now we change the setting to apply the new one and let the vehicle head for the same depot.
 
			* Note: the if is (true for requesting service == true for ordered to stop in depot)          */
 
			 * Now we change the setting to apply the new one and let the vehicle head for the same depot.
 
			 * Note: the if is (true for requesting service == true for ordered to stop in depot)          */
 
			if (flags & DC_EXEC) {
 
				TOGGLEBIT(v->current_order.flags, OFB_HALT_IN_DEPOT);
 
				InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
 
			}
 
			return 0;
 
		}
 

	
 
		if (p2 & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders
 
		if (flags & DC_EXEC) {
 
			if (HASBIT(v->current_order.flags, OFB_PART_OF_ORDERS)) {
 
				v->u.rail.days_since_order_progr = 0;
 
				v->cur_order_index++;
tunnelbridge_cmd.c
Show inline comments
 
@@ -909,40 +909,40 @@ uint GetBridgeFoundation(Slope tileh, Ax
 
		case SLOPE_STEEP_S: i = 2; break;
 
		case SLOPE_E:
 
		case SLOPE_STEEP_E: i = 4; break;
 
		case SLOPE_N:
 
		case SLOPE_STEEP_N: i = 6; break;
 
		default: return 0;
 
	}
 
	if (axis != AXIS_X) ++i;
 
	return i + 15;
 
}
 

	
 
/**
 
  * 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.<p> For bridge heads:
 
  * <ul><li>Bit 0: direction</li>
 
  * <li>Bit 1: northern or southern heads</li>
 
  * <li>Bit 2: Set if the bridge head is sloped</li>
 
  * <li>Bit 3 and more: Railtype Specific subset</li>
 
  * </ul>
 
  * For middle parts:
 
  * <ul><li>Bits 0-1: need to be 0</li>
 
  * <li>Bit 2: direction</li>
 
  * <li>Bit 3 and above: Railtype Specific subset</li>
 
  * </ul>
 
  * Please note that in this code, "roads" are treated as railtype 1, whilst the real railtypes are 0, 2 and 3
 
  */
 
 * 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.<p> For bridge heads:
 
 * <ul><li>Bit 0: direction</li>
 
 * <li>Bit 1: northern or southern heads</li>
 
 * <li>Bit 2: Set if the bridge head is sloped</li>
 
 * <li>Bit 3 and more: Railtype Specific subset</li>
 
 * </ul>
 
 * For middle parts:
 
 * <ul><li>Bits 0-1: need to be 0</li>
 
 * <li>Bit 2: direction</li>
 
 * <li>Bit 3 and above: Railtype Specific subset</li>
 
 * </ul>
 
 * 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;
 
	const PalSpriteID *b;
 
	bool ice = _m[ti->tile].m4 & 0x80;
 

	
 
	if (IsTunnel(ti->tile)) {
 
		if (GetTunnelTransportType(ti->tile) == TRANSPORT_RAIL) {
 
			image = GetRailTypeInfo(GetRailType(ti->tile))->base_sprites.tunnel;
 
		} else {
 
			image = SPR_TUNNEL_ENTRY_REAR_ROAD;
 
		}
variables.h
Show inline comments
 
@@ -175,34 +175,34 @@ typedef struct Patches {
 

	
 
	byte wait_oneway_signal;            // waitingtime in days before a oneway signal
 
	byte wait_twoway_signal;            // waitingtime in days before a twoway signal
 

	
 
	uint8 map_x;                        // Size of map
 
	uint8 map_y;
 

	
 
	byte drag_signals_density;          // many signals density
 
	bool ainew_active;                  // Is the new AI active?
 
	bool ai_in_multiplayer;             // Do we allow AIs in multiplayer
 

	
 
	/*
 
		* New Path Finding
 
		*/
 
	 * New Path Finding
 
	 */
 
	bool new_pathfinding_all; /* Use the newest pathfinding algorithm for all */
 

	
 
	/**
 
		* The maximum amount of search nodes a single NPF run should take. This
 
		* limit should make sure performance stays at acceptable levels at the cost
 
		* of not being perfect anymore. This will probably be fixed in a more
 
		* sophisticated way sometime soon
 
		*/
 
	 * The maximum amount of search nodes a single NPF run should take. This
 
	 * limit should make sure performance stays at acceptable levels at the cost
 
	 * of not being perfect anymore. This will probably be fixed in a more
 
	 * sophisticated way sometime soon
 
	 */
 
	uint32 npf_max_search_nodes;
 

	
 
	uint32 npf_rail_firstred_penalty;      /* The penalty for when the first signal is red (and it is not an exit or combo signal) */
 
	uint32 npf_rail_firstred_exit_penalty; /* The penalty for when the first signal is red (and it is an exit or combo signal) */
 
	uint32 npf_rail_lastred_penalty;       /* The penalty for when the last signal is red */
 
	uint32 npf_rail_station_penalty;       /* The penalty for station tiles */
 
	uint32 npf_rail_slope_penalty;         /* The penalty for sloping upwards */
 
	uint32 npf_rail_curve_penalty;         /* The penalty for curves */
 
	uint32 npf_rail_depot_reverse_penalty; /* The penalty for reversing in depots */
 
	uint32 npf_buoy_penalty;               /* The penalty for going over (through) a buoy */
 
	uint32 npf_water_curve_penalty;        /* The penalty for curves */
 
	uint32 npf_road_curve_penalty;         /* The penalty for curves */
vehicle.c
Show inline comments
 
@@ -335,28 +335,28 @@ static Vehicle *AllocateSingleVehicle(Ve
 
	return NULL;
 
}
 

	
 

	
 
Vehicle *AllocateVehicle(void)
 
{
 
	VehicleID counter = 0;
 
	return AllocateSingleVehicle(&counter);
 
}
 

	
 

	
 
/** Allocates a lot of vehicles and frees them again
 
* @param vl pointer to an array of vehicles to get allocated. Can be NULL if the vehicles aren't needed (makes it test only)
 
* @param num number of vehicles to allocate room for
 
* @return true if there is room to allocate all the vehicles
 
*/
 
 * @param vl pointer to an array of vehicles to get allocated. Can be NULL if the vehicles aren't needed (makes it test only)
 
 * @param num number of vehicles to allocate room for
 
 * @return true if there is room to allocate all the vehicles
 
 */
 
bool AllocateVehicles(Vehicle **vl, int num)
 
{
 
	int i;
 
	Vehicle *v;
 
	VehicleID counter = 0;
 

	
 
	for (i = 0; i != num; i++) {
 
		v = AllocateSingleVehicle(&counter);
 
		if (v == NULL) {
 
			return false;
 
		}
 
		if (vl != NULL) {
 
@@ -505,27 +505,27 @@ Vehicle *GetFirstVehicleInChain(const Ve
 
{
 
	Vehicle* u;
 

	
 
	assert(v != NULL);
 

	
 
	if (v->first != NULL) {
 
		if (IsFrontEngine(v->first) || IsFreeWagon(v->first)) return v->first;
 

	
 
		DEBUG(misc, 0) ("v->first cache faulty. We shouldn't be here, rebuilding cache!");
 
	}
 

	
 
	/* It is the fact (currently) that newly built vehicles do not have
 
	* their ->first pointer set. When this is the case, go up to the
 
	* first engine and set the pointers correctly. Also the first pointer
 
	* is not saved in a savegame, so this has to be fixed up after loading */
 
	 * their ->first pointer set. When this is the case, go up to the
 
	 * first engine and set the pointers correctly. Also the first pointer
 
	 * is not saved in a savegame, so this has to be fixed up after loading */
 

	
 
	/* Find the 'locomotive' or the first wagon in a chain */
 
	while ((u = GetPrevVehicleInChain_bruteforce(v)) != NULL) v = u;
 

	
 
	/* Set the first pointer of all vehicles in that chain to the first wagon */
 
	if (IsFrontEngine(v) || IsFreeWagon(v))
 
		for (u = (Vehicle *)v; u != NULL; u = u->next) u->first = (Vehicle *)v;
 

	
 
	return (Vehicle*)v;
 
}
 

	
 
uint CountVehiclesInChain(const Vehicle* v)
 
@@ -565,26 +565,26 @@ void DeleteVehicleChain(Vehicle *v)
 
void Aircraft_Tick(Vehicle *v);
 
void RoadVeh_Tick(Vehicle *v);
 
void Ship_Tick(Vehicle *v);
 
void Train_Tick(Vehicle *v);
 
static void EffectVehicle_Tick(Vehicle *v);
 
void DisasterVehicle_Tick(Vehicle *v);
 
static void MaybeReplaceVehicle(Vehicle *v);
 

	
 
// head of the linked list to tell what vehicles that visited a depot in a tick
 
static Vehicle* _first_veh_in_depot_list;
 

	
 
/** Adds a vehicle to the list of vehicles, that visited a depot this tick
 
* @param *v vehicle to add
 
*/
 
 * @param *v vehicle to add
 
 */
 
void VehicleEnteredDepotThisTick(Vehicle *v)
 
{
 
	// we need to set v->leave_depot_instantly as we have no control of it's contents at this time
 
	if (HASBIT(v->current_order.flags, OFB_HALT_IN_DEPOT) && !HASBIT(v->current_order.flags, OFB_PART_OF_ORDERS) && v->current_order.type == OT_GOTO_DEPOT) {
 
		// we keep the vehicle in the depot since the user ordered it to stay
 
		v->leave_depot_instantly = false;
 
	} else {
 
		// the vehicle do not plan on stopping in the depot, so we stop it to ensure that it will not reserve the path
 
		// out of the depot before we might autoreplace it to a different engine. The new engine would not own the reserved path
 
		// we store that we stopped the vehicle, so autoreplace can start it again
 
		v->vehstatus |= VS_STOPPED;
 
		v->leave_depot_instantly = true;
 
@@ -1528,28 +1528,28 @@ void AgeVehicle(Vehicle *v)
 
	InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
 

	
 
	if (age == -366) {
 
		ShowVehicleGettingOld(v, STR_01A0_IS_GETTING_OLD);
 
	} else if (age == 0) {
 
		ShowVehicleGettingOld(v, STR_01A1_IS_GETTING_VERY_OLD);
 
	} else if (age == 366*1 || age == 366*2 || age == 366*3 || age == 366*4 || age == 366*5) {
 
		ShowVehicleGettingOld(v, STR_01A2_IS_GETTING_VERY_OLD_AND);
 
	}
 
}
 

	
 
/** Clone a vehicle. If it is a train, it will clone all the cars too
 
* @param tile tile of the depot where the cloned vehicle is build
 
* @param p1 the original vehicle's index
 
* @param p2 1 = shared orders, else copied orders
 
*/
 
 * @param tile tile of the depot where the cloned vehicle is build
 
 * @param p1 the original vehicle's index
 
 * @param p2 1 = shared orders, else copied orders
 
 */
 
int32 CmdCloneVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Vehicle *v_front, *v;
 
	Vehicle *w_front, *w, *w_rear;
 
	int cost, total_cost = 0;
 
	uint32 build_argument = 2;
 

	
 
	if (!IsValidVehicleID(p1)) return CMD_ERROR;
 
	v = GetVehicle(p1);
 
	v_front = v;
 
	w = NULL;
 
	w_front = NULL;
 
@@ -1910,32 +1910,32 @@ static void MaybeReplaceVehicle(Vehicle 
 
			MoveVehicleCargo(v, temp);
 
			cost += DoCommand(0, temp->index, 0, flags, CMD_SELL_VEH(temp->type));
 
		}
 
	}
 

	
 
	if (IsLocalPlayer()) ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost);
 

	
 
	if (stopped) v->vehstatus &= ~VS_STOPPED;
 
	_current_player = OWNER_NONE;
 
}
 

	
 
/**
 
* @param sort_list list to store the list in. Note: it's presumed that it is big enough to store all vehicles in the game (worst case) and it will not check size
 
* @param type type of vehicle
 
* @param owner PlayerID of owner to generate a list for
 
* @param station index of station to generate a list for. INVALID_STATION when not used
 
* @param order index of oder to generate a list for. INVALID_ORDER when not used
 
* @param window_type tells what kind of window the list is for. Use the VLW flags in vehicle_gui.h
 
* @return the number of vehicles added to the list
 
*/
 
 * @param sort_list list to store the list in. Note: it's presumed that it is big enough to store all vehicles in the game (worst case) and it will not check size
 
 * @param type type of vehicle
 
 * @param owner PlayerID of owner to generate a list for
 
 * @param station index of station to generate a list for. INVALID_STATION when not used
 
 * @param order index of oder to generate a list for. INVALID_ORDER when not used
 
 * @param window_type tells what kind of window the list is for. Use the VLW flags in vehicle_gui.h
 
 * @return the number of vehicles added to the list
 
 */
 
uint GenerateVehicleSortList(const Vehicle** sort_list, byte type, PlayerID owner, StationID station, OrderID order, uint16 window_type)
 
{
 
	const uint subtype = (type != VEH_Aircraft) ? Train_Front : 2;
 
	uint n = 0;
 
	const Vehicle *v;
 

	
 
	switch (window_type) {
 
		case VLW_STATION_LIST: {
 
			FOR_ALL_VEHICLES(v) {
 
				if (v->type == type && (
 
					(type == VEH_Train && IsFrontEngine(v)) ||
 
					(type != VEH_Train && v->subtype <= subtype))) {
 
@@ -1976,31 +1976,31 @@ uint GenerateVehicleSortList(const Vehic
 
				}
 
			}
 
			break;
 
		}
 

	
 
		default: NOT_REACHED(); break;
 
	}
 

	
 
	return n;
 
}
 

	
 
/** send all vehicles of type to depots
 
* @param type type of vehicle
 
* @param flags the flags used for DoCommand()
 
* @param service should the vehicles only get service in the depots
 
* @param owner PlayerID of owner of the vehicles to send
 
* @param VLW_flag tells what kind of list requested the goto depot
 
* @return 0 for success and CMD_ERROR if no vehicle is able to go to depot
 
*/
 
 * @param type type of vehicle
 
 * @param flags the flags used for DoCommand()
 
 * @param service should the vehicles only get service in the depots
 
 * @param owner PlayerID of owner of the vehicles to send
 
 * @param VLW_flag tells what kind of list requested the goto depot
 
 * @return 0 for success and CMD_ERROR if no vehicle is able to go to depot
 
 */
 
int32 SendAllVehiclesToDepot(byte type, uint32 flags, bool service, PlayerID owner, uint16 vlw_flag, uint32 id)
 
{
 
	const Vehicle** sort_list;
 
	uint n, i;
 

	
 
	sort_list = malloc(GetVehicleArraySize() * sizeof(sort_list[0]));
 
	if (sort_list == NULL) {
 
		error("Could not allocate memory for the vehicle-goto-depot-list");
 
	}
 

	
 
	n = GenerateVehicleSortList(sort_list, type, owner, (vlw_flag == VLW_STATION_LIST) ? id : INVALID_STATION, (vlw_flag == VLW_SHARED_ORDERS) ? id : INVALID_ORDER, vlw_flag);
 

	
 
@@ -2535,38 +2535,38 @@ static void Load_VEHS(void)
 
		if (!AddBlockIfNeeded(&_vehicle_pool, index))
 
			error("Vehicles: failed loading savegame: too many vehicles");
 

	
 
		v = GetVehicle(index);
 
		SlObject(v, _veh_descs[SlReadByte()]);
 

	
 
		/* Old savegames used 'last_station_visited = 0xFF' */
 
		if (CheckSavegameVersion(5) && v->last_station_visited == 0xFF)
 
			v->last_station_visited = INVALID_STATION;
 

	
 
		if (CheckSavegameVersion(5)) {
 
			/* Convert the current_order.type (which is a mix of type and flags, because
 
			    in those versions, they both were 4 bits big) to type and flags */
 
			 *  in those versions, they both were 4 bits big) to type and flags */
 
			v->current_order.flags = (v->current_order.type & 0xF0) >> 4;
 
			v->current_order.type  =  v->current_order.type & 0x0F;
 
		}
 
	}
 

	
 
	/* Check for shared order-lists (we now use pointers for that) */
 
	if (CheckSavegameVersionOldStyle(5, 2)) {
 
		FOR_ALL_VEHICLES(v) {
 
			Vehicle *u;
 

	
 
			FOR_ALL_VEHICLES_FROM(u, v->index + 1) {
 
				/* If a vehicle has the same orders, add the link to eachother
 
				    in both vehicles */
 
				 *  in both vehicles */
 
				if (v->orders == u->orders) {
 
					v->next_shared = u;
 
					u->prev_shared = v;
 
					break;
 
				}
 
			}
 
		}
 
	}
 
}
 

	
 
const ChunkHandler _veh_chunk_handlers[] = {
 
	{ 'VEHS', Save_VEHS, Load_VEHS, CH_SPARSE_ARRAY | CH_LAST},
vehicle_gui.c
Show inline comments
 
@@ -616,28 +616,28 @@ static void DrawEngineArrayInReplaceWind
 
	sel[1] = sel2;
 

	
 
	selected_id[0] = selected_id1;
 
	selected_id[1] = selected_id2;
 

	
 
	switch (WP(w,replaceveh_d).vehicletype) {
 
		case VEH_Train: {
 
			RailType railtype = _railtype_selected_in_replace_gui;
 
			DrawString(157, 99 + (14 * w->vscroll.cap), _rail_types_list[railtype], 0x10);
 
			/* draw sorting criteria string */
 

	
 
			/* Ensure that custom engines which substituted wagons
 
			* are sorted correctly.
 
			* XXX - DO NOT EVER DO THIS EVER AGAIN! GRRR hacking in wagons as
 
			* engines to get more types.. Stays here until we have our own format
 
			* then it is exit!!! */
 
			 * are sorted correctly.
 
			 * XXX - DO NOT EVER DO THIS EVER AGAIN! GRRR hacking in wagons as
 
			 * engines to get more types.. Stays here until we have our own format
 
			 * then it is exit!!! */
 
			if (WP(w,replaceveh_d).wagon_btnstate) {
 
				train_engine_drawing_loop(&x, &y, &pos, &sel[0], &selected_id[0], railtype, w->vscroll.cap, true, false, true, true); // True engines
 
				train_engine_drawing_loop(&x2, &y2, &pos2, &sel[1], &selected_id[1], railtype, w->vscroll.cap, true, false, false, false); // True engines
 
				train_engine_drawing_loop(&x2, &y2, &pos2, &sel[1], &selected_id[1], railtype, w->vscroll.cap, false, false, false, false); // Feeble wagons
 
			} else {
 
				train_engine_drawing_loop(&x, &y, &pos, &sel[0], &selected_id[0], railtype, w->vscroll.cap, false, true, true, true);
 
				train_engine_drawing_loop(&x2, &y2, &pos2, &sel[1], &selected_id[1], railtype, w->vscroll.cap, false, true, false, true);
 
			}
 
			break;
 
		}
 

	
 
		case VEH_Road: {
video/cocoa_v.m
Show inline comments
 
@@ -1168,25 +1168,25 @@ static const char* QZ_SetVideoWindowed(u
 
		[ [ _cocoa_video_data.window contentView ] addSubview:_cocoa_video_data.qdview ];
 
		[ _cocoa_video_data.qdview release ];
 
		[ _cocoa_video_data.window makeKeyAndOrderFront:nil ];
 
	}
 

	
 
	LockPortBits([ _cocoa_video_data.qdview qdPort ]);
 
	_cocoa_video_data.realpixels = GetPixBaseAddr(GetPortPixMap([ _cocoa_video_data.qdview qdPort ]));
 
	_cocoa_video_data.pitch = GetPixRowBytes(GetPortPixMap([ _cocoa_video_data.qdview qdPort ]));
 
	UnlockPortBits([ _cocoa_video_data.qdview qdPort ]);
 

	
 
	/* _cocoa_video_data.realpixels now points to the window's pixels
 
	 * We want it to point to the *view's* pixels
 
	*/
 
	 */
 
	{
 
		int vOffset = [ _cocoa_video_data.window frame ].size.height - [ _cocoa_video_data.qdview frame ].size.height - [ _cocoa_video_data.qdview frame ].origin.y;
 
		int hOffset = [ _cocoa_video_data.qdview frame ].origin.x;
 

	
 
		_cocoa_video_data.realpixels = (uint8*)_cocoa_video_data.realpixels + (vOffset * _cocoa_video_data.pitch) + hOffset * (_cocoa_video_data.device_bpp / 8);
 
	}
 

	
 
	free(_cocoa_video_data.pixels);
 
	_cocoa_video_data.pixels = (uint8*)malloc(width * height);
 
	if (_cocoa_video_data.pixels == NULL) return "Failed to allocate 8-bit buffer";
 

	
 
	_cocoa_video_data.fullscreen = false;
window.c
Show inline comments
 
@@ -1262,27 +1262,27 @@ static void SendWindowMessageW(Window *w
 
 * @param lparam Specifies additional message-specific information
 
 */
 
void SendWindowMessage(WindowClass wnd_class, WindowNumber wnd_num, uint msg, uint wparam, uint lparam)
 
{
 
	Window *w = FindWindowById(wnd_class, wnd_num);
 
	if (w != NULL) SendWindowMessageW(w, msg, wparam, lparam);
 
}
 

	
 
static void HandleKeypress(uint32 key)
 
{
 
	Window *w;
 
	WindowEvent we;
 
 /* Stores if a window with a textfield for typing is open
 
  * If this is the case, keypress events are only passed to windows with text fields and
 
	* to thein this main toolbar. */
 
	/* Stores if a window with a textfield for typing is open
 
	 * If this is the case, keypress events are only passed to windows with text fields and
 
	 * to thein this main toolbar. */
 
	bool query_open = false;
 

	
 
	// Setup event
 
	we.keypress.event = WE_KEYPRESS;
 
	we.keypress.ascii = key & 0xFF;
 
	we.keypress.keycode = key >> 16;
 
	we.keypress.cont = true;
 

	
 
	// check if we have a query string window open before allowing hotkeys
 
	if (FindWindowById(WC_QUERY_STRING,       0) != NULL ||
 
			FindWindowById(WC_SEND_NETWORK_MSG,   0) != NULL ||
 
			FindWindowById(WC_GENERATE_LANDSCAPE, 0) != NULL ||
yapf/array.hpp
Show inline comments
 
/* $Id$ */
 

	
 
#ifndef  ARRAY_HPP
 
#define  ARRAY_HPP
 

	
 
#include "fixedsizearray.hpp"
 

	
 
/** Flexible array with size limit. Implemented as fixed size
 
    array of fixed size arrays */
 
 *  array of fixed size arrays */
 
template <class Titem_, int Tblock_size_ = 1024, int Tnum_blocks_ = Tblock_size_>
 
class CArrayT {
 
public:
 
	typedef Titem_ Titem; ///< Titem is now visible from outside
 
	typedef CFixedSizeArrayT<Titem_, Tblock_size_> CSubArray; ///< inner array
 
	typedef CFixedSizeArrayT<CSubArray, Tnum_blocks_> CSuperArray; ///< outer array
 

	
 
protected:
 
	CSuperArray     m_a; ///< array of arrays of items
 

	
 
public:
 
	ST_CONST(int, Tblock_size = Tblock_size_); ///< block size is now visible from outside
yapf/autocopyptr.hpp
Show inline comments
 
/* $Id$ */
 

	
 
#ifndef  AUTOCOPYPTR_HPP
 
#define  AUTOCOPYPTR_HPP
 

	
 
/** CAutoCopyPtrT - kind of CoW (Copy on Write) pointer.
 
		It is non-invasive smart pointer (reference counter is held outside
 
		of Tdata).
 
		When copied, its new copy shares the same underlaying structure Tdata.
 
		When dereferenced, its behavior depends on 2 factors:
 
		   - whether the data is shared (used by more than one pointer)
 
		   - type of access (read/write)
 
		  When shared pointer is dereferenced for write, new clone of Tdata
 
		is made first.
 
		Can't be used for polymorphic data types (interfaces).
 
*/
 
 *  It is non-invasive smart pointer (reference counter is held outside
 
 *  of Tdata).
 
 *  When copied, its new copy shares the same underlaying structure Tdata.
 
 *  When dereferenced, its behavior depends on 2 factors:
 
 *     - whether the data is shared (used by more than one pointer)
 
 *     - type of access (read/write)
 
 *    When shared pointer is dereferenced for write, new clone of Tdata
 
 *  is made first.
 
 *  Can't be used for polymorphic data types (interfaces).
 
 */
 
template <class Tdata_>
 
class CAutoCopyPtrT {
 
protected:
 
	typedef Tdata_ Tdata;
 

	
 
	struct CItem {
 
		int     m_ref_cnt;  ///< reference counter
 
		Tdata   m_data;     ///< custom data itself
 

	
 
		FORCEINLINE CItem()                  : m_ref_cnt(1)                     {};
 
		FORCEINLINE CItem(const Tdata& data) : m_ref_cnt(1), m_data(data)       {};
 
		FORCEINLINE CItem(const CItem& src)  : m_ref_cnt(1), m_data(src.m_data) {};
yapf/binaryheap.hpp
Show inline comments
 
/* $Id$ */
 

	
 
#ifndef  BINARYHEAP_HPP
 
#define  BINARYHEAP_HPP
 

	
 
//void* operator new (size_t size, void* p) {return p;}
 
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
 
//void operator delete (void* p, void* p2) {}
 
#endif
 

	
 

	
 
/**
 
* Binary Heap as C++ template.
 
*
 
* For information about Binary Heap algotithm,
 
*   see: http://www.policyalmanac.org/games/binaryHeaps.htm
 
*
 
* Implementation specific notes:
 
*
 
* 1) It allocates space for item pointers (array). Items are allocated elsewhere.
 
*
 
* 2) ItemPtr [0] is never used. Total array size is max_items + 1, because we
 
*    use indices 1..max_items instead of zero based C indexing.
 
*
 
* 3) Item of the binary heap should support these public members:
 
*    - 'lower-then' operator '<' - used for comparing items before moving
 
*
 
*/
 
 * Binary Heap as C++ template.
 
 *
 
 * For information about Binary Heap algotithm,
 
 *   see: http://www.policyalmanac.org/games/binaryHeaps.htm
 
 *
 
 * Implementation specific notes:
 
 *
 
 * 1) It allocates space for item pointers (array). Items are allocated elsewhere.
 
 *
 
 * 2) ItemPtr [0] is never used. Total array size is max_items + 1, because we
 
 *    use indices 1..max_items instead of zero based C indexing.
 
 *
 
 * 3) Item of the binary heap should support these public members:
 
 *    - 'lower-then' operator '<' - used for comparing items before moving
 
 *
 
 */
 

	
 
template <class Titem_>
 
class CBinaryHeapT {
 
public:
 
	typedef Titem_ *ItemPtr;
 
private:
 
	int                     m_size;     ///< Number of items in the heap
 
	int                     m_max_size; ///< Maximum number of items the heap can hold
 
	ItemPtr*                m_items;    ///< The heap item pointers
 

	
 
public:
 
	explicit CBinaryHeapT(int max_items = 102400)
 
@@ -44,57 +44,57 @@ public:
 
		m_items = new ItemPtr[max_items + 1];
 
	}
 

	
 
	~CBinaryHeapT()
 
	{
 
		Clear();
 
		delete [] m_items;
 
		m_items = NULL;
 
	}
 

	
 
public:
 
	/** Return the number of items stored in the priority queue.
 
	*   @return number of items in the queue */
 
	 *  @return number of items in the queue */
 
	FORCEINLINE int Size() const {return m_size;};
 

	
 
	/** Test if the priority queue is empty.
 
	*   @return true if empty */
 
	 *  @return true if empty */
 
	FORCEINLINE bool IsEmpty() const {return (m_size == 0);};
 

	
 
	/** Test if the priority queue is full.
 
	*   @return true if full. */
 
	 *  @return true if full. */
 
	FORCEINLINE bool IsFull() const {return (m_size >= m_max_size);};
 

	
 
	/** Find the smallest item in the priority queue.
 
	*   Return the smallest item, or throw assert if empty. */
 
	 *  Return the smallest item, or throw assert if empty. */
 
	FORCEINLINE Titem_& GetHead() {assert(!IsEmpty()); return *m_items[1];}
 

	
 
	/** Insert new item into the priority queue, maintaining heap order.
 
	* @return false if the queue is full. */
 
	 *  @return false if the queue is full. */
 
	bool Push(Titem_& new_item);
 

	
 
	/** Remove and return the smallest item from the priority queue. */
 
	FORCEINLINE Titem_& PopHead() {Titem_& ret = GetHead(); RemoveHead(); return ret;};
 

	
 
	/** Remove the smallest item from the priority queue. */
 
	void RemoveHead();
 

	
 
	/** Remove item specified by index */
 
	void RemoveByIdx(int idx);
 

	
 
	/** return index of the item that matches (using &item1 == &item2) the given item. */
 
	int FindLinear(const Titem_& item) const;
 

	
 
	/** Make the priority queue empty.
 
	* All remaining items will remain untouched. */
 
	 * All remaining items will remain untouched. */
 
	void Clear() {m_size = 0;};
 

	
 
	/** verifies the heap consistency (added during first YAPF debug phase) */
 
	void CheckConsistency();
 
};
 

	
 

	
 
template <class Titem_>
 
FORCEINLINE bool CBinaryHeapT<Titem_>::Push(Titem_& new_item)
 
{
 
	if (IsFull()) return false;
 

	
yapf/blob.hpp
Show inline comments
 
@@ -2,32 +2,32 @@
 

	
 
#ifndef  BLOB_HPP
 
#define  BLOB_HPP
 

	
 
template <class Titem_>
 
FORCEINLINE void MemCpyT(Titem_* d, const Titem_* s, int num_items = 1)
 
{
 
	memcpy(d, s, num_items * sizeof(Titem_));
 
}
 

	
 

	
 
/** Base class for simple binary blobs.
 
    Item is byte.
 
		The word 'simple' means:
 
		  - no configurable allocator type (always made from heap)
 
			- no smart deallocation - deallocation must be called from the same
 
			    module (DLL) where the blob was allocated
 
			- no configurable allocation policy (how big blocks should be allocated)
 
			- no extra ownership policy (i.e. 'copy on write') when blob is copied
 
			- no thread synchronization at all */
 
 *  Item is byte.
 
 *  The word 'simple' means:
 
 *    - no configurable allocator type (always made from heap)
 
 *    - no smart deallocation - deallocation must be called from the same
 
 *        module (DLL) where the blob was allocated
 
 *    - no configurable allocation policy (how big blocks should be allocated)
 
 *    - no extra ownership policy (i.e. 'copy on write') when blob is copied
 
 *    - no thread synchronization at all */
 
class CBlobBaseSimple {
 
protected:
 
	struct CHdr {
 
		int    m_size;      // actual blob size in bytes
 
		int    m_max_size;  // maximum (allocated) size in bytes
 
	};
 

	
 
	union {
 
		int8   *m_pData;
 
		CHdr   *m_pHdr_1;
 
	} ptr_u;
 

	
 
@@ -69,36 +69,36 @@ public:
 
		} else {
 
			assert(num_bytes >= 0);
 
		}
 
	}
 

	
 
	FORCEINLINE void AppendRaw(const CBlobBaseSimple& src)
 
	{
 
		if (!src.IsEmpty())
 
			memcpy(GrowRawSize(src.RawSize()), src.RawData(), src.RawSize());
 
	}
 

	
 
	/** Reallocate if there is no free space for num_bytes bytes.
 
	    @return pointer to the new data to be added */
 
	 *  @return pointer to the new data to be added */
 
	FORCEINLINE int8* MakeRawFreeSpace(int num_bytes)
 
	{
 
		assert(num_bytes >= 0);
 
		int new_size = RawSize() + num_bytes;
 
		if (new_size > MaxRawSize()) SmartAlloc(new_size);
 
		FixTail();
 
		return ptr_u.m_pData + RawSize();
 
	}
 

	
 
	/** Increase RawSize() by num_bytes.
 
	@return pointer to the new data added */
 
	 *  @return pointer to the new data added */
 
	FORCEINLINE int8* GrowRawSize(int num_bytes)
 
	{
 
		int8* pNewData = MakeRawFreeSpace(num_bytes);
 
		RawSizeRef() += num_bytes;
 
		return pNewData;
 
	}
 

	
 
	/** Decrease RawSize() by num_bytes. */
 
	FORCEINLINE void ReduceRawSize(int num_bytes)
 
	{
 
		if (MaxRawSize() > 0 && num_bytes > 0) {
 
			assert(num_bytes <= RawSize());
yapf/countedptr.hpp
Show inline comments
 
/* $Id$ */
 

	
 
#ifndef COUNTEDPTR_HPP
 
#define COUNTEDPTR_HPP
 

	
 
/** @file CCountedPtr - smart pointer implementation */
 

	
 
/** CCountedPtr - simple reference counting smart pointer.
 
*
 
*     One of the standard ways how to maintain object's lifetime.
 
*
 
*     See http://ootips.org/yonat/4dev/smart-pointers.html for more
 
*   general info about smart pointers.
 
*
 
*     This class implements ref-counted pointer for objects/interfaces that
 
*   support AddRef() and Release() methods.
 
*/
 
 *
 
 *     One of the standard ways how to maintain object's lifetime.
 
 *
 
 *     See http://ootips.org/yonat/4dev/smart-pointers.html for more
 
 *   general info about smart pointers.
 
 *
 
 *     This class implements ref-counted pointer for objects/interfaces that
 
 *   support AddRef() and Release() methods.
 
 */
 
template <class Tcls_>
 
class CCountedPtr {
 
	/** redefine the template argument to make it visible for derived classes */
 
public:
 
	typedef Tcls_ Tcls;
 

	
 
protected:
 
	/** here we hold our pointer to the target */
 
	Tcls* m_pT;
 

	
 
public:
 
	/** default (NULL) construct or construct from a raw pointer */
yapf/fixedsizearray.hpp
Show inline comments
 
/* $Id$ */
 

	
 
#ifndef  FIXEDSIZEARRAY_HPP
 
#define  FIXEDSIZEARRAY_HPP
 

	
 

	
 
/** fixed size array
 
    Upon construction it preallocates fixed size block of memory
 
		for all items, but doesn't construct them. Item's construction
 
		is delayed. */
 
 *  Upon construction it preallocates fixed size block of memory
 
 *  for all items, but doesn't construct them. Item's construction
 
 *  is delayed. */
 
template <class Titem_, int Tcapacity_>
 
struct CFixedSizeArrayT {
 
	/** the only member of fixed size array is pointer to the block
 
	    of C array of items. Header can be found on the offset -sizeof(CHdr). */
 
	 *  of C array of items. Header can be found on the offset -sizeof(CHdr). */
 
	Titem_ *m_items;
 

	
 
	/** header for fixed size array */
 
	struct CHdr
 
	{
 
		int    m_num_items; ///< number of items in the array
 
		int    m_ref_cnt;   ///< block reference counter (used by copy constructor and by destructor)
 
	};
 

	
 
	// make types and constants visible from outside
 
	typedef Titem_ Titem; // type of array item
 

	
yapf/follow_track.hpp
Show inline comments
 
/* $Id$ */
 

	
 
#ifndef  FOLLOW_TRACK_HPP
 
#define  FOLLOW_TRACK_HPP
 

	
 
#include "yapf.hpp"
 

	
 
/** Track follower helper template class (can serve pathfinders and vehicle
 
    controllers). See 6 different typedefs below for 3 different transport
 
    types w/ of w/o 90-deg turns allowed */
 
 *  controllers). See 6 different typedefs below for 3 different transport
 
 *  types w/ of w/o 90-deg turns allowed */
 
template <TransportType Ttr_type_, bool T90deg_turns_allowed_ = true>
 
struct CFollowTrackT : public FollowTrack_t
 
{
 
	CPerformanceTimer* m_pPerf;
 

	
 
	FORCEINLINE CFollowTrackT(const Vehicle* v = NULL, CPerformanceTimer* pPerf = NULL)
 
	{
 
		Init(v, pPerf);
 
	}
 

	
 
	FORCEINLINE void Init(const Vehicle* v, CPerformanceTimer* pPerf)
 
	{
 
@@ -29,25 +29,25 @@ struct CFollowTrackT : public FollowTrac
 
		m_exitdir = INVALID_DIAGDIR;
 
		m_is_station = m_is_tunnel = false;
 
		m_tiles_skipped = 0;
 
	}
 

	
 
	FORCEINLINE static TransportType TT() {return Ttr_type_;}
 
	FORCEINLINE static bool IsWaterTT() {return TT() == TRANSPORT_WATER;}
 
	FORCEINLINE static bool IsRailTT() {return TT() == TRANSPORT_RAIL;}
 
	FORCEINLINE static bool IsRoadTT() {return TT() == TRANSPORT_ROAD;}
 
	FORCEINLINE static bool Allow90degTurns() {return T90deg_turns_allowed_;}
 

	
 
	/** main follower routine. Fills all members and return true on success.
 
	    Otherwise returns false if track can't be followed. */
 
	 *  Otherwise returns false if track can't be followed. */
 
	FORCEINLINE bool Follow(TileIndex old_tile, Trackdir old_td)
 
	{
 
		m_old_tile = old_tile;
 
		m_old_td = old_td;
 
		assert((GetTileTrackStatus(m_old_tile, TT()) & TrackdirToTrackdirBits(m_old_td)) != 0);
 
		m_exitdir = TrackdirToExitdir(m_old_td);
 
		if (EnteredDepot()) return true;
 
		if (!CanExitOldTile()) return false;
 
		FollowTileExit();
 
		if (!QueryNewTileTrackStatus()) return TryReverse();
 
		if (!CanEnterNewTile()) return false;
 
		m_new_td_bits &= DiagdirReachesTrackdirs(m_exitdir);
yapf/hashtable.hpp
Show inline comments
 
@@ -86,55 +86,55 @@ struct CHashTableSlotT
 
			if (pItem->GetKey() == key) {
 
				// we have found the item, unlink and return it
 
				pPrev->SetHashNext(pItem->GetHashNext());
 
				pItem->SetHashNext(NULL);
 
				return *pItem;
 
			}
 
		}
 
		return *(Titem_*)NULL;
 
	}
 
};
 

	
 
/** @class CHashTableT<Titem, Thash_bits> - simple hash table
 
    of pointers allocated elsewhere.
 

	
 
    Supports: Add/Find/Remove of Titems.
 

	
 
    Your Titem must meet some extra requirements to be CHashTableT
 
    compliant:
 
      - its constructor/destructor (if any) must be public
 
      - if the copying of item requires an extra resource management,
 
          you must define also copy constructor
 
      - must support nested type (struct, class or typedef) Titem::Key
 
          that defines the type of key class for that item
 
      - must support public method:
 
          const Key& GetKey() const; // return the item's key object
 

	
 
		In addition, the Titem::Key class must support:
 
      - public method that calculates key's hash:
 
          int CalcHash() const;
 
			- public 'equality' operator to compare the key with another one
 
					bool operator == (const Key& other) const;
 
*/
 
 *  of pointers allocated elsewhere.
 
 *
 
 *  Supports: Add/Find/Remove of Titems.
 
 *
 
 *  Your Titem must meet some extra requirements to be CHashTableT
 
 *  compliant:
 
 *    - its constructor/destructor (if any) must be public
 
 *    - if the copying of item requires an extra resource management,
 
 *        you must define also copy constructor
 
 *    - must support nested type (struct, class or typedef) Titem::Key
 
 *        that defines the type of key class for that item
 
 *    - must support public method:
 
 *        const Key& GetKey() const; // return the item's key object
 
 *
 
 *  In addition, the Titem::Key class must support:
 
 *    - public method that calculates key's hash:
 
 *        int CalcHash() const;
 
 *    - public 'equality' operator to compare the key with another one
 
 *        bool operator == (const Key& other) const;
 
 */
 
template <class Titem_, int Thash_bits_>
 
class CHashTableT {
 
public:
 
	typedef Titem_ Titem;                       // make Titem_ visible from outside of class
 
	typedef typename Titem_::Key Tkey;          // make Titem_::Key a property of HashTable
 
	ST_CONST(int, Thash_bits = Thash_bits_);    // publish num of hash bits
 
	ST_CONST(int, Tcapacity = 1 << Thash_bits); // and num of slots 2^bits
 

	
 
protected:
 
	/** each slot contains pointer to the first item in the list,
 
	    Titem contains pointer to the next item - GetHashNext(), SetHashNext() */
 
	 *  Titem contains pointer to the next item - GetHashNext(), SetHashNext() */
 
	typedef CHashTableSlotT<Titem_> Slot;
 

	
 
	Slot*  m_slots;     // here we store our data (array of blobs)
 
	int    m_num_items; // item counter
 

	
 
public:
 
	// default constructor
 
	FORCEINLINE CHashTableT()
 
	{
 
		// construct all slots
 
		m_slots = new Slot[Tcapacity];
 
		m_num_items = 0;
yapf/nodelist.hpp
Show inline comments
 
/* $Id$ */
 

	
 
#ifndef  NODELIST_HPP
 
#define  NODELIST_HPP
 

	
 
#include "array.hpp"
 
#include "hashtable.hpp"
 
#include "binaryheap.hpp"
 

	
 
/** Hash table based node list multi-container class.
 
    Implements open list, closed list and priority queue for A-star
 
    path finder. */
 
 *  Implements open list, closed list and priority queue for A-star
 
 *  path finder. */
 
template <class Titem_, int Thash_bits_open_, int Thash_bits_closed_>
 
class CNodeList_HashTableT {
 
public:
 
	/** make Titem_ visible from outside of class */
 
	typedef Titem_ Titem;
 
	/** make Titem_::Key a property of HashTable */
 
	typedef typename Titem_::Key Key;
 
	/** type that we will use as item container */
 
	typedef CArrayT<Titem_, 65536, 256> CItemArray;
 
	/** how pointers to open nodes will be stored */
 
	typedef CHashTableT<Titem_, Thash_bits_open_  > COpenList;
 
	/** how pointers to closed nodes will be stored */
yapf/unittest/test_yapf.h
Show inline comments
 
@@ -151,26 +151,26 @@ struct CYapfTestBaseT
 
		m_x1 = x1;
 
		m_y1 = y1;
 
		m_x2 = x2;
 
		m_y2 = y2;
 
		m_td1 = td1;
 
	}
 

	
 
	/// to access inherited path finder
 
	Tpf& Yapf() {return *static_cast<Tpf*>(this);}
 
	FORCEINLINE char TransportTypeChar() const {return 'T';}
 

	
 
	/** Called by YAPF to move from the given node to the next tile. For each
 
	*   reachable trackdir on the new tile creates new node, initializes it
 
	*   and adds it to the open list by calling Yapf().AddNewNode(n) */
 
	 *  reachable trackdir on the new tile creates new node, initializes it
 
	 *  and adds it to the open list by calling Yapf().AddNewNode(n) */
 
	FORCEINLINE void PfFollowNode(Node& org)
 
	{
 
		int x_org = org.m_key.m_x;
 
		int y_org = org.m_key.m_y;
 
		int z_org = Map::MapZ(x_org, y_org);
 
		DiagDirection exitdir = TrackdirToExitdir(org.m_key.m_td);
 

	
 
		TileIndexDiffC diff = TileIndexDiffCByDir(exitdir);
 
		int x_new = x_org + diff.x;
 
		int y_new = y_org + diff.y;
 
		int z_new = Map::MapZ(x_new, y_new);
 

	
 
@@ -198,43 +198,43 @@ struct CYapfTestBaseT
 
	/// Called when YAPF needs to place origin nodes into open list
 
	FORCEINLINE void PfSetStartupNodes()
 
	{
 
		Node& n1 = Yapf().CreateNewNode();
 
		n1.m_key.m_x = m_x1;
 
		n1.m_key.m_y = m_y1;
 
		n1.m_key.m_td = m_td1;
 
		n1.m_key.m_exitdir = TrackdirToExitdir(n1.m_key.m_td);
 
		Yapf().AddStartupNode(n1);
 
	}
 

	
 
	/** Called by YAPF to calculate the cost from the origin to the given node.
 
	*   Calculates only the cost of given node, adds it to the parent node cost
 
	*   and stores the result into Node::m_cost member */
 
	 *  Calculates only the cost of given node, adds it to the parent node cost
 
	 *  and stores the result into Node::m_cost member */
 
	FORCEINLINE bool PfCalcCost(Node& n)
 
	{
 
		// base tile cost depending on distance
 
		int c = IsDiagonalTrackdir(n.m_key.m_td) ? 10 : 7;
 
		// additional penalty for curve
 
		if (n.m_parent != NULL && n.m_key.m_td != n.m_parent->m_key.m_td) c += 3;
 
		// z-difference cost
 
		int z_new = Map::MapZ(n.m_key.m_x, n.m_key.m_y);
 
		int z_old = Map::MapZ(n.m_parent->m_key.m_x, n.m_parent->m_key.m_y);
 
		if (z_new > z_old) n.m_cost += (z_new - z_old) * 10;
 
		// apply it
 
		n.m_cost = n.m_parent->m_cost + c;
 
		return true;
 
	}
 

	
 
	/** Called by YAPF to calculate cost estimate. Calculates distance to the destination
 
	*   adds it to the actual cost from origin and stores the sum to the Node::m_estimate */
 
	 *  adds it to the actual cost from origin and stores the sum to the Node::m_estimate */
 
	FORCEINLINE bool PfCalcEstimate(Node& n)
 
	{
 
		int dx = abs(n.m_key.m_x - m_x2);
 
		int dy = abs(n.m_key.m_y - m_y2);
 
		int dd = min(dx, dy);
 
		int dxy = abs(dx - dy);
 
		int d = 14 * dd + 10 * dxy;
 
		n.m_estimate = n.m_cost + d /*+ d / 4*/;
 
		return true;
 
	}
 

	
 
	/// Called by YAPF to detect if node ends in the desired destination
yapf/unittest/unittest.cpp
Show inline comments
 
@@ -100,41 +100,41 @@ int main(int argc, char** argv)
 

	
 

	
 
extern "C"
 
const TileIndexDiffC _tileoffs_by_dir[] = {
 
	{-1,  0},
 
	{ 0,  1},
 
	{ 1,  0},
 
	{ 0, -1}
 
};
 

	
 
extern "C"
 
const byte _ffb_64[128] = {
 
	0,0,1,0,2,0,1,0,
 
	3,0,1,0,2,0,1,0,
 
	4,0,1,0,2,0,1,0,
 
	3,0,1,0,2,0,1,0,
 
	5,0,1,0,2,0,1,0,
 
	3,0,1,0,2,0,1,0,
 
	4,0,1,0,2,0,1,0,
 
	3,0,1,0,2,0,1,0,
 
	 0,  0,  1,  0,  2,  0,  1,  0,
 
	 3,  0,  1,  0,  2,  0,  1,  0,
 
	 4,  0,  1,  0,  2,  0,  1,  0,
 
	 3,  0,  1,  0,  2,  0,  1,  0,
 
	 5,  0,  1,  0,  2,  0,  1,  0,
 
	 3,  0,  1,  0,  2,  0,  1,  0,
 
	 4,  0,  1,  0,  2,  0,  1,  0,
 
	 3,  0,  1,  0,  2,  0,  1,  0,
 

	
 
	0,0,0,2,0,4,4,6,
 
	0,8,8,10,8,12,12,14,
 
	0,16,16,18,16,20,20,22,
 
	16,24,24,26,24,28,28,30,
 
	0,32,32,34,32,36,36,38,
 
	32,40,40,42,40,44,44,46,
 
	32,48,48,50,48,52,52,54,
 
	48,56,56,58,56,60,60,62,
 
	 0,  0,  0,  2,  0,  4,  4,  6,
 
	 0,  8,  8, 10,  8, 12, 12, 14,
 
	 0, 16, 16, 18, 16, 20, 20, 22,
 
	16, 24, 24, 26, 24, 28, 28, 30,
 
	 0, 32, 32, 34, 32, 36, 36, 38,
 
	32, 40, 40, 42, 40, 44, 44, 46,
 
	32, 48, 48, 50, 48, 52, 52, 54,
 
	48, 56, 56, 58, 56, 60, 60, 62,
 
};
 

	
 
/* Maps a trackdir to the (4-way) direction the tile is exited when following
 
* that trackdir */
 
extern "C"
 
const DiagDirection _trackdir_to_exitdir[] = {
 
	DIAGDIR_NE,DIAGDIR_SE,DIAGDIR_NE,DIAGDIR_SE,DIAGDIR_SW,DIAGDIR_SE, DIAGDIR_NE,DIAGDIR_NE,
 
	DIAGDIR_SW,DIAGDIR_NW,DIAGDIR_NW,DIAGDIR_SW,DIAGDIR_NW,DIAGDIR_NE,
 
};
 

	
 
/* Maps a diagonal direction to the all trackdirs that are connected to any
 
* track entering in this direction (including those making 90 degree turns)
yapf/yapf.h
Show inline comments
 
/* $Id$ */
 

	
 
#ifndef  YAPF_H
 
#define  YAPF_H
 

	
 
#include "../debug.h"
 

	
 
/** Finds the best path for given ship.
 
	@param v        - the ship that needs to find a path
 
	@param tile     - the tile to find the path from (should be next tile the ship is about to enter)
 
	@param enterdir - diagonal direction which the ship will enter this new tile from
 
	@param tracks   - available tracks on the new tile (to choose from)
 
	@return         - the best trackdir for next turn or INVALID_TRACKDIR if the path could not be found
 
 * @param v        the ship that needs to find a path
 
 * @param tile     the tile to find the path from (should be next tile the ship is about to enter)
 
 * @param enterdir diagonal direction which the ship will enter this new tile from
 
 * @param tracks   available tracks on the new tile (to choose from)
 
 * @return         the best trackdir for next turn or INVALID_TRACKDIR if the path could not be found
 
 */
 
Trackdir YapfChooseShipTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks);
 

	
 
/** Finds the best path for given road vehicle.
 
	@param v        - the RV that needs to find a path
 
	@param tile     - the tile to find the path from (should be next tile the RV is about to enter)
 
	@param enterdir - diagonal direction which the RV will enter this new tile from
 
	@param tracks   - available tracks on the new tile (to choose from)
 
	@return         - the best trackdir for next turn or INVALID_TRACKDIR if the path could not be found
 
*/
 
 * @param v        the RV that needs to find a path
 
 * @param tile     the tile to find the path from (should be next tile the RV is about to enter)
 
 * @param enterdir diagonal direction which the RV will enter this new tile from
 
 * @param tracks   available tracks on the new tile (to choose from)
 
 * @return         the best trackdir for next turn or INVALID_TRACKDIR if the path could not be found
 
 */
 
Trackdir YapfChooseRoadTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir);
 

	
 
/** Finds the best path for given train.
 
	@param v        - the train that needs to find a path
 
	@param tile     - the tile to find the path from (should be next tile the train is about to enter)
 
	@param enterdir - diagonal direction which the RV will enter this new tile from
 
	@param tracks   - available tracks on the new tile (to choose from)
 
	@return         - the best trackdir for next turn or INVALID_TRACKDIR if the path could not be found
 
*/
 
 * @param v        the train that needs to find a path
 
 * @param tile     the tile to find the path from (should be next tile the train is about to enter)
 
 * @param enterdir diagonal direction which the RV will enter this new tile from
 
 * @param tracks   available tracks on the new tile (to choose from)
 
 * @return         the best trackdir for next turn or INVALID_TRACKDIR if the path could not be found
 
 */
 
Trackdir YapfChooseRailTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs);
 

	
 
/** Used by RV multistop feature to find the nearest road stop that has a free slot.
 
	@param v      - RV (its current tile will be the origin)
 
	@param tile   - destination tile
 
	@return       - distance from origin tile to the destination (number of road tiles) or UINT_MAX if path not found
 
*/
 
 * @param v      RV (its current tile will be the origin)
 
 * @param tile   destination tile
 
 * @return       distance from origin tile to the destination (number of road tiles) or UINT_MAX if path not found
 
 */
 
uint YapfRoadVehDistanceToTile(const Vehicle* v, TileIndex tile);
 

	
 
/** Used when user sends RV to the nearest depot or if RV needs servicing.
 
		Returns the nearest depot (or NULL if depot was not found).
 
*/
 
 * Returns the nearest depot (or NULL if depot was not found).
 
 */
 
Depot* YapfFindNearestRoadDepot(const Vehicle *v);
 

	
 
/** Used when user sends train to the nearest depot or if train needs servicing.
 
	@v            - train that needs to go to some depot
 
	@max_distance - max distance (number of track tiles) from the current train position
 
	                  (used also as optimization - the pathfinder can stop path finding if max_distance
 
	                  was reached and no depot was seen)
 
	@reverse_penalty - penalty that should be added for the path that requires reversing the train first
 
	@depot_tile   - receives the depot tile if depot was found
 
	@reversed     - receives true if train needs to reversed first
 
	@return       - the true if depot was found.
 
*/
 
 * @v            train that needs to go to some depot
 
 * @max_distance max distance (number of track tiles) from the current train position
 
 *                  (used also as optimization - the pathfinder can stop path finding if max_distance
 
 *                  was reached and no depot was seen)
 
 * @reverse_penalty penalty that should be added for the path that requires reversing the train first
 
 * @depot_tile   receives the depot tile if depot was found
 
 * @reversed     receives true if train needs to reversed first
 
 * @return       the true if depot was found.
 
 */
 
bool YapfFindNearestRailDepotTwoWay(Vehicle *v, int max_distance, int reverse_penalty, TileIndex* depot_tile, bool* reversed);
 

	
 
/** Returns true if it is better to reverse the train before leaving station */
 
bool YapfCheckReverseTrain(Vehicle* v);
 

	
 
/** Use this function to notify YAPF that track layout (or signal configuration) has change */
 
void YapfNotifyTrackLayoutChange(TileIndex tile, Track track);
 

	
 
/** performance measurement helpers */
 
void* NpfBeginInterval(void);
 
int NpfEndInterval(void* perf);
 

	
 

	
 
extern int _aystar_stats_open_size;
 
extern int _aystar_stats_closed_size;
 

	
 

	
 
/** Track followers. They should help whenever any new code will need to walk through
 
tracks, road or water tiles (pathfinders, signal controllers, vehicle controllers).
 
It is an attempt to introduce API that should simplify tasks listed above.
 
If you will need to use it:
 
	1. allocate/declare FollowTrack_t structure;
 
	2. call FollowTrackInit() and provide vehicle (if relevant)
 
	3. call one of 6 FollowTrackXxxx() APIs below
 
	4. check return value (if true then continue else stop)
 
	5. look at FollowTrack_t structure for the result
 
	6. optionally repeat steps 3..5
 
	7. in case of troubles contact KUDr
 
*/
 
 * tracks, road or water tiles (pathfinders, signal controllers, vehicle controllers).
 
 * It is an attempt to introduce API that should simplify tasks listed above.
 
 * If you will need to use it:
 
 *   1. allocate/declare FollowTrack_t structure;
 
 *   2. call FollowTrackInit() and provide vehicle (if relevant)
 
 *   3. call one of 6 FollowTrackXxxx() APIs below
 
 *   4. check return value (if true then continue else stop)
 
 *   5. look at FollowTrack_t structure for the result
 
 *   6. optionally repeat steps 3..5
 
 *   7. in case of troubles contact KUDr
 
 */
 

	
 
/** Base struct for track followers. */
 
typedef struct FollowTrack_t
 
{
 
	const Vehicle*      m_veh;           ///< moving vehicle
 
	TileIndex           m_old_tile;      ///< the origin (vehicle moved from) before move
 
	Trackdir            m_old_td;        ///< the trackdir (the vehicle was on) before move
 
	TileIndex           m_new_tile;      ///< the new tile (the vehicle has entered)
 
	TrackdirBits        m_new_td_bits;   ///< the new set of available trackdirs
 
	DiagDirection       m_exitdir;       ///< exit direction (leaving the old tile)
 
	bool                m_is_tunnel;     ///< last turn passed tunnel
 
	bool                m_is_station;    ///< last turn passed station
yapf/yapf_base.hpp
Show inline comments
 
@@ -5,52 +5,52 @@
 

	
 
EXTERN_C_BEGIN
 
#include "../debug.h"
 
EXTERN_C_END
 

	
 
#include "fixedsizearray.hpp"
 
#include "blob.hpp"
 
#include "nodelist.hpp"
 

	
 
extern int _total_pf_time_us;
 

	
 
/** CYapfBaseT - A-star type path finder base class.
 
		Derive your own pathfinder from it. You must provide the following template argument:
 
			Types      - used as collection of local types used in pathfinder
 

	
 
		Requirements for the Types struct:
 
		----------------------------------
 
		The following types must be defined in the 'Types' argument:
 
			- Types::Tpf - your pathfinder derived from CYapfBaseT
 
			- Types::NodeList - open/closed node list (look at CNodeList_HashTableT)
 
		NodeList needs to have defined local type Titem - defines the pathfinder node type.
 
		Node needs to define local type Key - the node key in the collection ()
 

	
 
		For node list you can use template class CNodeList_HashTableT, for which
 
		you need to declare only your node type. Look at test_yapf.h for an example.
 

	
 

	
 
		Requrements to your pathfinder class derived from CYapfBaseT:
 
		-------------------------------------------------------------
 
		Your pathfinder derived class needs to implement following methods:
 
			FORCEINLINE void PfSetStartupNodes()
 
			FORCEINLINE void PfFollowNode(Node& org)
 
			FORCEINLINE bool PfCalcCost(Node& n)
 
			FORCEINLINE bool PfCalcEstimate(Node& n)
 
			FORCEINLINE bool PfDetectDestination(Node& n)
 

	
 
		For more details about those methods, look at the end of CYapfBaseT
 
		declaration. There are some examples. For another example look at
 
		test_yapf.h (part or unittest project).
 
*/
 
 *  Derive your own pathfinder from it. You must provide the following template argument:
 
 *    Types      - used as collection of local types used in pathfinder
 
 *
 
 * Requirements for the Types struct:
 
 *  ----------------------------------
 
 *  The following types must be defined in the 'Types' argument:
 
 *    - Types::Tpf - your pathfinder derived from CYapfBaseT
 
 *    - Types::NodeList - open/closed node list (look at CNodeList_HashTableT)
 
 *  NodeList needs to have defined local type Titem - defines the pathfinder node type.
 
 *  Node needs to define local type Key - the node key in the collection ()
 
 *
 
 *  For node list you can use template class CNodeList_HashTableT, for which
 
 *  you need to declare only your node type. Look at test_yapf.h for an example.
 
 *
 
 *
 
 *  Requrements to your pathfinder class derived from CYapfBaseT:
 
 *  -------------------------------------------------------------
 
 *  Your pathfinder derived class needs to implement following methods:
 
 *    FORCEINLINE void PfSetStartupNodes()
 
 *    FORCEINLINE void PfFollowNode(Node& org)
 
 *    FORCEINLINE bool PfCalcCost(Node& n)
 
 *    FORCEINLINE bool PfCalcEstimate(Node& n)
 
 *    FORCEINLINE bool PfDetectDestination(Node& n)
 
 *
 
 *  For more details about those methods, look at the end of CYapfBaseT
 
 *  declaration. There are some examples. For another example look at
 
 *  test_yapf.h (part or unittest project).
 
 */
 
template <class Types>
 
class CYapfBaseT {
 
public:
 
	typedef typename Types::Tpf Tpf;           ///< the pathfinder class (derived from THIS class)
 
	typedef typename Types::NodeList NodeList; ///< our node list
 
	typedef typename NodeList::Titem Node;     ///< this will be our node type
 
	typedef typename Node::Key Key;            ///< key to hash tables
 

	
 

	
 
	NodeList             m_nodes;              ///< node list multi-container
 
protected:
 
	Node*                m_pBestDestNode;      ///< pointer to the destination node found at last round
 
@@ -96,30 +96,30 @@ public:
 
protected:
 
	/// to access inherited path finder
 
	FORCEINLINE Tpf& Yapf() {return *static_cast<Tpf*>(this);}
 

	
 
public:
 
	/// return current settings (can be custom - player based - but later)
 
	FORCEINLINE const YapfSettings& PfGetSettings() const
 
	{
 
		return *m_settings;
 
	}
 

	
 
	/** Main pathfinder routine:
 
			 - set startup node(s)
 
			 - main loop that stops if:
 
					- the destination was found
 
					- or the open list is empty (no route to destination).
 
					- or the maximum amount of loops reached - m_max_search_nodes (default = 10000)
 
			@return true if the path was found */
 
	 *   - set startup node(s)
 
	 *   - main loop that stops if:
 
	 *      - the destination was found
 
	 *      - or the open list is empty (no route to destination).
 
	 *      - or the maximum amount of loops reached - m_max_search_nodes (default = 10000)
 
	 * @return true if the path was found */
 
	inline bool FindPath(const Vehicle* v)
 
	{
 
		m_veh = v;
 

	
 
		CPerformanceTimer perf;
 
		perf.Start();
 
		Yapf().PfSetStartupNodes();
 

	
 
		while (true) {
 
			m_num_steps++;
 
			Node& n = m_nodes.GetBestOpenNode();
 
			if (&n == NULL)
 
@@ -151,34 +151,34 @@ public:
 
		float cache_hit_ratio = (float)m_stats_cache_hits / (float)(m_stats_cache_hits + m_stats_cost_calcs) * 100.0f;
 
		int cost = bDestFound ? m_pBestDestNode->m_cost : -1;
 
		int dist = bDestFound ? m_pBestDestNode->m_estimate - m_pBestDestNode->m_cost : -1;
 
#ifdef UNITTEST
 
		printf("%c%c%4d-%6d us -%5d rounds -%4d open -%5d closed - CHR %4.1f%% - c/d(%d, %d) - c%d(sc%d, ts%d, o%d) -- \n", bDestFound ? '-' : '!', ttc, veh_idx, t, m_num_steps, m_nodes.OpenCount(), m_nodes.ClosedCount(), cache_hit_ratio, cost, dist, m_perf_cost.Get(1000000), m_perf_slope_cost.Get(1000000), m_perf_ts_cost.Get(1000000), m_perf_other_cost.Get(1000000));
 
#else
 
		DEBUG(yapf, 3)("[YAPF][YAPF%c]%c%4d- %d us - %d rounds - %d open - %d closed - CHR %4.1f%% - c%d(sc%d, ts%d, o%d) -- ", ttc, bDestFound ? '-' : '!', veh_idx, t, m_num_steps, m_nodes.OpenCount(), m_nodes.ClosedCount(), cache_hit_ratio, cost, dist, m_perf_cost.Get(1000000), m_perf_slope_cost.Get(1000000), m_perf_ts_cost.Get(1000000), m_perf_other_cost.Get(1000000));
 
#endif
 
		return bDestFound;
 
	}
 

	
 
	/** If path was found return the best node that has reached the destination. Otherwise
 
			return the best visited node (which was nearest to the destination).
 
	*/
 
	 *  return the best visited node (which was nearest to the destination).
 
	 */
 
	FORCEINLINE Node& GetBestNode()
 
	{
 
		return (m_pBestDestNode != NULL) ? *m_pBestDestNode : *m_pBestIntermediateNode;
 
	}
 

	
 
	/** Calls NodeList::CreateNewNode() - allocates new node that can be filled and used
 
			as argument for AddStartupNode() or AddNewNode()
 
	*/
 
	 *  as argument for AddStartupNode() or AddNewNode()
 
	 */
 
	FORCEINLINE Node& CreateNewNode()
 
	{
 
		Node& node = *m_nodes.CreateNewNode();
 
		return node;
 
	}
 

	
 
	/** Add new node (created by CreateNewNode and filled with data) into open list */
 
	FORCEINLINE void AddStartupNode(Node& n)
 
	{
 
		Yapf().PfNodeCacheFetch(n);
 
		// insert the new node only if it is not there
 
		if (&m_nodes.FindOpenNode(n.m_key) == NULL) {
 
@@ -194,25 +194,25 @@ public:
 
	FORCEINLINE void AddMultipleNodes(Node* parent, TileIndex tile, TrackdirBits td_bits)
 
	{
 
		bool is_choice = (KillFirstBit2x64(td_bits) != 0);
 
		for (TrackdirBits rtds = td_bits; rtds != TRACKDIR_BIT_NONE; rtds = (TrackdirBits)KillFirstBit2x64(rtds)) {
 
			Trackdir td = (Trackdir)FindFirstBit2x64(rtds);
 
			Node& n = Yapf().CreateNewNode();
 
			n.Set(parent, tile, td, is_choice);
 
			Yapf().AddNewNode(n);
 
		}
 
	}
 

	
 
	/** AddNewNode() - called by Tderived::PfFollowNode() for each child node.
 
	    Nodes are evaluated here and added into open list */
 
	 *  Nodes are evaluated here and added into open list */
 
	void AddNewNode(Node& n)
 
	{
 
		// evaluate the node
 
		bool bCached = Yapf().PfNodeCacheFetch(n);
 
		if (!bCached) {
 
			m_stats_cost_calcs++;
 
		} else {
 
			m_stats_cache_hits++;
 
		}
 

	
 
		bool bValid = Yapf().PfCalcCost(n);
 

	
yapf/yapf_common.hpp
Show inline comments
 
@@ -120,42 +120,42 @@ protected:
 
	/// to access inherited path finder
 
	Tpf& Yapf() {return *static_cast<Tpf*>(this);}
 

	
 
public:
 
	/// Called by YAPF to detect if node ends in the desired destination
 
	FORCEINLINE bool PfDetectDestination(Node& n)
 
	{
 
		bool bDest = (n.m_key.m_tile == m_destTile) && ((m_destTrackdirs & TrackdirToTrackdirBits(n.GetTrackdir())) != TRACKDIR_BIT_NONE);
 
		return bDest;
 
	}
 

	
 
	/** Called by YAPF to calculate cost estimate. Calculates distance to the destination
 
	*   adds it to the actual cost from origin and stores the sum to the Node::m_estimate */
 
	 *  adds it to the actual cost from origin and stores the sum to the Node::m_estimate */
 
	inline bool PfCalcEstimate(Node& n)
 
	{
 
		int dx = abs(TileX(n.GetTile()) - TileX(m_destTile));
 
		int dy = abs(TileY(n.GetTile()) - TileY(m_destTile));
 
		assert(dx >= 0 && dy >= 0);
 
		int dd = min(dx, dy);
 
		int dxy = abs(dx - dy);
 
		int d = 14 * dd + 10 * dxy;
 
		n.m_estimate = n.m_cost + d /*+ d / 8*/;
 
		return true;
 
	}
 
};
 

	
 
/** YAPF template that uses Ttypes template argument to determine all YAPF
 
*   components (base classes) from which the actual YAPF is composed.
 
*   For example classes consult: CYapfRail_TypesT template and its instantiations:
 
*   CYapfRail1, CYapfRail2, CYapfRail3, CYapfAnyDepotRail1, CYapfAnyDepotRail2, CYapfAnyDepotRail3 */
 
 *  components (base classes) from which the actual YAPF is composed.
 
 *  For example classes consult: CYapfRail_TypesT template and its instantiations:
 
 *  CYapfRail1, CYapfRail2, CYapfRail3, CYapfAnyDepotRail1, CYapfAnyDepotRail2, CYapfAnyDepotRail3 */
 
template <class Ttypes>
 
class CYapfT
 
	: public Ttypes::PfBase         ///< Instance of CYapfBaseT - main YAPF loop and support base class
 
	, public Ttypes::PfCost         ///< Cost calculation provider base class
 
	, public Ttypes::PfCache        ///< Segment cost cache provider
 
	, public Ttypes::PfOrigin       ///< Origin (tile or two-tile origin)
 
	, public Ttypes::PfDestination  ///< Destination detector and distance (estimate) calculation provider
 
	, public Ttypes::PfFollow       ///< Node follower (stepping provider)
 
{
 
};
 

	
 

	
yapf/yapf_costcache.hpp
Show inline comments
 
/* $Id$ */
 
#ifndef  YAPF_COSTCACHE_HPP
 
#define  YAPF_COSTCACHE_HPP
 

	
 

	
 
/** CYapfSegmentCostCacheNoneT - the formal only yapf cost cache provider that implements
 
PfNodeCacheFetch() and PfNodeCacheFlush() callbacks. Used when nodes don't have CachedData
 
defined (they don't count with any segment cost caching).
 
*/
 
 * PfNodeCacheFetch() and PfNodeCacheFlush() callbacks. Used when nodes don't have CachedData
 
 * defined (they don't count with any segment cost caching).
 
 */
 
template <class Types>
 
class CYapfSegmentCostCacheNoneT
 
{
 
public:
 
	typedef typename Types::Tpf Tpf;              ///< the pathfinder class (derived from THIS class)
 
	typedef typename Types::NodeList::Titem Node; ///< this will be our node type
 

	
 
	/** Called by YAPF to attach cached or local segment cost data to the given node.
 
	*   @return true if globally cached data were used or false if local data was used */
 
	 *  @return true if globally cached data were used or false if local data was used */
 
	FORCEINLINE bool PfNodeCacheFetch(Node& n)
 
	{
 
		return false;
 
	};
 

	
 
	/** Called by YAPF to flush the cached segment cost data back into cache storage.
 
	*   Current cache implementation doesn't use that. */
 
	 *  Current cache implementation doesn't use that. */
 
	FORCEINLINE void PfNodeCacheFlush(Node& n)
 
	{
 
	};
 
};
 

	
 

	
 
/** CYapfSegmentCostCacheLocalT - the yapf cost cache provider that implements fake segment
 
cost caching functionality for yapf. Used when node needs caching, but you don't want to
 
cache the segment costs.
 
*/
 
 * cost caching functionality for yapf. Used when node needs caching, but you don't want to
 
 * cache the segment costs.
 
 */
 
template <class Types>
 
class CYapfSegmentCostCacheLocalT
 
{
 
public:
 
	typedef typename Types::Tpf Tpf;              ///< the pathfinder class (derived from THIS class)
 
	typedef typename Types::NodeList::Titem Node; ///< this will be our node type
 
	typedef typename Node::Key Key;               ///< key to hash tables
 
	typedef typename Node::CachedData CachedData;
 
	typedef typename CachedData::Key CacheKey;
 
	typedef CArrayT<CachedData> LocalCache;
 

	
 
protected:
 
	LocalCache      m_local_cache;
 

	
 
	/// to access inherited path finder
 
	FORCEINLINE Tpf& Yapf() {return *static_cast<Tpf*>(this);}
 

	
 
public:
 
	/** Called by YAPF to attach cached or local segment cost data to the given node.
 
	*   @return true if globally cached data were used or false if local data was used */
 
	 *  @return true if globally cached data were used or false if local data was used */
 
	FORCEINLINE bool PfNodeCacheFetch(Node& n)
 
	{
 
		CacheKey key(n.GetKey());
 
		Yapf().ConnectNodeToCachedData(n, *new (&m_local_cache.AddNC()) CachedData(key));
 
		return false;
 
	};
 

	
 
	/** Called by YAPF to flush the cached segment cost data back into cache storage.
 
	*   Current cache implementation doesn't use that. */
 
	 *  Current cache implementation doesn't use that. */
 
	FORCEINLINE void PfNodeCacheFlush(Node& n)
 
	{
 
	};
 
};
 

	
 

	
 
/** Base class for segment cost cache providers. Contains global counter
 
*   of track layout changes and static notification function called whenever
 
*   the track layout changes. It is implemented as base class because it needs
 
*   to be shared between all rail YAPF types (one shared counter, one notification
 
*   function. */
 
 *  of track layout changes and static notification function called whenever
 
 *  the track layout changes. It is implemented as base class because it needs
 
 *  to be shared between all rail YAPF types (one shared counter, one notification
 
 *  function. */
 
struct CSegmentCostCacheBase
 
{
 
	static int   s_rail_change_counter;
 

	
 
	static void NotifyTrackLayoutChange(TileIndex tile, Track track) {s_rail_change_counter++;}
 
};
 

	
 

	
 
/** CSegmentCostCacheT - template class providing hash-map and storage (heap)
 
    of Tsegment structures. Each rail node contains pointer to the segment
 
    that contains cached (or non-cached) segment cost information. Nodes can
 
    differ by key type, but they use the same segment type. Segment key should
 
    be always the same (TileIndex + DiagDirection) that represent the beginning
 
    of the segment (origin tile and exit-dir from this tile).
 
    Different CYapfCachedCostT types can share the same type of CSegmentCostCacheT.
 
    Look at CYapfRailSegment (yapf_node_rail.hpp) for the segment example */
 
 *  of Tsegment structures. Each rail node contains pointer to the segment
 
 *  that contains cached (or non-cached) segment cost information. Nodes can
 
 *  differ by key type, but they use the same segment type. Segment key should
 
 *  be always the same (TileIndex + DiagDirection) that represent the beginning
 
 *  of the segment (origin tile and exit-dir from this tile).
 
 *  Different CYapfCachedCostT types can share the same type of CSegmentCostCacheT.
 
 *  Look at CYapfRailSegment (yapf_node_rail.hpp) for the segment example */
 
template <class Tsegment>
 
struct CSegmentCostCacheT
 
	: public CSegmentCostCacheBase
 
{
 
	enum {c_hash_bits = 14};
 

	
 
	typedef CHashTableT<Tsegment, c_hash_bits> HashTable;
 
	typedef CArrayT<Tsegment> Heap;
 
	typedef typename Tsegment::Key Key;    ///< key to hash table
 

	
 
	HashTable    m_map;
 
	Heap         m_heap;
 
@@ -110,26 +110,26 @@ struct CSegmentCostCacheT
 
		if (item == NULL) {
 
			*found = false;
 
			item = new (&m_heap.AddNC()) Tsegment(key);
 
			m_map.Push(*item);
 
		} else {
 
			*found = true;
 
		}
 
		return *item;
 
	}
 
};
 

	
 
/** CYapfSegmentCostCacheGlobalT - the yapf cost cache provider that adds the segment cost
 
    caching functionality to yapf. Using this class as base of your will provide the global
 
		segment cost caching services for your Nodes.
 
 *  caching functionality to yapf. Using this class as base of your will provide the global
 
 *  segment cost caching services for your Nodes.
 
*/
 
template <class Types>
 
class CYapfSegmentCostCacheGlobalT
 
	: public CYapfSegmentCostCacheLocalT<Types>
 
{
 
public:
 
	typedef CYapfSegmentCostCacheLocalT<Types> Tlocal;
 
	typedef typename Types::Tpf Tpf;              ///< the pathfinder class (derived from THIS class)
 
	typedef typename Types::NodeList::Titem Node; ///< this will be our node type
 
	typedef typename Node::Key Key;    ///< key to hash tables
 
	typedef typename Node::CachedData CachedData;
 
	typedef typename CachedData::Key CacheKey;
 
@@ -164,37 +164,37 @@ protected:
 
			last_rail_change_counter = Cache::s_rail_change_counter;
 
			delete pC;
 
			pC = NULL;
 
		}
 

	
 
		if (pC == NULL)
 
			pC = new Cache();
 
		return *pC;
 
	}
 

	
 
public:
 
	/** Called by YAPF to attach cached or local segment cost data to the given node.
 
	*   @return true if globally cached data were used or false if local data was used */
 
	 *  @return true if globally cached data were used or false if local data was used */
 
	FORCEINLINE bool PfNodeCacheFetch(Node& n)
 
	{
 
		if (!Yapf().CanUseGlobalCache(n)) {
 
			return Tlocal::PfNodeCacheFetch(n);
 
		}
 
		CacheKey key(n.GetKey());
 
		bool found;
 
		CachedData& item = m_global_cache.Get(key, &found);
 
		Yapf().ConnectNodeToCachedData(n, item);
 
		return found;
 
	};
 

	
 
	/** Called by YAPF to flush the cached segment cost data back into cache storage.
 
	*   Current cache implementation doesn't use that. */
 
	 *  Current cache implementation doesn't use that. */
 
	FORCEINLINE void PfNodeCacheFlush(Node& n)
 
	{
 
	};
 

	
 
};
 

	
 

	
 

	
 

	
 
#endif /* YAPF_COSTCACHE_HPP */
yapf/yapf_costrail.hpp
Show inline comments
 
@@ -151,26 +151,26 @@ public:
 
			cost += Yapf().PfGetSettings().rail_longer_platform_penalty;
 
		} else if (needed_platform_length > platform_length) {
 
			// apply penalty for shorter platform than needed
 
			cost += Yapf().PfGetSettings().rail_shorter_platform_penalty;
 
		}
 
		return cost;
 
	}
 

	
 
public:
 
	FORCEINLINE void SetMaxCost(int max_cost) {m_max_cost = max_cost;}
 

	
 
	/** Called by YAPF to calculate the cost from the origin to the given node.
 
	*   Calculates only the cost of given node, adds it to the parent node cost
 
	*   and stores the result into Node::m_cost member */
 
	 *  Calculates only the cost of given node, adds it to the parent node cost
 
	 *  and stores the result into Node::m_cost member */
 
	FORCEINLINE bool PfCalcCost(Node& n)
 
	{
 
		assert(!n.flags_u.flags_s.m_targed_seen);
 
		CPerfStart perf_cost(Yapf().m_perf_cost);
 
		int parent_cost = (n.m_parent != NULL) ? n.m_parent->m_cost : 0;
 
		int first_tile_cost = 0;
 
		int segment_cost = 0;
 
		int extra_cost = 0;
 
		const Vehicle* v = Yapf().GetVehicle();
 

	
 
		// start at n.m_key.m_tile / n.m_key.m_td and walk to the end of segment
 
		TileIndex prev_tile      = (n.m_parent != NULL) ? n.m_parent->GetLastTile() : INVALID_TILE;
yapf/yapf_destrail.hpp
Show inline comments
 
@@ -37,25 +37,25 @@ public:
 
	{
 
		return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
 
	}
 

	
 
	/// Called by YAPF to detect if node ends in the desired destination
 
	FORCEINLINE bool PfDetectDestination(TileIndex tile, Trackdir td)
 
	{
 
		bool bDest = IsTileDepotType(tile, TRANSPORT_RAIL);
 
		return bDest;
 
	}
 

	
 
	/** Called by YAPF to calculate cost estimate. Calculates distance to the destination
 
	*   adds it to the actual cost from origin and stores the sum to the Node::m_estimate */
 
	 *  adds it to the actual cost from origin and stores the sum to the Node::m_estimate */
 
	FORCEINLINE bool PfCalcEstimate(Node& n)
 
	{
 
		n.m_estimate = n.m_cost;
 
		return true;
 
	}
 
};
 

	
 
template <class Types>
 
class CYapfDestinationTileOrStationRailT
 
	: public CYapfDestinationRailBase
 
{
 
public:
 
@@ -109,25 +109,25 @@ public:
 
		if (m_dest_station_id != INVALID_STATION) {
 
			bDest = IsRailwayStationTile(tile)
 
				&& (GetStationIndex(tile) == m_dest_station_id)
 
				&& (GetRailStationTrack(tile) == TrackdirToTrack(td));
 
		} else {
 
			bDest = (tile == m_destTile)
 
				&& ((m_destTrackdirs & TrackdirToTrackdirBits(td)) != TRACKDIR_BIT_NONE);
 
		}
 
		return bDest;
 
	}
 

	
 
	/** Called by YAPF to calculate cost estimate. Calculates distance to the destination
 
	*   adds it to the actual cost from origin and stores the sum to the Node::m_estimate */
 
	 *  adds it to the actual cost from origin and stores the sum to the Node::m_estimate */
 
	FORCEINLINE bool PfCalcEstimate(Node& n)
 
	{
 
		static int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
 
		static int dg_dir_to_y_offs[] = {0, 1, 0, -1};
 
		if (PfDetectDestination(n)) {
 
			n.m_estimate = n.m_cost;
 
			return true;
 
		}
 

	
 
		TileIndex tile = n.GetLastTile();
 
		DiagDirection exitdir = TrackdirToExitdir(n.GetLastTrackdir());
 
		int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
yapf/yapf_rail.cpp
Show inline comments
 
@@ -19,26 +19,26 @@ class CYapfFollowAnyDepotRailT
 
public:
 
	typedef typename Types::Tpf Tpf;                     ///< the pathfinder class (derived from THIS class)
 
	typedef typename Types::TrackFollower TrackFollower;
 
	typedef typename Types::NodeList::Titem Node;        ///< this will be our node type
 
	typedef typename Node::Key Key;                      ///< key to hash tables
 

	
 
protected:
 
	/// to access inherited path finder
 
	FORCEINLINE Tpf& Yapf() {return *static_cast<Tpf*>(this);}
 

	
 
public:
 
	/** Called by YAPF to move from the given node to the next tile. For each
 
	*   reachable trackdir on the new tile creates new node, initializes it
 
	*   and adds it to the open list by calling Yapf().AddNewNode(n) */
 
	 *  reachable trackdir on the new tile creates new node, initializes it
 
	 *  and adds it to the open list by calling Yapf().AddNewNode(n) */
 
	inline void PfFollowNode(Node& old_node)
 
	{
 
		TrackFollower F(Yapf().GetVehicle());
 
		if (F.Follow(old_node.GetLastTile(), old_node.GetLastTrackdir()))
 
			Yapf().AddMultipleNodes(&old_node, F.m_new_tile, F.m_new_td_bits);
 
	}
 

	
 
	/// return debug report character to identify the transportation type
 
	FORCEINLINE char TransportTypeChar() const {return 't';}
 

	
 
	static bool stFindNearestDepotTwoWay(Vehicle *v, TileIndex t1, Trackdir td1, TileIndex t2, Trackdir td2, int max_distance, int reverse_penalty, TileIndex* depot_tile, bool* reversed)
 
	{
 
@@ -82,26 +82,26 @@ class CYapfFollowRailT
 
public:
 
	typedef typename Types::Tpf Tpf;                     ///< the pathfinder class (derived from THIS class)
 
	typedef typename Types::TrackFollower TrackFollower;
 
	typedef typename Types::NodeList::Titem Node;        ///< this will be our node type
 
	typedef typename Node::Key Key;                      ///< key to hash tables
 

	
 
protected:
 
	/// to access inherited path finder
 
	FORCEINLINE Tpf& Yapf() {return *static_cast<Tpf*>(this);}
 

	
 
public:
 
	/** Called by YAPF to move from the given node to the next tile. For each
 
	*   reachable trackdir on the new tile creates new node, initializes it
 
	*   and adds it to the open list by calling Yapf().AddNewNode(n) */
 
	 *  reachable trackdir on the new tile creates new node, initializes it
 
	 *  and adds it to the open list by calling Yapf().AddNewNode(n) */
 
	inline void PfFollowNode(Node& old_node)
 
	{
 
		TrackFollower F(Yapf().GetVehicle());
 
		if (F.Follow(old_node.GetLastTile(), old_node.GetLastTrackdir()))
 
			Yapf().AddMultipleNodes(&old_node, F.m_new_tile, F.m_new_td_bits);
 
	}
 

	
 
	/// return debug report character to identify the transportation type
 
	FORCEINLINE char TransportTypeChar() const {return 't';}
 

	
 
	static Trackdir stChooseRailTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs)
 
	{
yapf/yapf_road.cpp
Show inline comments
 
@@ -55,26 +55,26 @@ protected:
 
				default:
 
					break;
 
			}
 
		} else {
 
			// non-diagonal trackdir
 
			cost = YAPF_TILE_CORNER_LENGTH + Yapf().PfGetSettings().road_curve_penalty;
 
		}
 
		return cost;
 
	}
 

	
 
public:
 
	/** Called by YAPF to calculate the cost from the origin to the given node.
 
	*   Calculates only the cost of given node, adds it to the parent node cost
 
	*   and stores the result into Node::m_cost member */
 
	 *  Calculates only the cost of given node, adds it to the parent node cost
 
	 *  and stores the result into Node::m_cost member */
 
	FORCEINLINE bool PfCalcCost(Node& n)
 
	{
 
		int segment_cost = 0;
 
		// start at n.m_key.m_tile / n.m_key.m_td and walk to the end of segment
 
		TileIndex tile = n.m_key.m_tile;
 
		Trackdir trackdir = n.m_key.m_td;
 
		while (true) {
 
			// base tile cost depending on distance between edges
 
			segment_cost += Yapf().OneTileCost(tile, trackdir);
 

	
 
			// stop if we have just entered the depot
 
			if (IsTileDepotType(tile, TRANSPORT_ROAD) && trackdir == DiagdirToDiagTrackdir(ReverseDiagDir(GetRoadDepotDirection(tile)))) {
 
@@ -135,25 +135,25 @@ public:
 

	
 
	/// to access inherited path finder
 
	Tpf& Yapf() {return *static_cast<Tpf*>(this);}
 

	
 
	/// Called by YAPF to detect if node ends in the desired destination
 
	FORCEINLINE bool PfDetectDestination(Node& n)
 
	{
 
		bool bDest = IsTileDepotType(n.m_segment_last_tile, TRANSPORT_ROAD);
 
		return bDest;
 
	}
 

	
 
	/** Called by YAPF to calculate cost estimate. Calculates distance to the destination
 
	*   adds it to the actual cost from origin and stores the sum to the Node::m_estimate */
 
	 *  adds it to the actual cost from origin and stores the sum to the Node::m_estimate */
 
	FORCEINLINE bool PfCalcEstimate(Node& n)
 
	{
 
		n.m_estimate = n.m_cost;
 
		return true;
 
	}
 
};
 

	
 

	
 
template <class Types>
 
class CYapfDestinationTileRoadT
 
{
 
public:
 
@@ -177,25 +177,25 @@ protected:
 
	/// to access inherited path finder
 
	Tpf& Yapf() {return *static_cast<Tpf*>(this);}
 

	
 
public:
 
	/// Called by YAPF to detect if node ends in the desired destination
 
	FORCEINLINE bool PfDetectDestination(Node& n)
 
	{
 
		bool bDest = (n.m_segment_last_tile == m_destTile) && ((m_destTrackdirs & TrackdirToTrackdirBits(n.m_segment_last_td)) != TRACKDIR_BIT_NONE);
 
		return bDest;
 
	}
 

	
 
	/** Called by YAPF to calculate cost estimate. Calculates distance to the destination
 
	*   adds it to the actual cost from origin and stores the sum to the Node::m_estimate */
 
	 *  adds it to the actual cost from origin and stores the sum to the Node::m_estimate */
 
	inline bool PfCalcEstimate(Node& n)
 
	{
 
		static int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
 
		static int dg_dir_to_y_offs[] = {0, 1, 0, -1};
 
		if (PfDetectDestination(n)) {
 
			n.m_estimate = n.m_cost;
 
			return true;
 
		}
 

	
 
		TileIndex tile = n.m_segment_last_tile;
 
		DiagDirection exitdir = TrackdirToExitdir(n.m_segment_last_td);
 
		int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
 
@@ -222,26 +222,26 @@ public:
 
	typedef typename Types::Tpf Tpf;                     ///< the pathfinder class (derived from THIS class)
 
	typedef typename Types::TrackFollower TrackFollower;
 
	typedef typename Types::NodeList::Titem Node;        ///< this will be our node type
 
	typedef typename Node::Key Key;                      ///< key to hash tables
 

	
 
protected:
 
	/// to access inherited path finder
 
	FORCEINLINE Tpf& Yapf() {return *static_cast<Tpf*>(this);}
 

	
 
public:
 

	
 
	/** Called by YAPF to move from the given node to the next tile. For each
 
	*   reachable trackdir on the new tile creates new node, initializes it
 
	*   and adds it to the open list by calling Yapf().AddNewNode(n) */
 
	 *  reachable trackdir on the new tile creates new node, initializes it
 
	 *  and adds it to the open list by calling Yapf().AddNewNode(n) */
 
	inline void PfFollowNode(Node& old_node)
 
	{
 
		TrackFollower F(Yapf().GetVehicle());
 
		if (F.Follow(old_node.m_segment_last_tile, old_node.m_segment_last_td))
 
			Yapf().AddMultipleNodes(&old_node, F.m_new_tile, F.m_new_td_bits);
 
	}
 

	
 
	/// return debug report character to identify the transportation type
 
	FORCEINLINE char TransportTypeChar() const {return 'r';}
 

	
 
	static Trackdir stChooseRoadTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir)
 
	{
yapf/yapf_settings.h
Show inline comments
 
/* $Id$ */
 
#if !defined(YAPF_SETTINGS_H) || defined(YS_DEF)
 

	
 
# ifndef  YAPF_SETTINGS_H
 
#  define  YAPF_SETTINGS_H
 
# endif
 

	
 
# ifndef YS_DEF
 
/*
 
*  if YS_DEF is not defined, we will only do following declaration:
 
*  typedef struct YapfSettings {
 
*    bool   disable_node_optimization;
 
*    uint32 max_search_nodes;
 
*    .... all other yapf related settings ...
 
*  } YapfSettings;
 
*
 
*  otherwise we will just expand YS_DEF_xx macros and then #undef them
 
*/
 
 *  if YS_DEF is not defined, we will only do following declaration:
 
 *  typedef struct YapfSettings {
 
 *    bool   disable_node_optimization;
 
 *    uint32 max_search_nodes;
 
 *    .... all other yapf related settings ...
 
 *  } YapfSettings;
 
 *
 
 *  otherwise we will just expand YS_DEF_xx macros and then #undef them
 
 */
 
#  define YS_DEF_BEGIN typedef struct YapfSettings {
 
#  define YS_DEF(type, name) type name;
 
#  define YS_DEF_END } YapfSettings;
 

	
 
# endif /* !YS_DEF */
 

	
 
# ifndef   YS_DEF_BEGIN
 
#  define  YS_DEF_BEGIN
 
# endif // YS_DEF_BEGIN
 

	
 
# ifndef   YS_DEF_END
 
#  define  YS_DEF_END
yapf/yapf_ship.cpp
Show inline comments
 
@@ -11,26 +11,26 @@ class CYapfFollowShipT
 
public:
 
	typedef typename Types::Tpf Tpf;                     ///< the pathfinder class (derived from THIS class)
 
	typedef typename Types::TrackFollower TrackFollower;
 
	typedef typename Types::NodeList::Titem Node;        ///< this will be our node type
 
	typedef typename Node::Key Key;                      ///< key to hash tables
 

	
 
protected:
 
	/// to access inherited path finder
 
	FORCEINLINE Tpf& Yapf() {return *static_cast<Tpf*>(this);}
 

	
 
public:
 
	/** Called by YAPF to move from the given node to the next tile. For each
 
	*   reachable trackdir on the new tile creates new node, initializes it
 
	*   and adds it to the open list by calling Yapf().AddNewNode(n) */
 
	 *  reachable trackdir on the new tile creates new node, initializes it
 
	 *  and adds it to the open list by calling Yapf().AddNewNode(n) */
 
	inline void PfFollowNode(Node& old_node)
 
	{
 
		TrackFollower F;
 
		if (F.Follow(old_node.m_key.m_tile, old_node.m_key.m_td))
 
			Yapf().AddMultipleNodes(&old_node, F.m_new_tile, F.m_new_td_bits);
 
	}
 

	
 
	/// return debug report character to identify the transportation type
 
	FORCEINLINE char TransportTypeChar() const {return 'w';}
 

	
 
	static Trackdir ChooseShipTrack(Vehicle *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks)
 
	{
 
@@ -86,41 +86,41 @@ class CYapfCostShipT
 
{
 
public:
 
	typedef typename Types::Tpf Tpf;              ///< the pathfinder class (derived from THIS class)
 
	typedef typename Types::NodeList::Titem Node; ///< this will be our node type
 
	typedef typename Node::Key Key;               ///< key to hash tables
 

	
 
protected:
 
	/// to access inherited path finder
 
	Tpf& Yapf() {return *static_cast<Tpf*>(this);}
 

	
 
public:
 
	/** Called by YAPF to calculate the cost from the origin to the given node.
 
	*   Calculates only the cost of given node, adds it to the parent node cost
 
	*   and stores the result into Node::m_cost member */
 
	 *  Calculates only the cost of given node, adds it to the parent node cost
 
	 *  and stores the result into Node::m_cost member */
 
	FORCEINLINE bool PfCalcCost(Node& n)
 
	{
 
		// base tile cost depending on distance
 
		int c = IsDiagonalTrackdir(n.GetTrackdir()) ? 10 : 7;
 
		// additional penalty for curves
 
		if (n.m_parent != NULL && n.GetTrackdir() != n.m_parent->GetTrackdir()) c += 3;
 
		// apply it
 
		n.m_cost = n.m_parent->m_cost + c;
 
		return true;
 
	}
 
};
 

	
 
/** Config struct of YAPF for ships.
 
		Defines all 6 base YAPF modules as classes providing services for CYapfBaseT.
 
*/
 
 *  Defines all 6 base YAPF modules as classes providing services for CYapfBaseT.
 
 */
 
template <class Tpf_, class Ttrack_follower, class Tnode_list>
 
struct CYapfShip_TypesT
 
{
 
	/** Types - shortcut for this struct type */
 
	typedef CYapfShip_TypesT<Tpf_, Ttrack_follower, Tnode_list>  Types;
 

	
 
	/** Tpf - pathfinder type */
 
	typedef Tpf_                              Tpf;
 
	/** track follower helper class */
 
	typedef Ttrack_follower                   TrackFollower;
 
	/** node list type */
 
	typedef Tnode_list                        NodeList;
0 comments (0 inline, 0 general)