(svn r9391) -Documentation : correct Doxygen of comments and @file inclusion. Time for P and Q files

pull/155/head
belugas 18 years ago
parent 4d86aa2479
commit e9295b82ff

@ -1,5 +1,7 @@
/* $Id$ */ /* $Id$ */
/** @file pathfind.cpp */
#include "stdafx.h" #include "stdafx.h"
#include "openttd.h" #include "openttd.h"
#include "bridge_map.h" #include "bridge_map.h"
@ -15,7 +17,7 @@
#include "variables.h" #include "variables.h"
#include "depot.h" #include "depot.h"
// remember which tiles we have already visited so we don't visit them again. /* remember which tiles we have already visited so we don't visit them again. */
static bool TPFSetTileBit(TrackPathFinder *tpf, TileIndex tile, int dir) static bool TPFSetTileBit(TrackPathFinder *tpf, TileIndex tile, int dir)
{ {
uint hash, val, offs; uint hash, val, offs;
@ -65,7 +67,7 @@ static bool TPFSetTileBit(TrackPathFinder *tpf, TileIndex tile, int dir)
tpf->hash_tile[hash] = PATHFIND_GET_LINK_OFFS(tpf, link); tpf->hash_tile[hash] = PATHFIND_GET_LINK_OFFS(tpf, link);
link->flags = tpf->hash_head[hash]; link->flags = tpf->hash_head[hash];
tpf->hash_head[hash] = 0xFFFF; /* multi link */ tpf->hash_head[hash] = 0xFFFF; // multi link
link->next = 0xFFFF; link->next = 0xFFFF;
} }
@ -142,9 +144,9 @@ static void TPFMode2(TrackPathFinder* tpf, TileIndex tile, DiagDirection directi
assert(tpf->tracktype == TRANSPORT_WATER); assert(tpf->tracktype == TRANSPORT_WATER);
// This addition will sometimes overflow by a single tile. /* This addition will sometimes overflow by a single tile.
// The use of TILE_MASK here makes sure that we still point at a valid * The use of TILE_MASK here makes sure that we still point at a valid
// tile, and then this tile will be in the sentinel row/col, so GetTileTrackStatus will fail. * tile, and then this tile will be in the sentinel row/col, so GetTileTrackStatus will fail. */
tile = TILE_MASK(tile + TileOffsByDiagDir(direction)); tile = TILE_MASK(tile + TileOffsByDiagDir(direction));
if (++tpf->rd.cur_length > 50) if (++tpf->rd.cur_length > 50)
@ -160,8 +162,8 @@ static void TPFMode2(TrackPathFinder* tpf, TileIndex tile, DiagDirection directi
if ( (bits & (bits - 1)) == 0 ) { if ( (bits & (bits - 1)) == 0 ) {
/* only one direction */ /* only one direction */
i = 0; i = 0;
while (!(bits&1)) while (!(bits & 1))
i++, bits>>=1; i++, bits >>= 1;
rd = tpf->rd; rd = tpf->rd;
goto continue_here; goto continue_here;
@ -172,7 +174,7 @@ static void TPFMode2(TrackPathFinder* tpf, TileIndex tile, DiagDirection directi
if (!(bits & 1)) continue; if (!(bits & 1)) continue;
rd = tpf->rd; rd = tpf->rd;
// Change direction 4 times only /* Change direction 4 times only */
if ((byte)i != tpf->rd.pft_var6) { if ((byte)i != tpf->rd.pft_var6) {
if (++tpf->rd.depth > 4) { if (++tpf->rd.depth > 4) {
tpf->rd = rd; tpf->rd = rd;
@ -189,7 +191,7 @@ continue_here:;
} }
tpf->rd = rd; tpf->rd = rd;
} while (++i, bits>>=1); } while (++i, bits >>= 1);
} }
@ -284,7 +286,7 @@ static void TPFMode1(TrackPathFinder* tpf, TileIndex tile, DiagDirection directi
/* Check in case of rail if the owner is the same */ /* Check in case of rail if the owner is the same */
if (tpf->tracktype == TRANSPORT_RAIL) { if (tpf->tracktype == TRANSPORT_RAIL) {
// don't enter train depot from the back /* don't enter train depot from the back */
if (IsTileDepotType(tile, TRANSPORT_RAIL) && GetRailDepotDirection(tile) == direction) return; if (IsTileDepotType(tile, TRANSPORT_RAIL) && GetRailDepotDirection(tile) == direction) return;
if (IsTileType(tile_org, MP_RAILWAY) || IsTileType(tile_org, MP_STATION) || IsTileType(tile_org, MP_TUNNELBRIDGE)) if (IsTileType(tile_org, MP_RAILWAY) || IsTileType(tile_org, MP_STATION) || IsTileType(tile_org, MP_TUNNELBRIDGE))
@ -292,12 +294,12 @@ static void TPFMode1(TrackPathFinder* tpf, TileIndex tile, DiagDirection directi
if (GetTileOwner(tile_org) != GetTileOwner(tile)) return; if (GetTileOwner(tile_org) != GetTileOwner(tile)) return;
} }
// check if the new tile can be entered from that direction /* check if the new tile can be entered from that direction */
if (tpf->tracktype == TRANSPORT_ROAD) { if (tpf->tracktype == TRANSPORT_ROAD) {
// road stops and depots now have a track (r4419) /* road stops and depots now have a track (r4419)
// don't enter road stop from the back * don't enter road stop from the back */
if (IsStandardRoadStopTile(tile) && ReverseDiagDir(GetRoadStopDir(tile)) != direction) return; if (IsStandardRoadStopTile(tile) && ReverseDiagDir(GetRoadStopDir(tile)) != direction) return;
// don't enter road depot from the back /* don't enter road depot from the back */
if (IsTileDepotType(tile, TRANSPORT_ROAD) && ReverseDiagDir(GetRoadDepotDirection(tile)) != direction) return; if (IsTileDepotType(tile, TRANSPORT_ROAD) && ReverseDiagDir(GetRoadDepotDirection(tile)) != direction) return;
} }
@ -323,7 +325,7 @@ static void TPFMode1(TrackPathFinder* tpf, TileIndex tile, DiagDirection directi
if ((byte)bits != tpf->var2) { if ((byte)bits != tpf->var2) {
bits &= _tpfmode1_and[direction]; bits &= _tpfmode1_and[direction];
bits = bits | (bits>>8); bits = bits | (bits >> 8);
} }
bits &= 0xBF; bits &= 0xBF;
@ -333,7 +335,7 @@ static void TPFMode1(TrackPathFinder* tpf, TileIndex tile, DiagDirection directi
i = FIND_FIRST_BIT(bits); i = FIND_FIRST_BIT(bits);
bits = KILL_FIRST_BIT(bits); bits = KILL_FIRST_BIT(bits);
tpf->the_dir = (Trackdir)((_otherdir_mask[direction] & (byte)(1 << i)) ? (i+8) : i); tpf->the_dir = (Trackdir)((_otherdir_mask[direction] & (byte)(1 << i)) ? (i + 8) : i);
rd = tpf->rd; rd = tpf->rd;
if (TPFSetTileBit(tpf, tile, tpf->the_dir) && if (TPFSetTileBit(tpf, tile, tpf->the_dir) &&
@ -375,7 +377,7 @@ static void TPFMode1(TrackPathFinder* tpf, TileIndex tile, DiagDirection directi
i = FIND_FIRST_BIT(bits); i = FIND_FIRST_BIT(bits);
bits = KILL_FIRST_BIT(bits); bits = KILL_FIRST_BIT(bits);
tpf->the_dir = (Trackdir)((_otherdir_mask[direction] & (byte)(1 << i)) ? (i+8) : i); tpf->the_dir = (Trackdir)((_otherdir_mask[direction] & (byte)(1 << i)) ? (i + 8) : i);
rd = tpf->rd; rd = tpf->rd;
if (TPFSetTileBit(tpf, tile, tpf->the_dir) && if (TPFSetTileBit(tpf, tile, tpf->the_dir) &&
!tpf->enum_proc(tile, tpf->userdata, tpf->the_dir, tpf->rd.cur_length, &tpf->rd.pft_var6) ) { !tpf->enum_proc(tile, tpf->userdata, tpf->the_dir, tpf->rd.cur_length, &tpf->rd.pft_var6) ) {
@ -401,10 +403,10 @@ void FollowTrack(TileIndex tile, uint16 flags, DiagDirection direction, TPFEnumP
tpf.rd.depth = 0; tpf.rd.depth = 0;
tpf.rd.pft_var6 = 0; tpf.rd.pft_var6 = 0;
tpf.var2 = HASBIT(flags, 15) ? 0x43 : 0xFF; /* 0x8000 */ tpf.var2 = HASBIT(flags, 15) ? 0x43 : 0xFF; // 0x8000
tpf.disable_tile_hash = HASBIT(flags, 12); /* 0x1000 */ tpf.disable_tile_hash = HASBIT(flags, 12); // 0x1000
tpf.hasbit_13 = HASBIT(flags, 13); /* 0x2000 */ tpf.hasbit_13 = HASBIT(flags, 13); // 0x2000
tpf.tracktype = (TransportType)(flags & 0xFF); tpf.tracktype = (TransportType)(flags & 0xFF);
@ -425,8 +427,8 @@ void FollowTrack(TileIndex tile, uint16 flags, DiagDirection direction, TPFEnumP
struct StackedItem { struct StackedItem {
TileIndex tile; TileIndex tile;
uint16 cur_length; // This is the current length to this tile. uint16 cur_length; ///< This is the current length to this tile.
uint16 priority; // This is the current length + estimated length to the goal. uint16 priority; ///< This is the current length + estimated length to the goal.
TrackdirByte track; TrackdirByte track;
byte depth; byte depth;
byte state; byte state;
@ -461,12 +463,12 @@ struct NewTrackPathFinder {
uint num_links_left; uint num_links_left;
uint nstack; uint nstack;
StackedItem stack[256]; // priority queue of stacked items StackedItem stack[256]; ///< priority queue of stacked items
uint16 hash_head[0x400]; // hash heads. 0 means unused. 0xFFFC = length, 0x3 = dir uint16 hash_head[0x400]; ///< hash heads. 0 means unused. 0xFFFC = length, 0x3 = dir
TileIndex hash_tile[0x400]; // tiles. or links. TileIndex hash_tile[0x400]; ///< tiles. or links.
HashLink links[0x400]; // hash links HashLink links[0x400]; ///< hash links
}; };
#define NTP_GET_LINK_OFFS(tpf, link) ((byte*)(link) - (byte*)tpf->links) #define NTP_GET_LINK_OFFS(tpf, link) ((byte*)(link) - (byte*)tpf->links)
@ -474,22 +476,22 @@ struct NewTrackPathFinder {
#define ARR(i) tpf->stack[(i)-1] #define ARR(i) tpf->stack[(i)-1]
// called after a new element was added in the queue at the last index. /** called after a new element was added in the queue at the last index.
// move it down to the proper position * move it down to the proper position */
static inline void HeapifyUp(NewTrackPathFinder *tpf) static inline void HeapifyUp(NewTrackPathFinder *tpf)
{ {
StackedItem si; StackedItem si;
int i = ++tpf->nstack; int i = ++tpf->nstack;
while (i != 1 && ARR(i).priority < ARR(i>>1).priority) { while (i != 1 && ARR(i).priority < ARR(i>>1).priority) {
// the child element is larger than the parent item. /* the child element is larger than the parent item.
// swap the child item and the parent item. * swap the child item and the parent item. */
si = ARR(i); ARR(i) = ARR(i>>1); ARR(i>>1) = si; si = ARR(i); ARR(i) = ARR(i >> 1); ARR(i >> 1) = si;
i>>=1; i >>= 1;
} }
} }
// called after the element 0 was eaten. fill it with a new element /** called after the element 0 was eaten. fill it with a new element */
static inline void HeapifyDown(NewTrackPathFinder *tpf) static inline void HeapifyDown(NewTrackPathFinder *tpf)
{ {
StackedItem si; StackedItem si;
@ -501,27 +503,27 @@ static inline void HeapifyDown(NewTrackPathFinder *tpf)
if (n == 0) return; // heap is empty so nothing to do? if (n == 0) return; // heap is empty so nothing to do?
// copy the last item to index 0. we use it as base for heapify. /* copy the last item to index 0. we use it as base for heapify. */
ARR(1) = ARR(n+1); ARR(1) = ARR(n + 1);
while ((j=i*2) <= n) { while ((j = i * 2) <= n) {
// figure out which is smaller of the children. /* figure out which is smaller of the children. */
if (j != n && ARR(j).priority > ARR(j+1).priority) if (j != n && ARR(j).priority > ARR(j + 1).priority)
j++; // right item is smaller j++; // right item is smaller
assert(i <= n && j <= n); assert(i <= n && j <= n);
if (ARR(i).priority <= ARR(j).priority) if (ARR(i).priority <= ARR(j).priority)
break; // base elem smaller than smallest, done! break; // base elem smaller than smallest, done!
// swap parent with the child /* swap parent with the child */
si = ARR(i); ARR(i) = ARR(j); ARR(j) = si; si = ARR(i); ARR(i) = ARR(j); ARR(j) = si;
i = j; i = j;
} }
} }
// mark a tile as visited and store the length of the path. /** mark a tile as visited and store the length of the path.
// if we already had a better path to this tile, return false. * if we already had a better path to this tile, return false.
// otherwise return true. * otherwise return true. */
static bool NtpVisit(NewTrackPathFinder* tpf, TileIndex tile, DiagDirection dir, uint length) static bool NtpVisit(NewTrackPathFinder* tpf, TileIndex tile, DiagDirection dir, uint length)
{ {
uint hash,head; uint hash,head;
@ -531,7 +533,7 @@ static bool NtpVisit(NewTrackPathFinder* tpf, TileIndex tile, DiagDirection dir,
hash = PATHFIND_HASH_TILE(tile); hash = PATHFIND_HASH_TILE(tile);
// never visited before? /* never visited before? */
if ((head=tpf->hash_head[hash]) == 0) { if ((head=tpf->hash_head[hash]) == 0) {
tpf->hash_tile[hash] = tile; tpf->hash_tile[hash] = tile;
tpf->hash_head[hash] = dir | (length << 2); tpf->hash_head[hash] = dir | (length << 2);
@ -541,15 +543,15 @@ static bool NtpVisit(NewTrackPathFinder* tpf, TileIndex tile, DiagDirection dir,
if (head != 0xffff) { if (head != 0xffff) {
if (tile == tpf->hash_tile[hash] && (head & 0x3) == (uint)dir) { if (tile == tpf->hash_tile[hash] && (head & 0x3) == (uint)dir) {
// longer length /* longer length */
if (length >= (head >> 2)) return false; if (length >= (head >> 2)) return false;
tpf->hash_head[hash] = dir | (length << 2); tpf->hash_head[hash] = dir | (length << 2);
return true; return true;
} }
// two tiles with the same hash, need to make a link /* two tiles with the same hash, need to make a link
// allocate a link. if out of links, handle this by returning * allocate a link. if out of links, handle this by returning
// that a tile was already visisted. * that a tile was already visisted. */
if (tpf->num_links_left == 0) { if (tpf->num_links_left == 0) {
DEBUG(ntp, 1, "No links left"); DEBUG(ntp, 1, "No links left");
return false; return false;
@ -564,12 +566,12 @@ static bool NtpVisit(NewTrackPathFinder* tpf, TileIndex tile, DiagDirection dir,
tpf->hash_tile[hash] = NTP_GET_LINK_OFFS(tpf, link); tpf->hash_tile[hash] = NTP_GET_LINK_OFFS(tpf, link);
link->typelength = tpf->hash_head[hash]; link->typelength = tpf->hash_head[hash];
tpf->hash_head[hash] = 0xFFFF; /* multi link */ tpf->hash_head[hash] = 0xFFFF; // multi link
link->next = 0xFFFF; link->next = 0xFFFF;
} else { } else {
// a linked list of many tiles, /* a linked list of many tiles,
// find the one corresponding to the tile, if it exists. * find the one corresponding to the tile, if it exists.
// otherwise make a new link * otherwise make a new link */
uint offs = tpf->hash_tile[hash]; uint offs = tpf->hash_tile[hash];
do { do {
@ -623,7 +625,7 @@ static bool NtpCheck(NewTrackPathFinder *tpf, TileIndex tile, uint dir, uint len
return length == (head >> 2); return length == (head >> 2);
} }
// else it's a linked list of many tiles /* else it's a linked list of many tiles */
offs = tpf->hash_tile[hash]; offs = tpf->hash_tile[hash];
for (;;) { for (;;) {
link = NTP_GET_LINK_PTR(tpf, offs); link = NTP_GET_LINK_PTR(tpf, offs);
@ -638,21 +640,21 @@ static bool NtpCheck(NewTrackPathFinder *tpf, TileIndex tile, uint dir, uint len
static const uint16 _is_upwards_slope[15] = { static const uint16 _is_upwards_slope[15] = {
0, // no tileh 0, ///< no tileh
(1 << TRACKDIR_X_SW) | (1 << TRACKDIR_Y_NW), // 1 (1 << TRACKDIR_X_SW) | (1 << TRACKDIR_Y_NW), ///< 1
(1 << TRACKDIR_X_SW) | (1 << TRACKDIR_Y_SE), // 2 (1 << TRACKDIR_X_SW) | (1 << TRACKDIR_Y_SE), ///< 2
(1 << TRACKDIR_X_SW), // 3 (1 << TRACKDIR_X_SW), ///< 3
(1 << TRACKDIR_X_NE) | (1 << TRACKDIR_Y_SE), // 4 (1 << TRACKDIR_X_NE) | (1 << TRACKDIR_Y_SE), ///< 4
0, // 5 0, ///< 5
(1 << TRACKDIR_Y_SE), // 6 (1 << TRACKDIR_Y_SE), ///< 6
0, // 7 0, ///< 7
(1 << TRACKDIR_X_NE) | (1 << TRACKDIR_Y_NW), // 8, (1 << TRACKDIR_X_NE) | (1 << TRACKDIR_Y_NW), ///< 8,
(1 << TRACKDIR_Y_NW), // 9 (1 << TRACKDIR_Y_NW), ///< 9
0, //10 0, ///< 10
0, //11, 0, ///< 11,
(1 << TRACKDIR_X_NE), //12 (1 << TRACKDIR_X_NE), ///< 12
0, //13 0, ///< 13
0, //14 0, ///< 14
}; };
static uint DistanceMoo(TileIndex t0, TileIndex t1) static uint DistanceMoo(TileIndex t0, TileIndex t1)
@ -660,27 +662,27 @@ static uint DistanceMoo(TileIndex t0, TileIndex t1)
const uint dx = delta(TileX(t0), TileX(t1)); const uint dx = delta(TileX(t0), TileX(t1));
const uint dy = delta(TileY(t0), TileY(t1)); const uint dy = delta(TileY(t0), TileY(t1));
const uint straightTracks = 2 * min(dx, dy); /* The number of straight (not full length) tracks */ const uint straightTracks = 2 * min(dx, dy); // The number of straight (not full length) tracks
/* OPTIMISATION: /* OPTIMISATION:
* Original: diagTracks = max(dx, dy) - min(dx,dy); * Original: diagTracks = max(dx, dy) - min(dx,dy);
* Proof: * Proof:
* (dx-dy) - straightTracks == (min + max) - straightTracks = min + // max - 2 * min = max - min */ * (dx-dy) - straightTracks == (min + max) - straightTracks = min + // max - 2 * min = max - min */
const uint diagTracks = dx + dy - straightTracks; /* The number of diagonal (full tile length) tracks. */ const uint diagTracks = dx + dy - straightTracks; // The number of diagonal (full tile length) tracks.
return diagTracks*DIAG_FACTOR + straightTracks*STR_FACTOR; return diagTracks*DIAG_FACTOR + straightTracks*STR_FACTOR;
} }
// These has to be small cause the max length of a track /* These has to be small cause the max length of a track
// is currently limited to 16384 * is currently limited to 16384 */
static const byte _length_of_track[16] = { static const byte _length_of_track[16] = {
DIAG_FACTOR, DIAG_FACTOR, STR_FACTOR, STR_FACTOR, STR_FACTOR, STR_FACTOR, 0, 0, DIAG_FACTOR, DIAG_FACTOR, STR_FACTOR, STR_FACTOR, STR_FACTOR, STR_FACTOR, 0, 0,
DIAG_FACTOR, DIAG_FACTOR, STR_FACTOR, STR_FACTOR, STR_FACTOR, STR_FACTOR, 0, 0 DIAG_FACTOR, DIAG_FACTOR, STR_FACTOR, STR_FACTOR, STR_FACTOR, STR_FACTOR, 0, 0
}; };
// new more optimized pathfinder for trains... /* new more optimized pathfinder for trains...
// Tile is the tile the train is at. * Tile is the tile the train is at.
// direction is the tile the train is moving towards. * direction is the tile the train is moving towards. */
static void NTPEnum(NewTrackPathFinder* tpf, TileIndex tile, DiagDirection direction) static void NTPEnum(NewTrackPathFinder* tpf, TileIndex tile, DiagDirection direction)
{ {
@ -692,8 +694,8 @@ static void NTPEnum(NewTrackPathFinder* tpf, TileIndex tile, DiagDirection direc
// Need to have a special case for the start. /* Need to have a special case for the start.
// We shouldn't call the callback for the current tile. * We shouldn't call the callback for the current tile. */
si.cur_length = 1; // Need to start at 1 cause 0 is a reserved value. si.cur_length = 1; // Need to start at 1 cause 0 is a reserved value.
si.depth = 0; si.depth = 0;
si.state = 0; si.state = 0;
@ -701,7 +703,7 @@ static void NTPEnum(NewTrackPathFinder* tpf, TileIndex tile, DiagDirection direc
goto start_at; goto start_at;
for (;;) { for (;;) {
// Get the next item to search from from the priority queue /* Get the next item to search from from the priority queue */
do { do {
if (tpf->nstack == 0) if (tpf->nstack == 0)
return; // nothing left? then we're done! return; // nothing left? then we're done!
@ -709,10 +711,10 @@ static void NTPEnum(NewTrackPathFinder* tpf, TileIndex tile, DiagDirection direc
tile = si.tile; tile = si.tile;
HeapifyDown(tpf); HeapifyDown(tpf);
// Make sure we havn't already visited this tile. /* Make sure we havn't already visited this tile. */
} while (!NtpCheck(tpf, tile, _tpf_prev_direction[si.track], si.cur_length)); } while (!NtpCheck(tpf, tile, _tpf_prev_direction[si.track], si.cur_length));
// Add the length of this track. /* Add the length of this track. */
si.cur_length += _length_of_track[si.track]; si.cur_length += _length_of_track[si.track];
callback_and_continue: callback_and_continue:
@ -723,8 +725,8 @@ callback_and_continue:
direction = _tpf_new_direction[si.track]; direction = _tpf_new_direction[si.track];
start_at: start_at:
// If the tile is the entry tile of a tunnel, and we're not going out of the tunnel, /* If the tile is the entry tile of a tunnel, and we're not going out of the tunnel,
// need to find the exit of the tunnel. * need to find the exit of the tunnel. */
if (IsTileType(tile, MP_TUNNELBRIDGE)) { if (IsTileType(tile, MP_TUNNELBRIDGE)) {
if (IsTunnel(tile)) { if (IsTunnel(tile)) {
if (GetTunnelDirection(tile) != ReverseDiagDir(direction)) { if (GetTunnelDirection(tile) != ReverseDiagDir(direction)) {
@ -733,7 +735,7 @@ start_at:
/* We are not just driving out of the tunnel */ /* We are not just driving out of the tunnel */
if (GetTunnelDirection(tile) != direction || if (GetTunnelDirection(tile) != direction ||
GetTunnelTransportType(tile) != tpf->tracktype) { GetTunnelTransportType(tile) != tpf->tracktype) {
// We are not driving into the tunnel, or it is an invalid tunnel /* We are not driving into the tunnel, or it is an invalid tunnel */
continue; continue;
} }
if (!HASBIT(tpf->railtypes, GetRailType(tile))) { if (!HASBIT(tpf->railtypes, GetRailType(tile))) {
@ -743,15 +745,15 @@ start_at:
flotr = FindLengthOfTunnel(tile, direction); flotr = FindLengthOfTunnel(tile, direction);
si.cur_length += flotr.length * DIAG_FACTOR; si.cur_length += flotr.length * DIAG_FACTOR;
tile = flotr.tile; tile = flotr.tile;
// tile now points to the exit tile of the tunnel /* tile now points to the exit tile of the tunnel */
} }
} else { } else {
TileIndex tile_end; TileIndex tile_end;
if (GetBridgeRampDirection(tile) != ReverseDiagDir(direction)) { if (GetBridgeRampDirection(tile) != ReverseDiagDir(direction)) {
// We are not just leaving the bridge /* We are not just leaving the bridge */
if (GetBridgeRampDirection(tile) != direction || if (GetBridgeRampDirection(tile) != direction ||
GetBridgeTransportType(tile) != tpf->tracktype) { GetBridgeTransportType(tile) != tpf->tracktype) {
// Not entering the bridge or not compatible /* Not entering the bridge or not compatible */
continue; continue;
} }
} }
@ -761,29 +763,29 @@ start_at:
} }
} }
// This is a special loop used to go through /* This is a special loop used to go through
// a rail net and find the first intersection * a rail net and find the first intersection */
tile_org = tile; tile_org = tile;
for (;;) { for (;;) {
assert(direction <= 3); assert(direction <= 3);
tile += TileOffsByDiagDir(direction); tile += TileOffsByDiagDir(direction);
// too long search length? bail out. /* too long search length? bail out. */
if (si.cur_length >= tpf->maxlength) { if (si.cur_length >= tpf->maxlength) {
DEBUG(ntp, 1, "Cur_length too big"); DEBUG(ntp, 1, "Cur_length too big");
bits = TRACK_BIT_NONE; bits = TRACK_BIT_NONE;
break; break;
} }
// Not a regular rail tile? /* Not a regular rail tile?
// Then we can't use the code below, but revert to more general code. * Then we can't use the code below, but revert to more general code. */
if (!IsTileType(tile, MP_RAILWAY) || !IsPlainRailTile(tile)) { if (!IsTileType(tile, MP_RAILWAY) || !IsPlainRailTile(tile)) {
// We found a tile which is not a normal railway tile. /* We found a tile which is not a normal railway tile.
// Determine which tracks that exist on this tile. * Determine which tracks that exist on this tile. */
uint32 ts = GetTileTrackStatus(tile, TRANSPORT_RAIL) & _tpfmode1_and[direction]; uint32 ts = GetTileTrackStatus(tile, TRANSPORT_RAIL) & _tpfmode1_and[direction];
bits = TrackdirBitsToTrackBits((TrackdirBits)(ts & TRACKDIR_BIT_MASK)); bits = TrackdirBitsToTrackBits((TrackdirBits)(ts & TRACKDIR_BIT_MASK));
// Check that the tile contains exactly one track /* Check that the tile contains exactly one track */
if (bits == 0 || KILL_FIRST_BIT(bits) != 0) break; if (bits == 0 || KILL_FIRST_BIT(bits) != 0) break;
if (!HASBIT(tpf->railtypes, GetRailType(tile))) { if (!HASBIT(tpf->railtypes, GetRailType(tile))) {
@ -791,12 +793,12 @@ start_at:
break; break;
} }
/////////////////// /*******************
// If we reach here, the tile has exactly one track. * If we reach here, the tile has exactly one track.
// tile - index to a tile that is not rail tile, but still straight (with optional signals) * tile - index to a tile that is not rail tile, but still straight (with optional signals)
// bits - bitmask of which track that exist on the tile (exactly one bit is set) * bits - bitmask of which track that exist on the tile (exactly one bit is set)
// direction - which direction are we moving in? * direction - which direction are we moving in?
/////////////////// *******************/
si.track = _new_trackdir[FIND_FIRST_BIT(bits)][direction]; si.track = _new_trackdir[FIND_FIRST_BIT(bits)][direction];
si.cur_length += _length_of_track[si.track]; si.cur_length += _length_of_track[si.track];
goto callback_and_continue; goto callback_and_continue;
@ -825,89 +827,89 @@ start_at:
si.cur_length += _length_of_track[track]; si.cur_length += _length_of_track[track];
// Check if this rail is an upwards slope. If it is, then add a penalty. /* Check if this rail is an upwards slope. If it is, then add a penalty.
// Small optimization here.. if (track&7)>1 then it can't be a slope so we avoid calling GetTileSlope * Small optimization here.. if (track&7)>1 then it can't be a slope so we avoid calling GetTileSlope */
if ((track & 7) <= 1 && (_is_upwards_slope[GetTileSlope(tile, NULL)] & (1 << track)) ) { if ((track & 7) <= 1 && (_is_upwards_slope[GetTileSlope(tile, NULL)] & (1 << track)) ) {
// upwards slope. add some penalty. // upwards slope. add some penalty.
si.cur_length += 4*DIAG_FACTOR; si.cur_length += 4 * DIAG_FACTOR;
} }
// railway tile with signals..? /* railway tile with signals..? */
if (HasSignals(tile)) { if (HasSignals(tile)) {
if (!HasSignalOnTrackdir(tile, track)) { if (!HasSignalOnTrackdir(tile, track)) {
// if one way signal not pointing towards us, stop going in this direction => End of rail segment. /* if one way signal not pointing towards us, stop going in this direction => End of rail segment. */
if (HasSignalOnTrackdir(tile, ReverseTrackdir(track))) { if (HasSignalOnTrackdir(tile, ReverseTrackdir(track))) {
bits = TRACK_BIT_NONE; bits = TRACK_BIT_NONE;
break; break;
} }
} else if (GetSignalStateByTrackdir(tile, track) == SIGNAL_STATE_GREEN) { } else if (GetSignalStateByTrackdir(tile, track) == SIGNAL_STATE_GREEN) {
// green signal in our direction. either one way or two way. /* green signal in our direction. either one way or two way. */
si.state |= 3; si.state |= 3;
} else { } else {
// reached a red signal. /* reached a red signal. */
if (HasSignalOnTrackdir(tile, ReverseTrackdir(track))) { if (HasSignalOnTrackdir(tile, ReverseTrackdir(track))) {
// two way red signal. unless we passed another green signal on the way, /* two way red signal. unless we passed another green signal on the way,
// stop going in this direction => End of rail segment. * stop going in this direction => End of rail segment.
// this is to prevent us from going into a full platform. * this is to prevent us from going into a full platform. */
if (!(si.state&1)) { if (!(si.state & 1)) {
bits = TRACK_BIT_NONE; bits = TRACK_BIT_NONE;
break; break;
} }
} }
if (!(si.state & 2)) { if (!(si.state & 2)) {
// Is this the first signal we see? And it's red... add penalty /* Is this the first signal we see? And it's red... add penalty */
si.cur_length += 10*DIAG_FACTOR; si.cur_length += 10 * DIAG_FACTOR;
si.state += 2; // remember that we added penalty. si.state += 2; // remember that we added penalty.
// Because we added a penalty, we can't just continue as usual. /* Because we added a penalty, we can't just continue as usual.
// Need to get out and let A* do it's job with * Need to get out and let A* do it's job with
// possibly finding an even shorter path. * possibly finding an even shorter path. */
break; break;
} }
} }
if (tpf->enum_proc(tile, tpf->userdata, si.first_track, si.cur_length)) if (tpf->enum_proc(tile, tpf->userdata, si.first_track, si.cur_length))
return; /* Don't process this tile any further */ return; // Don't process this tile any further
} }
// continue with the next track /* continue with the next track */
direction = _tpf_new_direction[track]; direction = _tpf_new_direction[track];
// safety check if we're running around chasing our tail... (infinite loop) /* safety check if we're running around chasing our tail... (infinite loop) */
if (tile == tile_org) { if (tile == tile_org) {
bits = TRACK_BIT_NONE; bits = TRACK_BIT_NONE;
break; break;
} }
} }
// There are no tracks to choose between. /* There are no tracks to choose between.
// Stop searching in this direction * Stop searching in this direction */
if (bits == TRACK_BIT_NONE) if (bits == TRACK_BIT_NONE)
continue; continue;
//////////////// /****************
// We got multiple tracks to choose between (intersection). * We got multiple tracks to choose between (intersection).
// Branch the search space into several branches. * Branch the search space into several branches.
//////////////// ****************/
// Check if we've already visited this intersection. /* Check if we've already visited this intersection.
// If we've already visited it with a better length, then * If we've already visited it with a better length, then
// there's no point in visiting it again. * there's no point in visiting it again. */
if (!NtpVisit(tpf, tile, direction, si.cur_length)) if (!NtpVisit(tpf, tile, direction, si.cur_length))
continue; continue;
// Push all possible alternatives that we can reach from here /* Push all possible alternatives that we can reach from here
// onto the priority heap. * onto the priority heap.
// 'bits' contains the tracks that we can choose between. * 'bits' contains the tracks that we can choose between. */
// First compute the estimated distance to the target. /* First compute the estimated distance to the target.
// This is used to implement A* * This is used to implement A* */
estimation = 0; estimation = 0;
if (tpf->dest != 0) if (tpf->dest != 0)
estimation = DistanceMoo(tile, tpf->dest); estimation = DistanceMoo(tile, tpf->dest);
si.depth++; si.depth++;
if (si.depth == 0) if (si.depth == 0)
continue; /* We overflowed our depth. No more searching in this direction. */ continue; // We overflowed our depth. No more searching in this direction.
si.tile = tile; si.tile = tile;
while (bits != TRACK_BIT_NONE) { while (bits != TRACK_BIT_NONE) {
Track track = RemoveFirstTrack(&bits); Track track = RemoveFirstTrack(&bits);
@ -915,7 +917,7 @@ start_at:
assert(si.track != 0xFF); assert(si.track != 0xFF);
si.priority = si.cur_length + estimation; si.priority = si.cur_length + estimation;
// out of stack items, bail out? /* out of stack items, bail out? */
if (tpf->nstack >= lengthof(tpf->stack)) { if (tpf->nstack >= lengthof(tpf->stack)) {
DEBUG(ntp, 1, "Out of stack"); DEBUG(ntp, 1, "Out of stack");
break; break;
@ -925,9 +927,9 @@ start_at:
HeapifyUp(tpf); HeapifyUp(tpf);
}; };
// If this is the first intersection, we need to fill the first_track member. /* If this is the first intersection, we need to fill the first_track member.
// so the code outside knows which path is better. * so the code outside knows which path is better.
// also randomize the order in which we search through them. * also randomize the order in which we search through them. */
if (si.depth == 1) { if (si.depth == 1) {
assert(tpf->nstack == 1 || tpf->nstack == 2 || tpf->nstack == 3); assert(tpf->nstack == 1 || tpf->nstack == 2 || tpf->nstack == 3);
if (tpf->nstack != 1) { if (tpf->nstack != 1) {
@ -944,12 +946,12 @@ start_at:
} }
} }
// Continue with the next from the queue... /* Continue with the next from the queue... */
} }
} }
// new pathfinder for trains. better and faster. /** new pathfinder for trains. better and faster. */
void NewTrainPathfind(TileIndex tile, TileIndex dest, RailTypeMask railtypes, DiagDirection direction, NTPEnumProc* enum_proc, void* data) void NewTrainPathfind(TileIndex tile, TileIndex dest, RailTypeMask railtypes, DiagDirection direction, NTPEnumProc* enum_proc, void* data)
{ {
NewTrackPathFinder tpf; NewTrackPathFinder tpf;

@ -1,5 +1,7 @@
/* $Id$ */ /* $Id$ */
/** @file pathfind.h */
#ifndef PATHFIND_H #ifndef PATHFIND_H
#define PATHFIND_H #define PATHFIND_H
@ -60,9 +62,9 @@ struct TrackPathFinder {
bool hasbit_13; bool hasbit_13;
uint16 hash_head[0x400]; uint16 hash_head[0x400];
TileIndex hash_tile[0x400]; /* stores the link index when multi link. */ TileIndex hash_tile[0x400]; ///< stores the link index when multi link.
TrackPathFinderLink links[0x400]; /* hopefully, this is enough. */ TrackPathFinderLink links[0x400]; ///< hopefully, this is enough.
}; };
void FollowTrack(TileIndex tile, uint16 flags, DiagDirection direction, TPFEnumProc* enum_proc, TPFAfterProc* after_proc, void* data); void FollowTrack(TileIndex tile, uint16 flags, DiagDirection direction, TPFEnumProc* enum_proc, TPFAfterProc* after_proc, void* data);

@ -1,5 +1,7 @@
/* $Id$ */ /* $Id$ */
/** @file player.h */
#ifndef PLAYER_H #ifndef PLAYER_H
#define PLAYER_H #define PLAYER_H
@ -13,7 +15,7 @@ struct PlayerEconomyEntry {
int32 income; int32 income;
int32 expenses; int32 expenses;
int32 delivered_cargo; int32 delivered_cargo;
int32 performance_history; // player score (scale 0-1000) int32 performance_history; ///< player score (scale 0-1000)
int64 company_value; int64 company_value;
}; };
@ -32,8 +34,8 @@ struct AiBuildRec {
struct PlayerAI { struct PlayerAI {
byte state; byte state;
byte tick; // Used to determine how often to move byte tick; ///< Used to determine how often to move
uint32 state_counter; // Can hold tile index! uint32 state_counter; ///< Can hold tile index!
uint16 timeout_counter; uint16 timeout_counter;
byte state_mode; byte state_mode;
@ -59,7 +61,7 @@ struct PlayerAI {
byte cur_dir_b; byte cur_dir_b;
byte start_dir_b; byte start_dir_b;
Vehicle *cur_veh; /* only used by some states */ Vehicle *cur_veh; ///< only used by some states
AiBuildRec src, dst, mid1, mid2; AiBuildRec src, dst, mid1, mid2;
@ -71,22 +73,22 @@ struct PlayerAI {
}; };
struct Ai_PathFinderInfo { struct Ai_PathFinderInfo {
TileIndex start_tile_tl; // tl = top-left TileIndex start_tile_tl; ///< tl = top-left
TileIndex start_tile_br; // br = bottom-right TileIndex start_tile_br; ///< br = bottom-right
TileIndex end_tile_tl; // tl = top-left TileIndex end_tile_tl; ///< tl = top-left
TileIndex end_tile_br; // br = bottom-right TileIndex end_tile_br; ///< br = bottom-right
byte start_direction; // 0 to 3 or AI_PATHFINDER_NO_DIRECTION byte start_direction; ///< 0 to 3 or AI_PATHFINDER_NO_DIRECTION
byte end_direction; // 0 to 3 or AI_PATHFINDER_NO_DIRECTION byte end_direction; ///< 0 to 3 or AI_PATHFINDER_NO_DIRECTION
TileIndex route[500]; TileIndex route[500];
byte route_extra[500]; // Some extra information about the route like bridge/tunnel byte route_extra[500]; ///< Some extra information about the route like bridge/tunnel
int route_length; int route_length;
int position; // Current position in the build-path, needed to build the path int position; ///< Current position in the build-path, needed to build the path
bool rail_or_road; // true = rail, false = road bool rail_or_road; ///< true = rail, false = road
}; };
// The amount of memory reserved for the AI-special-vehicles /* The amount of memory reserved for the AI-special-vehicles */
#define AI_MAX_SPECIAL_VEHICLES 100 #define AI_MAX_SPECIAL_VEHICLES 100
struct Ai_SpecialVehicle { struct Ai_SpecialVehicle {
@ -99,28 +101,28 @@ struct PlayerAiNew {
uint tick; uint tick;
uint idle; uint idle;
int temp; // A value used in more than one function, but it just temporary int temp; ///< A value used in more than one function, but it just temporary
// The use is pretty simple: with this we can 'think' about stuff ///< The use is pretty simple: with this we can 'think' about stuff
// in more than one tick, and more than one AI. A static will not ///< in more than one tick, and more than one AI. A static will not
// do, because they are not saved. This way, the AI is almost human ;) ///< do, because they are not saved. This way, the AI is almost human ;)
int counter; // For the same reason as temp, we have counter. It can count how int counter; ///< For the same reason as temp, we have counter. It can count how
// long we are trying something, and just abort if it takes too long ///< long we are trying something, and just abort if it takes too long
// Pathfinder stuff /* Pathfinder stuff */
Ai_PathFinderInfo path_info; Ai_PathFinderInfo path_info;
AyStar *pathfinder; AyStar *pathfinder;
// Route stuff /* Route stuff */
CargoID cargo; CargoID cargo;
byte tbt; // train/bus/truck 0/1/2 AI_TRAIN/AI_BUS/AI_TRUCK byte tbt; ///< train/bus/truck 0/1/2 AI_TRAIN/AI_BUS/AI_TRUCK
int new_cost; int new_cost;
byte action; byte action;
int last_id; // here is stored the last id of the searched city/industry int last_id; ///< here is stored the last id of the searched city/industry
Date last_vehiclecheck_date; // Used in CheckVehicle Date last_vehiclecheck_date; // Used in CheckVehicle
Ai_SpecialVehicle special_vehicles[AI_MAX_SPECIAL_VEHICLES]; // Some vehicles have some special flags Ai_SpecialVehicle special_vehicles[AI_MAX_SPECIAL_VEHICLES]; ///< Some vehicles have some special flags
TileIndex from_tile; TileIndex from_tile;
TileIndex to_tile; TileIndex to_tile;
@ -128,19 +130,19 @@ struct PlayerAiNew {
byte from_direction; byte from_direction;
byte to_direction; byte to_direction;
bool from_deliver; // True if this is the station that GIVES cargo bool from_deliver; ///< True if this is the station that GIVES cargo
bool to_deliver; bool to_deliver;
TileIndex depot_tile; TileIndex depot_tile;
DiagDirectionByte depot_direction; DiagDirectionByte depot_direction;
byte amount_veh; // How many vehicles we are going to build in this route byte amount_veh; ///< How many vehicles we are going to build in this route
byte cur_veh; // How many vehicles did we bought? byte cur_veh; ///< How many vehicles did we bought?
VehicleID veh_id; // Used when bought a vehicle VehicleID veh_id; ///< Used when bought a vehicle
VehicleID veh_main_id; // The ID of the first vehicle, for shared copy VehicleID veh_main_id; ///< The ID of the first vehicle, for shared copy
int from_ic; // ic = industry/city. This is the ID of them int from_ic; ///< ic = industry/city. This is the ID of them
byte from_type; // AI_NO_TYPE/AI_CITY/AI_INDUSTRY byte from_type; ///< AI_NO_TYPE/AI_CITY/AI_INDUSTRY
int to_ic; int to_ic;
byte to_type; byte to_type;
@ -160,7 +162,7 @@ struct Player {
int32 player_money; int32 player_money;
int32 current_loan; int32 current_loan;
int64 money64; // internal 64-bit version of the money. the 32-bit field will be clamped to plus minus 2 billion int64 money64; ///< internal 64-bit version of the money. the 32-bit field will be clamped to plus minus 2 billion
byte player_color; byte player_color;
Livery livery[LS_END]; Livery livery[LS_END];
@ -169,7 +171,7 @@ struct Player {
byte block_preview; byte block_preview;
PlayerByte index; PlayerByte index;
uint16 cargo_types; /* which cargo types were transported the last year */ uint16 cargo_types; ///< which cargo types were transported the last year
TileIndex location_of_house; TileIndex location_of_house;
TileIndex last_build_coordinate; TileIndex last_build_coordinate;
@ -180,7 +182,7 @@ struct Player {
byte num_valid_stat_ent; byte num_valid_stat_ent;
byte quarters_of_bankrupcy; byte quarters_of_bankrupcy;
byte bankrupt_asked; // which players were asked about buying it? byte bankrupt_asked; ///< which players were asked about buying it?
int16 bankrupt_timeout; int16 bankrupt_timeout;
int32 bankrupt_value; int32 bankrupt_value;
@ -192,12 +194,12 @@ struct Player {
int64 yearly_expenses[3][13]; int64 yearly_expenses[3][13];
PlayerEconomyEntry cur_economy; PlayerEconomyEntry cur_economy;
PlayerEconomyEntry old_economy[24]; PlayerEconomyEntry old_economy[24];
EngineRenewList engine_renew_list; // Defined later EngineRenewList engine_renew_list; ///< Defined later
bool engine_renew; bool engine_renew;
bool renew_keep_length; bool renew_keep_length;
int16 engine_renew_months; int16 engine_renew_months;
uint32 engine_renew_money; uint32 engine_renew_money;
uint16 num_engines[TOTAL_NUM_ENGINES]; // caches the number of engines of each type the player owns (no need to save this) uint16 num_engines[TOTAL_NUM_ENGINES]; ///< caches the number of engines of each type the player owns (no need to save this)
}; };
uint16 GetDrawStringPlayerColor(PlayerID player); uint16 GetDrawStringPlayerColor(PlayerID player);
@ -214,7 +216,7 @@ VARDEF PlayerID _local_player;
VARDEF PlayerID _current_player; VARDEF PlayerID _current_player;
VARDEF Player _players[MAX_PLAYERS]; VARDEF Player _players[MAX_PLAYERS];
// NOSAVE: can be determined from player structs /* NOSAVE: can be determined from player structs */
VARDEF byte _player_colors[MAX_PLAYERS]; VARDEF byte _player_colors[MAX_PLAYERS];
static inline byte ActivePlayerCount() static inline byte ActivePlayerCount()
@ -284,8 +286,8 @@ static inline RailType GetBestRailtype(const Player* p)
struct HighScore { struct HighScore {
char company[100]; char company[100];
StringID title; // NO_SAVE, has troubles with changing string-numbers. StringID title; ///< NO_SAVE, has troubles with changing string-numbers.
uint16 score; // do NOT change type, will break hs.dat uint16 score; ///< do NOT change type, will break hs.dat
}; };
VARDEF HighScore _highscore_table[5][5]; // 4 difficulty-settings (+ network); top 5 VARDEF HighScore _highscore_table[5][5]; // 4 difficulty-settings (+ network); top 5

@ -1,5 +1,7 @@
/* $Id$ */ /* $Id$ */
/** @file player_gui.cpp */
#include "stdafx.h" #include "stdafx.h"
#include "openttd.h" #include "openttd.h"
#include "table/sprites.h" #include "table/sprites.h"
@ -76,7 +78,7 @@ static void DrawPlayerEconomyStats(const Player *p, byte mode)
y = 171; y = 171;
// draw max loan aligned to loan below (y += 10) /* draw max loan aligned to loan below (y += 10) */
SetDParam64(0, (uint64)_economy.max_loan); SetDParam64(0, (uint64)_economy.max_loan);
DrawString(202, y+10, STR_MAX_LOAN, 0); DrawString(202, y+10, STR_MAX_LOAN, 0);
} else { } else {
@ -404,12 +406,12 @@ static void SelectPlayerLiveryWndProc(Window *w, WindowEvent *e)
} }
case 9: case 9:
case 10: // First colour dropdown case 10: /* First colour dropdown */
ShowColourDropDownMenu(w, 10); ShowColourDropDownMenu(w, 10);
break; break;
case 11: case 11:
case 12: // Second colour dropdown case 12: /* Second colour dropdown */
ShowColourDropDownMenu(w, 12); ShowColourDropDownMenu(w, 12);
break; break;
@ -761,7 +763,7 @@ static void PlayerCompanyWndProc(Window *w, WindowEvent *e)
DrawPlayerVehiclesAmount((PlayerID)w->window_number); DrawPlayerVehiclesAmount((PlayerID)w->window_number);
DrawString(110,48, STR_7006_COLOR_SCHEME, 0); DrawString(110,48, STR_7006_COLOR_SCHEME, 0);
// Draw company-colour bus /* Draw company-colour bus */
DrawSprite(SPR_VEH_BUS_SW_VIEW, PLAYER_SPRITE_COLOR(p->index), 215, 49); DrawSprite(SPR_VEH_BUS_SW_VIEW, PLAYER_SPRITE_COLOR(p->index), 215, 49);
DrawPlayerFace(p->face, p->player_color, 2, 16); DrawPlayerFace(p->face, p->player_color, 2, 16);
@ -882,7 +884,7 @@ static void PlayerCompanyWndProc(Window *w, WindowEvent *e)
case WE_ON_EDIT_TEXT: { case WE_ON_EDIT_TEXT: {
char *b = e->we.edittext.str; char *b = e->we.edittext.str;
// empty string is allowed for password /* empty string is allowed for password */
if (*b == '\0' && WP(w,def_d).byte_1 != 2) return; if (*b == '\0' && WP(w,def_d).byte_1 != 2) return;
_cmd_text = b; _cmd_text = b;
@ -987,7 +989,7 @@ void ShowBuyCompanyDialog(uint player)
static void SetupHighScoreEndWindow(Window *w, uint *x, uint *y) static void SetupHighScoreEndWindow(Window *w, uint *x, uint *y)
{ {
uint i; uint i;
// resize window to "full-screen" /* resize window to "full-screen" */
w->width = _screen.width; w->width = _screen.width;
w->height = _screen.height; w->height = _screen.height;
w->widget[0].right = w->width - 1; w->widget[0].right = w->width - 1;
@ -1004,7 +1006,7 @@ static void SetupHighScoreEndWindow(Window *w, uint *x, uint *y)
extern StringID EndGameGetPerformanceTitleFromValue(uint value); extern StringID EndGameGetPerformanceTitleFromValue(uint value);
/* End game window shown at the end of the game */ /** End game window shown at the end of the game */
static void EndGameWndProc(Window *w, WindowEvent *e) static void EndGameWndProc(Window *w, WindowEvent *e)
{ {
switch (e->event) { switch (e->event) {
@ -1106,14 +1108,14 @@ static const WindowDesc _endgame_desc = {
EndGameWndProc EndGameWndProc
}; };
/* Show the highscore table for a given difficulty. When called from /** Show the highscore table for a given difficulty. When called from
* endgame ranking is set to the top5 element that was newly added * endgame ranking is set to the top5 element that was newly added
* and is thus highlighted */ * and is thus highlighted */
void ShowHighscoreTable(int difficulty, int8 ranking) void ShowHighscoreTable(int difficulty, int8 ranking)
{ {
Window *w; Window *w;
// pause game to show the chart /* pause game to show the chart */
if (!_networking) DoCommandP(0, 1, 0, NULL, CMD_PAUSE); if (!_networking) DoCommandP(0, 1, 0, NULL, CMD_PAUSE);
/* Close all always on-top windows to get a clean screen */ /* Close all always on-top windows to get a clean screen */
@ -1130,7 +1132,7 @@ void ShowHighscoreTable(int difficulty, int8 ranking)
} }
} }
/* Show the endgame victory screen in 2050. Update the new highscore /** Show the endgame victory screen in 2050. Update the new highscore
* if it was high enough */ * if it was high enough */
void ShowEndGameChart() void ShowEndGameChart()
{ {
@ -1162,7 +1164,7 @@ void ShowEndGameChart()
w->window_number = lengthof(_highscore_table) - 1; w->window_number = lengthof(_highscore_table) - 1;
WP(w, highscore_d).rank = SaveHighScoreValueNetwork(); WP(w, highscore_d).rank = SaveHighScoreValueNetwork();
} else { } else {
// in single player _local player is always valid /* in single player _local player is always valid */
const Player *p = GetPlayer(_local_player); const Player *p = GetPlayer(_local_player);
w->window_number = _opt.diff_level; w->window_number = _opt.diff_level;
WP(w, highscore_d).rank = SaveHighScoreValue(p); WP(w, highscore_d).rank = SaveHighScoreValue(p);

@ -219,7 +219,7 @@ void SubtractMoneyFromPlayerFract(PlayerID player, int32 cost)
if (cost != 0) SubtractMoneyFromAnyPlayer(p, cost); if (cost != 0) SubtractMoneyFromAnyPlayer(p, cost);
} }
// the player_money field is kept as it is, but money64 contains the actual amount of money. /** the player_money field is kept as it is, but money64 contains the actual amount of money. */
void UpdatePlayerMoney32(Player *p) void UpdatePlayerMoney32(Player *p)
{ {
if (p->money64 < -2000000000) { if (p->money64 < -2000000000) {
@ -272,7 +272,7 @@ bool CheckTileOwnership(TileIndex tile)
if (owner == _current_player) return true; if (owner == _current_player) return true;
_error_message = STR_013B_OWNED_BY; _error_message = STR_013B_OWNED_BY;
// no need to get the name of the owner unless we're the local player (saves some time) /* no need to get the name of the owner unless we're the local player (saves some time) */
if (IsLocalPlayer()) GetNameOfOwner(owner, tile); if (IsLocalPlayer()) GetNameOfOwner(owner, tile);
return false; return false;
} }
@ -298,7 +298,7 @@ static void GenerateCompanyName(Player *p)
strp = t->townnameparts; strp = t->townnameparts;
verify_name:; verify_name:;
// No player must have this name already /* No player must have this name already */
FOR_ALL_PLAYERS(pp) { FOR_ALL_PLAYERS(pp) {
if (pp->name_1 == str && pp->name_2 == strp) goto bad_town_name; if (pp->name_1 == str && pp->name_2 == strp) goto bad_town_name;
} }
@ -345,17 +345,17 @@ static byte GeneratePlayerColor()
uint32 r; uint32 r;
Player *p; Player *p;
// Initialize array /* Initialize array */
for (i = 0; i != 16; i++) colors[i] = i; for (i = 0; i != 16; i++) colors[i] = i;
// And randomize it /* And randomize it */
n = 100; n = 100;
do { do {
r = Random(); r = Random();
COLOR_SWAP(GB(r, 0, 4), GB(r, 4, 4)); COLOR_SWAP(GB(r, 0, 4), GB(r, 4, 4));
} while (--n); } while (--n);
// Bubble sort it according to the values in table 1 /* Bubble sort it according to the values in table 1 */
i = 16; i = 16;
do { do {
for (j = 0; j != 15; j++) { for (j = 0; j != 15; j++) {
@ -365,7 +365,7 @@ static byte GeneratePlayerColor()
} }
} while (--i); } while (--i);
// Move the colors that look similar to each player's color to the side /* Move the colors that look similar to each player's color to the side */
FOR_ALL_PLAYERS(p) if (p->is_active) { FOR_ALL_PLAYERS(p) if (p->is_active) {
pcolor = p->player_color; pcolor = p->player_color;
for (i=0; i!=16; i++) if (colors[i] == pcolor) { for (i=0; i!=16; i++) if (colors[i] == pcolor) {
@ -392,7 +392,7 @@ static byte GeneratePlayerColor()
} }
} }
// Return the first available color /* Return the first available color */
for (i = 0;; i++) { for (i = 0;; i++) {
if (colors[i] != 0xFF) return colors[i]; if (colors[i] != 0xFF) return colors[i];
} }
@ -429,7 +429,7 @@ restart:;
static Player *AllocatePlayer() static Player *AllocatePlayer()
{ {
Player *p; Player *p;
// Find a free slot /* Find a free slot */
FOR_ALL_PLAYERS(p) { FOR_ALL_PLAYERS(p) {
if (!p->is_active) { if (!p->is_active) {
PlayerID i = p->index; PlayerID i = p->index;
@ -457,7 +457,7 @@ Player *DoStartupNewPlayer(bool is_ai)
p = AllocatePlayer(); p = AllocatePlayer();
if (p == NULL) return NULL; if (p == NULL) return NULL;
// Make a color /* Make a color */
p->player_color = GeneratePlayerColor(); p->player_color = GeneratePlayerColor();
ResetPlayerLivery(p); ResetPlayerLivery(p);
_player_colors[p->index] = p->player_color; _player_colors[p->index] = p->player_color;
@ -467,7 +467,7 @@ Player *DoStartupNewPlayer(bool is_ai)
p->money64 = p->player_money = p->current_loan = 100000; p->money64 = p->player_money = p->current_loan = 100000;
p->is_ai = is_ai; p->is_ai = is_ai;
p->ai.state = 5; /* AIS_WANT_NEW_ROUTE */ p->ai.state = 5; // AIS_WANT_NEW_ROUTE
p->share_owners[0] = p->share_owners[1] = p->share_owners[2] = p->share_owners[3] = PLAYER_SPECTATOR; p->share_owners[0] = p->share_owners[1] = p->share_owners[2] = p->share_owners[3] = PLAYER_SPECTATOR;
p->avail_railtypes = GetPlayerRailtypes(p->index); p->avail_railtypes = GetPlayerRailtypes(p->index);
@ -497,7 +497,7 @@ Player *DoStartupNewPlayer(bool is_ai)
void StartupPlayers() void StartupPlayers()
{ {
// The AI starts like in the setting with +2 month max /* The AI starts like in the setting with +2 month max */
_next_competitor_start = _opt.diff.competitor_start_time * 90 * DAY_TICKS + RandomRange(60 * DAY_TICKS) + 1; _next_competitor_start = _opt.diff.competitor_start_time * 90 * DAY_TICKS + RandomRange(60 * DAY_TICKS) + 1;
} }
@ -506,13 +506,13 @@ static void MaybeStartNewPlayer()
uint n; uint n;
Player *p; Player *p;
// count number of competitors /* count number of competitors */
n = 0; n = 0;
FOR_ALL_PLAYERS(p) { FOR_ALL_PLAYERS(p) {
if (p->is_active && p->is_ai) n++; if (p->is_active && p->is_ai) n++;
} }
// when there's a lot of computers in game, the probability that a new one starts is lower /* when there's a lot of computers in game, the probability that a new one starts is lower */
if (n < (uint)_opt.diff.max_no_competitors && if (n < (uint)_opt.diff.max_no_competitors &&
n < (_network_server ? n < (_network_server ?
InteractiveRandomRange(_opt.diff.max_no_competitors + 2) : InteractiveRandomRange(_opt.diff.max_no_competitors + 2) :
@ -523,7 +523,7 @@ static void MaybeStartNewPlayer()
DoCommandP(0, 1, 0, NULL, CMD_PLAYER_CTRL); DoCommandP(0, 1, 0, NULL, CMD_PLAYER_CTRL);
} }
// The next AI starts like the difficulty setting said, with +2 month max /* The next AI starts like the difficulty setting said, with +2 month max */
_next_competitor_start = _opt.diff.competitor_start_time * 90 * DAY_TICKS + 1; _next_competitor_start = _opt.diff.competitor_start_time * 90 * DAY_TICKS + 1;
_next_competitor_start += _network_server ? InteractiveRandomRange(60 * DAY_TICKS) : RandomRange(60 * DAY_TICKS); _next_competitor_start += _network_server ? InteractiveRandomRange(60 * DAY_TICKS) : RandomRange(60 * DAY_TICKS);
} }
@ -549,7 +549,7 @@ void OnTick_Players()
MaybeStartNewPlayer(); MaybeStartNewPlayer();
} }
// index is the next parameter in _decode_parameters to set up /** index is the next parameter in _decode_parameters to set up */
StringID GetPlayerNameString(PlayerID player, uint index) StringID GetPlayerNameString(PlayerID player, uint index)
{ {
if (IsHumanPlayer(player) && IsValidPlayer(player)) { if (IsHumanPlayer(player) && IsValidPlayer(player)) {
@ -565,7 +565,7 @@ void PlayersYearlyLoop()
{ {
Player *p; Player *p;
// Copy statistics /* Copy statistics */
FOR_ALL_PLAYERS(p) { FOR_ALL_PLAYERS(p) {
if (p->is_active) { if (p->is_active) {
memmove(&p->yearly_expenses[1], &p->yearly_expenses[0], sizeof(p->yearly_expenses) - sizeof(p->yearly_expenses[0])); memmove(&p->yearly_expenses[1], &p->yearly_expenses[0], sizeof(p->yearly_expenses) - sizeof(p->yearly_expenses[0]));
@ -700,16 +700,16 @@ int32 CmdSetAutoReplace(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
if (!IsEngineIndex(new_engine_type)) if (!IsEngineIndex(new_engine_type))
return CMD_ERROR; return CMD_ERROR;
// check that the new vehicle type is the same as the original one /* check that the new vehicle type is the same as the original one */
if (GetEngine(old_engine_type)->type != GetEngine(new_engine_type)->type) if (GetEngine(old_engine_type)->type != GetEngine(new_engine_type)->type)
return CMD_ERROR; return CMD_ERROR;
// make sure that we do not replace a plane with a helicopter or vise versa /* make sure that we do not replace a plane with a helicopter or vise versa */
if (GetEngine(new_engine_type)->type == VEH_AIRCRAFT && if (GetEngine(new_engine_type)->type == VEH_AIRCRAFT &&
(AircraftVehInfo(old_engine_type)->subtype & AIR_CTOL) != (AircraftVehInfo(new_engine_type)->subtype & AIR_CTOL)) (AircraftVehInfo(old_engine_type)->subtype & AIR_CTOL) != (AircraftVehInfo(new_engine_type)->subtype & AIR_CTOL))
return CMD_ERROR; return CMD_ERROR;
// make sure that the player can actually buy the new engine /* make sure that the player can actually buy the new engine */
if (!HASBIT(GetEngine(new_engine_type)->player_avail, _current_player)) if (!HASBIT(GetEngine(new_engine_type)->player_avail, _current_player))
return CMD_ERROR; return CMD_ERROR;
@ -946,7 +946,7 @@ StringID EndGameGetPerformanceTitleFromValue(uint value)
return _endgame_perf_titles[value]; return _endgame_perf_titles[value];
} }
/* Return true if any cheat has been used, false otherwise */ /** Return true if any cheat has been used, false otherwise */
static bool CheatHasBeenUsed() static bool CheatHasBeenUsed()
{ {
const Cheat* cht = (Cheat*)&_cheats; const Cheat* cht = (Cheat*)&_cheats;
@ -959,7 +959,7 @@ static bool CheatHasBeenUsed()
return false; return false;
} }
/* Save the highscore for the player */ /** Save the highscore for the player */
int8 SaveHighScoreValue(const Player *p) int8 SaveHighScoreValue(const Player *p)
{ {
HighScore *hs = _highscore_table[_opt.diff_level]; HighScore *hs = _highscore_table[_opt.diff_level];
@ -972,7 +972,7 @@ int8 SaveHighScoreValue(const Player *p)
for (i = 0; i < lengthof(_highscore_table[0]); i++) { for (i = 0; i < lengthof(_highscore_table[0]); i++) {
/* You are in the TOP5. Move all values one down and save us there */ /* You are in the TOP5. Move all values one down and save us there */
if (hs[i].score <= score) { if (hs[i].score <= score) {
// move all elements one down starting from the replaced one /* move all elements one down starting from the replaced one */
memmove(&hs[i + 1], &hs[i], sizeof(HighScore) * (lengthof(_highscore_table[0]) - i - 1)); memmove(&hs[i + 1], &hs[i], sizeof(HighScore) * (lengthof(_highscore_table[0]) - i - 1));
SetDParam(0, p->president_name_1); SetDParam(0, p->president_name_1);
SetDParam(1, p->president_name_2); SetDParam(1, p->president_name_2);
@ -988,7 +988,7 @@ int8 SaveHighScoreValue(const Player *p)
return -1; // too bad; we did not make it into the top5 return -1; // too bad; we did not make it into the top5
} }
/* Sort all players given their performance */ /** Sort all players given their performance */
static int CDECL HighScoreSorter(const void *a, const void *b) static int CDECL HighScoreSorter(const void *a, const void *b)
{ {
const Player *pa = *(const Player* const*)a; const Player *pa = *(const Player* const*)a;
@ -1027,7 +1027,7 @@ int8 SaveHighScoreValueNetwork()
hs->score = pl[i]->old_economy[0].performance_history; hs->score = pl[i]->old_economy[0].performance_history;
hs->title = EndGameGetPerformanceTitleFromValue(hs->score); hs->title = EndGameGetPerformanceTitleFromValue(hs->score);
// get the ranking of the local player /* get the ranking of the local player */
if (pl[i]->index == _local_player) player = i; if (pl[i]->index == _local_player) player = i;
} }
} }
@ -1036,7 +1036,7 @@ int8 SaveHighScoreValueNetwork()
return player; return player;
} }
/* Save HighScore table to file */ /** Save HighScore table to file */
void SaveToHighScore() void SaveToHighScore()
{ {
FILE *fp = fopen(_highscore_file, "wb"); FILE *fp = fopen(_highscore_file, "wb");
@ -1053,14 +1053,14 @@ void SaveToHighScore()
fwrite(&length, sizeof(length), 1, fp); // write away string length fwrite(&length, sizeof(length), 1, fp); // write away string length
fwrite(hs->company, length, 1, fp); fwrite(hs->company, length, 1, fp);
fwrite(&hs->score, sizeof(hs->score), 1, fp); fwrite(&hs->score, sizeof(hs->score), 1, fp);
fwrite("", 2, 1, fp); /* XXX - placeholder for hs->title, not saved anymore; compatibility */ fwrite("", 2, 1, fp); // XXX - placeholder for hs->title, not saved anymore; compatibility
} }
} }
fclose(fp); fclose(fp);
} }
} }
/* Initialize the highscore table to 0 and if any file exists, load in values */ /** Initialize the highscore table to 0 and if any file exists, load in values */
void LoadFromHighScore() void LoadFromHighScore()
{ {
FILE *fp = fopen(_highscore_file, "rb"); FILE *fp = fopen(_highscore_file, "rb");
@ -1078,7 +1078,7 @@ void LoadFromHighScore()
fread(hs->company, 1, length, fp); fread(hs->company, 1, length, fp);
fread(&hs->score, sizeof(hs->score), 1, fp); fread(&hs->score, sizeof(hs->score), 1, fp);
fseek(fp, 2, SEEK_CUR); /* XXX - placeholder for hs->title, not saved anymore; compatibility */ fseek(fp, 2, SEEK_CUR); // XXX - placeholder for hs->title, not saved anymore; compatibility
hs->title = EndGameGetPerformanceTitleFromValue(hs->score); hs->title = EndGameGetPerformanceTitleFromValue(hs->score);
} }
} }
@ -1089,7 +1089,7 @@ void LoadFromHighScore()
_patches.ending_year = 2051; _patches.ending_year = 2051;
} }
// Save/load of players /* Save/load of players */
static const SaveLoad _player_desc[] = { static const SaveLoad _player_desc[] = {
SLE_VAR(Player, name_2, SLE_UINT32), SLE_VAR(Player, name_2, SLE_UINT32),
SLE_VAR(Player, name_1, SLE_STRINGID), SLE_VAR(Player, name_1, SLE_STRINGID),
@ -1099,7 +1099,7 @@ static const SaveLoad _player_desc[] = {
SLE_VAR(Player, face, SLE_UINT32), SLE_VAR(Player, face, SLE_UINT32),
// money was changed to a 64 bit field in savegame version 1. /* money was changed to a 64 bit field in savegame version 1. */
SLE_CONDVAR(Player, money64, SLE_VAR_I64 | SLE_FILE_I32, 0, 0), SLE_CONDVAR(Player, money64, SLE_VAR_I64 | SLE_FILE_I32, 0, 0),
SLE_CONDVAR(Player, money64, SLE_INT64, 1, SL_MAX_VERSION), SLE_CONDVAR(Player, money64, SLE_INT64, 1, SL_MAX_VERSION),
@ -1127,14 +1127,14 @@ static const SaveLoad _player_desc[] = {
SLE_VAR(Player, bankrupt_timeout, SLE_INT16), SLE_VAR(Player, bankrupt_timeout, SLE_INT16),
SLE_VAR(Player, bankrupt_value, SLE_INT32), SLE_VAR(Player, bankrupt_value, SLE_INT32),
// yearly expenses was changed to 64-bit in savegame version 2. /* yearly expenses was changed to 64-bit in savegame version 2. */
SLE_CONDARR(Player, yearly_expenses, SLE_FILE_I32 | SLE_VAR_I64, 3 * 13, 0, 1), SLE_CONDARR(Player, yearly_expenses, SLE_FILE_I32 | SLE_VAR_I64, 3 * 13, 0, 1),
SLE_CONDARR(Player, yearly_expenses, SLE_INT64, 3 * 13, 2, SL_MAX_VERSION), SLE_CONDARR(Player, yearly_expenses, SLE_INT64, 3 * 13, 2, SL_MAX_VERSION),
SLE_CONDVAR(Player, is_ai, SLE_BOOL, 2, SL_MAX_VERSION), SLE_CONDVAR(Player, is_ai, SLE_BOOL, 2, SL_MAX_VERSION),
SLE_CONDVAR(Player, is_active, SLE_BOOL, 4, SL_MAX_VERSION), SLE_CONDVAR(Player, is_active, SLE_BOOL, 4, SL_MAX_VERSION),
// Engine renewal settings /* Engine renewal settings */
SLE_CONDNULL(512, 16, 18), SLE_CONDNULL(512, 16, 18),
SLE_CONDREF(Player, engine_renew_list, REF_ENGINE_RENEWS, 19, SL_MAX_VERSION), SLE_CONDREF(Player, engine_renew_list, REF_ENGINE_RENEWS, 19, SL_MAX_VERSION),
SLE_CONDVAR(Player, engine_renew, SLE_BOOL, 16, SL_MAX_VERSION), SLE_CONDVAR(Player, engine_renew, SLE_BOOL, 16, SL_MAX_VERSION),
@ -1142,14 +1142,14 @@ static const SaveLoad _player_desc[] = {
SLE_CONDVAR(Player, engine_renew_money, SLE_UINT32, 16, SL_MAX_VERSION), SLE_CONDVAR(Player, engine_renew_money, SLE_UINT32, 16, SL_MAX_VERSION),
SLE_CONDVAR(Player, renew_keep_length, SLE_BOOL, 2, SL_MAX_VERSION), // added with 16.1, but was blank since 2 SLE_CONDVAR(Player, renew_keep_length, SLE_BOOL, 2, SL_MAX_VERSION), // added with 16.1, but was blank since 2
// reserve extra space in savegame here. (currently 63 bytes) /* reserve extra space in savegame here. (currently 63 bytes) */
SLE_CONDNULL(63, 2, SL_MAX_VERSION), SLE_CONDNULL(63, 2, SL_MAX_VERSION),
SLE_END() SLE_END()
}; };
static const SaveLoad _player_economy_desc[] = { static const SaveLoad _player_economy_desc[] = {
// these were changed to 64-bit in savegame format 2 /* these were changed to 64-bit in savegame format 2 */
SLE_CONDVAR(PlayerEconomyEntry, income, SLE_INT32, 0, 1), SLE_CONDVAR(PlayerEconomyEntry, income, SLE_INT32, 0, 1),
SLE_CONDVAR(PlayerEconomyEntry, expenses, SLE_INT32, 0, 1), SLE_CONDVAR(PlayerEconomyEntry, expenses, SLE_INT32, 0, 1),
SLE_CONDVAR(PlayerEconomyEntry, company_value, SLE_FILE_I32 | SLE_VAR_I64, 0, 1), SLE_CONDVAR(PlayerEconomyEntry, company_value, SLE_FILE_I32 | SLE_VAR_I64, 0, 1),
@ -1236,7 +1236,7 @@ static void SaveLoad_PLYR(Player* p)
SlObject(p, _player_desc); SlObject(p, _player_desc);
// Write AI? /* Write AI? */
if (!IsHumanPlayer(p->index)) { if (!IsHumanPlayer(p->index)) {
SlObject(&p->ai, _player_ai_desc); SlObject(&p->ai, _player_ai_desc);
for (i = 0; i != p->ai.num_build_rec; i++) { for (i = 0; i != p->ai.num_build_rec; i++) {
@ -1244,15 +1244,15 @@ static void SaveLoad_PLYR(Player* p)
} }
} }
// Write economy /* Write economy */
SlObject(&p->cur_economy, _player_economy_desc); SlObject(&p->cur_economy, _player_economy_desc);
// Write old economy entries. /* Write old economy entries. */
for (i = 0; i < p->num_valid_stat_ent; i++) { for (i = 0; i < p->num_valid_stat_ent; i++) {
SlObject(&p->old_economy[i], _player_economy_desc); SlObject(&p->old_economy[i], _player_economy_desc);
} }
// Write each livery entry. /* Write each livery entry. */
for (i = 0; i < LS_END; i++) { for (i = 0; i < LS_END; i++) {
SlObject(&p->livery[i], _player_livery_desc); SlObject(&p->livery[i], _player_livery_desc);
} }

@ -1,5 +1,7 @@
/* $Id$ */ /* $Id$ */
/** @file queue.cpp */
#include "stdafx.h" #include "stdafx.h"
#include "openttd.h" #include "openttd.h"
#include "queue.h" #include "queue.h"
@ -91,10 +93,10 @@ void init_InsSort(Queue* q)
#define BINARY_HEAP_BLOCKSIZE (1 << BINARY_HEAP_BLOCKSIZE_BITS) #define BINARY_HEAP_BLOCKSIZE (1 << BINARY_HEAP_BLOCKSIZE_BITS)
#define BINARY_HEAP_BLOCKSIZE_MASK (BINARY_HEAP_BLOCKSIZE - 1) #define BINARY_HEAP_BLOCKSIZE_MASK (BINARY_HEAP_BLOCKSIZE - 1)
// To make our life easy, we make the next define /* To make our life easy, we make the next define
// Because Binary Heaps works with array from 1 to n, * Because Binary Heaps works with array from 1 to n,
// and C with array from 0 to n-1, and we don't like typing * and C with array from 0 to n-1, and we don't like typing
// q->data.binaryheap.elements[i - 1] every time, we use this define. * q->data.binaryheap.elements[i - 1] every time, we use this define. */
#define BIN_HEAP_ARR(i) q->data.binaryheap.elements[((i) - 1) >> BINARY_HEAP_BLOCKSIZE_BITS][((i) - 1) & BINARY_HEAP_BLOCKSIZE_MASK] #define BIN_HEAP_ARR(i) q->data.binaryheap.elements[((i) - 1) >> BINARY_HEAP_BLOCKSIZE_BITS][((i) - 1) & BINARY_HEAP_BLOCKSIZE_MASK]
static void BinaryHeap_Clear(Queue* q, bool free_values) static void BinaryHeap_Clear(Queue* q, bool free_values)
@ -114,7 +116,7 @@ static void BinaryHeap_Clear(Queue* q, bool free_values)
/* For every element in the block */ /* For every element in the block */
if ((q->data.binaryheap.size >> BINARY_HEAP_BLOCKSIZE_BITS) == i && if ((q->data.binaryheap.size >> BINARY_HEAP_BLOCKSIZE_BITS) == i &&
(q->data.binaryheap.size & BINARY_HEAP_BLOCKSIZE_MASK) == j) { (q->data.binaryheap.size & BINARY_HEAP_BLOCKSIZE_MASK) == j) {
break; /* We're past the last element */ break; // We're past the last element
} }
free(q->data.binaryheap.elements[i][j].item); free(q->data.binaryheap.elements[i][j].item);
} }
@ -160,13 +162,13 @@ static bool BinaryHeap_Push(Queue* q, void* item, int priority)
#endif #endif
} }
// Add the item at the end of the array /* Add the item at the end of the array */
BIN_HEAP_ARR(q->data.binaryheap.size + 1).priority = priority; BIN_HEAP_ARR(q->data.binaryheap.size + 1).priority = priority;
BIN_HEAP_ARR(q->data.binaryheap.size + 1).item = item; BIN_HEAP_ARR(q->data.binaryheap.size + 1).item = item;
q->data.binaryheap.size++; q->data.binaryheap.size++;
// Now we are going to check where it belongs. As long as the parent is /* Now we are going to check where it belongs. As long as the parent is
// bigger, we switch with the parent * bigger, we switch with the parent */
{ {
BinaryHeapNode temp; BinaryHeapNode temp;
int i; int i;
@ -174,16 +176,16 @@ static bool BinaryHeap_Push(Queue* q, void* item, int priority)
i = q->data.binaryheap.size; i = q->data.binaryheap.size;
while (i > 1) { while (i > 1) {
// Get the parent of this object (divide by 2) /* Get the parent of this object (divide by 2) */
j = i / 2; j = i / 2;
// Is the parent bigger then the current, switch them /* Is the parent bigger then the current, switch them */
if (BIN_HEAP_ARR(i).priority <= BIN_HEAP_ARR(j).priority) { if (BIN_HEAP_ARR(i).priority <= BIN_HEAP_ARR(j).priority) {
temp = BIN_HEAP_ARR(j); temp = BIN_HEAP_ARR(j);
BIN_HEAP_ARR(j) = BIN_HEAP_ARR(i); BIN_HEAP_ARR(j) = BIN_HEAP_ARR(i);
BIN_HEAP_ARR(i) = temp; BIN_HEAP_ARR(i) = temp;
i = j; i = j;
} else { } else {
// It is not, we're done! /* It is not, we're done! */
break; break;
} }
} }
@ -200,20 +202,20 @@ static bool BinaryHeap_Delete(Queue* q, void* item, int priority)
printf("[BinaryHeap] Deleting an element. There are %d elements left\n", q->data.binaryheap.size); printf("[BinaryHeap] Deleting an element. There are %d elements left\n", q->data.binaryheap.size);
#endif #endif
// First, we try to find the item.. /* First, we try to find the item.. */
do { do {
if (BIN_HEAP_ARR(i + 1).item == item) break; if (BIN_HEAP_ARR(i + 1).item == item) break;
i++; i++;
} while (i < q->data.binaryheap.size); } while (i < q->data.binaryheap.size);
// We did not find the item, so we return false /* We did not find the item, so we return false */
if (i == q->data.binaryheap.size) return false; if (i == q->data.binaryheap.size) return false;
// Now we put the last item over the current item while decreasing the size of the elements /* Now we put the last item over the current item while decreasing the size of the elements */
q->data.binaryheap.size--; q->data.binaryheap.size--;
BIN_HEAP_ARR(i + 1) = BIN_HEAP_ARR(q->data.binaryheap.size + 1); BIN_HEAP_ARR(i + 1) = BIN_HEAP_ARR(q->data.binaryheap.size + 1);
// Now the only thing we have to do, is resort it.. /* Now the only thing we have to do, is resort it..
// On place i there is the item to be sorted.. let's start there * On place i there is the item to be sorted.. let's start there */
{ {
uint j; uint j;
BinaryHeapNode temp; BinaryHeapNode temp;
@ -224,25 +226,25 @@ static bool BinaryHeap_Delete(Queue* q, void* item, int priority)
for (;;) { for (;;) {
j = i; j = i;
// Check if we have 2 childs /* Check if we have 2 childs */
if (2 * j + 1 <= q->data.binaryheap.size) { if (2 * j + 1 <= q->data.binaryheap.size) {
// Is this child smaller than the parent? /* Is this child smaller than the parent? */
if (BIN_HEAP_ARR(j).priority >= BIN_HEAP_ARR(2 * j).priority) i = 2 * j; if (BIN_HEAP_ARR(j).priority >= BIN_HEAP_ARR(2 * j).priority) i = 2 * j;
// Yes, we _need_ to use i here, not j, because we want to have the smallest child /* Yes, we _need_ to use i here, not j, because we want to have the smallest child
// This way we get that straight away! * This way we get that straight away! */
if (BIN_HEAP_ARR(i).priority >= BIN_HEAP_ARR(2 * j + 1).priority) i = 2 * j + 1; if (BIN_HEAP_ARR(i).priority >= BIN_HEAP_ARR(2 * j + 1).priority) i = 2 * j + 1;
// Do we have one child? /* Do we have one child? */
} else if (2 * j <= q->data.binaryheap.size) { } else if (2 * j <= q->data.binaryheap.size) {
if (BIN_HEAP_ARR(j).priority >= BIN_HEAP_ARR(2 * j).priority) i = 2 * j; if (BIN_HEAP_ARR(j).priority >= BIN_HEAP_ARR(2 * j).priority) i = 2 * j;
} }
// One of our childs is smaller than we are, switch /* One of our childs is smaller than we are, switch */
if (i != j) { if (i != j) {
temp = BIN_HEAP_ARR(j); temp = BIN_HEAP_ARR(j);
BIN_HEAP_ARR(j) = BIN_HEAP_ARR(i); BIN_HEAP_ARR(j) = BIN_HEAP_ARR(i);
BIN_HEAP_ARR(i) = temp; BIN_HEAP_ARR(i) = temp;
} else { } else {
// None of our childs is smaller, so we stay here.. stop :) /* None of our childs is smaller, so we stay here.. stop :) */
break; break;
} }
} }
@ -261,9 +263,9 @@ static void* BinaryHeap_Pop(Queue* q)
if (q->data.binaryheap.size == 0) return NULL; if (q->data.binaryheap.size == 0) return NULL;
// The best item is always on top, so give that as result /* The best item is always on top, so give that as result */
result = BIN_HEAP_ARR(1).item; result = BIN_HEAP_ARR(1).item;
// And now we should get rid of this item... /* And now we should get rid of this item... */
BinaryHeap_Delete(q, BIN_HEAP_ARR(1).item, BIN_HEAP_ARR(1).priority); BinaryHeap_Delete(q, BIN_HEAP_ARR(1).item, BIN_HEAP_ARR(1).priority);
return result; return result;
@ -279,8 +281,8 @@ void init_BinaryHeap(Queue* q, uint max_size)
q->free = BinaryHeap_Free; q->free = BinaryHeap_Free;
q->data.binaryheap.max_size = max_size; q->data.binaryheap.max_size = max_size;
q->data.binaryheap.size = 0; q->data.binaryheap.size = 0;
// We malloc memory in block of BINARY_HEAP_BLOCKSIZE /* We malloc memory in block of BINARY_HEAP_BLOCKSIZE
// It autosizes when it runs out of memory * It autosizes when it runs out of memory */
q->data.binaryheap.elements = CallocT<BinaryHeapNode*>((max_size - 1) / BINARY_HEAP_BLOCKSIZE + 1); q->data.binaryheap.elements = CallocT<BinaryHeapNode*>((max_size - 1) / BINARY_HEAP_BLOCKSIZE + 1);
q->data.binaryheap.elements[0] = MallocT<BinaryHeapNode>(BINARY_HEAP_BLOCKSIZE); q->data.binaryheap.elements[0] = MallocT<BinaryHeapNode>(BINARY_HEAP_BLOCKSIZE);
q->data.binaryheap.blocks = 1; q->data.binaryheap.blocks = 1;
@ -428,7 +430,7 @@ void clear_Hash(Hash* h, bool free_values)
h->size = 0; h->size = 0;
} }
/* Finds the node that that saves this key pair. If it is not /** Finds the node that that saves this key pair. If it is not
* found, returns NULL. If it is found, *prev is set to the * found, returns NULL. If it is found, *prev is set to the
* node before the one found, or if the node found was the first in the bucket * node before the one found, or if the node found was the first in the bucket
* to NULL. If it is not found, *prev is set to the last HashNode in the * to NULL. If it is not found, *prev is set to the last HashNode in the
@ -482,7 +484,7 @@ static HashNode* Hash_FindNode(const Hash* h, uint key1, uint key2, HashNode** p
void* Hash_Delete(Hash* h, uint key1, uint key2) void* Hash_Delete(Hash* h, uint key1, uint key2)
{ {
void* result; void* result;
HashNode* prev; /* Used as output var for below function call */ HashNode* prev; // Used as output var for below function call
HashNode* node = Hash_FindNode(h, key1, key2, &prev); HashNode* node = Hash_FindNode(h, key1, key2, &prev);
if (node == NULL) { if (node == NULL) {

@ -1,5 +1,7 @@
/* $Id$ */ /* $Id$ */
/** @file queue.h */
#ifndef QUEUE_H #ifndef QUEUE_H
#define QUEUE_H #define QUEUE_H
@ -64,14 +66,14 @@ struct Queue{
struct { struct {
uint max_size; uint max_size;
uint size; uint size;
uint blocks; /* The amount of blocks for which space is reserved in elements */ uint blocks; ///< The amount of blocks for which space is reserved in elements
BinaryHeapNode** elements; BinaryHeapNode** elements;
} binaryheap; } binaryheap;
} data; } data;
}; };
/* /**
* Insertion Sorter * Insertion Sorter
*/ */
@ -89,7 +91,7 @@ void init_InsSort(Queue* q);
/* The amount of elements that will be malloc'd at a time */ /* The amount of elements that will be malloc'd at a time */
#define BINARY_HEAP_BLOCKSIZE_BITS 10 #define BINARY_HEAP_BLOCKSIZE_BITS 10
/* Initializes a binary heap and allocates internal memory for maximum of /** Initializes a binary heap and allocates internal memory for maximum of
* max_size elements */ * max_size elements */
void init_BinaryHeap(Queue* q, uint max_size); void init_BinaryHeap(Queue* q, uint max_size);
@ -124,33 +126,33 @@ struct Hash {
/* Call these function to manipulate a hash */ /* Call these function to manipulate a hash */
/* Deletes the value with the specified key pair from the hash and returns /** Deletes the value with the specified key pair from the hash and returns
* that value. Returns NULL when the value was not present. The value returned * that value. Returns NULL when the value was not present. The value returned
* is _not_ free()'d! */ * is _not_ free()'d! */
void* Hash_Delete(Hash* h, uint key1, uint key2); void* Hash_Delete(Hash* h, uint key1, uint key2);
/* Sets the value associated with the given key pair to the given value. /** Sets the value associated with the given key pair to the given value.
* Returns the old value if the value was replaced, NULL when it was not yet present. */ * Returns the old value if the value was replaced, NULL when it was not yet present. */
void* Hash_Set(Hash* h, uint key1, uint key2, void* value); void* Hash_Set(Hash* h, uint key1, uint key2, void* value);
/* Gets the value associated with the given key pair, or NULL when it is not /** Gets the value associated with the given key pair, or NULL when it is not
* present. */ * present. */
void* Hash_Get(const Hash* h, uint key1, uint key2); void* Hash_Get(const Hash* h, uint key1, uint key2);
/* Call these function to create/destroy a hash */ /* Call these function to create/destroy a hash */
/* Builds a new hash in an existing struct. Make sure that hash() always /** Builds a new hash in an existing struct. Make sure that hash() always
* returns a hash less than num_buckets! Call delete_hash after use */ * returns a hash less than num_buckets! Call delete_hash after use */
void init_Hash(Hash* h, Hash_HashProc* hash, uint num_buckets); void init_Hash(Hash* h, Hash_HashProc* hash, uint num_buckets);
/* /**
* Deletes the hash and cleans up. Only cleans up memory allocated by new_Hash * Deletes the hash and cleans up. Only cleans up memory allocated by new_Hash
* & friends. If free is true, it will call free() on all the values that * & friends. If free is true, it will call free() on all the values that
* are left in the hash. * are left in the hash.
*/ */
void delete_Hash(Hash* h, bool free_values); void delete_Hash(Hash* h, bool free_values);
/* /**
* Cleans the hash, but keeps the memory allocated * Cleans the hash, but keeps the memory allocated
*/ */
void clear_Hash(Hash* h, bool free_values); void clear_Hash(Hash* h, bool free_values);
/* /**
* Gets the current size of the Hash * Gets the current size of the Hash
*/ */
uint Hash_Size(const Hash* h); uint Hash_Size(const Hash* h);

Loading…
Cancel
Save