Changeset - r6423:c3b8b9853091
[Not reviewed]
master
0 12 0
belugas - 18 years ago 2007-04-04 04:08:47
belugas@openttd.org
(svn r9559) -Documentation: doxygen and comment changes: 'U' and 'V' now. Almost done. Yeah. I know, I've already said that...
12 files changed with 254 insertions and 216 deletions:
0 comments (0 inline, 0 general)
src/unix.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/** @file unix.cpp */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "functions.h"
 
#include "window.h"
 
#include "string.h"
 
#include "table/strings.h"
 
@@ -24,25 +26,25 @@
 

	
 

	
 
#ifdef __MORPHOS__
 
#include <exec/types.h>
 
ULONG __stack = (1024*1024)*2; // maybe not that much is needed actually ;)
 

	
 
// The system supplied definition of SIG_IGN does not match
 
/* The system supplied definition of SIG_IGN does not match */
 
#undef SIG_IGN
 
#define SIG_IGN (void (*)(int))1
 
#endif /* __MORPHOS__ */
 

	
 
#ifdef __AMIGA__
 
#warning add stack symbol to avoid that user needs to set stack manually (tokai)
 
// ULONG __stack =
 
#endif
 

	
 
#if defined(__APPLE__)
 
	#if defined(WITH_SDL)
 
		//the mac implementation needs this file included in the same file as main()
 
		/*the mac implementation needs this file included in the same file as main() */
 
		#include <SDL.h>
 
	#endif
 
#endif
 

	
 
bool FiosIsRoot(const char *path)
 
{
 
@@ -101,17 +103,17 @@ void ShowInfo(const char *str)
 
	fprintf(stderr, "%s\n", str);
 
}
 

	
 
void ShowOSErrorBox(const char *buf)
 
{
 
#if defined(__APPLE__)
 
	// this creates an NSAlertPanel with the contents of 'buf'
 
	// this is the native and nicest way to do this on OSX
 
	/* this creates an NSAlertPanel with the contents of 'buf'
 
	 * this is the native and nicest way to do this on OSX */
 
	ShowMacDialog( buf, "See readme for more info\nMost likely you are missing files from the original TTD", "Quit" );
 
#else
 
	// all systems, but OSX
 
	/* all systems, but OSX */
 
	fprintf(stderr, "\033[1;31mError: %s\033[0;39m\n", buf);
 
#endif
 
}
 

	
 
#ifdef WITH_COCOA
 
void cocoaSetupAutoreleasePool();
 
@@ -148,16 +150,16 @@ int CDECL main(int argc, char* argv[])
 
bool InsertTextBufferClipboard(Textbuf *tb)
 
{
 
	return false;
 
}
 

	
 

	
 
// multi os compatible sleep function
 
/* multi os compatible sleep function */
 

	
 
#ifdef __AMIGA__
 
// usleep() implementation
 
/* usleep() implementation */
 
#	include <devices/timer.h>
 
#	include <dos/dos.h>
 

	
 
	extern struct Device      *TimerBase    = NULL;
 
	extern struct MsgPort     *TimerPort    = NULL;
 
	extern struct timerequest *TimerRequest = NULL;
 
@@ -171,13 +173,13 @@ void CSleep(int milliseconds)
 
		snooze(milliseconds * 1000);
 
	#elif defined(__AMIGA__)
 
	{
 
		ULONG signals;
 
		ULONG TimerSigBit = 1 << TimerPort->mp_SigBit;
 

	
 
		// send IORequest
 
		/* send IORequest */
 
		TimerRequest->tr_node.io_Command = TR_ADDREQUEST;
 
		TimerRequest->tr_time.tv_secs    = (milliseconds * 1000) / 1000000;
 
		TimerRequest->tr_time.tv_micro   = (milliseconds * 1000) % 1000000;
 
		SendIO((struct IORequest *)TimerRequest);
 

	
 
		if (!((signals = Wait(TimerSigBit | SIGBREAKF_CTRL_C)) & TimerSigBit) ) {
 
@@ -240,13 +242,13 @@ static const char *convert_tofrom_fs(ico
 
	iconv(convd, NULL, NULL, NULL, NULL);
 
	if (iconv(convd, &inbuf, &inlen, &outbuf, &outlen) == (size_t)(-1)) {
 
		DEBUG(misc, 0, "[iconv] error converting '%s'. Errno %d", name, errno);
 
	}
 

	
 
	*outbuf = '\0';
 
	// FIX: invalid characters will abort conversion, but they shouldn't occur?
 
	/* FIX: invalid characters will abort conversion, but they shouldn't occur? */
 
	return buf;
 
}
 

	
 
/** Convert from OpenTTD's encoding to that of the local environment
 
 * @param name pointer to a valid string that will be converted
 
 * @return pointer to a new stringbuffer that contains the converted string */
src/unmovable.h
Show inline comments
 
/* $Id$ */
 

	
 
/** @file unmovable.h */
 

	
 
#ifndef UNMOVABLE_H
 
#define UNMOVABLE_H
 

	
 
void UpdateCompanyHQ(Player *p, uint score);
 

	
 
#endif /* UNMOVABLE_H */
src/unmovable_cmd.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/** @file unmovable_cmd.cpp */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "table/strings.h"
 
#include "table/sprites.h"
 
#include "functions.h"
 
#include "map.h"
 
@@ -41,13 +43,13 @@ static int32 DestroyCompanyHQ(PlayerID p
 
		DoClearSquare(t + TileDiffXY(1, 0));
 
		DoClearSquare(t + TileDiffXY(1, 1));
 
		p->location_of_house = 0; // reset HQ position
 
		InvalidateWindow(WC_COMPANY, pid);
 
	}
 

	
 
	// cost of relocating company is 1% of company value
 
	/* cost of relocating company is 1% of company value */
 
	return CalculateCompanyValue(p) / 100;
 
}
 

	
 
void UpdateCompanyHQ(Player *p, uint score)
 
{
 
	byte val;
 
@@ -66,31 +68,33 @@ void UpdateCompanyHQ(Player *p, uint sco
 
	MarkTileDirtyByTile(tile + TileDiffXY(0, 0));
 
	MarkTileDirtyByTile(tile + TileDiffXY(0, 1));
 
	MarkTileDirtyByTile(tile + TileDiffXY(1, 0));
 
	MarkTileDirtyByTile(tile + TileDiffXY(1, 1));
 
}
 

	
 
extern int32 CheckFlatLandBelow(TileIndex tile, uint w, uint h, uint flags, uint invalid_dirs, StationID* station);
 

	
 
/** Build or relocate the HQ. This depends if the HQ is already built or not
 
 * @param tile tile where the HQ will be built or relocated to
 
 * @param flags type of operation
 
 * @param p1 unused
 
 * @param p2 unused
 
 */
 
extern int32 CheckFlatLandBelow(TileIndex tile, uint w, uint h, uint flags, uint invalid_dirs, StationID* station);
 
int32 CmdBuildCompanyHQ(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Player *p = GetPlayer(_current_player);
 
	int cost;
 
	int32 ret;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_PROPERTY);
 

	
 
	ret = CheckFlatLandBelow(tile, 2, 2, flags, 0, NULL);
 
	if (CmdFailed(ret)) return ret;
 
	cost = ret;
 

	
 
	if (p->location_of_house != 0) { /* Moving HQ */
 
	if (p->location_of_house != 0) { // Moving HQ
 
		cost += DestroyCompanyHQ(_current_player, flags);
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		int score = UpdateCompanyRatingAndValue(p, false);
 

	
 
@@ -221,13 +225,13 @@ static int32 ClearTile_Unmovable(TileInd
 
	}
 

	
 
	if (IsOwnedLand(tile)) {
 
		return DoCommand(tile, 0, 0, flags, CMD_SELL_LAND_AREA);
 
	}
 

	
 
	// checks if you're allowed to remove unmovable things
 
	/* checks if you're allowed to remove unmovable things */
 
	if (_game_mode != GM_EDITOR && _current_player != OWNER_WATER && ((flags & DC_AUTO || !_cheats.magic_bulldozer.value)) )
 
		return_cmd_error(STR_5800_OBJECT_IN_THE_WAY);
 

	
 
	if (IsStatue(tile)) {
 
		TownID town = GetStatueTownID(tile);
 
		CLRBIT(GetTown(town)->statues, _current_player);
 
@@ -249,20 +253,20 @@ static void GetAcceptedCargo_Unmovable(T
 

	
 
	/* HQ accepts passenger and mail; but we have to divide the values
 
	 * between 4 tiles it occupies! */
 

	
 
	level = GetCompanyHQSize(tile) + 1;
 

	
 
	// Top town building generates 10, so to make HQ interesting, the top
 
	// type makes 20.
 
	/* Top town building generates 10, so to make HQ interesting, the top
 
	 * type makes 20. */
 
	ac[CT_PASSENGERS] = max(1U, level);
 

	
 
	// Top town building generates 4, HQ can make up to 8. The
 
	// proportion passengers:mail is different because such a huge
 
	// commercial building generates unusually high amount of mail
 
	// correspondence per physical visitor.
 
	/* Top town building generates 4, HQ can make up to 8. The
 
	 * proportion passengers:mail is different because such a huge
 
	 * commercial building generates unusually high amount of mail
 
	 * correspondence per physical visitor. */
 
	ac[CT_MAIL] = max(1U, level / 2);
 
}
 

	
 

	
 
static void GetTileDesc_Unmovable(TileIndex tile, TileDesc *td)
 
{
 
@@ -292,22 +296,22 @@ static void TileLoop_Unmovable(TileIndex
 
	 * between 4 tiles it occupies! */
 

	
 
	level = GetCompanyHQSize(tile) + 1;
 
	assert(level < 6);
 

	
 
	r = Random();
 
	// Top town buildings generate 250, so the top HQ type makes 256.
 
	/* Top town buildings generate 250, so the top HQ type makes 256. */
 
	if (GB(r, 0, 8) < (256 / 4 / (6 - level))) {
 
		uint amt = GB(r, 0, 8) / 8 / 4 + 1;
 
		if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
 
		MoveGoodsToStation(tile, 2, 2, CT_PASSENGERS, amt);
 
	}
 

	
 
	// Top town building generates 90, HQ can make up to 196. The
 
	// proportion passengers:mail is about the same as in the acceptance
 
	// equations.
 
	/* Top town building generates 90, HQ can make up to 196. The
 
	 * proportion passengers:mail is about the same as in the acceptance
 
	 * equations. */
 
	if (GB(r, 8, 8) < (196 / 4 / (6 - level))) {
 
		uint amt = GB(r, 8, 8) / 8 / 4 + 1;
 
		if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
 
		MoveGoodsToStation(tile, 2, 2, CT_MAIL, amt);
 
	}
 
}
src/unmovable_map.h
Show inline comments
 
/* $Id$ */
 

	
 
/** @file unmovable_map.h */
 

	
 
#ifndef UNMOVABLE_MAP_H
 
#define UNMOVABLE_MAP_H
 

	
 
enum {
 
	HQ_NUM_TILE = 4,
 
	HQ_NUM_SIZE = 5
src/variables.h
Show inline comments
 
/* $Id$ */
 

	
 
/** @file variables.h */
 

	
 
#ifndef VARIABLES_H
 
#define VARIABLES_H
 

	
 
#include "yapf/yapf_settings.h"
 

	
 
// ********* START OF SAVE REGION
 
/* ********* START OF SAVE REGION */
 
#if !defined(MAX_PATH)
 
# define MAX_PATH 260
 
#endif
 

	
 
#include "gfx.h"
 

	
 
// Prices and also the fractional part.
 
/* Prices and also the fractional part. */
 
VARDEF Prices _price;
 
VARDEF uint16 _price_frac[NUM_PRICES];
 

	
 
VARDEF uint32 _cargo_payment_rates[NUM_CARGO];
 
VARDEF uint16 _cargo_payment_rates_frac[NUM_CARGO];
 

	
 
@@ -35,53 +37,53 @@ struct GameOptions {
 
 * either ingame, or loaded. Also used for networking games */
 
VARDEF GameOptions _opt;
 

	
 
/* These are the default options for a new game */
 
VARDEF GameOptions _opt_newgame;
 

	
 
// Pointer to one of the two _opt OR _opt_newgame structs
 
/* Pointer to one of the two _opt OR _opt_newgame structs */
 
VARDEF GameOptions *_opt_ptr;
 

	
 
// Amount of game ticks
 
/* Amount of game ticks */
 
VARDEF uint16 _tick_counter;
 

	
 
// This one is not used anymore.
 
/* This one is not used anymore. */
 
VARDEF VehicleID _vehicle_id_ctr_day;
 

	
 
// Skip aging of cargo?
 
/* Skip aging of cargo? */
 
VARDEF byte _age_cargo_skip_counter;
 

	
 
// Position in tile loop
 
/* Position in tile loop */
 
VARDEF TileIndex _cur_tileloop_tile;
 

	
 
// Also save scrollpos_x, scrollpos_y and zoom
 
/* Also save scrollpos_x, scrollpos_y and zoom */
 
VARDEF uint16 _disaster_delay;
 

	
 
// Determines what station to operate on in the
 
//  tick handler.
 
/* Determines what station to operate on in the
 
 *  tick handler. */
 
VARDEF uint16 _station_tick_ctr;
 

	
 
VARDEF uint32 _random_seeds[2][2];
 

	
 
// Iterator through all towns in OnTick_Town
 
/* Iterator through all towns in OnTick_Town */
 
VARDEF uint32 _cur_town_ctr;
 
// Frequency iterator at the same place
 
/* Frequency iterator at the same place */
 
VARDEF uint32 _cur_town_iter;
 

	
 
VARDEF uint _cur_player_tick_index;
 
VARDEF uint _next_competitor_start;
 

	
 
// Determines how often to run the tree loop
 
/* Determines how often to run the tree loop */
 
VARDEF byte _trees_tick_ctr;
 

	
 
// Keep track of current game position
 
/* Keep track of current game position */
 
VARDEF int _saved_scrollpos_x;
 
VARDEF int _saved_scrollpos_y;
 
VARDEF byte _saved_scrollpos_zoom;
 

	
 
// ********* END OF SAVE REGION
 
/* ********* END OF SAVE REGION */
 

	
 
struct Patches {
 
	bool modified_catchment;            // different-size catchment areas
 
	bool vehicle_speed;                 // show vehicle speed
 
	bool build_on_slopes;               // allow building on slopes
 
	bool mammoth_trains;                // allow very long trains
 
@@ -198,28 +200,28 @@ struct Patches {
 
	 * 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 */
 
	uint32 npf_crossing_penalty;           /* The penalty for level crossings */
 
	uint32 npf_road_drive_through_penalty; /* The penalty for going through a drive-through road stop */
 
	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
 
	uint32 npf_crossing_penalty;           // The penalty for level crossings
 
	uint32 npf_road_drive_through_penalty; // The penalty for going through a drive-through road stop
 

	
 
	bool population_in_label; // Show the population of a town in his label?
 

	
 
	uint8 freight_trains; ///< Value to multiply the weight of cargo by
 
	uint8 freight_trains; // Value to multiply the weight of cargo by
 

	
 
	/** YAPF settings */
 
	YapfSettings  yapf;
 

	
 
	uint8 scrollwheel_scrolling;
 
	uint8 scrollwheel_multiplier;
 
@@ -231,15 +233,15 @@ VARDEF Patches _patches;
 
struct Cheat {
 
	bool been_used; // has this cheat been used before?
 
	bool value;     // tells if the bool cheat is active or not
 
};
 

	
 

	
 
// WARNING! Do _not_ remove entries in Cheats struct or change the order
 
// of the existing ones! Would break downward compatibility.
 
// Only add new entries at the end of the struct!
 
/* WARNING! Do _not_ remove entries in Cheats struct or change the order
 
 * of the existing ones! Would break downward compatibility.
 
 * Only add new entries at the end of the struct! */
 

	
 
struct Cheats {
 
	Cheat magic_bulldozer;  // dynamite industries, unmovables
 
	Cheat switch_player;    // change to another player
 
	Cheat money;            // get rich
 
	Cheat crossing_tunnels; // allow tunnels that cross each other
 
@@ -265,13 +267,13 @@ struct Paths {
 
	char *heightmap_dir;
 
	char *second_data_dir;
 
};
 

	
 
VARDEF Paths _paths;
 

	
 
// NOSAVE: Used in palette animations only, not really important.
 
/* NOSAVE: Used in palette animations only, not really important. */
 
VARDEF int _timer_counter;
 

	
 

	
 
VARDEF uint32 _frame_counter;
 

	
 
VARDEF bool _is_old_ai_player; // current player is an oldAI player? (enables a lot of cheats..)
 
@@ -288,26 +290,26 @@ VARDEF StringID _error_message;
 
VARDEF int32 _additional_cash_required;
 

	
 
VARDEF uint32 _decode_parameters[20];
 

	
 
VARDEF bool _rightclick_emulate;
 

	
 
// IN/OUT parameters to commands
 
/* IN/OUT parameters to commands */
 
VARDEF byte _yearly_expenses_type;
 
VARDEF TileIndex _terraform_err_tile;
 
VARDEF TileIndex _build_tunnel_endtile;
 
VARDEF bool _generating_world;
 

	
 
// Deals with the type of the savegame, independent of extension
 
/* Deals with the type of the savegame, independent of extension */
 
struct SmallFiosItem {
 
	int mode;             // savegame/scenario type (old, new)
 
	char name[MAX_PATH];  // name
 
	char title[255];      // internal name of the game
 
};
 

	
 
// Used when switching from the intro menu.
 
/* Used when switching from the intro menu. */
 
VARDEF byte _switch_mode;
 
VARDEF StringID _switch_mode_errorstr;
 
VARDEF SmallFiosItem _file_to_saveload;
 

	
 

	
 

	
 
@@ -369,30 +371,30 @@ static inline void SetDParam64(uint n, u
 
static inline uint32 GetDParam(uint n)
 
{
 
	assert(n < lengthof(_decode_parameters));
 
	return _decode_parameters[n];
 
}
 

	
 
// Used to bind a C string name to a dparam number.
 
// NOTE: This has a short lifetime. You can't
 
//       use this string much later or it will be gone.
 
/* Used to bind a C string name to a dparam number.
 
 * NOTE: This has a short lifetime. You can't
 
 *       use this string much later or it will be gone. */
 
void SetDParamStr(uint n, const char *str);
 

	
 
// This function takes a C-string and allocates a temporary string ID.
 
// The duration of the bound string is valid only until the next acll to GetString,
 
// so be careful.
 
/** This function takes a C-string and allocates a temporary string ID.
 
 * The duration of the bound string is valid only until the next acll to GetString,
 
 * so be careful. */
 
StringID BindCString(const char *str);
 

	
 

	
 
#define COPY_IN_DPARAM(offs,src,num) memcpy(_decode_parameters + offs, src, sizeof(uint32) * (num))
 
#define COPY_OUT_DPARAM(dst,offs,num) memcpy(dst,_decode_parameters + offs, sizeof(uint32) * (num))
 

	
 

	
 
#define SET_EXPENSES_TYPE(x) _yearly_expenses_type = x;
 

	
 
/* landscape.c */
 
/* landscape.cpp */
 
extern const byte _tileh_to_sprite[32];
 
extern const Slope _inclined_tileh[16];
 

	
 
extern const TileTypeProcs * const _tile_type_procs[16];
 

	
 
/* misc */
src/vehicle.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/** @file vehicle.cpp */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "road_map.h"
 
#include "roadveh.h"
 
#include "ship.h"
 
#include "spritecache.h"
 
@@ -101,13 +103,13 @@ void VehicleServiceInDepot(Vehicle *v)
 
	InvalidateWindow(WC_VEHICLE_DETAILS, v->index); // ensure that last service date and reliability are updated
 
}
 

	
 
bool VehicleNeedsService(const Vehicle *v)
 
{
 
	if (v->vehstatus & VS_CRASHED)
 
		return false; /* Crashed vehicles don't need service anymore */
 
		return false; // Crashed vehicles don't need service anymore
 

	
 
	if (_patches.no_servicing_if_no_breakdowns && _opt.diff.vehicle_breakdowns == 0) {
 
		return EngineHasReplacementForPlayer(GetPlayer(v->owner), v->engine_type);  /* Vehicles set for autoreplacing needs to go to a depot even if breakdowns are turned off */
 
	}
 

	
 
	return _patches.servint_ispercent ?
 
@@ -212,13 +214,13 @@ void VehiclePositionChanged(Vehicle *v)
 
	v->left_coord = pt.x;
 
	v->top_coord = pt.y;
 
	v->right_coord = pt.x + spr->width + 2;
 
	v->bottom_coord = pt.y + spr->height + 2;
 
}
 

	
 
// Called after load to update coordinates
 
/** Called after load to update coordinates */
 
void AfterLoadVehicles()
 
{
 
	Vehicle *v;
 

	
 
	FOR_ALL_VEHICLES(v) {
 
		v->first = NULL;
 
@@ -308,13 +310,13 @@ Vehicle *ForceAllocateSpecialVehicle()
 
		if (!IsValidVehicle(v)) return InitializeVehicle(v);
 
	}
 

	
 
	return NULL;
 
}
 

	
 
/*
 
/**
 
 * finds a free vehicle in the memory or allocates a new one
 
 * returns a pointer to the first free vehicle or NULL if all vehicles are in use
 
 * *skip_vehicles is an offset to where in the array we should begin looking
 
 * this is to avoid looping though the same vehicles more than once after we learned that they are not free
 
 * this feature is used by AllocateVehicles() since it need to allocate more than one and when
 
 * another block is added to _Vehicle_pool, since we only do that when we know it's already full
 
@@ -324,13 +326,13 @@ static Vehicle *AllocateSingleVehicle(Ve
 
	/* See note by ForceAllocateSpecialVehicle() why we skip the
 
	 * first blocks */
 
	Vehicle *v;
 
	const int offset = (1 << Vehicle_POOL_BLOCK_SIZE_BITS) * BLOCKS_FOR_SPECIAL_VEHICLES;
 

	
 
	/* We don't use FOR_ALL here, because FOR_ALL skips invalid items.
 
	 * TODO - This is just a temporary stage, this will be removed. */
 
	 * @todo - This is just a temporary stage, this will be removed. */
 
	if (*skip_vehicles < (_Vehicle_pool.total_items - offset)) { // make sure the offset in the array is not larger than the array itself
 
		for (v = GetVehicle(offset + *skip_vehicles); v != NULL; v = (v->index + 1U < GetVehiclePoolSize()) ? GetVehicle(v->index + 1) : NULL) {
 
			(*skip_vehicles)++;
 
			if (!IsValidVehicle(v)) return InitializeVehicle(v);
 
		}
 
	}
 
@@ -378,13 +380,13 @@ bool AllocateVehicles(Vehicle **vl, int 
 
static Vehicle *_vehicle_position_hash[0x1000];
 

	
 
void *VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
 
{
 
	Point pt = RemapCoords(TileX(tile) * TILE_SIZE, TileY(tile) * TILE_SIZE, 0);
 

	
 
	// The hash area to scan
 
	/* The hash area to scan */
 
	const int xl = GB(pt.x - 174, 7, 6);
 
	const int xu = GB(pt.x + 104, 7, 6);
 
	const int yl = GB(pt.y - 294, 6, 6) << 6;
 
	const int yu = GB(pt.y +  56, 6, 6) << 6;
 

	
 
	int x;
 
@@ -495,13 +497,13 @@ Vehicle *GetPrevVehicleInChain(const Veh
 
{
 
	Vehicle *u;
 
	assert(v != NULL);
 

	
 
	u = GetFirstVehicleInChain(v);
 

	
 
	// Check to see if this is the first
 
	/* Check to see if this is the first */
 
	if (v == u) return NULL;
 

	
 
	for (; u->next != v; u = u->next) assert(u->next != NULL);
 

	
 
	return u;
 
}
 
@@ -603,28 +605,28 @@ 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);
 

	
 
// head of the linked list to tell what vehicles that visited a depot in a tick
 
/** 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
 
 */
 
void VehicleEnteredDepotThisTick(Vehicle *v)
 
{
 
	// we need to set v->leave_depot_instantly as we have no control of it's contents at this time
 
	/* 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
 
		/* 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
 
		/* 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;
 
	}
 

	
 
	if (_first_veh_in_depot_list == NULL) {
 
		_first_veh_in_depot_list = v;
 
@@ -647,14 +649,14 @@ static VehicleTickProc* _vehicle_tick_pr
 

	
 
void CallVehicleTicks()
 
{
 
	Vehicle *v;
 

	
 
#ifdef ENABLE_NETWORK
 
	// hotfix for desync problem:
 
	//  for MP games invalidate the YAPF cache every tick to keep it exactly the same on the server and all clients
 
	/* hotfix for desync problem:
 
	 *  for MP games invalidate the YAPF cache every tick to keep it exactly the same on the server and all clients */
 
	if (_networking) {
 
		YapfNotifyTrackLayoutChange(INVALID_TILE, INVALID_TRACK);
 
	}
 
#endif //ENABLE_NETWORK
 

	
 
	_first_veh_in_depot_list = NULL; // now we are sure it's initialized at the start of each tick
 
@@ -676,13 +678,13 @@ void CallVehicleTicks()
 

	
 
				/* Play an alterate running sound every 16 ticks */
 
				if (GB(v->tick_counter, 0, 4) == 0) PlayVehicleSound(v, v->cur_speed > 0 ? VSE_RUNNING_16 : VSE_STOPPED_16);
 
		}
 
	}
 

	
 
	// now we handle all the vehicles that entered a depot this tick
 
	/* now we handle all the vehicles that entered a depot this tick */
 
	v = _first_veh_in_depot_list;
 
	while (v != NULL) {
 
		Vehicle *w = v->depot_list;
 
		v->depot_list = NULL; // it should always be NULL at the end of each tick
 
		MaybeReplaceVehicle(v, false, true);
 
		v = w;
 
@@ -692,25 +694,25 @@ void CallVehicleTicks()
 
static bool CanFillVehicle_FullLoadAny(Vehicle *v)
 
{
 
	uint32 full = 0, not_full = 0;
 
	bool keep_loading = false;
 
	const GoodsEntry *ge = GetStation(v->last_station_visited)->goods;
 

	
 
	//special handling of aircraft
 

	
 
	//if the aircraft carries passengers and is NOT full, then
 
	//continue loading, no matter how much mail is in
 
	/* special handling of aircraft */
 

	
 
	/* if the aircraft carries passengers and is NOT full, then
 
	 *continue loading, no matter how much mail is in */
 
	if (v->type == VEH_AIRCRAFT &&
 
			IsCargoInClass(v->cargo_type, CC_PASSENGERS) &&
 
			v->cargo_cap != v->cargo_count) {
 
		return true;
 
	}
 

	
 
	// patch should return "true" to continue loading, i.e. when there is no cargo type that is fully loaded.
 
	/* patch should return "true" to continue loading, i.e. when there is no cargo type that is fully loaded. */
 
	do {
 
		//Should never happen, but just in case future additions change this
 
		/* Should never happen, but just in case future additions change this */
 
		assert(v->cargo_type<32);
 

	
 
		if (v->cargo_cap != 0) {
 
			uint32 mask = 1 << v->cargo_type;
 

	
 
			if (v->cargo_cap == v->cargo_count) {
 
@@ -723,13 +725,13 @@ static bool CanFillVehicle_FullLoadAny(V
 
			} else {
 
				not_full |= mask;
 
			}
 
		}
 
	} while ((v = v->next) != NULL);
 

	
 
	// continue loading if there is a non full cargo type and no cargo type that is full
 
	/* continue loading if there is a non full cargo type and no cargo type that is full */
 
	return keep_loading || (not_full && (full & ~not_full) == 0);
 
}
 

	
 
bool CanFillVehicle(Vehicle *v)
 
{
 
	TileIndex tile = v->tile;
 
@@ -740,13 +742,13 @@ bool CanFillVehicle(Vehicle *v)
 
				IsTileType(TILE_ADDXY(tile, -1,  0), MP_STATION) ||
 
				IsTileType(TILE_ADDXY(tile,  0,  1), MP_STATION) ||
 
				IsTileType(TILE_ADDXY(tile,  0, -1), MP_STATION) ||
 
				IsTileType(TILE_ADDXY(tile, -2,  0), MP_STATION)
 
			))) {
 

	
 
		// If patch is active, use alternative CanFillVehicle-function
 
		/* If patch is active, use alternative CanFillVehicle-function */
 
		if (_patches.full_load_any && v->current_order.flags & OF_FULL_LOAD) return CanFillVehicle_FullLoadAny(v);
 

	
 
		do {
 
			if (v->cargo_count != v->cargo_cap) return true;
 
		} while ((v = v->next) != NULL);
 
	}
 
@@ -818,19 +820,19 @@ static void DoDrawVehicle(const Vehicle 
 
	AddSortableSpriteToDraw(image, pal, v->x_pos + v->x_offs, v->y_pos + v->y_offs,
 
		v->sprite_width, v->sprite_height, v->z_height, v->z_pos);
 
}
 

	
 
void ViewportAddVehicles(DrawPixelInfo *dpi)
 
{
 
	// The bounding rectangle
 
	/* The bounding rectangle */
 
	const int l = dpi->left;
 
	const int r = dpi->left + dpi->width;
 
	const int t = dpi->top;
 
	const int b = dpi->top + dpi->height;
 

	
 
	// The hash area to scan
 
	/* The hash area to scan */
 
	const int xl = GB(l - 70, 7, 6);
 
	const int xu = GB(r,      7, 6);
 
	const int yl = GB(t - 70, 6, 6) << 6;
 
	const int yu = GB(b,      6, 6) << 6;
 

	
 
	int x;
 
@@ -1564,13 +1566,13 @@ static const StringID _vehicle_type_name
 
};
 

	
 
static void ShowVehicleGettingOld(Vehicle *v, StringID msg)
 
{
 
	if (v->owner != _local_player) return;
 

	
 
	// Do not show getting-old message if autorenew is active
 
	/* Do not show getting-old message if autorenew is active */
 
	if (GetPlayer(v->owner)->engine_renew) return;
 

	
 
	SetDParam(0, _vehicle_type_names[v->type]);
 
	SetDParam(1, v->unitnumber);
 
	AddNewsItem(msg, NEWS_FLAGS(NM_SMALL, NF_VIEWPORT|NF_VEHICLE, NT_ADVICE, 0), v->index, 0);
 
}
 
@@ -1596,12 +1598,13 @@ void AgeVehicle(Vehicle *v)
 
		ShowVehicleGettingOld(v, STR_01A2_IS_GETTING_VERY_OLD_AND);
 
	}
 
}
 

	
 
/** Starts or stops a lot of vehicles
 
 * @param tile Tile of the depot where the vehicles are started/stopped (only used for depots)
 
 * @param flags type of operation
 
 * @param p1 Station/Order/Depot ID (only used for vehicle list windows)
 
 * @param p2 bitmask
 
 *   - bit 0-4 Vehicle type
 
 *   - bit 5 false = start vehicles, true = stop vehicles
 
 *   - bit 6 if set, then it's a vehicle list window, not a depot and Tile is ignored in this case
 
 *   - bit 8-11 Vehicle List Window type (ignored unless bit 1 is set)
 
@@ -1662,16 +1665,17 @@ int32 CmdMassStartStopVehicle(TileIndex 
 

	
 
	free(vl);
 
	return return_value;
 
}
 

	
 
/** Sells all vehicles in a depot
 
* @param tile Tile of the depot where the depot is
 
* @param p1 Vehicle type
 
* @param p2 unused
 
*/
 
 * @param tile Tile of the depot where the depot is
 
 * @param flags type of operation
 
 * @param p1 Vehicle type
 
 * @param p2 unused
 
 */
 
int32 CmdDepotSellAllVehicles(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Vehicle **engines = NULL;
 
	Vehicle **wagons = NULL;
 
	uint16 engine_list_length = 0;
 
	uint16 engine_count = 0;
 
@@ -1714,16 +1718,17 @@ int32 CmdDepotSellAllVehicles(TileIndex 
 
	free(wagons);
 
	if (cost == 0) return CMD_ERROR; // no vehicles to sell
 
	return cost;
 
}
 

	
 
/** Autoreplace all vehicles in the depot
 
* @param tile Tile of the depot where the vehicles are
 
* @param p1 Type of vehicle
 
* @param p2 Unused
 
*/
 
 * @param tile Tile of the depot where the vehicles are
 
 * @param flags type of operation
 
 * @param p1 Type of vehicle
 
 * @param p2 Unused
 
 */
 
int32 CmdDepotMassAutoReplace(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Vehicle **vl = NULL;
 
	uint16 engine_list_length = 0;
 
	uint16 engine_count = 0;
 
	uint i, x = 0, y = 0, z = 0;
 
@@ -1781,12 +1786,13 @@ int32 CmdDepotMassAutoReplace(TileIndex 
 
	free(vl);
 
	return cost;
 
}
 

	
 
/** 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 flags type of operation
 
 * @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;
 
@@ -1811,13 +1817,13 @@ int32 CmdCloneVehicle(TileIndex tile, ui
 
	 */
 

	
 
	if (!CheckOwnership(v->owner)) return CMD_ERROR;
 

	
 
	if (v->type == VEH_TRAIN && (!IsFrontEngine(v) || v->u.rail.crash_anim_pos >= 4400)) return CMD_ERROR;
 

	
 
	// check that we can allocate enough vehicles
 
	/* check that we can allocate enough vehicles */
 
	if (!(flags & DC_EXEC)) {
 
		int veh_counter = 0;
 
		do {
 
			veh_counter++;
 
		} while ((v = v->next) != NULL);
 

	
 
@@ -1859,27 +1865,27 @@ int32 CmdCloneVehicle(TileIndex tile, ui
 

	
 
			if (v->type == VEH_TRAIN && HASBIT(v->u.rail.flags, VRF_REVERSE_DIRECTION)) {
 
				SETBIT(w->u.rail.flags, VRF_REVERSE_DIRECTION);
 
			}
 

	
 
			if (v->type == VEH_TRAIN && !IsFrontEngine(v)) {
 
				// this s a train car
 
				// add this unit to the end of the train
 
				/* this s a train car
 
				 * add this unit to the end of the train */
 
				DoCommand(0, (w_rear->index << 16) | w->index, 1, flags, CMD_MOVE_RAIL_VEHICLE);
 
			} else {
 
				// this is a front engine or not a train. It need orders
 
				/* this is a front engine or not a train. It need orders */
 
				w_front = w;
 
				w->service_interval = v->service_interval;
 
				DoCommand(0, (v->index << 16) | w->index, p2 & 1 ? CO_SHARE : CO_COPY, flags, CMD_CLONE_ORDER);
 
			}
 
			w_rear = w; // trains needs to know the last car in the train, so they can add more in next loop
 
		}
 
	} while (v->type == VEH_TRAIN && (v = GetNextVehicle(v)) != NULL);
 

	
 
	if (flags & DC_EXEC && v_front->type == VEH_TRAIN) {
 
		// for trains this needs to be the front engine due to the callback function
 
		/* for trains this needs to be the front engine due to the callback function */
 
		_new_vehicle_id = w_front->index;
 
	}
 

	
 
	/* Set the expense type last as refitting will make the cost go towards
 
	 * running costs... */
 
	SET_EXPENSES_TYPE(EXPENSES_NEW_VEHICLES);
 
@@ -2217,12 +2223,13 @@ void VehicleEnterDepot(Vehicle *v)
 
		}
 
	}
 
}
 

	
 
/** Give a custom name to your vehicle
 
 * @param tile unused
 
 * @param flags type of operation
 
 * @param p1 vehicle ID to name
 
 * @param p2 unused
 
 */
 
int32 CmdNameVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Vehicle *v;
 
@@ -2250,12 +2257,13 @@ int32 CmdNameVehicle(TileIndex tile, uin
 
	return 0;
 
}
 

	
 

	
 
/** Change the service interval of a vehicle
 
 * @param tile unused
 
 * @param flags type of operation
 
 * @param p1 vehicle ID that is being service-interval-changed
 
 * @param p2 new service interval
 
 */
 
int32 CmdChangeServiceInt(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Vehicle* v;
 
@@ -2346,33 +2354,33 @@ Direction GetDirectionTowards(const Vehi
 
Trackdir GetVehicleTrackdir(const Vehicle* v)
 
{
 
	if (v->vehstatus & VS_CRASHED) return INVALID_TRACKDIR;
 

	
 
	switch (v->type) {
 
		case VEH_TRAIN:
 
			if (v->u.rail.track == TRACK_BIT_DEPOT) /* We'll assume the train is facing outwards */
 
				return DiagdirToDiagTrackdir(GetRailDepotDirection(v->tile)); /* Train in depot */
 

	
 
			if (v->u.rail.track == TRACK_BIT_WORMHOLE) /* train in tunnel, so just use his direction and assume a diagonal track */
 
			if (v->u.rail.track == TRACK_BIT_DEPOT) // We'll assume the train is facing outwards
 
				return DiagdirToDiagTrackdir(GetRailDepotDirection(v->tile)); // Train in depot
 

	
 
			if (v->u.rail.track == TRACK_BIT_WORMHOLE) // train in tunnel, so just use his direction and assume a diagonal track
 
				return DiagdirToDiagTrackdir(DirToDiagDir(v->direction));
 

	
 
			return TrackDirectionToTrackdir(FindFirstTrack(v->u.rail.track), v->direction);
 

	
 
		case VEH_SHIP:
 
			if (IsShipInDepot(v))
 
				/* We'll assume the ship is facing outwards */
 
				// We'll assume the ship is facing outwards
 
				return DiagdirToDiagTrackdir(GetShipDepotDirection(v->tile));
 

	
 
			return TrackDirectionToTrackdir(FindFirstTrack(v->u.ship.state), v->direction);
 

	
 
		case VEH_ROAD:
 
			if (IsRoadVehInDepot(v)) /* We'll assume the road vehicle is facing outwards */
 
			if (IsRoadVehInDepot(v)) // We'll assume the road vehicle is facing outwards
 
				return DiagdirToDiagTrackdir(GetRoadDepotDirection(v->tile));
 

	
 
			if (IsStandardRoadStopTile(v->tile)) /* We'll assume the road vehicle is facing outwards */
 
				return DiagdirToDiagTrackdir(GetRoadStopDir(v->tile)); /* Road vehicle in a station */
 
			if (IsStandardRoadStopTile(v->tile)) // We'll assume the road vehicle is facing outwards
 
				return DiagdirToDiagTrackdir(GetRoadStopDir(v->tile)); // Road vehicle in a station
 

	
 
			if (IsDriveThroughStopTile(v->tile)) return DiagdirToDiagTrackdir(DirToDiagDir(v->direction));
 

	
 
			/* If vehicle's state is a valid track direction (vehicle is not turning around) return it */
 
			if (!IsReversingRoadTrackdir((Trackdir)v->u.road.state)) return (Trackdir)v->u.road.state;
 

	
 
@@ -2419,22 +2427,22 @@ UnitID GetFreeUnitNumber(byte type)
 
	if (max > gmax) {
 
		gmax = max;
 
		free(cache);
 
		cache = MallocT<bool>(max + 1);
 
	}
 

	
 
	// Clear the cache
 
	/* Clear the cache */
 
	memset(cache, 0, (max + 1) * sizeof(*cache));
 

	
 
	// Fill the cache
 
	/* Fill the cache */
 
	FOR_ALL_VEHICLES(u) {
 
		if (u->type == type && u->owner == _current_player && u->unitnumber != 0 && u->unitnumber <= max)
 
			cache[u->unitnumber] = true;
 
	}
 

	
 
	// Find the first unused unit number
 
	/* Find the first unused unit number */
 
	for (unit = 1; unit <= max; unit++) {
 
		if (!cache[unit]) break;
 
	}
 

	
 
	return unit;
 
}
 
@@ -2559,13 +2567,13 @@ SpriteID GetVehiclePalette(const Vehicle
 
			v->owner, v->u.rail.first_engine, v);
 
	}
 

	
 
	return GetEngineColourMap(v->engine_type, v->owner, INVALID_ENGINE, v);
 
}
 

	
 
// Save and load of vehicles
 
/** Save and load of vehicles */
 
extern const SaveLoad _common_veh_desc[] = {
 
	    SLE_VAR(Vehicle, subtype,              SLE_UINT8),
 

	
 
	    SLE_REF(Vehicle, next,                 REF_VEHICLE_OLD),
 
	    SLE_VAR(Vehicle, string_id,            SLE_STRINGID),
 
	SLE_CONDVAR(Vehicle, unitnumber,           SLE_FILE_U8  | SLE_VAR_U16,  0, 7),
 
@@ -2664,13 +2672,13 @@ extern const SaveLoad _common_veh_desc[]
 
	    SLE_VAR(Vehicle, random_bits,          SLE_UINT8),
 
	    SLE_VAR(Vehicle, waiting_triggers,     SLE_UINT8),
 

	
 
	    SLE_REF(Vehicle, next_shared,          REF_VEHICLE),
 
	    SLE_REF(Vehicle, prev_shared,          REF_VEHICLE),
 

	
 
	// reserve extra space in savegame here. (currently 10 bytes)
 
	/* reserve extra space in savegame here. (currently 10 bytes) */
 
	SLE_CONDNULL(10,                                                       2, SL_MAX_VERSION),
 

	
 
	SLE_END()
 
};
 

	
 

	
 
@@ -2683,13 +2691,13 @@ static const SaveLoad _train_desc[] = {
 
	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRail, track),                  SLE_UINT8),
 

	
 
	SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleRail, flags),                  SLE_UINT8,  2, SL_MAX_VERSION),
 
	SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleRail, days_since_order_progr), SLE_UINT16, 2, SL_MAX_VERSION),
 

	
 
	SLE_CONDNULL(2, 2, 19),
 
	// reserve extra space in savegame here. (currently 11 bytes)
 
	/* reserve extra space in savegame here. (currently 11 bytes) */
 
	SLE_CONDNULL(11, 2, SL_MAX_VERSION),
 

	
 
	SLE_END()
 
};
 

	
 
static const SaveLoad _roadveh_desc[] = {
 
@@ -2703,24 +2711,24 @@ static const SaveLoad _roadveh_desc[] = 
 
	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, crashed_ctr),    SLE_UINT16),
 
	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, reverse_ctr),    SLE_UINT8),
 

	
 
	SLE_CONDREFX(offsetof(Vehicle, u) + offsetof(VehicleRoad, slot),     REF_ROADSTOPS, 6, SL_MAX_VERSION),
 
	SLE_CONDNULL(1,                                                                     6, SL_MAX_VERSION),
 
	SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleRoad, slot_age), SLE_UINT8,     6, SL_MAX_VERSION),
 
	// reserve extra space in savegame here. (currently 16 bytes)
 
	/* reserve extra space in savegame here. (currently 16 bytes) */
 
	SLE_CONDNULL(16,                                                                    2, SL_MAX_VERSION),
 

	
 
	SLE_END()
 
};
 

	
 
static const SaveLoad _ship_desc[] = {
 
	SLE_WRITEBYTE(Vehicle, type, VEH_SHIP, 2), // Ship type. VEH_SHIP in mem, 2 in file.
 
	SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
 
	SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleShip, state), SLE_UINT8),
 

	
 
	// reserve extra space in savegame here. (currently 16 bytes)
 
	/* reserve extra space in savegame here. (currently 16 bytes) */
 
	SLE_CONDNULL(16, 2, SL_MAX_VERSION),
 

	
 
	SLE_END()
 
};
 

	
 
static const SaveLoad _aircraft_desc[] = {
 
@@ -2733,13 +2741,13 @@ static const SaveLoad _aircraft_desc[] =
 
	SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleAir, targetairport),   SLE_UINT16,                5, SL_MAX_VERSION),
 

	
 
	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleAir, state),           SLE_UINT8),
 

	
 
	SLE_CONDVARX(offsetof(Vehicle, u) + offsetof(VehicleAir, previous_pos),    SLE_UINT8,                 2, SL_MAX_VERSION),
 

	
 
	// reserve extra space in savegame here. (currently 15 bytes)
 
	/* reserve extra space in savegame here. (currently 15 bytes) */
 
	SLE_CONDNULL(15,                                                                                      2, SL_MAX_VERSION),
 

	
 
	SLE_END()
 
};
 

	
 
static const SaveLoad _special_desc[] = {
 
@@ -2765,13 +2773,13 @@ static const SaveLoad _special_desc[] = 
 
	    SLE_VAR(Vehicle, progress,      SLE_UINT8),
 
	    SLE_VAR(Vehicle, vehstatus,     SLE_UINT8),
 

	
 
	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleSpecial, unk0), SLE_UINT16),
 
	    SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleSpecial, unk2), SLE_UINT8),
 

	
 
	// reserve extra space in savegame here. (currently 16 bytes)
 
	/* reserve extra space in savegame here. (currently 16 bytes) */
 
	SLE_CONDNULL(16, 2, SL_MAX_VERSION),
 

	
 
	SLE_END()
 
};
 

	
 
static const SaveLoad _disaster_desc[] = {
 
@@ -2807,13 +2815,13 @@ static const SaveLoad _disaster_desc[] =
 
	SLE_CONDVAR(Vehicle, age,           SLE_INT32,                  31, SL_MAX_VERSION),
 
	    SLE_VAR(Vehicle, tick_counter,  SLE_UINT8),
 

	
 
	   SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleDisaster, image_override), SLE_UINT16),
 
	   SLE_VARX(offsetof(Vehicle, u) + offsetof(VehicleDisaster, unk2),           SLE_UINT16),
 

	
 
	// reserve extra space in savegame here. (currently 16 bytes)
 
	/* reserve extra space in savegame here. (currently 16 bytes) */
 
	SLE_CONDNULL(16,                                                 2, SL_MAX_VERSION),
 

	
 
	SLE_END()
 
};
 

	
 

	
 
@@ -2823,24 +2831,24 @@ static const void *_veh_descs[] = {
 
	_ship_desc,
 
	_aircraft_desc,
 
	_special_desc,
 
	_disaster_desc,
 
};
 

	
 
// Will be called when the vehicles need to be saved.
 
/** Will be called when the vehicles need to be saved. */
 
static void Save_VEHS()
 
{
 
	Vehicle *v;
 
	// Write the vehicles
 
	/* Write the vehicles */
 
	FOR_ALL_VEHICLES(v) {
 
		SlSetArrayIndex(v->index);
 
		SlObject(v, (SaveLoad*)_veh_descs[v->type]);
 
	}
 
}
 

	
 
// Will be called when vehicles need to be loaded.
 
/** Will be called when vehicles need to be loaded. */
 
static void Load_VEHS()
 
{
 
	int index;
 
	Vehicle *v;
 

	
 
	while ((index = SlIterateArray()) != -1) {
src/vehicle.h
Show inline comments
 
/* $Id$ */
 

	
 
/** @vehicle.h */
 

	
 
#ifndef VEHICLE_H
 
#define VEHICLE_H
 

	
 
#include "oldpool.h"
 
#include "order.h"
 
#include "rail.h"
 
@@ -105,76 +107,76 @@ enum EffectVehicle {
 

	
 
struct VehicleRail {
 
	uint16 last_speed; // NOSAVE: only used in UI
 
	uint16 crash_anim_pos;
 
	uint16 days_since_order_progr;
 

	
 
	// cached values, recalculated on load and each time a vehicle is added to/removed from the consist.
 
	/* cached values, recalculated on load and each time a vehicle is added to/removed from the consist. */
 
	uint16 cached_max_speed;  // max speed of the consist. (minimum of the max speed of all vehicles in the consist)
 
	uint32 cached_power;      // total power of the consist.
 
	uint8 cached_veh_length;  // length of this vehicle in units of 1/8 of normal length, cached because this can be set by a callback
 
	uint16 cached_total_length; ///< Length of the whole train, valid only for first engine.
 

	
 
	// cached values, recalculated when the cargo on a train changes (in addition to the conditions above)
 
	/* cached values, recalculated when the cargo on a train changes (in addition to the conditions above) */
 
	uint32 cached_weight;     // total weight of the consist.
 
	uint32 cached_veh_weight; // weight of the vehicle.
 
	uint32 cached_max_te;     // max tractive effort of consist
 
	/**
 
	 * Position/type of visual effect.
 
	 * bit 0 - 3 = position of effect relative to vehicle. (0 = front, 8 = centre, 15 = rear)
 
	 * bit 4 - 5 = type of effect. (0 = default for engine class, 1 = steam, 2 = diesel, 3 = electric)
 
	 * bit     6 = disable visual effect.
 
	 * bit     7 = disable powered wagons.
 
	 */
 
	byte cached_vis_effect;
 

	
 
	// NOSAVE: for wagon override - id of the first engine in train
 
	// 0xffff == not in train
 
	/* NOSAVE: for wagon override - id of the first engine in train
 
	 * 0xffff == not in train */
 
	EngineID first_engine;
 

	
 
	TrackBitsByte track;
 
	byte force_proceed;
 
	RailTypeByte railtype;
 
	RailTypeMask compatible_railtypes;
 

	
 
	byte flags;
 

	
 
	// Link between the two ends of a multiheaded engine
 
	/* Link between the two ends of a multiheaded engine */
 
	Vehicle *other_multiheaded_part;
 
};
 

	
 
enum {
 
	VRF_REVERSING         = 0,
 

	
 
	// used to calculate if train is going up or down
 
	/* used to calculate if train is going up or down */
 
	VRF_GOINGUP           = 1,
 
	VRF_GOINGDOWN         = 2,
 

	
 
	// used to store if a wagon is powered or not
 
	/* used to store if a wagon is powered or not */
 
	VRF_POWEREDWAGON      = 3,
 

	
 
	// used to reverse the visible direction of the vehicle
 
	/* used to reverse the visible direction of the vehicle */
 
	VRF_REVERSE_DIRECTION = 4,
 

	
 
	// used to mark train as lost because PF can't find the route
 
	/* used to mark train as lost because PF can't find the route */
 
	VRF_NO_PATH_TO_DESTINATION = 5,
 

	
 
	// used to mark that electric train engine is allowed to run on normal rail
 
	/* used to mark that electric train engine is allowed to run on normal rail */
 
	VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL = 6,
 
};
 

	
 
struct VehicleAir {
 
	uint16 crashed_counter;
 
	byte pos;
 
	byte previous_pos;
 
	StationID targetairport;
 
	byte state;
 
};
 

	
 
struct VehicleRoad {
 
	byte state;             /// @see RoadVehicleStates
 
	byte state;             ///< @see RoadVehicleStates
 
	byte frame;
 
	uint16 blocked_ctr;
 
	byte overtaking;
 
	byte overtaking_ctr;
 
	uint16 crashed_ctr;
 
	byte reverse_ctr;
 
@@ -207,13 +209,13 @@ struct Vehicle {
 
	Vehicle *first;          // NOSAVE: pointer to the first vehicle in the chain
 
	Vehicle *depot_list;     //NOSAVE: linked list to tell what vehicles entered a depot during the last tick. Used by autoreplace
 

	
 
	StringID string_id;      // Displayed string
 

	
 
	UnitID unitnumber;       // unit number, for display purposes only
 
	PlayerByte owner;          // which player owns the vehicle?
 
	PlayerByte owner;        // which player owns the vehicle?
 

	
 
	TileIndex tile;          // Current tile index
 
	TileIndex dest_tile;     // Heading for this tile
 

	
 
	int32 x_pos;             // coordinates
 
	int32 y_pos;
 
@@ -228,15 +230,15 @@ struct Vehicle {
 
	byte sprite_height;      // height of vehicle sprite
 
	byte z_height;           // z-height of vehicle sprite
 
	int8 x_offs;             // x offset for vehicle sprite
 
	int8 y_offs;             // y offset for vehicle sprite
 
	EngineID engine_type;
 

	
 
	// for randomized variational spritegroups
 
	// bitmask used to resolve them; parts of it get reseeded when triggers
 
	// of corresponding spritegroups get matched
 
	/* for randomized variational spritegroups
 
	 * bitmask used to resolve them; parts of it get reseeded when triggers
 
	 * of corresponding spritegroups get matched */
 
	byte random_bits;
 
	byte waiting_triggers;   // triggers to be yet matched
 

	
 
	uint16 max_speed;        // maximum speed
 
	uint16 cur_speed;        // current speed
 
	byte subspeed;           // fractional speed
 
@@ -266,21 +268,21 @@ struct Vehicle {
 
	VehicleOrderID num_orders;      ///< How many orders there are in the list
 

	
 
	Vehicle *next_shared;    ///< If not NULL, this points to the next vehicle that shared the order
 
	Vehicle *prev_shared;    ///< If not NULL, this points to the prev vehicle that shared the order
 
	/* End Order-stuff */
 

	
 
	// Boundaries for the current position in the world and a next hash link.
 
	// NOSAVE: All of those can be updated with VehiclePositionChanged()
 
	/* Boundaries for the current position in the world and a next hash link.
 
	 * NOSAVE: All of those can be updated with VehiclePositionChanged() */
 
	int32 left_coord;
 
	int32 top_coord;
 
	int32 right_coord;
 
	int32 bottom_coord;
 
	Vehicle *next_hash;
 

	
 
	// Related to age and service time
 
	/* Related to age and service time */
 
	Date age;     // Age in days
 
	Date max_age; // Maximum age
 
	Date date_of_last_service;
 
	Date service_interval;
 
	uint16 reliability;
 
	uint16 reliability_spd_dec;
 
@@ -489,13 +491,13 @@ static inline bool IsPlayerBuildableVehi
 

	
 
#define FOR_ALL_VEHICLES_FROM(v, start) for (v = GetVehicle(start); v != NULL; v = (v->index + 1U < GetVehiclePoolSize()) ? GetVehicle(v->index + 1) : NULL) if (IsValidVehicle(v))
 
#define FOR_ALL_VEHICLES(v) FOR_ALL_VEHICLES_FROM(v, 0)
 

	
 
/**
 
 * Check if an index is a vehicle-index (so between 0 and max-vehicles)
 
 *
 
 * @param index of the vehicle to query
 
 * @return Returns true if the vehicle-id is in range
 
 */
 
static inline bool IsValidVehicleID(uint index)
 
{
 
	return index < GetVehiclePoolSize() && IsValidVehicle(GetVehicle(index));
 
}
 
@@ -510,35 +512,42 @@ static inline Order *GetVehicleOrder(con
 
	while (order != NULL && index-- > 0)
 
		order = order->next;
 

	
 
	return order;
 
}
 

	
 
/* Returns the last order of a vehicle, or NULL if it doesn't exists */
 
/**
 
 * Returns the last order of a vehicle, or NULL if it doesn't exists
 
 * @param v Vehicle to query
 
 * @return last order of a vehicle, if available
 
 */
 
static inline Order *GetLastVehicleOrder(const Vehicle *v)
 
{
 
	Order *order = v->orders;
 

	
 
	if (order == NULL) return NULL;
 

	
 
	while (order->next != NULL)
 
		order = order->next;
 

	
 
	return order;
 
}
 

	
 
/* Get the first vehicle of a shared-list, so we only have to walk forwards */
 
/** Get the first vehicle of a shared-list, so we only have to walk forwards
 
 * @param v Vehicle to query
 
 * @return first vehicle of a shared-list
 
 */
 
static inline Vehicle *GetFirstVehicleFromSharedList(const Vehicle *v)
 
{
 
	Vehicle *u = (Vehicle *)v;
 
	while (u->prev_shared != NULL) u = u->prev_shared;
 

	
 
	return u;
 
}
 

	
 
// NOSAVE: Return values from various commands.
 
/* NOSAVE: Return values from various commands. */
 
VARDEF VehicleID _new_vehicle_id;
 
VARDEF uint16 _returned_refit_capacity;
 

	
 
static const VehicleID INVALID_VEHICLE = 0xFFFF;
 

	
 
/**
src/vehicle_gui.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/** @file vehicle_gui.cpp */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "debug.h"
 
#include "functions.h"
 
#include "player.h"
 
#include "station.h"
 
@@ -159,18 +161,18 @@ static void SortVehicleList(vehiclelist_
 
void DepotSortList(Vehicle **v, uint16 length)
 
{
 
	_internal_sort_order = 0;
 
	qsort((void*)v, length, sizeof(v[0]), _vehicle_sorter[0]);
 
}
 

	
 
// draw the vehicle profit button in the vehicle list window.
 
/** draw the vehicle profit button in the vehicle list window. */
 
void DrawVehicleProfitButton(const Vehicle *v, int x, int y)
 
{
 
	SpriteID pal;
 

	
 
	// draw profit-based colored icons
 
	/* draw profit-based colored icons */
 
	if (v->age <= 365 * 2) {
 
		pal = PALETTE_TO_GREY;
 
	} else if (v->profit_last_year < 0) {
 
		pal = PALETTE_TO_RED;
 
	} else if (v->profit_last_year < 10000) {
 
		pal = PALETTE_TO_YELLOW;
 
@@ -418,12 +420,13 @@ static const WindowDesc _vehicle_refit_d
 
	_vehicle_refit_widgets,
 
	VehicleRefitWndProc,
 
};
 

	
 
/** Show the refit window for a vehicle
 
* @param *v The vehicle to show the refit window for
 
* @param order of the vehicle (?)
 
*/
 
void ShowVehicleRefitWindow(const Vehicle *v, VehicleOrderID order)
 
{
 
	Window *w;
 

	
 
	DeleteWindowById(WC_VEHICLE_REFIT, v->index);
 
@@ -463,32 +466,32 @@ void ShowVehicleRefitWindow(const Vehicl
 
				break;
 
			default: NOT_REACHED();
 
		}
 
	}
 
}
 

	
 
/* Display additional text from NewGRF in the purchase information window */
 
/** Display additional text from NewGRF in the purchase information window */
 
uint ShowAdditionalText(int x, int y, uint w, EngineID engine)
 
{
 
	uint16 callback = GetVehicleCallback(CBID_VEHICLE_ADDITIONAL_TEXT, 0, 0, engine, NULL);
 
	if (callback == CALLBACK_FAILED) return 0;
 

	
 
	// STR_02BD is used to start the string with {BLACK}
 
	/* STR_02BD is used to start the string with {BLACK} */
 
	SetDParam(0, GetGRFStringID(GetEngineGRFID(engine), 0xD000 + callback));
 
	return DrawStringMultiLine(x, y, STR_02BD, w);
 
}
 

	
 
/* Count the number of bits that are set in a mask */
 
/** Count the number of bits that are set in a mask */
 
static uint CountBits(uint32 mask)
 
{
 
	uint c = 0;
 
	for (; mask != 0; mask >>= 1) if (HASBIT(mask, 0)) c++;
 
	return c;
 
}
 

	
 
/* Display list of cargo types of the engine, for the purchase information window */
 
/** Display list of cargo types of the engine, for the purchase information window */
 
uint ShowRefitOptionsList(int x, int y, uint w, EngineID engine)
 
{
 
	/* List of cargo types of this engine */
 
	uint32 cmask = EngInfo(engine)->refit_mask;
 
	/* List of cargo types available in this climate */
 
	uint32 lmask = _cargo_mask;
 
@@ -526,13 +529,13 @@ uint ShowRefitOptionsList(int x, int y, 
 
	/* Terminate and display the completed string */
 
	*b = '\0';
 
	return DrawStringMultiLine(x, y, STR_SPEC_USERSTRING, w);
 
}
 

	
 

	
 
// if the sorting criteria had the same value, sort vehicle by unitnumber
 
/* if the sorting criteria had the same value, sort vehicle by unitnumber */
 
#define VEHICLEUNITNUMBERSORTER(r, a, b) {if (r == 0) {r = a->unitnumber - b->unitnumber;}}
 

	
 
static int CDECL VehicleNumberSorter(const void *a, const void *b)
 
{
 
	const Vehicle* va = *(const Vehicle**)a;
 
	const Vehicle* vb = *(const Vehicle**)b;
 
@@ -1137,13 +1140,13 @@ void PlayerVehWndProc(Window *w, WindowE
 
		}	break;
 

	
 
		case WE_DROPDOWN_SELECT: /* we have selected a dropdown item in the list */
 
			switch (e->we.dropdown.button) {
 
				case VLW_WIDGET_SORT_BY_PULLDOWN:
 
					if (vl->l.sort_type != e->we.dropdown.index) {
 
						// value has changed -> resort
 
						/* value has changed -> resort */
 
						vl->l.flags |= VL_RESORT;
 
						vl->l.sort_type = e->we.dropdown.index;
 
						vl->_sorting->criteria = vl->l.sort_type;
 
					}
 
					break;
 
				case VLW_WIDGET_MANAGE_VEHICLES_DROPDOWN:
src/vehicle_gui.h
Show inline comments
 
/* $Id$ */
 

	
 
/** @file vehicle_gui.h */
 

	
 
#ifndef VEHICLE_GUI_H
 
#define VEHICLE_GUI_H
 

	
 
#include "window.h"
 
#include "vehicle.h"
 

	
src/viewport.cpp
Show inline comments
 
@@ -22,13 +22,13 @@
 
#include "waypoint.h"
 
#include "variables.h"
 
#include "train.h"
 

	
 
#define VIEWPORT_DRAW_MEM (65536 * 2)
 

	
 
// XXX - maximum viewports is maximum windows - 2 (main toolbar + status bar)
 
/* XXX - maximum viewports is maximum windows - 2 (main toolbar + status bar) */
 
static ViewPort _viewports[25 - 2];
 
static uint32 _active_viewports;    ///< bitmasked variable where each bit signifies if a viewport is in use or not
 
assert_compile(lengthof(_viewports) < sizeof(_active_viewports) * 8);
 

	
 
static bool _added_tile_sprite;
 
static bool _offset_ground_sprites;
 
@@ -88,14 +88,14 @@ struct ParentSpriteToDraw {
 
	ChildScreenSpriteToDraw *child;
 
	byte unk16;
 
	byte zmin;
 
	byte zmax;
 
};
 

	
 
// Quick hack to know how much memory to reserve when allocating from the spritelist
 
// to prevent a buffer overflow.
 
/* Quick hack to know how much memory to reserve when allocating from the spritelist
 
 * to prevent a buffer overflow. */
 
#define LARGEST_SPRITELIST_STRUCT ParentSpriteToDraw
 

	
 
struct ViewportDrawer {
 
	DrawPixelInfo dpi;
 

	
 
	byte *spritelist_mem;
 
@@ -435,13 +435,13 @@ void DrawGroundSpriteAt(SpriteID image, 
 
	vd->last_tile = &ts->next;
 
}
 

	
 
void DrawGroundSprite(SpriteID image, SpriteID pal)
 
{
 
	if (_offset_ground_sprites) {
 
		// offset ground sprite because of foundation?
 
		/* offset ground sprite because of foundation? */
 
		AddChildSpriteScreen(image, pal, _cur_vd->offs_x, _cur_vd->offs_y);
 
	} else {
 
		_added_tile_sprite = true;
 
		DrawGroundSpriteAt(image, pal, _cur_ti->x, _cur_ti->y, _cur_ti->z);
 
	}
 
}
 
@@ -490,18 +490,18 @@ void AddSortableSpriteToDraw(SpriteID im
 
		DEBUG(sprite, 0, "Out of sprite memory");
 
		return;
 
	}
 
	ps = (ParentSpriteToDraw*)vd->spritelist_mem;
 

	
 
	if (vd->parent_list >= vd->eof_parent_list) {
 
		// This can happen rarely, mostly when you zoom out completely
 
		//  and have a lot of stuff that moves (and is added to the
 
		//  sort-list, this function). To solve it, increase
 
		//  parent_list somewhere below to a higher number.
 
		// This can not really hurt you, it just gives some black
 
		//  spots on the screen ;)
 
		/* This can happen rarely, mostly when you zoom out completely
 
		 *  and have a lot of stuff that moves (and is added to the
 
		 *  sort-list, this function). To solve it, increase
 
		 *  parent_list somewhere below to a higher number.
 
		 * This can not really hurt you, it just gives some black
 
		 *  spots on the screen ;) */
 
		DEBUG(sprite, 0, "Out of sprite memory (parent_list)");
 
		return;
 
	}
 

	
 
	pt = RemapCoords(x, y, z);
 
	spr = GetSprite(image & SPRITE_MASK);
 
@@ -643,37 +643,37 @@ static const int _AutorailType[6][2] = {
 

	
 
static void DrawTileSelection(const TileInfo *ti)
 
{
 
	SpriteID image;
 
	SpriteID pal;
 

	
 
	// Draw a red error square?
 
	/* Draw a red error square? */
 
	if (_thd.redsq != 0 && _thd.redsq == ti->tile) {
 
		DrawSelectionSprite(SPR_SELECT_TILE + _tileh_to_sprite[ti->tileh], PALETTE_TILE_RED_PULSATING, ti);
 
		return;
 
	}
 

	
 
	// no selection active?
 
	/* no selection active? */
 
	if (_thd.drawstyle == 0) return;
 

	
 
	// Inside the inner area?
 
	/* Inside the inner area? */
 
	if (IS_INSIDE_1D(ti->x, _thd.pos.x, _thd.size.x) &&
 
			IS_INSIDE_1D(ti->y, _thd.pos.y, _thd.size.y)) {
 
		if (_thd.drawstyle & HT_RECT) {
 
			image = SPR_SELECT_TILE + _tileh_to_sprite[ti->tileh];
 
			DrawSelectionSprite(image, _thd.make_square_red ? PALETTE_SEL_TILE_RED : PAL_NONE, ti);
 
		} else if (_thd.drawstyle & HT_POINT) {
 
			// Figure out the Z coordinate for the single dot.
 
			/* Figure out the Z coordinate for the single dot. */
 
			byte z = ti->z;
 
			if (ti->tileh & SLOPE_N) {
 
				z += TILE_HEIGHT;
 
				if (ti->tileh == SLOPE_STEEP_N) z += TILE_HEIGHT;
 
			}
 
			DrawGroundSpriteAt(_cur_dpi->zoom != 2 ? SPR_DOT : SPR_DOT_SMALL, PAL_NONE, ti->x, ti->y, z);
 
		} else if (_thd.drawstyle & HT_RAIL /*&& _thd.place_mode == VHM_RAIL*/) {
 
			// autorail highlight piece under cursor
 
			/* autorail highlight piece under cursor */
 
			uint type = _thd.drawstyle & 0xF;
 
			int offset;
 

	
 
			assert(type <= 5);
 

	
 
			offset = _AutorailTilehSprite[ti->tileh][_AutorailType[type][0]];
 
@@ -685,13 +685,13 @@ static void DrawTileSelection(const Tile
 
				pal = PALETTE_TO_RED;
 
			}
 

	
 
			DrawSelectionSprite(image, _thd.make_square_red ? PALETTE_SEL_TILE_RED : pal, ti);
 

	
 
		} else if (IsPartOfAutoLine(ti->x, ti->y)) {
 
			// autorail highlighting long line
 
			/* autorail highlighting long line */
 
			int dir = _thd.drawstyle & ~0xF0;
 
			int offset;
 
			uint side;
 

	
 
			if (dir < 2) {
 
				side = 0;
 
@@ -711,18 +711,18 @@ static void DrawTileSelection(const Tile
 

	
 
			DrawSelectionSprite(image, _thd.make_square_red ? PALETTE_SEL_TILE_RED : pal, ti);
 
		}
 
		return;
 
	}
 

	
 
	// Check if it's inside the outer area?
 
	/* Check if it's inside the outer area? */
 
	if (_thd.outersize.x &&
 
			_thd.size.x < _thd.size.x + _thd.outersize.x &&
 
			IS_INSIDE_1D(ti->x, _thd.pos.x + _thd.offs.x, _thd.size.x + _thd.outersize.x) &&
 
			IS_INSIDE_1D(ti->y, _thd.pos.y + _thd.offs.y, _thd.size.y + _thd.outersize.y)) {
 
		// Draw a blue rect.
 
		/* Draw a blue rect. */
 
		DrawSelectionSprite(SPR_SELECT_TILE + _tileh_to_sprite[ti->tileh], PALETTE_SEL_TILE_BLUE, ti);
 
		return;
 
	}
 
}
 

	
 
static void ViewportAddLandscape()
 
@@ -731,17 +731,17 @@ static void ViewportAddLandscape()
 
	int x, y, width, height;
 
	TileInfo ti;
 
	bool direction;
 

	
 
	_cur_ti = &ti;
 

	
 
	// Transform into tile coordinates and round to closest full tile
 
	/* Transform into tile coordinates and round to closest full tile */
 
	x = ((vd->dpi.top >> 1) - (vd->dpi.left >> 2)) & ~0xF;
 
	y = ((vd->dpi.top >> 1) + (vd->dpi.left >> 2) - 0x10) & ~0xF;
 

	
 
	// determine size of area
 
	/* determine size of area */
 
	{
 
		Point pt = RemapCoords(x, y, 241);
 
		width = (vd->dpi.left + vd->dpi.width - pt.x + 95) >> 6;
 
		height = (vd->dpi.top + vd->dpi.height - pt.y) >> 5 << 1;
 
	}
 

	
 
@@ -1125,13 +1125,13 @@ static void ViewportSortParentSprites(Pa
 
								ps->zmin < ps2->zmax
 
							)) {
 
						continue;
 
					}
 
				}
 

	
 
				// Swap the two sprites ps and ps2 using bubble-sort algorithm.
 
				/* Swap the two sprites ps and ps2 using bubble-sort algorithm. */
 
				psd3 = psd;
 
				do {
 
					ParentSpriteToDraw* temp = *psd3;
 
					*psd3 = ps2;
 
					ps2 = temp;
 

	
 
@@ -1270,14 +1270,14 @@ void ViewportDoDraw(const ViewPort *vp, 
 

	
 
	ViewportAddTownNames(&vd.dpi);
 
	ViewportAddStationNames(&vd.dpi);
 
	ViewportAddSigns(&vd.dpi);
 
	ViewportAddWaypoints(&vd.dpi);
 

	
 
	// This assert should never happen (because the length of the parent_list
 
	//  is checked)
 
	/* This assert should never happen (because the length of the parent_list
 
	 *  is checked) */
 
	assert(vd.parent_list <= endof(parent_list));
 

	
 
	if (vd.first_tile != NULL) ViewportDrawTileSprites(vd.first_tile);
 

	
 
	/* null terminate parent sprite list */
 
	*vd.parent_list = NULL;
 
@@ -1287,14 +1287,14 @@ void ViewportDoDraw(const ViewPort *vp, 
 

	
 
	if (vd.first_string != NULL) ViewportDrawStrings(&vd.dpi, vd.first_string);
 

	
 
	_cur_dpi = old_dpi;
 
}
 

	
 
// Make sure we don't draw a too big area at a time.
 
// If we do, the sprite memory will overflow.
 
/** Make sure we don't draw a too big area at a time.
 
 * If we do, the sprite memory will overflow. */
 
static void ViewportDrawChk(const ViewPort *vp, int left, int top, int right, int bottom)
 
{
 
	if (((bottom - top) * (right - left) << (2 * vp->zoom)) > 180000) {
 
		if ((bottom - top) > (right - left)) {
 
			int t = (top + bottom) >> 1;
 
			ViewportDrawChk(vp, left, top, right, t);
 
@@ -1356,26 +1356,26 @@ void UpdateViewportPosition(Window *w)
 
	} else {
 
		int x;
 
		int y;
 
		int vx;
 
		int vy;
 

	
 
		// Center of the viewport is hot spot
 
		/* Center of the viewport is hot spot */
 
		x = WP(w,vp_d).scrollpos_x + vp->virtual_width / 2;
 
		y = WP(w,vp_d).scrollpos_y + vp->virtual_height / 2;
 
		// Convert viewport coordinates to map coordinates
 
		// Calculation is scaled by 4 to avoid rounding errors
 
		/* Convert viewport coordinates to map coordinates
 
		 * Calculation is scaled by 4 to avoid rounding errors */
 
		vx = -x + y * 2;
 
		vy =  x + y * 2;
 
		// clamp to size of map
 
		/* clamp to size of map */
 
		vx = clamp(vx, 0 * 4, MapMaxX() * TILE_SIZE * 4);
 
		vy = clamp(vy, 0 * 4, MapMaxY() * TILE_SIZE * 4);
 
		// Convert map coordinates to viewport coordinates
 
		/* Convert map coordinates to viewport coordinates */
 
		x = (-vx + vy) / 2;
 
		y = ( vx + vy) / 4;
 
		// Set position
 
		/* Set position */
 
		WP(w, vp_d).scrollpos_x = x - vp->virtual_width / 2;
 
		WP(w, vp_d).scrollpos_y = y - vp->virtual_height / 2;
 

	
 
		SetViewportPosition(w, WP(w, vp_d).scrollpos_x, WP(w, vp_d).scrollpos_y);
 
	}
 
}
 
@@ -1856,19 +1856,19 @@ void SetTileSelectBigSize(int ox, int oy
 
	_thd.offs.x = ox * TILE_SIZE;
 
	_thd.offs.y = oy * TILE_SIZE;
 
	_thd.new_outersize.x = sx * TILE_SIZE;
 
	_thd.new_outersize.y = sy * TILE_SIZE;
 
}
 

	
 
/* returns the best autorail highlight type from map coordinates */
 
/** returns the best autorail highlight type from map coordinates */
 
static byte GetAutorailHT(int x, int y)
 
{
 
	return HT_RAIL | _AutorailPiece[x & 0xF][y & 0xF];
 
}
 

	
 
// called regular to update tile highlighting in all cases
 
/** called regular to update tile highlighting in all cases */
 
void UpdateTileSelection()
 
{
 
	int x1;
 
	int y1;
 

	
 
	_thd.new_drawstyle = 0;
 
@@ -1909,33 +1909,33 @@ void UpdateTileSelection()
 
			}
 
			_thd.new_pos.x = x1 & ~0xF;
 
			_thd.new_pos.y = y1 & ~0xF;
 
		}
 
	}
 

	
 
	// redraw selection
 
	/* redraw selection */
 
	if (_thd.drawstyle != _thd.new_drawstyle ||
 
			_thd.pos.x != _thd.new_pos.x || _thd.pos.y != _thd.new_pos.y ||
 
			_thd.size.x != _thd.new_size.x || _thd.size.y != _thd.new_size.y ||
 
	    _thd.outersize.x != _thd.new_outersize.x ||
 
	    _thd.outersize.y != _thd.new_outersize.y) {
 
		// clear the old selection?
 
		/* clear the old selection? */
 
		if (_thd.drawstyle) SetSelectionTilesDirty();
 

	
 
		_thd.drawstyle = _thd.new_drawstyle;
 
		_thd.pos = _thd.new_pos;
 
		_thd.size = _thd.new_size;
 
		_thd.outersize = _thd.new_outersize;
 
		_thd.dirty = 0xff;
 

	
 
		// draw the new selection?
 
		/* draw the new selection? */
 
		if (_thd.new_drawstyle) SetSelectionTilesDirty();
 
	}
 
}
 

	
 
// highlighting tiles while only going over them with the mouse
 
/** highlighting tiles while only going over them with the mouse */
 
void VpStartPlaceSizing(TileIndex tile, int user)
 
{
 
	_thd.userdata = user;
 
	_thd.selend.x = TileX(tile) * TILE_SIZE;
 
	_thd.selstart.x = TileX(tile) * TILE_SIZE;
 
	_thd.selend.y = TileY(tile) * TILE_SIZE;
 
@@ -1979,13 +1979,13 @@ void VpSetPresizeRange(TileIndex from, T
 
static void VpStartPreSizing()
 
{
 
	_thd.selend.x = -1;
 
	_special_mouse_mode = WSM_PRESIZE;
 
}
 

	
 
/* returns information about the 2x1 piece to be build.
 
/** returns information about the 2x1 piece to be build.
 
 * The lower bits (0-3) are the track type. */
 
static byte Check2x1AutoRail(int mode)
 
{
 
	int fxpy = _tile_fract_coords.x + _tile_fract_coords.y;
 
	int sxpy = (_thd.selend.x & 0xF) + (_thd.selend.y & 0xF);
 
	int fxmy = _tile_fract_coords.x - _tile_fract_coords.y;
 
@@ -2130,13 +2130,13 @@ static int CalcHeightdiff(HighLightStyle
 
	/* Minimap shows height in intervals of 50 meters, let's do the same */
 
	return (int)(h1 - h0) * 50;
 
}
 

	
 
static const StringID measure_strings_length[] = {STR_NULL, STR_MEASURE_LENGTH, STR_MEASURE_LENGTH_HEIGHTDIFF};
 

	
 
// while dragging
 
/** while dragging */
 
static void CalcRaildirsDrawstyle(TileHighlightData *thd, int x, int y, int method)
 
{
 
	HighLightStyle b;
 
	uint w, h;
 

	
 
	int dx = thd->selstart.x - (thd->selend.x & ~0xF);
 
@@ -2381,39 +2381,39 @@ calc_heightdiff_single_direction:;
 
	}
 

	
 
	_thd.selend.x = x;
 
	_thd.selend.y = y;
 
}
 

	
 
// while dragging
 
/** while dragging */
 
bool VpHandlePlaceSizingDrag()
 
{
 
	Window *w;
 
	WindowEvent e;
 

	
 
	if (_special_mouse_mode != WSM_SIZING) return true;
 

	
 
	e.we.place.userdata = _thd.userdata;
 

	
 
	// stop drag mode if the window has been closed
 
	/* stop drag mode if the window has been closed */
 
	w = FindWindowById(_thd.window_class,_thd.window_number);
 
	if (w == NULL) {
 
		ResetObjectToPlace();
 
		return false;
 
	}
 

	
 
	// while dragging execute the drag procedure of the corresponding window (mostly VpSelectTilesWithMethod() )
 
	/* while dragging execute the drag procedure of the corresponding window (mostly VpSelectTilesWithMethod() ) */
 
	if (_left_button_down) {
 
		e.event = WE_PLACE_DRAG;
 
		e.we.place.pt = GetTileBelowCursor();
 
		w->wndproc(w, &e);
 
		return false;
 
	}
 

	
 
	// mouse button released..
 
	// keep the selected tool, but reset it to the original mode.
 
	/* mouse button released..
 
	 * keep the selected tool, but reset it to the original mode. */
 
	_special_mouse_mode = WSM_NONE;
 
	if (_thd.next_drawstyle == HT_RECT) {
 
		_thd.place_mode = VHM_RECT;
 
	} else if ((e.we.place.userdata & 0xF) == VPM_SIGNALDIRS) { // some might call this a hack... -- Dominik
 
		_thd.place_mode = VHM_RECT;
 
	} else if (_thd.next_drawstyle & HT_LINE) {
 
@@ -2422,13 +2422,13 @@ bool VpHandlePlaceSizingDrag()
 
		_thd.place_mode = VHM_RAIL;
 
	} else {
 
		_thd.place_mode = VHM_POINT;
 
	}
 
	SetTileSelectSize(1, 1);
 

	
 
	// and call the mouseup event.
 
	/* and call the mouseup event. */
 
	e.event = WE_PLACE_MOUSEUP;
 
	e.we.place.pt = _thd.selend;
 
	e.we.place.tile = TileVirtXY(e.we.place.pt.x, e.we.place.pt.y);
 
	e.we.place.starttile = TileVirtXY(_thd.selstart.x, _thd.selstart.y);
 
	w->wndproc(w, &e);
 

	
 
@@ -2443,13 +2443,13 @@ void SetObjectToPlaceWnd(CursorID icon, 
 
#include "table/animcursors.h"
 

	
 
void SetObjectToPlace(CursorID icon, SpriteID pal, byte mode, WindowClass window_class, WindowNumber window_num)
 
{
 
	Window *w;
 

	
 
	// undo clicking on button
 
	/* undo clicking on button */
 
	if (_thd.place_mode != 0) {
 
		_thd.place_mode = 0;
 
		w = FindWindowById(_thd.window_class, _thd.window_number);
 
		if (w != NULL) CallWindowEventNP(w, WE_ABORT_PLACE_OBJ);
 
	}
 

	
src/viewport.h
Show inline comments
 
/* $Id$ */
 

	
 
/** @file viewport.h */
 

	
 
#ifndef VIEWPORT_H
 
#define VIEWPORT_H
 

	
 
struct ViewPort {
 
	int left,top;                       // screen coordinates for the viewport
 
	int width, height;                  // screen width/height for the viewport
 
@@ -12,13 +14,13 @@ struct ViewPort {
 

	
 
	byte zoom;
 
};
 

	
 
void SetSelectionRed(bool);
 

	
 
/* viewport.c */
 
/* viewport.cpp */
 
void InitViewports();
 
void DeleteWindowViewport(Window *w);
 
void AssignWindowViewport(Window *w, int x, int y,
 
	int width, int height, uint32 follow_flags, byte zoom);
 
ViewPort *IsPtInWindowViewport(const Window *w, int x, int y);
 
Point GetTileBelowCursor();
 
@@ -71,34 +73,34 @@ enum {
 
	VPM_RAILDIRS        = 3,
 
	VPM_X_AND_Y         = 4,
 
	VPM_X_AND_Y_LIMITED = 5,
 
	VPM_SIGNALDIRS      = 6
 
};
 

	
 
// viewport highlight mode (for highlighting tiles below cursor)
 
/* viewport highlight mode (for highlighting tiles below cursor) */
 
enum {
 
	VHM_NONE    = 0, // default
 
	VHM_RECT    = 1, // rectangle (stations, depots, ...)
 
	VHM_POINT   = 2, // point (lower land, raise land, level land, ...)
 
	VHM_SPECIAL = 3, // special mode used for highlighting while dragging (and for tunnels/docks)
 
	VHM_DRAG    = 4, // dragging items in the depot windows
 
	VHM_RAIL    = 5, // rail pieces
 
	VHM_NONE    = 0, ///< default
 
	VHM_RECT    = 1, ///< rectangle (stations, depots, ...)
 
	VHM_POINT   = 2, ///< point (lower land, raise land, level land, ...)
 
	VHM_SPECIAL = 3, ///< special mode used for highlighting while dragging (and for tunnels/docks)
 
	VHM_DRAG    = 4, ///< dragging items in the depot windows
 
	VHM_RAIL    = 5, ///< rail pieces
 
};
 

	
 
void VpSelectTilesWithMethod(int x, int y, int method);
 

	
 
// highlighting draw styles
 
/* highlighting draw styles */
 
typedef byte HighLightStyle;
 
enum HighLightStyles {
 
	HT_NONE   = 0x00,
 
	HT_RECT   = 0x80,
 
	HT_POINT  = 0x40,
 
	HT_LINE   = 0x20, /* used for autorail highlighting (longer streches)
 
	                   * (uses lower bits to indicate direction) */
 
	HT_RAIL   = 0x10, /* autorail (one piece)
 
	                  * (uses lower bits to indicate direction) */
 
	HT_LINE   = 0x20,    ///< used for autorail highlighting (longer streches)
 
	                     ///< (uses lower bits to indicate direction)
 
	HT_RAIL   = 0x10,    ///< autorail (one piece)
 
	                     ///< (uses lower bits to indicate direction)
 
	HT_DRAG_MASK = 0xF0, ///< masks the drag-type
 

	
 
	/* lower bits (used with HT_LINE and HT_RAIL):
 
	 * (see ASCII art in autorail.h for a visual interpretation) */
 
	HT_DIR_X  = 0,    ///< X direction
 
	HT_DIR_Y  = 1,    ///< Y direction
 
@@ -135,13 +137,13 @@ struct TileHighlightData {
 

	
 
	int userdata;
 
	TileIndex redsq;
 
};
 

	
 

	
 
// common button handler
 
/* common button handler */
 
bool HandlePlacePushButton(Window *w, int widget, CursorID cursor, int mode, PlaceProc *placeproc);
 

	
 
VARDEF Point _tile_fract_coords;
 

	
 
extern TileHighlightData _thd;
 

	
src/void_map.h
Show inline comments
 
/* $Id$ */
 

	
 
/** @file void_map.h */
 

	
 
#ifndef VOID_MAP_H
 
#define VOID_MAP_H
 

	
 
static inline void MakeVoid(TileIndex t)
 
{
 
	SetTileType(t, MP_VOID);
0 comments (0 inline, 0 general)