Changeset - r23538:8df50944b27a
[Not reviewed]
master
! ! !
Henry Wilson - 6 years ago 2019-03-03 17:30:09
m3henry@googlemail.com
Codechange: Removed SmallVector completely
69 files changed with 109 insertions and 127 deletions:
0 comments (0 inline, 0 general)
src/animated_tile.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file animated_tile.cpp Everything related to animated tiles. */
 

	
 
#include "stdafx.h"
 
#include "core/alloc_func.hpp"
 
#include "core/smallvec_type.hpp"
 
#include "tile_cmd.h"
 
#include "viewport_func.h"
 
#include "framerate_type.h"
 

	
 
#include "safeguards.h"
 

	
 
/** The table/list with animated tiles. */
 
SmallVector<TileIndex, 256> _animated_tiles;
 
std::vector<TileIndex> _animated_tiles;
 

	
 
/**
 
 * Removes the given tile from the animated tile table.
 
 * @param tile the tile to remove
 
 */
 
void DeleteAnimatedTile(TileIndex tile)
 
{
 
	auto to_remove = std::find(_animated_tiles.begin(), _animated_tiles.end(), tile);
 
	if (to_remove != _animated_tiles.end()) {
 
		/* The order of the remaining elements must stay the same, otherwise the animation loop may miss a tile. */
 
		_animated_tiles.erase(to_remove);
 
		MarkTileDirtyByTile(tile);
 
	}
 
}
 

	
 
/**
 
 * Add the given tile to the animated tile table (if it does not exist
 
 * on that table yet). Also increases the size of the table if necessary.
 
 * @param tile the tile to make animated
 
 */
 
void AddAnimatedTile(TileIndex tile)
 
{
 
	MarkTileDirtyByTile(tile);
 
	include(_animated_tiles, tile);
src/company_gui.cpp
Show inline comments
 
@@ -541,49 +541,49 @@ public:
 
		int icon_y_offset = height / 2;
 
		int text_y_offset = (height - FONT_HEIGHT_NORMAL) / 2 + 1;
 
		DrawSprite(SPR_VEH_BUS_SIDE_VIEW, PALETTE_RECOLOUR_START + (this->result % COLOUR_END),
 
				rtl ? right - 2 - ScaleGUITrad(14) : left + ScaleGUITrad(14) + 2,
 
				top + icon_y_offset);
 
		DrawString(rtl ? left + 2 : left + ScaleGUITrad(28) + 4,
 
				rtl ? right - ScaleGUITrad(28) - 4 : right - 2,
 
				top + text_y_offset, this->String(), sel ? TC_WHITE : TC_BLACK);
 
	}
 
};
 

	
 
static const int LEVEL_WIDTH = 10; ///< Indenting width of a sub-group in pixels
 

	
 
typedef GUIList<const Group*> GUIGroupList;
 

	
 
/** Company livery colour scheme window. */
 
struct SelectCompanyLiveryWindow : public Window {
 
private:
 
	uint32 sel;
 
	LiveryClass livery_class;
 
	Dimension square;
 
	uint rows;
 
	uint line_height;
 
	GUIGroupList groups;
 
	SmallVector<int, 32> indents;
 
	std::vector<int> indents;
 
	Scrollbar *vscroll;
 

	
 
	void ShowColourDropDownMenu(uint32 widget)
 
	{
 
		uint32 used_colours = 0;
 
		const Company *c;
 
		const Livery *livery, *default_livery = NULL;
 
		bool primary = widget == WID_SCL_PRI_COL_DROPDOWN;
 
		byte default_col;
 

	
 
		/* Disallow other company colours for the primary colour */
 
		if (this->livery_class < LC_GROUP_RAIL && HasBit(this->sel, LS_DEFAULT) && primary) {
 
			FOR_ALL_COMPANIES(c) {
 
				if (c->index != _local_company) SetBit(used_colours, c->colour);
 
			}
 
		}
 

	
 
		c = Company::Get((CompanyID)this->window_number);
 

	
 
		if (this->livery_class < LC_GROUP_RAIL) {
 
			/* Get the first selected livery to use as the default dropdown item */
 
			LiveryScheme scheme;
 
			for (scheme = LS_BEGIN; scheme < LS_END; scheme++) {
 
				if (HasBit(this->sel, scheme)) break;
src/core/pool_type.hpp
Show inline comments
 
@@ -5,49 +5,49 @@
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file pool_type.hpp Defintion of Pool, structure used to access PoolItems, and PoolItem, base structure for Vehicle, Town, and other indexed items. */
 

	
 
#ifndef POOL_TYPE_HPP
 
#define POOL_TYPE_HPP
 

	
 
#include "smallvec_type.hpp"
 
#include "enum_type.hpp"
 

	
 
/** Various types of a pool. */
 
enum PoolType {
 
	PT_NONE    = 0x00, ///< No pool is selected.
 
	PT_NORMAL  = 0x01, ///< Normal pool containing game objects.
 
	PT_NCLIENT = 0x02, ///< Network client pools.
 
	PT_NADMIN  = 0x04, ///< Network admin pool.
 
	PT_DATA    = 0x08, ///< NewGRF or other data, that is not reset together with normal pools.
 
	PT_ALL     = 0x0F, ///< All pool types.
 
};
 
DECLARE_ENUM_AS_BIT_SET(PoolType)
 

	
 
typedef SmallVector<struct PoolBase *, 4> PoolVector; ///< Vector of pointers to PoolBase
 
typedef std::vector<struct PoolBase *> PoolVector; ///< Vector of pointers to PoolBase
 

	
 
/** Base class for base of all pools. */
 
struct PoolBase {
 
	const PoolType type; ///< Type of this pool.
 

	
 
	/**
 
	 * Function used to access the vector of all pools.
 
	 * @return pointer to vector of all pools
 
	 */
 
	static PoolVector *GetPools()
 
	{
 
		static PoolVector *pools = new PoolVector();
 
		return pools;
 
	}
 

	
 
	static void Clean(PoolType);
 

	
 
	/**
 
	 * Constructor registers this object in the pool vector.
 
	 * @param pt type of this pool.
 
	 */
 
	PoolBase(PoolType pt) : type(pt)
 
	{
 
		PoolBase::GetPools()->push_back(this);
src/core/smallmap_type.hpp
Show inline comments
 
@@ -19,49 +19,49 @@
 
 * Simple pair of data. Both types have to be POD ("Plain Old Data")!
 
 * @tparam T Key type.
 
 * @tparam U Value type.
 
 */
 
template <typename T, typename U>
 
struct SmallPair {
 
	T first;
 
	U second;
 

	
 
	/** Initializes this Pair with data */
 
	inline SmallPair(const T &first, const U &second) : first(first), second(second) { }
 
	SmallPair() = default;
 
};
 

	
 
/**
 
 * Implementation of simple mapping class. Both types have to be POD ("Plain Old Data")!
 
 * It has inherited accessors from SmallVector().
 
 * @tparam T Key type.
 
 * @tparam U Value type.
 
 * @tparam S Unit of allocation.
 
 *
 
 * @see SmallVector
 
 */
 
template <typename T, typename U, uint S = 16>
 
struct SmallMap : SmallVector<SmallPair<T, U>, S> {
 
struct SmallMap : std::vector<SmallPair<T, U> > {
 
	typedef ::SmallPair<T, U> Pair;
 
	typedef Pair *iterator;
 
	typedef const Pair *const_iterator;
 

	
 
	/** Creates new SmallMap. Data are initialized in SmallVector constructor */
 
	inline SmallMap() { }
 
	/** Data are freed in SmallVector destructor */
 
	inline ~SmallMap() { }
 

	
 
	/**
 
	 * Finds given key in this map
 
	 * @param key key to find
 
	 * @return &Pair(key, data) if found, this->End() if not
 
	 */
 
	inline typename std::vector<Pair>::const_iterator Find(const T &key) const
 
	{
 
		typename std::vector<Pair>::const_iterator it;
 
		for (it = std::vector<Pair>::begin(); it != std::vector<Pair>::end(); it++) {
 
			if (key == it->first) return it;
 
		}
 
		return it;
 
	}
 

	
 
	/**
src/core/smallstack_type.hpp
Show inline comments
 
@@ -66,49 +66,49 @@ public:
 

	
 
private:
 

	
 
	inline Tindex FindFirstFree()
 
	{
 
		Tindex index = this->first_free;
 
		for (; index < this->first_unused; index++) {
 
			if (!this->data[index].valid) return index;
 
		}
 

	
 
		if (index >= this->data.size() && index < Tmax_size) {
 
			this->data.resize(index + 1);
 
		}
 
		return index;
 
	}
 

	
 
	struct SimplePoolPoolItem : public Titem {
 
		bool valid;
 
	};
 

	
 
	Tindex first_unused;
 
	Tindex first_free;
 

	
 
	ThreadMutex *mutex;
 
	SmallVector<SimplePoolPoolItem, Tgrowth_step> data;
 
	std::vector<SimplePoolPoolItem> data;
 
};
 

	
 
/**
 
 * Base class for SmallStack. We cannot add this into SmallStack itself as
 
 * certain compilers don't like it.
 
 */
 
template <typename Titem, typename Tindex>
 
struct SmallStackItem {
 
	Tindex next; ///< Pool index of next item.
 
	Titem value; ///< Value of current item.
 

	
 
	/**
 
	 * Create a new item.
 
	 * @param value Value of the item.
 
	 * @param next Next item in the stack.
 
	 */
 
	inline SmallStackItem(const Titem &value, Tindex next) :
 
		next(next), value(value) {}
 
	SmallStackItem() = default;
 
};
 

	
 
/**
 
 * Minimal stack that uses a pool to avoid pointers. It has some peculiar
 
 * properties that make it useful for passing around lists of IDs but not much
src/core/smallvec_type.hpp
Show inline comments
 
@@ -13,141 +13,124 @@
 
#define SMALLVEC_TYPE_HPP
 

	
 
#include "alloc_func.hpp"
 
#include "mem_func.hpp"
 
#include <vector>
 
#include <algorithm>
 

	
 
/**
 
 * Helper function to append an item to a vector if it is not already contained
 
 * Consider using std::set, std::unordered_set or std::flat_set in new code
 
 *
 
 * @param vec A reference to the vector to be extended
 
 * @param item Reference to the item to be copy-constructed if not found
 
 *
 
 * @return Whether the item was already present
 
 */
 
template <typename T>
 
inline bool include(std::vector<T>& vec, const T &item)
 
{
 
	const bool is_member = std::find(vec.begin(), vec.end(), item) != vec.end();
 
	if (!is_member) vec.emplace_back(item);
 
	return is_member;
 
}
 

	
 

	
 
/**
 
 * Simple vector template class.
 
 *
 
 * @note There are no asserts in the class so you have
 
 *       to care about that you grab an item which is
 
 *       inside the list.
 
 *
 
 * @tparam T The type of the items stored
 
 * @tparam S The steps of allocation
 
 */
 

	
 

	
 
template <typename T, uint S>
 
using SmallVector = std::vector<T>;
 

	
 
/**
 
 * Helper function to get the index of an item
 
 * Consider using std::set, std::unordered_set or std::flat_set in new code
 
 *
 
 * @param vec A reference to the vector to be extended
 
 * @param item Reference to the item to be search for
 
 *
 
 * @return Index of element if found, otherwise -1
 
 */
 
template <typename T>
 
int find_index(std::vector<T> const& vec, T const& item)
 
{
 
	auto const it = std::find(vec.begin(), vec.end(), item);
 
	if (it != vec.end()) return it - vec.begin();
 

	
 
	return -1;
 
}
 

	
 
/**
 
 * Helper function to append N default-constructed elements and get a pointer to the first new element
 
 * Consider using std::back_inserter in new code
 
 *
 
 * @param vec A reference to the vector to be extended
 
 * @param num The number of elements to default-construct
 
 * @param num Number of elements to be default-constructed
 
 *
 
 * @return Pointer to the first new element
 
 */
 
template <typename T>
 
inline T* grow(std::vector<T>& vec, std::size_t num)
 
T* grow(std::vector<T>& vec, std::size_t num)
 
{
 
	const std::size_t pos = vec.size();
 
	std::size_t const pos = vec.size();
 
	vec.resize(pos + num);
 
	return vec.data() + pos;
 
}
 

	
 

	
 
/**
 
 * Simple vector template class, with automatic free.
 
 *
 
 * @note There are no asserts in the class so you have
 
 *       to care about that you grab an item which is
 
 *       inside the list.
 
 *
 
 * @param T The type of the items stored, must be a pointer
 
 * @param S The steps of allocation
 
 */
 
template <typename T, uint S>
 
class AutoFreeSmallVector : public SmallVector<T, S> {
 
class AutoFreeSmallVector : public std::vector<T> {
 
public:
 
	~AutoFreeSmallVector()
 
	{
 
		this->Clear();
 
	}
 

	
 
	/**
 
	 * Remove all items from the list.
 
	 */
 
	inline void Clear()
 
	{
 
		for (uint i = 0; i < std::vector<T>::size(); i++) {
 
			free(std::vector<T>::operator[](i));
 
		}
 

	
 
		std::vector<T>::clear();
 
	}
 
};
 

	
 
/**
 
 * Simple vector template class, with automatic delete.
 
 *
 
 * @note There are no asserts in the class so you have
 
 *       to care about that you grab an item which is
 
 *       inside the list.
 
 *
 
 * @param T The type of the items stored, must be a pointer
 
 * @param S The steps of allocation
 
 */
 
template <typename T, uint S>
 
class AutoDeleteSmallVector : public SmallVector<T, S> {
 
class AutoDeleteSmallVector : public std::vector<T> {
 
public:
 
	~AutoDeleteSmallVector()
 
	{
 
		this->Clear();
 
	}
 

	
 
	/**
 
	 * Remove all items from the list.
 
	 */
 
	inline void Clear()
 
	{
 
		for (uint i = 0; i < std::vector<T>::size(); i++) {
 
			delete std::vector<T>::operator[](i);
 
		}
 

	
 
		std::vector<T>::clear();
 
	}
 
};
 

	
 
typedef AutoFreeSmallVector<char*, 4> StringList; ///< Type for a list of strings.
 

	
 
#endif /* SMALLVEC_TYPE_HPP */
src/economy.cpp
Show inline comments
 
@@ -56,49 +56,49 @@
 

	
 
#include "safeguards.h"
 

	
 

	
 
/* Initialize the cargo payment-pool */
 
CargoPaymentPool _cargo_payment_pool("CargoPayment");
 
INSTANTIATE_POOL_METHODS(CargoPayment)
 

	
 
/**
 
 * Multiply two integer values and shift the results to right.
 
 *
 
 * This function multiplies two integer values. The result is
 
 * shifted by the amount of shift to right.
 
 *
 
 * @param a The first integer
 
 * @param b The second integer
 
 * @param shift The amount to shift the value to right.
 
 * @return The shifted result
 
 */
 
static inline int32 BigMulS(const int32 a, const int32 b, const uint8 shift)
 
{
 
	return (int32)((int64)a * (int64)b >> shift);
 
}
 

	
 
typedef SmallVector<Industry *, 16> SmallIndustryList;
 
typedef std::vector<Industry *> SmallIndustryList;
 

	
 
/**
 
 * Score info, values used for computing the detailed performance rating.
 
 */
 
const ScoreInfo _score_info[] = {
 
	{     120, 100}, // SCORE_VEHICLES
 
	{      80, 100}, // SCORE_STATIONS
 
	{   10000, 100}, // SCORE_MIN_PROFIT
 
	{   50000,  50}, // SCORE_MIN_INCOME
 
	{  100000, 100}, // SCORE_MAX_INCOME
 
	{   40000, 400}, // SCORE_DELIVERED
 
	{       8,  50}, // SCORE_CARGO
 
	{10000000,  50}, // SCORE_MONEY
 
	{  250000,  50}, // SCORE_LOAN
 
	{       0,   0}  // SCORE_TOTAL
 
};
 

	
 
int64 _score_part[MAX_COMPANIES][SCORE_END];
 
Economy _economy;
 
Prices _price;
 
Money _additional_cash_required;
 
static PriceMultipliers _price_base_multiplier;
 

	
 
/**
src/engine_base.h
Show inline comments
 
@@ -135,49 +135,49 @@ struct Engine : EnginePool::PoolItem<&_e
 
	/**
 
	 * Retrieve the NewGRF the engine is tied to.
 
	 * This is the GRF providing the Action 3.
 
	 * @return NewGRF associated to the engine.
 
	 */
 
	const GRFFile *GetGRF() const
 
	{
 
		return this->grf_prop.grffile;
 
	}
 

	
 
	uint32 GetGRFID() const;
 
};
 

	
 
struct EngineIDMapping {
 
	uint32 grfid;          ///< The GRF ID of the file the entity belongs to
 
	uint16 internal_id;    ///< The internal ID within the GRF file
 
	VehicleTypeByte type;  ///< The engine type
 
	uint8  substitute_id;  ///< The (original) entity ID to use if this GRF is not available (currently not used)
 
};
 

	
 
/**
 
 * Stores the mapping of EngineID to the internal id of newgrfs.
 
 * Note: This is not part of Engine, as the data in the EngineOverrideManager and the engine pool get resetted in different cases.
 
 */
 
struct EngineOverrideManager : SmallVector<EngineIDMapping, 256> {
 
struct EngineOverrideManager : std::vector<EngineIDMapping> {
 
	static const uint NUM_DEFAULT_ENGINES; ///< Number of default entries
 

	
 
	void ResetToDefaultMapping();
 
	EngineID GetID(VehicleType type, uint16 grf_local_id, uint32 grfid);
 

	
 
	static bool ResetToCurrentNewGRFConfig();
 
};
 

	
 
extern EngineOverrideManager _engine_mngr;
 

	
 
#define FOR_ALL_ENGINES_FROM(var, start) FOR_ALL_ITEMS_FROM(Engine, engine_index, var, start)
 
#define FOR_ALL_ENGINES(var) FOR_ALL_ENGINES_FROM(var, 0)
 

	
 
#define FOR_ALL_ENGINES_OF_TYPE(e, engine_type) FOR_ALL_ENGINES(e) if (e->type == engine_type)
 

	
 
static inline const EngineInfo *EngInfo(EngineID e)
 
{
 
	return &Engine::Get(e)->info;
 
}
 

	
 
static inline const RailVehicleInfo *RailVehInfo(EngineID e)
 
{
 
	return &Engine::Get(e)->u.rail;
 
}
src/fios.cpp
Show inline comments
 
@@ -634,49 +634,49 @@ const char *FiosGetScreenshotDir()
 
	return fios_screenshot_path;
 
}
 

	
 
/** Basic data to distinguish a scenario. Used in the server list window */
 
struct ScenarioIdentifier {
 
	uint32 scenid;           ///< ID for the scenario (generated by content).
 
	uint8 md5sum[16];        ///< MD5 checksum of file.
 
	char filename[MAX_PATH]; ///< filename of the file.
 

	
 
	bool operator == (const ScenarioIdentifier &other) const
 
	{
 
		return this->scenid == other.scenid &&
 
				memcmp(this->md5sum, other.md5sum, sizeof(this->md5sum)) == 0;
 
	}
 

	
 
	bool operator != (const ScenarioIdentifier &other) const
 
	{
 
		return !(*this == other);
 
	}
 
};
 

	
 
/**
 
 * Scanner to find the unique IDs of scenarios
 
 */
 
class ScenarioScanner : protected FileScanner, public SmallVector<ScenarioIdentifier, 8> {
 
class ScenarioScanner : protected FileScanner, public std::vector<ScenarioIdentifier> {
 
	bool scanned; ///< Whether we've already scanned
 
public:
 
	/** Initialise */
 
	ScenarioScanner() : scanned(false) {}
 

	
 
	/**
 
	 * Scan, but only if it's needed.
 
	 * @param rescan whether to force scanning even when it's not necessary
 
	 */
 
	void Scan(bool rescan)
 
	{
 
		if (this->scanned && !rescan) return;
 

	
 
		this->FileScanner::Scan(".id", SCENARIO_DIR, true, true);
 
		this->scanned = true;
 
	}
 

	
 
	bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename) override
 
	{
 
		FILE *f = FioFOpenFile(filename, "r", SCENARIO_DIR);
 
		if (f == NULL) return false;
 

	
 
		ScenarioIdentifier id;
 
		int fret = fscanf(f, "%i", &id.scenid);
src/fios.h
Show inline comments
 
@@ -177,49 +177,49 @@ public:
 
	/**
 
	 * Get a reference to the indicated file information. File information must exist.
 
	 * @return The requested file information.
 
	 */
 
	inline FiosItem &operator[](uint index)
 
	{
 
		return this->files[index];
 
	}
 

	
 
	/** Remove all items from the list. */
 
	inline void Clear()
 
	{
 
		this->files.clear();
 
	}
 

	
 
	/** Compact the list down to the smallest block size boundary. */
 
	inline void Compact()
 
	{
 
		this->files.shrink_to_fit();
 
	}
 

	
 
	void BuildFileList(AbstractFileType abstract_filetype, SaveLoadOperation fop);
 
	const FiosItem *FindItem(const char *file);
 

	
 
	SmallVector<FiosItem, 32> files; ///< The list of files.
 
	std::vector<FiosItem> files; ///< The list of files.
 
};
 

	
 
enum SortingBits {
 
	SORT_ASCENDING  = 0,
 
	SORT_DESCENDING = 1,
 
	SORT_BY_DATE    = 0,
 
	SORT_BY_NAME    = 2
 
};
 
DECLARE_ENUM_AS_BIT_SET(SortingBits)
 

	
 
/* Variables to display file lists */
 
extern SortingBits _savegame_sort_order;
 

	
 
void ShowSaveLoadDialog(AbstractFileType abstract_filetype, SaveLoadOperation fop);
 

	
 
void FiosGetSavegameList(SaveLoadOperation fop, FileList &file_list);
 
void FiosGetScenarioList(SaveLoadOperation fop, FileList &file_list);
 
void FiosGetHeightmapList(SaveLoadOperation fop, FileList &file_list);
 

	
 
const char *FiosBrowseTo(const FiosItem *item);
 

	
 
StringID FiosGetDescText(const char **path, uint64 *total_free);
 
bool FiosDelete(const char *name);
 
void FiosMakeHeightmapName(char *buf, const char *name, const char *last);
src/group_gui.cpp
Show inline comments
 
@@ -100,49 +100,49 @@ static const NWidgetPart _nested_group_w
 
};
 

	
 
class VehicleGroupWindow : public BaseVehicleListWindow {
 
private:
 
	/* Columns in the group list */
 
	enum ListColumns {
 
		VGC_NAME,          ///< Group name.
 
		VGC_PROTECT,       ///< Autoreplace protect icon.
 
		VGC_AUTOREPLACE,   ///< Autoreplace active icon.
 
		VGC_PROFIT,        ///< Profit icon.
 
		VGC_NUMBER,        ///< Number of vehicles in the group.
 

	
 
		VGC_END
 
	};
 

	
 
	VehicleID vehicle_sel; ///< Selected vehicle
 
	GroupID group_sel;     ///< Selected group (for drag/drop)
 
	GroupID group_rename;  ///< Group being renamed, INVALID_GROUP if none
 
	GroupID group_over;    ///< Group over which a vehicle is dragged, INVALID_GROUP if none
 
	GroupID group_confirm; ///< Group awaiting delete confirmation
 
	GUIGroupList groups;   ///< List of groups
 
	uint tiny_step_height; ///< Step height for the group list
 
	Scrollbar *group_sb;
 

	
 
	SmallVector<int, 16> indents; ///< Indentation levels
 
	std::vector<int> indents; ///< Indentation levels
 

	
 
	Dimension column_size[VGC_END]; ///< Size of the columns in the group list.
 

	
 
	void AddChildren(GUIGroupList *source, GroupID parent, int indent)
 
	{
 
		for (const Group *g : *source) {
 
			if (g->parent != parent) continue;
 
			this->groups.push_back(g);
 
			this->indents.push_back(indent);
 
			AddChildren(source, g->index, indent + 1);
 
		}
 
	}
 

	
 
	/** Sort the groups by their name */
 
	static int CDECL GroupNameSorter(const Group * const *a, const Group * const *b)
 
	{
 
		static const Group *last_group[2] = { NULL, NULL };
 
		static char         last_name[2][64] = { "", "" };
 

	
 
		if (*a != last_group[0]) {
 
			last_group[0] = *a;
 
			SetDParam(0, (*a)->index);
 
			GetString(last_name[0], STR_GROUP_NAME, lastof(last_name[0]));
 
		}
src/hotkeys.cpp
Show inline comments
 
@@ -3,49 +3,49 @@
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file hotkeys.cpp Implementation of hotkey related functions */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "hotkeys.h"
 
#include "ini_type.h"
 
#include "string_func.h"
 
#include "window_gui.h"
 

	
 
#include "safeguards.h"
 

	
 
char *_hotkeys_file;
 

	
 
/**
 
 * List of all HotkeyLists.
 
 * This is a pointer to ensure initialisation order with the various static HotkeyList instances.
 
 */
 
static SmallVector<HotkeyList*, 16> *_hotkey_lists = NULL;
 
static std::vector<HotkeyList*> *_hotkey_lists = NULL;
 

	
 
/** String representation of a keycode */
 
struct KeycodeNames {
 
	const char *name;       ///< Name of the keycode
 
	WindowKeyCodes keycode; ///< The keycode
 
};
 

	
 
/** Array of non-standard keycodes that can be used in the hotkeys config file. */
 
static const KeycodeNames _keycode_to_name[] = {
 
	{"SHIFT", WKC_SHIFT},
 
	{"CTRL", WKC_CTRL},
 
	{"ALT", WKC_ALT},
 
	{"META", WKC_META},
 
	{"GLOBAL", WKC_GLOBAL_HOTKEY},
 
	{"ESC", WKC_ESC},
 
	{"DEL", WKC_DELETE},
 
	{"BACKSPACE", WKC_BACKSPACE},
 
	{"RETURN", WKC_RETURN},
 
	{"BACKQUOTE", WKC_BACKQUOTE},
 
	{"F1", WKC_F1},
 
	{"F2", WKC_F2},
 
	{"F3", WKC_F3},
 
	{"F4", WKC_F4},
 
	{"F5", WKC_F5},
 
@@ -233,49 +233,49 @@ Hotkey::Hotkey(uint16 default_keycode, c
 
Hotkey::Hotkey(const uint16 *default_keycodes, const char *name, int num) :
 
	name(name),
 
	num(num)
 
{
 
	const uint16 *keycode = default_keycodes;
 
	while (*keycode != 0) {
 
		this->AddKeycode(*keycode);
 
		keycode++;
 
	}
 
}
 

	
 
/**
 
 * Add a keycode to this hotkey, from now that keycode will be matched
 
 * in addition to any previously added keycodes.
 
 * @param keycode The keycode to add.
 
 */
 
void Hotkey::AddKeycode(uint16 keycode)
 
{
 
	include(this->keycodes, keycode);
 
}
 

	
 
HotkeyList::HotkeyList(const char *ini_group, Hotkey *items, GlobalHotkeyHandlerFunc global_hotkey_handler) :
 
	global_hotkey_handler(global_hotkey_handler), ini_group(ini_group), items(items)
 
{
 
	if (_hotkey_lists == NULL) _hotkey_lists = new SmallVector<HotkeyList*, 16>();
 
	if (_hotkey_lists == NULL) _hotkey_lists = new std::vector<HotkeyList*>();
 
	_hotkey_lists->push_back(this);
 
}
 

	
 
HotkeyList::~HotkeyList()
 
{
 
	_hotkey_lists->erase(std::find(_hotkey_lists->begin(), _hotkey_lists->end(), this));
 
}
 

	
 
/**
 
 * Load HotkeyList from IniFile.
 
 * @param ini IniFile to load from.
 
 */
 
void HotkeyList::Load(IniFile *ini)
 
{
 
	IniGroup *group = ini->GetGroup(this->ini_group);
 
	for (Hotkey *hotkey = this->items; hotkey->name != NULL; ++hotkey) {
 
		IniItem *item = group->GetItem(hotkey->name, false);
 
		if (item != NULL) {
 
			hotkey->keycodes.clear();
 
			if (item->value != NULL) ParseHotkeys(hotkey, item->value);
 
		}
 
	}
 
}
 

	
src/hotkeys.h
Show inline comments
 
@@ -8,49 +8,49 @@
 
 */
 

	
 
/** @file hotkeys.h %Hotkey related functions. */
 

	
 
#ifndef HOTKEYS_H
 
#define HOTKEYS_H
 

	
 
#include "core/smallvec_type.hpp"
 
#include "gfx_type.h"
 
#include "window_type.h"
 
#include "string_type.h"
 

	
 
/**
 
 * All data for a single hotkey. The name (for saving/loading a configfile),
 
 * a list of keycodes and a number to help identifying this hotkey.
 
 */
 
struct Hotkey {
 
	Hotkey(uint16 default_keycode, const char *name, int num);
 
	Hotkey(const uint16 *default_keycodes, const char *name, int num);
 

	
 
	void AddKeycode(uint16 keycode);
 

	
 
	const char *name;
 
	int num;
 
	SmallVector<uint16, 1> keycodes;
 
	std::vector<uint16> keycodes;
 
};
 

	
 
#define HOTKEY_LIST_END Hotkey((uint16)0, NULL, -1)
 

	
 
struct IniFile;
 

	
 
/**
 
 * List of hotkeys for a window.
 
 */
 
struct HotkeyList {
 
	typedef EventState (*GlobalHotkeyHandlerFunc)(int hotkey);
 

	
 
	HotkeyList(const char *ini_group, Hotkey *items, GlobalHotkeyHandlerFunc global_hotkey_handler = NULL);
 
	~HotkeyList();
 

	
 
	void Load(IniFile *ini);
 
	void Save(IniFile *ini) const;
 

	
 
	int CheckMatch(uint16 keycode, bool global_only = false) const;
 

	
 
	GlobalHotkeyHandlerFunc global_hotkey_handler;
 
private:
 
	const char *ini_group;
 
	Hotkey *items;
src/industry_cmd.cpp
Show inline comments
 
@@ -1863,49 +1863,49 @@ static void DoCreateNewIndustry(Industry
 
/**
 
 * Helper function for Build/Fund an industry
 
 * @param tile tile where industry is built
 
 * @param type of industry to build
 
 * @param flags of operations to conduct
 
 * @param indspec pointer to industry specifications
 
 * @param itspec_index the index of the itsepc to build/fund
 
 * @param random_var8f random seed (possibly) used by industries
 
 * @param random_initial_bits The random bits the industry is going to have after construction.
 
 * @param founder Founder of the industry
 
 * @param creation_type The circumstances the industry is created under.
 
 * @param[out] ip Pointer to store newly created industry.
 
 * @return Succeeded or failed command.
 
 *
 
 * @post \c *ip contains the newly created industry if all checks are successful and the \a flags request actual creation, else it contains \c NULL afterwards.
 
 */
 
static CommandCost CreateNewIndustryHelper(TileIndex tile, IndustryType type, DoCommandFlag flags, const IndustrySpec *indspec, uint itspec_index, uint32 random_var8f, uint16 random_initial_bits, Owner founder, IndustryAvailabilityCallType creation_type, Industry **ip)
 
{
 
	assert(itspec_index < indspec->num_table);
 
	const IndustryTileTable *it = indspec->table[itspec_index];
 
	bool custom_shape_check = false;
 

	
 
	*ip = NULL;
 

	
 
	SmallVector<ClearedObjectArea, 1> object_areas(_cleared_object_areas);
 
	std::vector<ClearedObjectArea> object_areas(_cleared_object_areas);
 
	CommandCost ret = CheckIfIndustryTilesAreFree(tile, it, itspec_index, type, random_initial_bits, founder, creation_type, &custom_shape_check);
 
	_cleared_object_areas = object_areas;
 
	if (ret.Failed()) return ret;
 

	
 
	if (HasBit(GetIndustrySpec(type)->callback_mask, CBM_IND_LOCATION)) {
 
		ret = CheckIfCallBackAllowsCreation(tile, type, itspec_index, random_var8f, random_initial_bits, founder, creation_type);
 
	} else {
 
		ret = _check_new_industry_procs[indspec->check_proc](tile);
 
	}
 
	if (ret.Failed()) return ret;
 

	
 
	if (!custom_shape_check && _settings_game.game_creation.land_generator == LG_TERRAGENESIS && _generating_world &&
 
			!_ignore_restrictions && !CheckIfCanLevelIndustryPlatform(tile, DC_NO_WATER, it, type)) {
 
		return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
 
	}
 

	
 
	ret = CheckIfFarEnoughFromConflictingIndustry(tile, type);
 
	if (ret.Failed()) return ret;
 

	
 
	Town *t = NULL;
 
	ret = FindTownForIndustry(tile, type, &t);
 
	if (ret.Failed()) return ret;
 
	assert(t != NULL);
 

	
src/industry_gui.cpp
Show inline comments
 
@@ -2134,49 +2134,49 @@ next_cargo: ;
 
 * - A #CFT_CARGO_LABEL field is also always put in a column of #CFT_INDUSTRY fields.
 
 * - The top row contains #CFT_HEADER and #CFT_SMALL_EMPTY fields.
 
 * - Cargo connections have a column of their own (#CFT_CARGO fields).
 
 * - Cargo accepted or produced by an industry, but not carried in a cargo connection, is drawn in the space of a cargo column attached to the industry.
 
 *   The information however is part of the industry.
 
 *
 
 * This results in the following invariants:
 
 * - Width of a #CFT_INDUSTRY column is large enough to hold all industry type labels, all cargo labels, and all header texts.
 
 * - Height of a #CFT_INDUSTRY is large enough to hold a header line, or a industry type line, \c N cargo labels
 
 *   (where \c N is the maximum number of cargoes connected between industries), \c N connections of cargo types, and space
 
 *   between two industry types (1/2 above it, and 1/2 underneath it).
 
 * - Width of a cargo field (#CFT_CARGO) is large enough to hold \c N vertical columns (one for each type of cargo).
 
 *   Also, space is needed between an industry and the leftmost/rightmost column to draw the non-carried cargoes.
 
 * - Height of a #CFT_CARGO field is equally high as the height of the #CFT_INDUSTRY.
 
 * - A field at the top (#CFT_HEADER or #CFT_SMALL_EMPTY) match the width of the fields below them (#CFT_INDUSTRY respectively
 
 *   #CFT_CARGO), the height should be sufficient to display the header text.
 
 *
 
 * When displaying the cargoes around an industry type, five columns are needed (supplying industries, accepted cargoes, the industry,
 
 * produced cargoes, customer industries). Displaying the industries around a cargo needs three columns (supplying industries, the cargo,
 
 * customer industries). The remaining two columns are set to #CFT_EMPTY with a width equal to the average of a cargo and an industry column.
 
 */
 
struct IndustryCargoesWindow : public Window {
 
	static const int HOR_TEXT_PADDING, VERT_TEXT_PADDING;
 

	
 
	typedef SmallVector<CargoesRow, 4> Fields;
 
	typedef std::vector<CargoesRow> Fields;
 

	
 
	Fields fields;  ///< Fields to display in the #WID_IC_PANEL.
 
	uint ind_cargo; ///< If less than #NUM_INDUSTRYTYPES, an industry type, else a cargo id + NUM_INDUSTRYTYPES.
 
	Dimension cargo_textsize; ///< Size to hold any cargo text, as well as STR_INDUSTRY_CARGOES_SELECT_CARGO.
 
	Dimension ind_textsize;   ///< Size to hold any industry type text, as well as STR_INDUSTRY_CARGOES_SELECT_INDUSTRY.
 
	Scrollbar *vscroll;
 

	
 
	IndustryCargoesWindow(int id) : Window(&_industry_cargoes_desc)
 
	{
 
		this->OnInit();
 
		this->CreateNestedTree();
 
		this->vscroll = this->GetScrollbar(WID_IC_SCROLLBAR);
 
		this->FinishInitNested(0);
 
		this->OnInvalidateData(id);
 
	}
 

	
 
	void OnInit() override
 
	{
 
		/* Initialize static CargoesField size variables. */
 
		Dimension d = GetStringBoundingBox(STR_INDUSTRY_CARGOES_PRODUCERS);
 
		d = maxdim(d, GetStringBoundingBox(STR_INDUSTRY_CARGOES_CUSTOMERS));
 
		d.width  += WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT;
 
		d.height += WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM;
 
		CargoesField::small_height = d.height;
src/language.h
Show inline comments
 
@@ -75,40 +75,40 @@ struct LanguagePackHeader {
 
	}
 

	
 
	/**
 
	 * Get the index for the given case.
 
	 * @param case_str The string representation of the case.
 
	 * @return The index of the case, or MAX_NUM_CASES when the case is unknown.
 
	 */
 
	uint8 GetCaseIndex(const char *case_str) const
 
	{
 
		for (uint8 i = 0; i < MAX_NUM_CASES; i++) {
 
			if (strcmp(case_str, this->cases[i]) == 0) return i;
 
		}
 
		return MAX_NUM_CASES;
 
	}
 
};
 
/** Make sure the size is right. */
 
assert_compile(sizeof(LanguagePackHeader) % 4 == 0);
 

	
 
/** Metadata about a single language. */
 
struct LanguageMetadata : public LanguagePackHeader {
 
	char file[MAX_PATH]; ///< Name of the file we read this data from.
 
};
 

	
 
/** Type for the list of language meta data. */
 
typedef SmallVector<LanguageMetadata, 4> LanguageList;
 
typedef std::vector<LanguageMetadata> LanguageList;
 

	
 
/** The actual list of language meta data. */
 
extern LanguageList _languages;
 

	
 
/** The currently loaded language. */
 
extern const LanguageMetadata *_current_language;
 

	
 
#ifdef WITH_ICU_I18N
 
extern icu::Collator *_current_collator;
 
#endif /* WITH_ICU_I18N */
 

	
 
bool ReadLanguagePack(const LanguageMetadata *lang);
 
const LanguageMetadata *GetLanguage(byte newgrflangid);
 

	
 
#endif /* LANGUAGE_H */
src/linkgraph/linkgraph.h
Show inline comments
 
@@ -414,49 +414,49 @@ public:
 

	
 
		/**
 
		 * Update the node's location on the map.
 
		 * @param xy New location.
 
		 */
 
		void UpdateLocation(TileIndex xy)
 
		{
 
			this->node.xy = xy;
 
		}
 

	
 
		/**
 
		 * Set the node's demand.
 
		 * @param demand New demand for the node.
 
		 */
 
		void SetDemand(uint demand)
 
		{
 
			this->node.demand = demand;
 
		}
 

	
 
		void AddEdge(NodeID to, uint capacity, uint usage, EdgeUpdateMode mode);
 
		void UpdateEdge(NodeID to, uint capacity, uint usage, EdgeUpdateMode mode);
 
		void RemoveEdge(NodeID to);
 
	};
 

	
 
	typedef SmallVector<BaseNode, 16> NodeVector;
 
	typedef std::vector<BaseNode> NodeVector;
 
	typedef SmallMatrix<BaseEdge> EdgeMatrix;
 

	
 
	/** Minimum effective distance for timeout calculation. */
 
	static const uint MIN_TIMEOUT_DISTANCE = 32;
 

	
 
	/** Minimum number of days between subsequent compressions of a LG. */
 
	static const uint COMPRESSION_INTERVAL = 256;
 

	
 
	/**
 
	 * Scale a value from a link graph of age orig_age for usage in one of age
 
	 * target_age. Make sure that the value stays > 0 if it was > 0 before.
 
	 * @param val Value to be scaled.
 
	 * @param target_age Age of the target link graph.
 
	 * @param orig_age Age of the original link graph.
 
	 * @return scaled value.
 
	 */
 
	inline static uint Scale(uint val, uint target_age, uint orig_age)
 
	{
 
		return val > 0 ? max(1U, val * target_age / orig_age) : 0;
 
	}
 

	
 
	/** Bare constructor, only for save/load. */
 
	LinkGraph() : cargo(INVALID_CARGO), last_compression(0) {}
 
	/**
src/linkgraph/linkgraphjob.h
Show inline comments
 
@@ -29,49 +29,49 @@ extern LinkGraphJobPool _link_graph_job_
 
 * Class for calculation jobs to be run on link graphs.
 
 */
 
class LinkGraphJob : public LinkGraphJobPool::PoolItem<&_link_graph_job_pool>{
 
private:
 
	/**
 
	 * Annotation for a link graph edge.
 
	 */
 
	struct EdgeAnnotation {
 
		uint demand;             ///< Transport demand between the nodes.
 
		uint unsatisfied_demand; ///< Demand over this edge that hasn't been satisfied yet.
 
		uint flow;               ///< Planned flow over this edge.
 
		void Init();
 
	};
 

	
 
	/**
 
	 * Annotation for a link graph node.
 
	 */
 
	struct NodeAnnotation {
 
		uint undelivered_supply; ///< Amount of supply that hasn't been distributed yet.
 
		PathList paths;          ///< Paths through this node, sorted so that those with flow == 0 are in the back.
 
		FlowStatMap flows;       ///< Planned flows to other nodes.
 
		void Init(uint supply);
 
	};
 

	
 
	typedef SmallVector<NodeAnnotation, 16> NodeAnnotationVector;
 
	typedef std::vector<NodeAnnotation> NodeAnnotationVector;
 
	typedef SmallMatrix<EdgeAnnotation> EdgeAnnotationMatrix;
 

	
 
	friend const SaveLoad *GetLinkGraphJobDesc();
 
	friend class LinkGraphSchedule;
 

	
 
protected:
 
	const LinkGraph link_graph;       ///< Link graph to by analyzed. Is copied when job is started and mustn't be modified later.
 
	const LinkGraphSettings settings; ///< Copy of _settings_game.linkgraph at spawn time.
 
	ThreadObject *thread;             ///< Thread the job is running in or NULL if it's running in the main thread.
 
	Date join_date;                   ///< Date when the job is to be joined.
 
	NodeAnnotationVector nodes;       ///< Extra node data necessary for link graph calculation.
 
	EdgeAnnotationMatrix edges;       ///< Extra edge data necessary for link graph calculation.
 

	
 
	void EraseFlows(NodeID from);
 
	void JoinThread();
 
	void SpawnThread();
 

	
 
public:
 

	
 
	/**
 
	 * A job edge. Wraps a link graph edge and an edge annotation. The
 
	 * annotation can be modified, the edge is constant.
 
	 */
 
	class Edge : public LinkGraph::ConstEdge {
src/music/midifile.hpp
Show inline comments
 
@@ -3,49 +3,49 @@
 
/*
 
* This file is part of OpenTTD.
 
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
*/
 

	
 
/* @file midifile.hpp Parser for standard MIDI files */
 

	
 
#ifndef MUSIC_MIDIFILE_HPP
 
#define MUSIC_MIDIFILE_HPP
 

	
 
#include "../stdafx.h"
 
#include "../core/smallvec_type.hpp"
 
#include "midi.h"
 
#include <vector>
 
#include <string>
 

	
 
struct MusicSongInfo;
 

	
 
struct MidiFile {
 
	struct DataBlock {
 
		uint32 ticktime;           ///< tick number since start of file this block should be triggered at
 
		uint32 realtime;           ///< real-time (microseconds) since start of file this block should be triggered at
 
		SmallVector<byte, 8> data; ///< raw midi data contained in block
 
		std::vector<byte> data; ///< raw midi data contained in block
 
		DataBlock(uint32 _ticktime = 0) : ticktime(_ticktime) { }
 
	};
 
	struct TempoChange {
 
		uint32 ticktime; ///< tick number since start of file this tempo change occurs at
 
		uint32 tempo;    ///< new tempo in microseconds per tick
 
		TempoChange(uint32 _ticktime, uint32 _tempo) : ticktime(_ticktime), tempo(_tempo) { }
 
	};
 

	
 
	std::vector<DataBlock> blocks;   ///< sequential time-annotated data of file, merged to a single track
 
	std::vector<TempoChange> tempos; ///< list of tempo changes in file
 
	uint16 tickdiv;                  ///< ticks per quarter note
 

	
 
	MidiFile();
 
	~MidiFile();
 

	
 
	bool LoadFile(const char *filename);
 
	bool LoadMpsData(const byte *data, size_t length);
 
	bool LoadSong(const MusicSongInfo &song);
 
	void MoveFrom(MidiFile &other);
 

	
 
	bool WriteSMF(const char *filename);
 

	
 
	static std::string GetSMFFile(const MusicSongInfo &song);
 
	static bool ReadSMFHeader(const char *filename, SMFHeader &header);
src/network/core/address.h
Show inline comments
 
/* $Id$ */
 

	
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file core/address.h Wrapper for network addresses. */
 

	
 
#ifndef NETWORK_CORE_ADDRESS_H
 
#define NETWORK_CORE_ADDRESS_H
 

	
 
#include "os_abstraction.h"
 
#include "config.h"
 
#include "../../string_func.h"
 
#include "../../core/smallmap_type.hpp"
 

	
 
class NetworkAddress;
 
typedef SmallVector<NetworkAddress, 4> NetworkAddressList; ///< Type for a list of addresses.
 
typedef std::vector<NetworkAddress> NetworkAddressList; ///< Type for a list of addresses.
 
typedef SmallMap<NetworkAddress, SOCKET, 4> SocketList;    ///< Type for a mapping between address and socket.
 

	
 
/**
 
 * Wrapper for (un)resolved network addresses; there's no reason to transform
 
 * a numeric IP to a string and then back again to pass it to functions. It
 
 * furthermore allows easier delaying of the hostname lookup.
 
 */
 
class NetworkAddress {
 
private:
 
	char hostname[NETWORK_HOSTNAME_LENGTH]; ///< The hostname
 
	int address_length;                     ///< The length of the resolved address
 
	sockaddr_storage address;               ///< The resolved address
 
	bool resolved;                          ///< Whether the address has been (tried to be) resolved
 

	
 
	/**
 
	 * Helper function to resolve something to a socket.
 
	 * @param runp information about the socket to try not
 
	 * @return the opened socket or INVALID_SOCKET
 
	 */
 
	typedef SOCKET (*LoopProc)(addrinfo *runp);
 

	
 
	SOCKET Resolve(int family, int socktype, int flags, SocketList *sockets, LoopProc func);
 
public:
 
	/**
src/network/core/tcp_connect.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/**
 
 * @file tcp_connect.cpp Basic functions to create connections without blocking.
 
 */
 

	
 
#include "../../stdafx.h"
 
#include "../../thread/thread.h"
 

	
 
#include "tcp.h"
 

	
 
#include "../../safeguards.h"
 

	
 
/** List of connections that are currently being created */
 
static SmallVector<TCPConnecter *,  1> _tcp_connecters;
 
static std::vector<TCPConnecter *> _tcp_connecters;
 

	
 
/**
 
 * Create a new connecter for the given address
 
 * @param address the (un)resolved address to connect to
 
 */
 
TCPConnecter::TCPConnecter(const NetworkAddress &address) :
 
	connected(false),
 
	aborted(false),
 
	killed(false),
 
	sock(INVALID_SOCKET),
 
	address(address)
 
{
 
	_tcp_connecters.push_back(this);
 
	if (!ThreadObject::New(TCPConnecter::ThreadEntry, this, &this->thread, "ottd:tcp")) {
 
		this->Connect();
 
	}
 
}
 

	
 
/** The actual connection function */
 
void TCPConnecter::Connect()
 
{
 
	this->sock = this->address.Connect();
 
	if (this->sock == INVALID_SOCKET) {
 
		this->aborted = true;
src/network/core/tcp_http.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/**
 
 * @file tcp_http.cpp Basic functions to receive and send HTTP TCP packets.
 
 */
 

	
 
#include "../../stdafx.h"
 
#include "../../debug.h"
 
#include "../../rev.h"
 
#include "../network_func.h"
 

	
 
#include "tcp_http.h"
 

	
 
#include "../../safeguards.h"
 

	
 
/** List of open HTTP connections. */
 
static SmallVector<NetworkHTTPSocketHandler *, 1> _http_connections;
 
static std::vector<NetworkHTTPSocketHandler *> _http_connections;
 

	
 
/**
 
 * Start the querying
 
 * @param s        the socket of this connection
 
 * @param callback the callback for HTTP retrieval
 
 * @param host     the hostname of the server to connect to
 
 * @param url      the url at the server
 
 * @param data     the data to send
 
 * @param depth    the depth (redirect recursion) of the queries
 
 */
 
NetworkHTTPSocketHandler::NetworkHTTPSocketHandler(SOCKET s,
 
		HTTPCallback *callback, const char *host, const char *url,
 
		const char *data, int depth) :
 
	NetworkSocketHandler(),
 
	recv_pos(0),
 
	recv_length(0),
 
	callback(callback),
 
	data(data),
 
	redirect_depth(depth),
 
	sock(s)
 
{
 
	size_t bufferSize = strlen(url) + strlen(host) + strlen(GetNetworkRevisionString()) + (data == NULL ? 0 : strlen(data)) + 128;
 
	char *buffer = AllocaM(char, bufferSize);
 

	
src/network/network_content.h
Show inline comments
 
/* $Id$ */
 

	
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file network_content.h Part of the network protocol handling content distribution. */
 

	
 
#ifndef NETWORK_CONTENT_H
 
#define NETWORK_CONTENT_H
 

	
 
#include "core/tcp_content.h"
 
#include "core/tcp_http.h"
 

	
 
/** Vector with content info */
 
typedef SmallVector<ContentInfo *, 16> ContentVector;
 
typedef std::vector<ContentInfo *> ContentVector;
 
/** Vector with constant content info */
 
typedef SmallVector<const ContentInfo *, 16> ConstContentVector;
 
typedef std::vector<const ContentInfo *> ConstContentVector;
 

	
 
/** Iterator for the content vector */
 
typedef ContentInfo **ContentIterator;
 
/** Iterator for the constant content vector */
 
typedef const ContentInfo * const * ConstContentIterator;
 

	
 
/** Callbacks for notifying others about incoming data */
 
struct ContentCallback {
 
	/**
 
	 * Callback for when the connection has finished
 
	 * @param success whether the connection was made or that we failed to make it
 
	 */
 
	virtual void OnConnect(bool success) {}
 

	
 
	/**
 
	 * Callback for when the connection got disconnected.
 
	 */
 
	virtual void OnDisconnect() {}
 

	
 
	/**
 
	 * We received a content info.
 
	 * @param ci the content info
 
	 */
 
	virtual void OnReceiveContentInfo(const ContentInfo *ci) {}
 

	
 
	/**
 
	 * We have progress in the download of a file
 
	 * @param ci the content info of the file
 
	 * @param bytes the number of bytes downloaded since the previous call
 
	 */
 
	virtual void OnDownloadProgress(const ContentInfo *ci, int bytes) {}
 

	
 
	/**
 
	 * We have finished downloading a file
 
	 * @param cid the ContentID of the downloaded file
 
	 */
 
	virtual void OnDownloadComplete(ContentID cid) {}
 

	
 
	/** Silentium */
 
	virtual ~ContentCallback() {}
 
};
 

	
 
/**
 
 * Socket handler for the content server connection
 
 */
 
class ClientNetworkContentSocketHandler : public NetworkContentSocketHandler, ContentCallback, HTTPCallback {
 
protected:
 
	typedef SmallVector<ContentID, 4> ContentIDList; ///< List of content IDs to (possibly) select.
 
	SmallVector<ContentCallback *, 2> callbacks; ///< Callbacks to notify "the world"
 
	typedef std::vector<ContentID> ContentIDList; ///< List of content IDs to (possibly) select.
 
	std::vector<ContentCallback *> callbacks; ///< Callbacks to notify "the world"
 
	ContentIDList requested;                     ///< ContentIDs we already requested (so we don't do it again)
 
	ContentVector infos;                         ///< All content info we received
 
	SmallVector<char, 1024> http_response;       ///< The HTTP response to the requests we've been doing
 
	std::vector<char> http_response;       ///< The HTTP response to the requests we've been doing
 
	int http_response_index;                     ///< Where we are, in the response, with handling it
 

	
 
	FILE *curFile;        ///< Currently downloaded file
 
	ContentInfo *curInfo; ///< Information about the currently downloaded file
 
	bool isConnecting;    ///< Whether we're connecting
 
	uint32 lastActivity;  ///< The last time there was network activity
 

	
 
	friend class NetworkContentConnecter;
 

	
 
	bool Receive_SERVER_INFO(Packet *p) override;
 
	bool Receive_SERVER_CONTENT(Packet *p) override;
 

	
 
	ContentInfo *GetContent(ContentID cid);
 
	void DownloadContentInfo(ContentID cid);
 

	
 
	void OnConnect(bool success) override;
 
	void OnDisconnect() override;
 
	void OnReceiveContentInfo(const ContentInfo *ci) override;
 
	void OnDownloadProgress(const ContentInfo *ci, int bytes) override;
 
	void OnDownloadComplete(ContentID cid) override;
 

	
 
	void OnFailure() override;
 
	void OnReceiveData(const char *data, size_t length) override;
 

	
src/network/network_content_gui.cpp
Show inline comments
 
@@ -139,49 +139,49 @@ void BaseNetworkContentDownloadStatusWin
 
	} else {
 
		str = STR_CONTENT_DOWNLOAD_INITIALISE;
 
	}
 

	
 
	y += FONT_HEIGHT_NORMAL + 5;
 
	DrawStringMultiLine(r.left + 2, r.right - 2, y, y + FONT_HEIGHT_NORMAL * 2, str, TC_FROMSTRING, SA_CENTER);
 
}
 

	
 
void BaseNetworkContentDownloadStatusWindow::OnDownloadProgress(const ContentInfo *ci, int bytes)
 
{
 
	if (ci->id != this->cur_id) {
 
		strecpy(this->name, ci->filename, lastof(this->name));
 
		this->cur_id = ci->id;
 
		this->downloaded_files++;
 
	}
 

	
 
	this->downloaded_bytes += bytes;
 
	this->SetDirty();
 
}
 

	
 

	
 
/** Window for showing the download status of content */
 
struct NetworkContentDownloadStatusWindow : public BaseNetworkContentDownloadStatusWindow {
 
private:
 
	SmallVector<ContentType, 4> receivedTypes;     ///< Types we received so we can update their cache
 
	std::vector<ContentType> receivedTypes;     ///< Types we received so we can update their cache
 

	
 
public:
 
	/**
 
	 * Create a new download window based on a list of content information
 
	 * with flags whether to download them or not.
 
	 */
 
	NetworkContentDownloadStatusWindow() : BaseNetworkContentDownloadStatusWindow(&_network_content_download_status_window_desc)
 
	{
 
		this->parent = FindWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_CONTENT_LIST);
 
	}
 

	
 
	/** Free whatever we've allocated */
 
	~NetworkContentDownloadStatusWindow()
 
	{
 
		TarScanner::Mode mode = TarScanner::NONE;
 
		for (auto ctype : this->receivedTypes) {
 
			switch (ctype) {
 
				case CONTENT_TYPE_AI:
 
				case CONTENT_TYPE_AI_LIBRARY:
 
					/* AI::Rescan calls the scanner. */
 
					break;
 
				case CONTENT_TYPE_GAME:
 
				case CONTENT_TYPE_GAME_LIBRARY:
 
					/* Game::Rescan calls the scanner. */
src/network/network_gui.cpp
Show inline comments
 
@@ -1707,49 +1707,49 @@ static void ClientList_SpeakToClient(con
 
	ShowNetworkChatQueryWindow(DESTTYPE_CLIENT, ci->client_id);
 
}
 

	
 
static void ClientList_SpeakToCompany(const NetworkClientInfo *ci)
 
{
 
	ShowNetworkChatQueryWindow(DESTTYPE_TEAM, ci->client_playas);
 
}
 

	
 
static void ClientList_SpeakToAll(const NetworkClientInfo *ci)
 
{
 
	ShowNetworkChatQueryWindow(DESTTYPE_BROADCAST, 0);
 
}
 

	
 
/** Popup selection window to chose an action to perform */
 
struct NetworkClientListPopupWindow : Window {
 
	/** Container for actions that can be executed. */
 
	struct ClientListAction {
 
		StringID name;                ///< Name of the action to execute
 
		ClientList_Action_Proc *proc; ///< Action to execute
 
	};
 

	
 
	uint sel_index;
 
	ClientID client_id;
 
	Point desired_location;
 
	SmallVector<ClientListAction, 2> actions; ///< Actions to execute
 
	std::vector<ClientListAction> actions; ///< Actions to execute
 

	
 
	/**
 
	 * Add an action to the list of actions to execute.
 
	 * @param name the name of the action
 
	 * @param proc the procedure to execute for the action
 
	 */
 
	inline void AddAction(StringID name, ClientList_Action_Proc *proc)
 
	{
 
		this->actions.push_back({name, proc});
 
	}
 

	
 
	NetworkClientListPopupWindow(WindowDesc *desc, int x, int y, ClientID client_id) :
 
			Window(desc),
 
			sel_index(0), client_id(client_id)
 
	{
 
		this->desired_location.x = x;
 
		this->desired_location.y = y;
 

	
 
		const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
 

	
 
		if (_network_own_client_id != ci->client_id) {
 
			this->AddAction(STR_NETWORK_CLIENTLIST_SPEAK_TO_CLIENT, &ClientList_SpeakToClient);
 
		}
 

	
src/newgrf.cpp
Show inline comments
 
@@ -44,49 +44,49 @@
 
#include "network/network.h"
 
#include <map>
 
#include "smallmap_gui.h"
 
#include "genworld.h"
 
#include "error.h"
 
#include "vehicle_func.h"
 
#include "language.h"
 
#include "vehicle_base.h"
 

	
 
#include "table/strings.h"
 
#include "table/build_industry.h"
 

	
 
#include "safeguards.h"
 

	
 
/* TTDPatch extended GRF format codec
 
 * (c) Petr Baudis 2004 (GPL'd)
 
 * Changes by Florian octo Forster are (c) by the OpenTTD development team.
 
 *
 
 * Contains portions of documentation by TTDPatch team.
 
 * Thanks especially to Josef Drexler for the documentation as well as a lot
 
 * of help at #tycoon. Also thanks to Michael Blunck for his GRF files which
 
 * served as subject to the initial testing of this codec. */
 

	
 
/** List of all loaded GRF files */
 
static SmallVector<GRFFile *, 16> _grf_files;
 
static std::vector<GRFFile *> _grf_files;
 

	
 
/** Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E */
 
byte _misc_grf_features = 0;
 

	
 
/** 32 * 8 = 256 flags. Apparently TTDPatch uses this many.. */
 
static uint32 _ttdpatch_flags[8];
 

	
 
/** Indicates which are the newgrf features currently loaded ingame */
 
GRFLoadedFeatures _loaded_newgrf_features;
 

	
 
static const uint MAX_SPRITEGROUP = UINT8_MAX; ///< Maximum GRF-local ID for a spritegroup.
 

	
 
/** Temporary data during loading of GRFs */
 
struct GrfProcessingState {
 
private:
 
	/** Definition of a single Action1 spriteset */
 
	struct SpriteSet {
 
		SpriteID sprite;  ///< SpriteID of the first sprite of the set.
 
		uint num_sprites; ///< Number of sprites in the set.
 
	};
 

	
 
	/** Currently referenceable spritesets */
 
	std::map<uint, SpriteSet> spritesets[GSF_END];
 

	
 
@@ -438,49 +438,49 @@ static GRFError *DisableGrf(StringID mes
 
		file = _cur.grffile;
 
	}
 

	
 
	config->status = GCS_DISABLED;
 
	if (file != NULL) ClearTemporaryNewGRFData(file);
 
	if (config == _cur.grfconfig) _cur.skip_sprites = -1;
 

	
 
	if (message != STR_NULL) {
 
		delete config->error;
 
		config->error = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, message);
 
		if (config == _cur.grfconfig) config->error->param_value[0] = _cur.nfo_line;
 
	}
 

	
 
	return config->error;
 
}
 

	
 
/**
 
 * Information for mapping static StringIDs.
 
 */
 
struct StringIDMapping {
 
	uint32 grfid;     ///< Source NewGRF.
 
	StringID source;  ///< Source StringID (GRF local).
 
	StringID *target; ///< Destination for mapping result.
 
};
 
typedef SmallVector<StringIDMapping, 16> StringIDMappingVector;
 
typedef std::vector<StringIDMapping> StringIDMappingVector;
 
static StringIDMappingVector _string_to_grf_mapping;
 

	
 
/**
 
 * Record a static StringID for getting translated later.
 
 * @param source Source StringID (GRF local).
 
 * @param target Destination for the mapping result.
 
 */
 
static void AddStringForMapping(StringID source, StringID *target)
 
{
 
	*target = STR_UNDEFINED;
 
	_string_to_grf_mapping.push_back({_cur.grffile->grfid, source, target});
 
}
 

	
 
/**
 
 * Perform a mapping from TTDPatch's string IDs to OpenTTD's
 
 * string IDs, but only for the ones we are aware off; the rest
 
 * like likely unused and will show a warning.
 
 * @param str the string ID to convert
 
 * @return the converted string ID
 
 */
 
static StringID TTDPStringIDToOTTDStringIDMapping(StringID str)
 
{
 
	/* StringID table for TextIDs 0x4E->0x6D */
 
	static const StringID units_volume[] = {
 
@@ -1880,49 +1880,49 @@ static ChangeInfoResult StationChangeInf
 
				(*spec)->cls_id = StationClass::Allocate(BSWAP32(classid));
 
				break;
 
			}
 

	
 
			case 0x09: // Define sprite layout
 
				statspec->tiles = buf->ReadExtendedByte();
 
				delete[] statspec->renderdata; // delete earlier loaded stuff
 
				statspec->renderdata = new NewGRFSpriteLayout[statspec->tiles];
 

	
 
				for (uint t = 0; t < statspec->tiles; t++) {
 
					NewGRFSpriteLayout *dts = &statspec->renderdata[t];
 
					dts->consistent_max_offset = UINT16_MAX; // Spritesets are unknown, so no limit.
 

	
 
					if (buf->HasData(4) && *(uint32*)buf->Data() == 0) {
 
						buf->Skip(4);
 
						extern const DrawTileSprites _station_display_datas_rail[8];
 
						dts->Clone(&_station_display_datas_rail[t % 8]);
 
						continue;
 
					}
 

	
 
					ReadSpriteLayoutSprite(buf, false, false, false, GSF_STATIONS, &dts->ground);
 
					/* On error, bail out immediately. Temporary GRF data was already freed */
 
					if (_cur.skip_sprites < 0) return CIR_DISABLED;
 

	
 
					static SmallVector<DrawTileSeqStruct, 8> tmp_layout;
 
					static std::vector<DrawTileSeqStruct> tmp_layout;
 
					tmp_layout.clear();
 
					for (;;) {
 
						/* no relative bounding box support */
 
						/*C++17: DrawTileSeqStruct &dtss = */ tmp_layout.emplace_back();
 
						DrawTileSeqStruct &dtss = tmp_layout.back();
 
						MemSetT(&dtss, 0);
 

	
 
						dtss.delta_x = buf->ReadByte();
 
						if (dtss.IsTerminator()) break;
 
						dtss.delta_y = buf->ReadByte();
 
						dtss.delta_z = buf->ReadByte();
 
						dtss.size_x = buf->ReadByte();
 
						dtss.size_y = buf->ReadByte();
 
						dtss.size_z = buf->ReadByte();
 

	
 
						ReadSpriteLayoutSprite(buf, false, true, false, GSF_STATIONS, &dtss.image);
 
						/* On error, bail out immediately. Temporary GRF data was already freed */
 
						if (_cur.skip_sprites < 0) return CIR_DISABLED;
 
					}
 
					dts->Clone(tmp_layout.data());
 
				}
 
				break;
 

	
 
			case 0x0A: { // Copy sprite layout
 
@@ -4766,49 +4766,49 @@ static void NewSpriteGroup(ByteReader *b
 
	switch (type) {
 
		/* Deterministic Sprite Group */
 
		case 0x81: // Self scope, byte
 
		case 0x82: // Parent scope, byte
 
		case 0x85: // Self scope, word
 
		case 0x86: // Parent scope, word
 
		case 0x89: // Self scope, dword
 
		case 0x8A: // Parent scope, dword
 
		{
 
			byte varadjust;
 
			byte varsize;
 

	
 
			assert(DeterministicSpriteGroup::CanAllocateItem());
 
			DeterministicSpriteGroup *group = new DeterministicSpriteGroup();
 
			act_group = group;
 
			group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
 

	
 
			switch (GB(type, 2, 2)) {
 
				default: NOT_REACHED();
 
				case 0: group->size = DSG_SIZE_BYTE;  varsize = 1; break;
 
				case 1: group->size = DSG_SIZE_WORD;  varsize = 2; break;
 
				case 2: group->size = DSG_SIZE_DWORD; varsize = 4; break;
 
			}
 

	
 
			static SmallVector<DeterministicSpriteGroupAdjust, 16> adjusts;
 
			static std::vector<DeterministicSpriteGroupAdjust> adjusts;
 
			adjusts.clear();
 

	
 
			/* Loop through the var adjusts. Unfortunately we don't know how many we have
 
			 * from the outset, so we shall have to keep reallocing. */
 
			do {
 
				/*C++17: DeterministicSpriteGroupAdjust &adjust = */ adjusts.emplace_back();
 
				DeterministicSpriteGroupAdjust &adjust = adjusts.back();
 

	
 
				/* The first var adjust doesn't have an operation specified, so we set it to add. */
 
				adjust.operation = adjusts.size() == 1 ? DSGA_OP_ADD : (DeterministicSpriteGroupAdjustOperation)buf->ReadByte();
 
				adjust.variable  = buf->ReadByte();
 
				if (adjust.variable == 0x7E) {
 
					/* Link subroutine group */
 
					adjust.subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte());
 
				} else {
 
					adjust.parameter = IsInsideMM(adjust.variable, 0x60, 0x80) ? buf->ReadByte() : 0;
 
				}
 

	
 
				varadjust = buf->ReadByte();
 
				adjust.shift_num = GB(varadjust, 0, 5);
 
				adjust.type      = (DeterministicSpriteGroupAdjustType)GB(varadjust, 6, 2);
 
				adjust.and_mask  = buf->ReadVarSize(varsize);
 

	
 
				if (adjust.type != DSGA_TYPE_NONE) {
src/newgrf.h
Show inline comments
 
@@ -101,52 +101,52 @@ struct GRFLabel {
 
};
 

	
 
/** Dynamic data of a loaded NewGRF */
 
struct GRFFile : ZeroedMemoryAllocator {
 
	char *filename;
 
	uint32 grfid;
 
	byte grf_version;
 

	
 
	uint sound_offset;
 
	uint16 num_sounds;
 

	
 
	struct StationSpec **stations;
 
	struct HouseSpec **housespec;
 
	struct IndustrySpec **industryspec;
 
	struct IndustryTileSpec **indtspec;
 
	struct ObjectSpec **objectspec;
 
	struct AirportSpec **airportspec;
 
	struct AirportTileSpec **airtspec;
 

	
 
	uint32 param[0x80];
 
	uint param_end;  ///< one more than the highest set parameter
 

	
 
	GRFLabel *label; ///< Pointer to the first label. This is a linked list, not an array.
 

	
 
	SmallVector<CargoLabel, 4> cargo_list;          ///< Cargo translation table (local ID -> label)
 
	std::vector<CargoLabel> cargo_list;          ///< Cargo translation table (local ID -> label)
 
	uint8 cargo_map[NUM_CARGO];                     ///< Inverse cargo translation table (CargoID -> local ID)
 

	
 
	SmallVector<RailTypeLabel, 4> railtype_list;    ///< Railtype translation table
 
	std::vector<RailTypeLabel> railtype_list;    ///< Railtype translation table
 
	RailTypeByte railtype_map[RAILTYPE_END];
 

	
 
	CanalProperties canal_local_properties[CF_END]; ///< Canal properties as set by this NewGRF
 

	
 
	struct LanguageMap *language_map; ///< Mappings related to the languages.
 

	
 
	int traininfo_vehicle_pitch;  ///< Vertical offset for draing train images in depot GUI and vehicle details
 
	uint traininfo_vehicle_width; ///< Width (in pixels) of a 8/8 train vehicle in depot GUI and vehicle details
 

	
 
	uint32 grf_features;                     ///< Bitset of GrfSpecFeature the grf uses
 
	PriceMultipliers price_base_multipliers; ///< Price base multipliers as set by the grf.
 

	
 
	GRFFile(const struct GRFConfig *config);
 
	~GRFFile();
 

	
 
	/** Get GRF Parameter with range checking */
 
	uint32 GetParam(uint number) const
 
	{
 
		/* Note: We implicitly test for number < lengthof(this->param) and return 0 for invalid parameters.
 
		 *       In fact this is the more important test, as param is zeroed anyway. */
 
		assert(this->param_end <= lengthof(this->param));
 
		return (number < this->param_end) ? this->param[number] : 0;
 
	}
 
};
src/newgrf_commons.cpp
Show inline comments
 
@@ -558,49 +558,49 @@ bool ConvertBooleanCallback(const GRFFil
 
	if (cb_res > 1) ErrorUnknownCallbackResult(grffile->grfid, cbid, cb_res);
 
	return cb_res != 0;
 
}
 

	
 
/**
 
 * Converts a callback result into a boolean.
 
 * For grf version < 8 the first 8 bit of the result are checked for zero or non-zero.
 
 * For grf version >= 8 the callback result must be 0 or 1.
 
 * @param grffile NewGRF returning the value.
 
 * @param cbid Callback returning the value.
 
 * @param cb_res Callback result.
 
 * @return Boolean value. True if cb_res != 0.
 
 */
 
bool Convert8bitBooleanCallback(const GRFFile *grffile, uint16 cbid, uint16 cb_res)
 
{
 
	assert(cb_res != CALLBACK_FAILED); // We do not know what to return
 

	
 
	if (grffile->grf_version < 8) return GB(cb_res, 0, 8) != 0;
 

	
 
	if (cb_res > 1) ErrorUnknownCallbackResult(grffile->grfid, cbid, cb_res);
 
	return cb_res != 0;
 
}
 

	
 

	
 
/* static */ SmallVector<DrawTileSeqStruct, 8> NewGRFSpriteLayout::result_seq;
 
/* static */ std::vector<DrawTileSeqStruct> NewGRFSpriteLayout::result_seq;
 

	
 
/**
 
 * Clone the building sprites of a spritelayout.
 
 * @param source The building sprites to copy.
 
 */
 
void NewGRFSpriteLayout::Clone(const DrawTileSeqStruct *source)
 
{
 
	assert(this->seq == NULL);
 
	assert(source != NULL);
 

	
 
	size_t count = 1; // 1 for the terminator
 
	const DrawTileSeqStruct *element;
 
	foreach_draw_tile_seq(element, source) count++;
 

	
 
	DrawTileSeqStruct *sprites = MallocT<DrawTileSeqStruct>(count);
 
	MemCpyT(sprites, source, count);
 
	this->seq = sprites;
 
}
 

	
 
/**
 
 * Clone a spritelayout.
 
 * @param source The spritelayout to copy.
 
 */
 
void NewGRFSpriteLayout::Clone(const NewGRFSpriteLayout *source)
src/newgrf_commons.h
Show inline comments
 
@@ -149,49 +149,49 @@ struct NewGRFSpriteLayout : ZeroedMemory
 
	 * used directly.
 
	 * @return true if preprocessing is needed
 
	 */
 
	bool NeedsPreprocessing() const
 
	{
 
		return this->registers != NULL;
 
	}
 

	
 
	uint32 PrepareLayout(uint32 orig_offset, uint32 newgrf_ground_offset, uint32 newgrf_offset, uint constr_stage, bool separate_ground) const;
 
	void ProcessRegisters(uint8 resolved_var10, uint32 resolved_sprite, bool separate_ground) const;
 

	
 
	/**
 
	 * Returns the result spritelayout after preprocessing.
 
	 * @pre #PrepareLayout() and #ProcessRegisters() need calling first.
 
	 * @return result spritelayout
 
	 */
 
	const DrawTileSeqStruct *GetLayout(PalSpriteID *ground) const
 
	{
 
		DrawTileSeqStruct *front = result_seq.data();
 
		*ground = front->image;
 
		return front + 1;
 
	}
 

	
 
private:
 
	static SmallVector<DrawTileSeqStruct, 8> result_seq; ///< Temporary storage when preprocessing spritelayouts.
 
	static std::vector<DrawTileSeqStruct> result_seq; ///< Temporary storage when preprocessing spritelayouts.
 
};
 

	
 
/**
 
 * Maps an entity id stored on the map to a GRF file.
 
 * Entities are objects used ingame (houses, industries, industry tiles) for
 
 * which we need to correlate the ids from the grf files with the ones in the
 
 * the savegames themselves.
 
 * An array of EntityIDMapping structs is saved with the savegame so
 
 * that those GRFs can be loaded in a different order, or removed safely. The
 
 * index in the array is the entity's ID stored on the map.
 
 *
 
 * The substitute ID is the ID of an original entity that should be used instead
 
 * if the GRF containing the new entity is not available.
 
 */
 
struct EntityIDMapping {
 
	uint32 grfid;          ///< The GRF ID of the file the entity belongs to
 
	uint8  entity_id;      ///< The entity ID within the GRF file
 
	uint8  substitute_id;  ///< The (original) entity ID to use if this GRF is not available
 
};
 

	
 
class OverrideManagerBase {
 
protected:
 
	uint16 *entity_overrides;
 
	uint32 *grfid_overrides;
src/newgrf_config.h
Show inline comments
 
@@ -151,49 +151,49 @@ struct GRFTextWrapper : public SimpleCou
 

	
 
/** Information about GRF, used in the game and (part of it) in savegames */
 
struct GRFConfig : ZeroedMemoryAllocator {
 
	GRFConfig(const char *filename = NULL);
 
	GRFConfig(const GRFConfig &config);
 
	~GRFConfig();
 

	
 
	GRFIdentifier ident;                           ///< grfid and md5sum to uniquely identify newgrfs
 
	uint8 original_md5sum[16];                     ///< MD5 checksum of original file if only a 'compatible' file was loaded
 
	char *filename;                                ///< Filename - either with or without full path
 
	GRFTextWrapper *name;                          ///< NOSAVE: GRF name (Action 0x08)
 
	GRFTextWrapper *info;                          ///< NOSAVE: GRF info (author, copyright, ...) (Action 0x08)
 
	GRFTextWrapper *url;                           ///< NOSAVE: URL belonging to this GRF.
 
	GRFError *error;                               ///< NOSAVE: Error/Warning during GRF loading (Action 0x0B)
 

	
 
	uint32 version;                                ///< NOSAVE: Version a NewGRF can set so only the newest NewGRF is shown
 
	uint32 min_loadable_version;                   ///< NOSAVE: Minimum compatible version a NewGRF can define
 
	uint8 flags;                                   ///< NOSAVE: GCF_Flags, bitset
 
	GRFStatus status;                              ///< NOSAVE: GRFStatus, enum
 
	uint32 grf_bugs;                               ///< NOSAVE: bugs in this GRF in this run, @see enum GRFBugs
 
	uint32 param[0x80];                            ///< GRF parameters
 
	uint8 num_params;                              ///< Number of used parameters
 
	uint8 num_valid_params;                        ///< NOSAVE: Number of valid parameters (action 0x14)
 
	uint8 palette;                                 ///< GRFPalette, bitset
 
	SmallVector<GRFParameterInfo *, 4> param_info; ///< NOSAVE: extra information about the parameters
 
	std::vector<GRFParameterInfo *> param_info; ///< NOSAVE: extra information about the parameters
 
	bool has_param_defaults;                       ///< NOSAVE: did this newgrf specify any defaults for it's parameters
 

	
 
	struct GRFConfig *next;                        ///< NOSAVE: Next item in the linked list
 

	
 
	void CopyParams(const GRFConfig &src);
 

	
 
	const char *GetTextfile(TextfileType type) const;
 
	const char *GetName() const;
 
	const char *GetDescription() const;
 
	const char *GetURL() const;
 

	
 
	void SetParameterDefaults();
 
	void SetSuitablePalette();
 
	void FinalizeParameterInfo();
 
};
 

	
 
/** Method to find GRFs using FindGRFConfig */
 
enum FindGRFConfigMode {
 
	FGCM_EXACT,       ///< Only find Grfs matching md5sum
 
	FGCM_COMPATIBLE,  ///< Find best compatible Grf wrt. desired_version
 
	FGCM_NEWEST,      ///< Find newest Grf
 
	FGCM_NEWEST_VALID,///< Find newest Grf, ignoring Grfs with GCF_INVALID set
 
	FGCM_ANY,         ///< Use first found
 
};
src/newgrf_debug.h
Show inline comments
 
@@ -8,40 +8,40 @@
 
 */
 

	
 
/** @file newgrf_debug.h Functions/types related to NewGRF debugging. */
 

	
 
#ifndef NEWGRF_DEBUG_H
 
#define NEWGRF_DEBUG_H
 

	
 
#include "newgrf.h"
 
#include "core/smallvec_type.hpp"
 
#include "tile_type.h"
 
#include "vehicle_type.h"
 

	
 
/** Current state of spritepicker */
 
enum NewGrfDebugSpritePickerMode {
 
	SPM_NONE,
 
	SPM_WAIT_CLICK,
 
	SPM_REDRAW,
 
};
 

	
 
/** Spritepicker of SpriteAligner */
 
struct NewGrfDebugSpritePicker {
 
	NewGrfDebugSpritePickerMode mode;   ///< Current state
 
	void *clicked_pixel;                ///< Clicked pixel (pointer to blitter buffer)
 
	uint32 click_time;                  ///< Realtime tick when clicked to detect next frame
 
	SmallVector<SpriteID, 256> sprites; ///< Sprites found
 
	std::vector<SpriteID> sprites; ///< Sprites found
 
};
 

	
 
extern NewGrfDebugSpritePicker _newgrf_debug_sprite_picker;
 

	
 
bool IsNewGRFInspectable(GrfSpecFeature feature, uint index);
 
void ShowNewGRFInspectWindow(GrfSpecFeature feature, uint index, const uint32 grfid = 0);
 
void InvalidateNewGRFInspectWindow(GrfSpecFeature feature, uint index);
 
void DeleteNewGRFInspectWindow(GrfSpecFeature feature, uint index);
 

	
 
GrfSpecFeature GetGrfSpecFeature(TileIndex tile);
 
GrfSpecFeature GetGrfSpecFeature(VehicleType type);
 

	
 
void ShowSpriteAlignerWindow();
 

	
 
#endif /* NEWGRF_DEBUG_H */
src/newgrf_debug_gui.cpp
Show inline comments
 
@@ -26,49 +26,49 @@
 
#include "object_base.h"
 
#include "station_base.h"
 
#include "town.h"
 
#include "vehicle_base.h"
 
#include "train.h"
 
#include "roadveh.h"
 

	
 
#include "newgrf_airporttiles.h"
 
#include "newgrf_debug.h"
 
#include "newgrf_object.h"
 
#include "newgrf_spritegroup.h"
 
#include "newgrf_station.h"
 
#include "newgrf_town.h"
 
#include "newgrf_railtype.h"
 
#include "newgrf_industries.h"
 
#include "newgrf_industrytiles.h"
 

	
 
#include "widgets/newgrf_debug_widget.h"
 

	
 
#include "table/strings.h"
 

	
 
#include "safeguards.h"
 

	
 
/** The sprite picker. */
 
NewGrfDebugSpritePicker _newgrf_debug_sprite_picker = { SPM_NONE, NULL, 0, SmallVector<SpriteID, 256>() };
 
NewGrfDebugSpritePicker _newgrf_debug_sprite_picker = { SPM_NONE, NULL, 0, std::vector<SpriteID>() };
 

	
 
/**
 
 * Get the feature index related to the window number.
 
 * @param window_number The window to get the feature index from.
 
 * @return the feature index
 
 */
 
static inline uint GetFeatureIndex(uint window_number)
 
{
 
	return GB(window_number, 0, 24);
 
}
 

	
 
/**
 
 * Get the window number for the inspect window given a
 
 * feature and index.
 
 * @param feature The feature we want to inspect.
 
 * @param index   The index/identifier of the feature to inspect.
 
 * @return the InspectWindow (Window)Number
 
 */
 
static inline uint GetInspectWindowNumber(GrfSpecFeature feature, uint index)
 
{
 
	assert((index >> 24) == 0);
 
	return (feature << 24) | index;
 
}
 

	
 
@@ -873,49 +873,49 @@ struct SpriteAlignerWindow : Window {
 
			case WID_SA_SPRITE: {
 
				/* Center the sprite ourselves */
 
				const Sprite *spr = GetSprite(this->current_sprite, ST_NORMAL);
 
				int width  = r.right  - r.left + 1 - WD_BEVEL_LEFT - WD_BEVEL_RIGHT;
 
				int height = r.bottom - r.top  + 1 - WD_BEVEL_TOP - WD_BEVEL_BOTTOM;
 
				int x = -UnScaleGUI(spr->x_offs) + (width  - UnScaleGUI(spr->width) ) / 2;
 
				int y = -UnScaleGUI(spr->y_offs) + (height - UnScaleGUI(spr->height)) / 2;
 

	
 
				DrawPixelInfo new_dpi;
 
				if (!FillDrawPixelInfo(&new_dpi, r.left + WD_BEVEL_LEFT, r.top + WD_BEVEL_TOP, width, height)) break;
 
				DrawPixelInfo *old_dpi = _cur_dpi;
 
				_cur_dpi = &new_dpi;
 

	
 
				DrawSprite(this->current_sprite, PAL_NONE, x, y, NULL, ZOOM_LVL_GUI);
 

	
 
				_cur_dpi = old_dpi;
 

	
 
				break;
 
			}
 

	
 
			case WID_SA_LIST: {
 
				const NWidgetBase *nwid = this->GetWidget<NWidgetBase>(widget);
 
				int step_size = nwid->resize_y;
 

	
 
				SmallVector<SpriteID, 256> &list = _newgrf_debug_sprite_picker.sprites;
 
				std::vector<SpriteID> &list = _newgrf_debug_sprite_picker.sprites;
 
				int max = min<int>(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), list.size());
 

	
 
				int y = r.top + WD_FRAMERECT_TOP;
 
				for (int i = this->vscroll->GetPosition(); i < max; i++) {
 
					SetDParam(0, list[i]);
 
					DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_BLACK_COMMA, TC_FROMSTRING, SA_RIGHT | SA_FORCE);
 
					y += step_size;
 
				}
 
				break;
 
			}
 
		}
 
	}
 

	
 
	void OnClick(Point pt, int widget, int click_count) override
 
	{
 
		switch (widget) {
 
			case WID_SA_PREVIOUS:
 
				do {
 
					this->current_sprite = (this->current_sprite == 0 ? GetMaxSpriteID() :  this->current_sprite) - 1;
 
				} while (GetSpriteType(this->current_sprite) != ST_NORMAL);
 
				this->SetDirty();
 
				break;
 

	
 
			case WID_SA_GOTO:
src/newgrf_engine.cpp
Show inline comments
 
@@ -1164,90 +1164,90 @@ static void DoTriggerVehicle(Vehicle *v,
 
			/* Do not do any recursion */
 
			break;
 
	}
 
}
 

	
 
void TriggerVehicle(Vehicle *v, VehicleTrigger trigger)
 
{
 
	if (trigger == VEHICLE_TRIGGER_DEPOT) {
 
		/* store that the vehicle entered a depot this tick */
 
		VehicleEnteredDepotThisTick(v);
 
	}
 

	
 
	v->InvalidateNewGRFCacheOfChain();
 
	DoTriggerVehicle(v, trigger, 0, true);
 
	v->InvalidateNewGRFCacheOfChain();
 
}
 

	
 
/* Functions for changing the order of vehicle purchase lists */
 

	
 
struct ListOrderChange {
 
	EngineID engine;
 
	uint target;      ///< local ID
 
};
 

	
 
static SmallVector<ListOrderChange, 16> _list_order_changes;
 
static std::vector<ListOrderChange> _list_order_changes;
 

	
 
/**
 
 * Record a vehicle ListOrderChange.
 
 * @param engine Engine to move
 
 * @param target Local engine ID to move \a engine in front of
 
 * @note All sorting is done later in CommitVehicleListOrderChanges
 
 */
 
void AlterVehicleListOrder(EngineID engine, uint target)
 
{
 
	/* Add the list order change to a queue */
 
	_list_order_changes.push_back({engine, target});
 
}
 

	
 
/**
 
 * Comparator function to sort engines via scope-GRFID and local ID.
 
 * @param a left side
 
 * @param b right side
 
 * @return comparison result
 
 */
 
static int CDECL EnginePreSort(const EngineID *a, const EngineID *b)
 
{
 
	const EngineIDMapping &id_a = _engine_mngr.at(*a);
 
	const EngineIDMapping &id_b = _engine_mngr.at(*b);
 

	
 
	/* 1. Sort by engine type */
 
	if (id_a.type != id_b.type) return (int)id_a.type - (int)id_b.type;
 

	
 
	/* 2. Sort by scope-GRFID */
 
	if (id_a.grfid != id_b.grfid) return id_a.grfid < id_b.grfid ? -1 : 1;
 

	
 
	/* 3. Sort by local ID */
 
	return (int)id_a.internal_id - (int)id_b.internal_id;
 
}
 

	
 
/**
 
 * Deternine default engine sorting and execute recorded ListOrderChanges from AlterVehicleListOrder.
 
 */
 
void CommitVehicleListOrderChanges()
 
{
 
	/* Pre-sort engines by scope-grfid and local index */
 
	SmallVector<EngineID, 16> ordering;
 
	std::vector<EngineID> ordering;
 
	Engine *e;
 
	FOR_ALL_ENGINES(e) {
 
		ordering.push_back(e->index);
 
	}
 
	QSortT(ordering.data(), ordering.size(), EnginePreSort);
 

	
 
	/* Apply Insertion-Sort operations */
 
	for (const ListOrderChange &it : _list_order_changes) {
 
		EngineID source = it.engine;
 
		uint local_target = it.target;
 

	
 
		const EngineIDMapping *id_source = _engine_mngr.data() + source;
 
		if (id_source->internal_id == local_target) continue;
 

	
 
		EngineID target = _engine_mngr.GetID(id_source->type, local_target, id_source->grfid);
 
		if (target == INVALID_ENGINE) continue;
 

	
 
		int source_index = find_index(ordering, source);
 
		int target_index = find_index(ordering, target);
 

	
 
		assert(source_index >= 0 && target_index >= 0);
 
		assert(source_index != target_index);
 

	
 
		EngineID *list = ordering.data();
src/newgrf_sound.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file newgrf_sound.cpp Handling NewGRF provided sounds. */
 

	
 
#include "stdafx.h"
 
#include "engine_base.h"
 
#include "newgrf.h"
 
#include "newgrf_engine.h"
 
#include "newgrf_sound.h"
 
#include "vehicle_base.h"
 
#include "sound_func.h"
 
#include "fileio_func.h"
 
#include "debug.h"
 
#include "settings_type.h"
 

	
 
#include "safeguards.h"
 

	
 
static SmallVector<SoundEntry, 8> _sounds;
 
static std::vector<SoundEntry> _sounds;
 

	
 

	
 
/**
 
 * Allocate sound slots.
 
 * @param num Number of slots to allocate.
 
 * @return First allocated slot.
 
 */
 
SoundEntry *AllocateSound(uint num)
 
{
 
	SoundEntry *sound = grow(_sounds, num);
 
	MemSetT(sound, 0, num);
 
	return sound;
 
}
 

	
 

	
 
void InitializeSoundPool()
 
{
 
	_sounds.clear();
 

	
 
	/* Copy original sound data to the pool */
 
	SndCopyToPool();
 
}
 

	
 

	
src/newgrf_text.cpp
Show inline comments
 
@@ -146,64 +146,64 @@ public:
 
 * Holder of the above structure.
 
 * Putting both grfid and stringid together allows us to avoid duplicates,
 
 * since it is NOT SUPPOSED to happen.
 
 */
 
struct GRFTextEntry {
 
	uint32 grfid;
 
	uint16 stringid;
 
	StringID def_string;
 
	GRFText *textholder;
 
};
 

	
 

	
 
static uint _num_grf_texts = 0;
 
static GRFTextEntry _grf_text[TAB_SIZE_NEWGRF];
 
static byte _currentLangID = GRFLX_ENGLISH;  ///< by default, english is used.
 

	
 
/**
 
 * Get the mapping from the NewGRF supplied ID to OpenTTD's internal ID.
 
 * @param newgrf_id The NewGRF ID to map.
 
 * @param gender    Whether to map genders or cases.
 
 * @return The, to OpenTTD's internal ID, mapped index, or -1 if there is no mapping.
 
 */
 
int LanguageMap::GetMapping(int newgrf_id, bool gender) const
 
{
 
	const SmallVector<Mapping, 1> &map = gender ? this->gender_map : this->case_map;
 
	const std::vector<Mapping> &map = gender ? this->gender_map : this->case_map;
 
	for (const Mapping &m : map) {
 
		if (m.newgrf_id == newgrf_id) return m.openttd_id;
 
	}
 
	return -1;
 
}
 

	
 
/**
 
 * Get the mapping from OpenTTD's internal ID to the NewGRF supplied ID.
 
 * @param openttd_id The OpenTTD ID to map.
 
 * @param gender     Whether to map genders or cases.
 
 * @return The, to the NewGRF supplied ID, mapped index, or -1 if there is no mapping.
 
 */
 
int LanguageMap::GetReverseMapping(int openttd_id, bool gender) const
 
{
 
	const SmallVector<Mapping, 1> &map = gender ? this->gender_map : this->case_map;
 
	const std::vector<Mapping> &map = gender ? this->gender_map : this->case_map;
 
	for (const Mapping &m : map) {
 
		if (m.openttd_id == openttd_id) return m.newgrf_id;
 
	}
 
	return -1;
 
}
 

	
 
/** Helper structure for mapping choice lists. */
 
struct UnmappedChoiceList : ZeroedMemoryAllocator {
 
	/** Clean everything up. */
 
	~UnmappedChoiceList()
 
	{
 
		for (SmallPair<byte, char *> p : this->strings) {
 
			free(p.second);
 
		}
 
	}
 

	
 
	/**
 
	 * Initialise the mapping.
 
	 * @param type   The type of mapping.
 
	 * @param old_d  The old begin of the string, i.e. from where to start writing again.
 
	 * @param offset The offset to get the plural/gender from.
 
	 */
 
	UnmappedChoiceList(StringControlCode type, char *old_d, int offset) :
 
		type(type), old_d(old_d), offset(offset)
src/newgrf_text.h
Show inline comments
 
@@ -36,34 +36,34 @@ void CleanUpGRFText(struct GRFText *grft
 
bool CheckGrfLangID(byte lang_id, byte grf_version);
 

	
 
void StartTextRefStackUsage(const GRFFile *grffile, byte numEntries, const uint32 *values = NULL);
 
void StopTextRefStackUsage();
 
void RewindTextRefStack();
 
bool UsingNewGRFTextStack();
 
struct TextRefStack *CreateTextRefStackBackup();
 
void RestoreTextRefStackBackup(struct TextRefStack *backup);
 
uint RemapNewGRFStringControlCode(uint scc, char *buf_start, char **buff, const char **str, int64 *argv, uint argv_size, bool modify_argv);
 

	
 
/** Mapping of language data between a NewGRF and OpenTTD. */
 
struct LanguageMap {
 
	/** Mapping between NewGRF and OpenTTD IDs. */
 
	struct Mapping {
 
		byte newgrf_id;  ///< NewGRF's internal ID for a case/gender.
 
		byte openttd_id; ///< OpenTTD's internal ID for a case/gender.
 
	};
 

	
 
	/* We need a vector and can't use SmallMap due to the fact that for "setting" a
 
	 * gender of a string or requesting a case for a substring we want to map from
 
	 * the NewGRF's internal ID to OpenTTD's ID whereas for the choice lists we map
 
	 * the genders/cases/plural OpenTTD IDs to the NewGRF's internal IDs. In this
 
	 * case a NewGRF developer/translator might want a different translation for
 
	 * both cases. Thus we are basically implementing a multi-map. */
 
	SmallVector<Mapping, 1> gender_map; ///< Mapping of NewGRF and OpenTTD IDs for genders.
 
	SmallVector<Mapping, 1> case_map;   ///< Mapping of NewGRF and OpenTTD IDs for cases.
 
	std::vector<Mapping> gender_map; ///< Mapping of NewGRF and OpenTTD IDs for genders.
 
	std::vector<Mapping> case_map;   ///< Mapping of NewGRF and OpenTTD IDs for cases.
 
	int plural_form;                    ///< The plural form used for this language.
 

	
 
	int GetMapping(int newgrf_id, bool gender) const;
 
	int GetReverseMapping(int openttd_id, bool gender) const;
 
	static const LanguageMap *GetLanguageMap(uint32 grfid, uint8 language_id);
 
};
 

	
 
#endif /* NEWGRF_TEXT_H */
src/object_base.h
Show inline comments
 
@@ -71,27 +71,27 @@ struct Object : ObjectPool::PoolItem<&_o
 
	}
 

	
 
	/** Resets object counts. */
 
	static inline void ResetTypeCounts()
 
	{
 
		memset(&counts, 0, sizeof(counts));
 
	}
 

	
 
protected:
 
	static uint16 counts[NUM_OBJECTS]; ///< Number of objects per type ingame
 
};
 

	
 
#define FOR_ALL_OBJECTS_FROM(var, start) FOR_ALL_ITEMS_FROM(Object, object_index, var, start)
 
#define FOR_ALL_OBJECTS(var) FOR_ALL_OBJECTS_FROM(var, 0)
 

	
 
/**
 
 * Keeps track of removed objects during execution/testruns of commands.
 
 */
 
struct ClearedObjectArea {
 
	TileIndex first_tile;  ///< The first tile being cleared, which then causes the whole object to be cleared.
 
	TileArea area;         ///< The area of the object.
 
};
 

	
 
ClearedObjectArea *FindClearedObject(TileIndex tile);
 
extern SmallVector<ClearedObjectArea, 4> _cleared_object_areas;
 
extern std::vector<ClearedObjectArea> _cleared_object_areas;
 

	
 
#endif /* OBJECT_BASE_H */
src/object_cmd.cpp
Show inline comments
 
@@ -421,49 +421,49 @@ static int GetSlopePixelZ_Object(TileInd
 
		return GetTileMaxPixelZ(tile);
 
	}
 
}
 

	
 
static Foundation GetFoundation_Object(TileIndex tile, Slope tileh)
 
{
 
	return IsObjectType(tile, OBJECT_OWNED_LAND) ? FOUNDATION_NONE : FlatteningFoundation(tileh);
 
}
 

	
 
/**
 
 * Perform the actual removal of the object from the map.
 
 * @param o The object to really clear.
 
 */
 
static void ReallyClearObjectTile(Object *o)
 
{
 
	Object::DecTypeCount(o->type);
 
	TILE_AREA_LOOP(tile_cur, o->location) {
 
		DeleteNewGRFInspectWindow(GSF_OBJECTS, tile_cur);
 

	
 
		MakeWaterKeepingClass(tile_cur, GetTileOwner(tile_cur));
 
	}
 
	delete o;
 
}
 

	
 
SmallVector<ClearedObjectArea, 4> _cleared_object_areas;
 
std::vector<ClearedObjectArea> _cleared_object_areas;
 

	
 
/**
 
 * Find the entry in _cleared_object_areas which occupies a certain tile.
 
 * @param tile Tile of interest
 
 * @return Occupying entry, or NULL if none
 
 */
 
ClearedObjectArea *FindClearedObject(TileIndex tile)
 
{
 
	TileArea ta = TileArea(tile, 1, 1);
 

	
 
	for (ClearedObjectArea &coa : _cleared_object_areas) {
 
		if (coa.area.Intersects(ta)) return &coa;
 
	}
 

	
 
	return NULL;
 
}
 

	
 
static CommandCost ClearTile_Object(TileIndex tile, DoCommandFlag flags)
 
{
 
	/* Get to the northern most tile. */
 
	Object *o = Object::GetByTile(tile);
 
	TileArea ta = o->location;
 

	
 
	ObjectType type = o->type;
src/openttd.cpp
Show inline comments
 
@@ -1153,68 +1153,68 @@ void SwitchToMode(SwitchMode new_mode)
 
			SetLocalCompany(OWNER_NONE);
 
			GenerateWorld(GWM_RANDOM, 1 << _settings_game.game_creation.map_x, 1 << _settings_game.game_creation.map_y);
 
			/* XXX: set date */
 
			MarkWholeScreenDirty();
 
			break;
 

	
 
		default: NOT_REACHED();
 
	}
 
}
 

	
 

	
 
/**
 
 * Check the validity of some of the caches.
 
 * Especially in the sense of desyncs between
 
 * the cached value and what the value would
 
 * be when calculated from the 'base' data.
 
 */
 
static void CheckCaches()
 
{
 
	/* Return here so it is easy to add checks that are run
 
	 * always to aid testing of caches. */
 
	if (_debug_desync_level <= 1) return;
 

	
 
	/* Check the town caches. */
 
	SmallVector<TownCache, 4> old_town_caches;
 
	std::vector<TownCache> old_town_caches;
 
	Town *t;
 
	FOR_ALL_TOWNS(t) {
 
		old_town_caches.push_back(t->cache);
 
	}
 

	
 
	extern void RebuildTownCaches();
 
	RebuildTownCaches();
 
	RebuildSubsidisedSourceAndDestinationCache();
 

	
 
	uint i = 0;
 
	FOR_ALL_TOWNS(t) {
 
		if (MemCmpT(old_town_caches.data() + i, &t->cache) != 0) {
 
			DEBUG(desync, 2, "town cache mismatch: town %i", (int)t->index);
 
		}
 
		i++;
 
	}
 

	
 
	/* Check company infrastructure cache. */
 
	SmallVector<CompanyInfrastructure, 4> old_infrastructure;
 
	std::vector<CompanyInfrastructure> old_infrastructure;
 
	Company *c;
 
	FOR_ALL_COMPANIES(c) old_infrastructure.push_back(c->infrastructure);
 

	
 
	extern void AfterLoadCompanyStats();
 
	AfterLoadCompanyStats();
 

	
 
	i = 0;
 
	FOR_ALL_COMPANIES(c) {
 
		if (MemCmpT(old_infrastructure.data() + i, &c->infrastructure) != 0) {
 
			DEBUG(desync, 2, "infrastructure cache mismatch: company %i", (int)c->index);
 
		}
 
		i++;
 
	}
 

	
 
	/* Strict checking of the road stop cache entries */
 
	const RoadStop *rs;
 
	FOR_ALL_ROADSTOPS(rs) {
 
		if (IsStandardRoadStopTile(rs->xy)) continue;
 

	
 
		assert(rs->GetEntry(DIAGDIR_NE) != rs->GetEntry(DIAGDIR_NW));
 
		rs->GetEntry(DIAGDIR_NE)->CheckIntegrity(rs);
 
		rs->GetEntry(DIAGDIR_NW)->CheckIntegrity(rs);
 
	}
 

	
src/rail.h
Show inline comments
 
@@ -97,49 +97,49 @@ enum RailTrackBridgeOffset {
 
/**
 
 * Offsets from base sprite for fence sprites. These are in the order of
 
 *  the sprites in the original data files.
 
 */
 
enum RailFenceOffset {
 
	RFO_FLAT_X_NW,     //!< Slope FLAT, Track X,     Fence NW
 
	RFO_FLAT_Y_NE,     //!< Slope FLAT, Track Y,     Fence NE
 
	RFO_FLAT_LEFT,     //!< Slope FLAT, Track LEFT,  Fence E
 
	RFO_FLAT_UPPER,    //!< Slope FLAT, Track UPPER, Fence S
 
	RFO_SLOPE_SW_NW,   //!< Slope SW,   Track X,     Fence NW
 
	RFO_SLOPE_SE_NE,   //!< Slope SE,   Track Y,     Fence NE
 
	RFO_SLOPE_NE_NW,   //!< Slope NE,   Track X,     Fence NW
 
	RFO_SLOPE_NW_NE,   //!< Slope NW,   Track Y,     Fence NE
 
	RFO_FLAT_X_SE,     //!< Slope FLAT, Track X,     Fence SE
 
	RFO_FLAT_Y_SW,     //!< Slope FLAT, Track Y,     Fence SW
 
	RFO_FLAT_RIGHT,    //!< Slope FLAT, Track RIGHT, Fence W
 
	RFO_FLAT_LOWER,    //!< Slope FLAT, Track LOWER, Fence N
 
	RFO_SLOPE_SW_SE,   //!< Slope SW,   Track X,     Fence SE
 
	RFO_SLOPE_SE_SW,   //!< Slope SE,   Track Y,     Fence SW
 
	RFO_SLOPE_NE_SE,   //!< Slope NE,   Track X,     Fence SE
 
	RFO_SLOPE_NW_SW,   //!< Slope NW,   Track Y,     Fence SW
 
};
 

	
 
/** List of rail type labels. */
 
typedef SmallVector<RailTypeLabel, 4> RailTypeLabelList;
 
typedef std::vector<RailTypeLabel> RailTypeLabelList;
 

	
 
/**
 
 * This struct contains all the info that is needed to draw and construct tracks.
 
 */
 
class RailtypeInfo {
 
public:
 
	/**
 
	 * Struct containing the main sprites. @note not all sprites are listed, but only
 
	 *  the ones used directly in the code
 
	 */
 
	struct {
 
		SpriteID track_y;      ///< single piece of rail in Y direction, with ground
 
		SpriteID track_ns;     ///< two pieces of rail in North and South corner (East-West direction)
 
		SpriteID ground;       ///< ground sprite for a 3-way switch
 
		SpriteID single_x;     ///< single piece of rail in X direction, without ground
 
		SpriteID single_y;     ///< single piece of rail in Y direction, without ground
 
		SpriteID single_n;     ///< single piece of rail in the northern corner
 
		SpriteID single_s;     ///< single piece of rail in the southern corner
 
		SpriteID single_e;     ///< single piece of rail in the eastern corner
 
		SpriteID single_w;     ///< single piece of rail in the western corner
 
		SpriteID single_sloped;///< single piece of rail for slopes
 
		SpriteID crossing;     ///< level crossing, rail in X direction
 
		SpriteID tunnel;       ///< tunnel sprites base
 
	} base_sprites;
src/rail_cmd.cpp
Show inline comments
 
@@ -20,49 +20,49 @@
 
#include "train.h"
 
#include "autoslope.h"
 
#include "water.h"
 
#include "tunnelbridge_map.h"
 
#include "vehicle_func.h"
 
#include "sound_func.h"
 
#include "tunnelbridge.h"
 
#include "elrail_func.h"
 
#include "town.h"
 
#include "pbs.h"
 
#include "company_base.h"
 
#include "core/backup_type.hpp"
 
#include "date_func.h"
 
#include "strings_func.h"
 
#include "company_gui.h"
 
#include "object_map.h"
 

	
 
#include "table/strings.h"
 
#include "table/railtypes.h"
 
#include "table/track_land.h"
 

	
 
#include "safeguards.h"
 

	
 
/** Helper type for lists/vectors of trains */
 
typedef SmallVector<Train *, 16> TrainList;
 
typedef std::vector<Train *> TrainList;
 

	
 
RailtypeInfo _railtypes[RAILTYPE_END];
 
RailType _sorted_railtypes[RAILTYPE_END];
 
uint8 _sorted_railtypes_size;
 
RailTypes _railtypes_hidden_mask;
 

	
 
/** Enum holding the signal offset in the sprite sheet according to the side it is representing. */
 
enum SignalOffsets {
 
	SIGNAL_TO_SOUTHWEST,
 
	SIGNAL_TO_NORTHEAST,
 
	SIGNAL_TO_SOUTHEAST,
 
	SIGNAL_TO_NORTHWEST,
 
	SIGNAL_TO_EAST,
 
	SIGNAL_TO_WEST,
 
	SIGNAL_TO_SOUTH,
 
	SIGNAL_TO_NORTH,
 
};
 

	
 
/**
 
 * Reset all rail type information to its default values.
 
 */
 
void ResetRailTypes()
 
{
 
	assert_compile(lengthof(_original_railtypes) <= lengthof(_railtypes));
 
@@ -1582,49 +1582,49 @@ CommandCost CmdConvertRail(TileIndex til
 
				if (RailNoLevelCrossings(totype)) {
 
					error.MakeError(STR_ERROR_CROSSING_DISALLOWED);
 
					continue;
 
				}
 
				break;
 
			case MP_TUNNELBRIDGE:
 
				if (GetTunnelBridgeTransportType(tile) != TRANSPORT_RAIL) continue;
 
				break;
 
			default: continue;
 
		}
 

	
 
		/* Original railtype we are converting from */
 
		RailType type = GetRailType(tile);
 

	
 
		/* Converting to the same type or converting 'hidden' elrail -> rail */
 
		if (type == totype || (_settings_game.vehicle.disable_elrails && totype == RAILTYPE_RAIL && type == RAILTYPE_ELECTRIC)) continue;
 

	
 
		/* Trying to convert other's rail */
 
		CommandCost ret = CheckTileOwnership(tile);
 
		if (ret.Failed()) {
 
			error = ret;
 
			continue;
 
		}
 

	
 
		SmallVector<Train *, 2> vehicles_affected;
 
		std::vector<Train *> vehicles_affected;
 

	
 
		/* Vehicle on the tile when not converting Rail <-> ElRail
 
		 * Tunnels and bridges have special check later */
 
		if (tt != MP_TUNNELBRIDGE) {
 
			if (!IsCompatibleRail(type, totype)) {
 
				CommandCost ret = IsPlainRailTile(tile) ? EnsureNoTrainOnTrackBits(tile, GetTrackBits(tile)) : EnsureNoVehicleOnGround(tile);
 
				if (ret.Failed()) {
 
					error = ret;
 
					continue;
 
				}
 
			}
 
			if (flags & DC_EXEC) { // we can safely convert, too
 
				TrackBits reserved = GetReservedTrackbits(tile);
 
				Track     track;
 
				while ((track = RemoveFirstTrack(&reserved)) != INVALID_TRACK) {
 
					Train *v = GetTrainForReservation(tile, track);
 
					if (v != NULL && !HasPowerOnRail(v->railtype, totype)) {
 
						/* No power on new rail type, reroute. */
 
						FreeTrainTrackReservation(v);
 
						vehicles_affected.push_back(v);
 
					}
 
				}
 

	
 
				/* Update the company infrastructure counters. */
src/saveload/afterload.cpp
Show inline comments
 
@@ -2174,49 +2174,49 @@ bool AfterLoadGame()
 
		/* We didn't store cargo payment yet, so make them for vehicles that are
 
		 * currently at a station and loading/unloading. If they don't get any
 
		 * payment anymore they just removed in the next load/unload cycle.
 
		 * However, some 0.7 versions might have cargo payment. For those we just
 
		 * add cargopayment for the vehicles that don't have it.
 
		 */
 
		Station *st;
 
		FOR_ALL_STATIONS(st) {
 
			std::list<Vehicle *>::iterator iter;
 
			for (iter = st->loading_vehicles.begin(); iter != st->loading_vehicles.end(); ++iter) {
 
				/* There are always as many CargoPayments as Vehicles. We need to make the
 
				 * assert() in Pool::GetNew() happy by calling CanAllocateItem(). */
 
				assert_compile(CargoPaymentPool::MAX_SIZE == VehiclePool::MAX_SIZE);
 
				assert(CargoPayment::CanAllocateItem());
 
				Vehicle *v = *iter;
 
				if (v->cargo_payment == NULL) v->cargo_payment = new CargoPayment(v);
 
			}
 
		}
 
	}
 

	
 
	if (IsSavegameVersionBefore(SLV_122)) {
 
		/* Animated tiles would sometimes not be actually animated or
 
		 * in case of old savegames duplicate. */
 

	
 
		extern SmallVector<TileIndex, 256> _animated_tiles;
 
		extern std::vector<TileIndex> _animated_tiles;
 

	
 
		for (auto tile = _animated_tiles.begin(); tile < _animated_tiles.end(); /* Nothing */) {
 
			/* Remove if tile is not animated */
 
			bool remove = _tile_type_procs[GetTileType(*tile)]->animate_tile_proc == NULL;
 

	
 
			/* and remove if duplicate */
 
			for (auto j = _animated_tiles.begin(); !remove && j < tile; j++) {
 
				remove = *tile == *j;
 
			}
 

	
 
			if (remove) {
 
				DeleteAnimatedTile(*tile);
 
			} else {
 
				tile++;
 
			}
 
		}
 
	}
 

	
 
	if (IsSavegameVersionBefore(SLV_124) && !IsSavegameVersionBefore(SLV_1)) {
 
		/* The train station tile area was added, but for really old (TTDPatch) it's already valid. */
 
		Waypoint *wp;
 
		FOR_ALL_WAYPOINTS(wp) {
 
			if (wp->facilities & FACIL_TRAIN) {
 
				wp->train_station.tile = wp->xy;
 
@@ -2918,49 +2918,49 @@ bool AfterLoadGame()
 
		_settings_game.locale.units_volume   = Clamp(_old_units, 1, 2);
 
		_settings_game.locale.units_force    = 2;
 
		_settings_game.locale.units_height   = Clamp(_old_units, 0, 2);
 
	}
 

	
 
	if (IsSavegameVersionBefore(SLV_186)) {
 
		/* Move ObjectType from map to pool */
 
		for (TileIndex t = 0; t < map_size; t++) {
 
			if (IsTileType(t, MP_OBJECT)) {
 
				Object *o = Object::Get(_m[t].m2);
 
				o->type = _m[t].m5;
 
				_m[t].m5 = 0; // zero upper bits of (now bigger) ObjectID
 
			}
 
		}
 
	}
 

	
 
	if (IsSavegameVersionBefore(SLV_188)) {
 
		/* Fix articulated road vehicles.
 
		 * Some curves were shorter than other curves.
 
		 * Now they have the same length, but that means that trailing articulated parts will
 
		 * take longer to go through the curve than the parts in front which already left the courve.
 
		 * So, make articulated parts catch up. */
 
		RoadVehicle *v;
 
		bool roadside = _settings_game.vehicle.road_side == 1;
 
		SmallVector<uint, 16> skip_frames;
 
		std::vector<uint> skip_frames;
 
		FOR_ALL_ROADVEHICLES(v) {
 
			if (!v->IsFrontEngine()) continue;
 
			skip_frames.clear();
 
			TileIndex prev_tile = v->tile;
 
			uint prev_tile_skip = 0;
 
			uint cur_skip = 0;
 
			for (RoadVehicle *u = v; u != NULL; u = u->Next()) {
 
				if (u->tile != prev_tile) {
 
					prev_tile_skip = cur_skip;
 
					prev_tile = u->tile;
 
				} else {
 
					cur_skip = prev_tile_skip;
 
				}
 

	
 
				/*C++17: uint &this_skip = */ skip_frames.push_back(prev_tile_skip);
 
				uint &this_skip = skip_frames.back();
 

	
 
				/* The following 3 curves now take longer than before */
 
				switch (u->state) {
 
					case 2:
 
						cur_skip++;
 
						if (u->frame <= (roadside ? 9 : 5)) this_skip = cur_skip;
 
						break;
 

	
src/saveload/animated_tile_sl.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file animated_tile_sl.cpp Code handling saving and loading of animated tiles */
 

	
 
#include "../stdafx.h"
 
#include "../tile_type.h"
 
#include "../core/alloc_func.hpp"
 
#include "../core/smallvec_type.hpp"
 

	
 
#include "saveload.h"
 

	
 
#include "../safeguards.h"
 

	
 
extern SmallVector<TileIndex, 256> _animated_tiles;
 
extern std::vector<TileIndex> _animated_tiles;
 

	
 
/**
 
 * Save the ANIT chunk.
 
 */
 
static void Save_ANIT()
 
{
 
	SlSetLength(_animated_tiles.size() * sizeof(_animated_tiles.front()));
 
	SlArray(_animated_tiles.data(), _animated_tiles.size(), SLE_UINT32);
 
}
 

	
 
/**
 
 * Load the ANIT chunk; the chunk containing the animated tiles.
 
 */
 
static void Load_ANIT()
 
{
 
	/* Before version 80 we did NOT have a variable length animated tile table */
 
	if (IsSavegameVersionBefore(SLV_80)) {
 
		/* In pre version 6, we has 16bit per tile, now we have 32bit per tile, convert it ;) */
 
		TileIndex anim_list[256];
 
		SlArray(anim_list, 256, IsSavegameVersionBefore(SLV_6) ? (SLE_FILE_U16 | SLE_VAR_U32) : SLE_UINT32);
 

	
 
		for (int i = 0; i < 256; i++) {
 
			if (anim_list[i] == 0) break;
 
			_animated_tiles.push_back(anim_list[i]);
src/saveload/labelmaps_sl.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file labelmaps_sl.cpp Code handling saving and loading of rail type label mappings */
 

	
 
#include "../stdafx.h"
 
#include "../station_map.h"
 
#include "../tunnelbridge_map.h"
 

	
 
#include "saveload.h"
 

	
 
#include "../safeguards.h"
 

	
 
static SmallVector<RailTypeLabel, RAILTYPE_END> _railtype_list;
 
static std::vector<RailTypeLabel> _railtype_list;
 

	
 
/**
 
 * Test if any saved rail type labels are different to the currently loaded
 
 * rail types, which therefore requires conversion.
 
 * @return true if (and only if) conversion due to rail type changes is needed.
 
 */
 
static bool NeedRailTypeConversion()
 
{
 
	for (uint i = 0; i < _railtype_list.size(); i++) {
 
		if ((RailType)i < RAILTYPE_END) {
 
			const RailtypeInfo *rti = GetRailTypeInfo((RailType)i);
 
			if (rti->label != _railtype_list[i]) return true;
 
		} else {
 
			if (_railtype_list[i] != 0) return true;
 
		}
 
	}
 

	
 
	/* No rail type conversion is necessary */
 
	return false;
 
}
 

	
 
void AfterLoadLabelMaps()
 
{
 
	if (NeedRailTypeConversion()) {
 
		SmallVector<RailType, RAILTYPE_END> railtype_conversion_map;
 
		std::vector<RailType> railtype_conversion_map;
 

	
 
		for (uint i = 0; i < _railtype_list.size(); i++) {
 
			RailType r = GetRailTypeByLabel(_railtype_list[i]);
 
			if (r == INVALID_RAILTYPE) r = RAILTYPE_BEGIN;
 

	
 
			railtype_conversion_map.push_back(r);
 
		}
 

	
 
		for (TileIndex t = 0; t < MapSize(); t++) {
 
			switch (GetTileType(t)) {
 
				case MP_RAILWAY:
 
					SetRailType(t, railtype_conversion_map[GetRailType(t)]);
 
					break;
 

	
 
				case MP_ROAD:
 
					if (IsLevelCrossing(t)) {
 
						SetRailType(t, railtype_conversion_map[GetRailType(t)]);
 
					}
 
					break;
 

	
 
				case MP_STATION:
 
					if (HasStationRail(t)) {
 
						SetRailType(t, railtype_conversion_map[GetRailType(t)]);
 
					}
src/saveload/linkgraph_sl.cpp
Show inline comments
 
@@ -30,49 +30,49 @@ static uint16 _num_nodes;
 
 * @return SaveLoad array for link graph.
 
 */
 
const SaveLoad *GetLinkGraphDesc()
 
{
 
	static const SaveLoad link_graph_desc[] = {
 
		 SLE_VAR(LinkGraph, last_compression, SLE_INT32),
 
		SLEG_VAR(_num_nodes,                  SLE_UINT16),
 
		 SLE_VAR(LinkGraph, cargo,            SLE_UINT8),
 
		 SLE_END()
 
	};
 
	return link_graph_desc;
 
}
 

	
 
/**
 
 * Get a SaveLoad array for a link graph job. The settings struct is derived from
 
 * the global settings saveload array. The exact entries are calculated when the function
 
 * is called the first time.
 
 * It's necessary to keep a copy of the settings for each link graph job so that you can
 
 * change the settings while in-game and still not mess with current link graph runs.
 
 * Of course the settings have to be saved and loaded, too, to avoid desyncs.
 
 * @return Array of SaveLoad structs.
 
 */
 
const SaveLoad *GetLinkGraphJobDesc()
 
{
 
	static SmallVector<SaveLoad, 16> saveloads;
 
	static std::vector<SaveLoad> saveloads;
 
	static const char *prefix = "linkgraph.";
 

	
 
	/* Build the SaveLoad array on first call and don't touch it later on */
 
	if (saveloads.size() == 0) {
 
		size_t offset_gamesettings = cpp_offsetof(GameSettings, linkgraph);
 
		size_t offset_component = cpp_offsetof(LinkGraphJob, settings);
 

	
 
		size_t prefixlen = strlen(prefix);
 

	
 
		int setting = 0;
 
		const SettingDesc *desc = GetSettingDescription(setting);
 
		while (desc->save.cmd != SL_END) {
 
			if (desc->desc.name != NULL && strncmp(desc->desc.name, prefix, prefixlen) == 0) {
 
				SaveLoad sl = desc->save;
 
				char *&address = reinterpret_cast<char *&>(sl.address);
 
				address -= offset_gamesettings;
 
				address += offset_component;
 
				saveloads.push_back(sl);
 
			}
 
			desc = GetSettingDescription(++setting);
 
		}
 

	
 
		const SaveLoad job_desc[] = {
 
			SLE_VAR(LinkGraphJob, join_date,        SLE_INT32),
src/saveload/oldloader_sl.cpp
Show inline comments
 
@@ -470,49 +470,49 @@ static inline byte RemapTTOColour(byte t
 
{
 
	/** Lossy remapping of TTO colours to TTD colours. SVXConverter uses the same conversion. */
 
	static const byte tto_colour_remap[] = {
 
		COLOUR_DARK_BLUE,  COLOUR_GREY,       COLOUR_YELLOW,     COLOUR_RED,
 
		COLOUR_PURPLE,     COLOUR_DARK_GREEN, COLOUR_ORANGE,     COLOUR_PALE_GREEN,
 
		COLOUR_BLUE,       COLOUR_GREEN,      COLOUR_CREAM,      COLOUR_BROWN,
 
		COLOUR_WHITE,      COLOUR_LIGHT_BLUE, COLOUR_MAUVE,      COLOUR_PINK
 
	};
 

	
 
	if ((size_t)tto >= lengthof(tto_colour_remap)) return COLOUR_GREY; // this shouldn't happen
 

	
 
	return tto_colour_remap[tto];
 
}
 

	
 
static inline uint RemapTownIndex(uint x)
 
{
 
	return _savegame_type == SGT_TTO ? (x - 0x264) / 78 : (x - 0x264) / 94;
 
}
 

	
 
static inline uint RemapOrderIndex(uint x)
 
{
 
	return _savegame_type == SGT_TTO ? (x - 0x1AC4) / 2 : (x - 0x1C18) / 2;
 
}
 

	
 
extern SmallVector<TileIndex, 256> _animated_tiles;
 
extern std::vector<TileIndex> _animated_tiles;
 
extern char *_old_name_array;
 

	
 
static uint32 _old_town_index;
 
static uint16 _old_string_id;
 
static uint16 _old_string_id_2;
 

	
 
static void ReadTTDPatchFlags()
 
{
 
	if (_read_ttdpatch_flags) return;
 

	
 
	_read_ttdpatch_flags = true;
 

	
 
	/* Set default values */
 
	_old_vehicle_multiplier = 1;
 
	_ttdp_version = 0;
 
	_old_extra_chunk_nums = 0;
 
	_bump_assert_value = 0;
 

	
 
	if (_savegame_type == SGT_TTO) return;
 

	
 
	/* TTDPatch misuses _old_map3 for flags.. read them! */
 
	_old_vehicle_multiplier = _old_map3[0];
 
	/* Somehow.... there was an error in some savegames, so 0 becomes 1
 
	 * and 1 becomes 2. The rest of the values are okay */
src/saveload/waypoint_sl.cpp
Show inline comments
 
@@ -21,49 +21,49 @@
 
#include "saveload_internal.h"
 

	
 
#include "../safeguards.h"
 

	
 
/** Helper structure to convert from the old waypoint system. */
 
struct OldWaypoint {
 
	size_t index;
 
	TileIndex xy;
 
	TownID town_index;
 
	Town *town;
 
	uint16 town_cn;
 
	StringID string_id;
 
	char *name;
 
	uint8 delete_ctr;
 
	Date build_date;
 
	uint8 localidx;
 
	uint32 grfid;
 
	const StationSpec *spec;
 
	OwnerByte owner;
 

	
 
	size_t new_index;
 
};
 

	
 
/** Temporary array with old waypoints. */
 
static SmallVector<OldWaypoint, 16> _old_waypoints;
 
static std::vector<OldWaypoint> _old_waypoints;
 

	
 
/**
 
 * Update the waypoint orders to get the new waypoint ID.
 
 * @param o the order 'list' to check.
 
 */
 
static void UpdateWaypointOrder(Order *o)
 
{
 
	if (!o->IsType(OT_GOTO_WAYPOINT)) return;
 

	
 
	for (OldWaypoint &wp : _old_waypoints) {
 
		if (wp.index != o->GetDestination()) continue;
 

	
 
		o->SetDestination((DestinationID)wp.new_index);
 
		return;
 
	}
 
}
 

	
 
/**
 
 * Perform all steps to upgrade from the old waypoints to the new version
 
 * that uses station. This includes some old saveload mechanics.
 
 */
 
void MoveWaypointsToBaseStations()
 
{
 
	/* In version 17, ground type is moved from m2 to m4 for depots and
src/script/squirrel_helper.hpp
Show inline comments
 
@@ -8,49 +8,49 @@
 
 */
 

	
 
/** @file squirrel_helper.hpp declarations and parts of the implementation of the class for convert code */
 

	
 
#ifndef SQUIRREL_HELPER_HPP
 
#define SQUIRREL_HELPER_HPP
 

	
 
#include "squirrel.hpp"
 
#include "../core/smallvec_type.hpp"
 
#include "../economy_type.h"
 
#include "../string_func.h"
 
#include "squirrel_helper_type.hpp"
 

	
 
template <class CL, ScriptType ST> const char *GetClassName();
 

	
 
/**
 
 * The Squirrel convert routines
 
 */
 
namespace SQConvert {
 
	/**
 
	 * Pointers assigned to this class will be free'd when this instance
 
	 *  comes out of scope. Useful to make sure you can use stredup(),
 
	 *  without leaking memory.
 
	 */
 
	struct SQAutoFreePointers : SmallVector<void *, 1> {
 
	struct SQAutoFreePointers : std::vector<void *> {
 
		~SQAutoFreePointers()
 
		{
 
			for (uint i = 0; i < std::vector<void *>::size(); i++) free(std::vector<void *>::operator[](i));
 
		}
 
	};
 

	
 
	template <bool Y> struct YesT {
 
		static const bool Yes = Y;
 
		static const bool No = !Y;
 
	};
 

	
 
	/**
 
	 * Helper class to recognize if the given type is void. Usage: 'IsVoidT<T>::Yes'
 
	 */
 
	template <typename T> struct IsVoidT : YesT<false> {};
 
	template <> struct IsVoidT<void> : YesT<true> {};
 

	
 
	/**
 
	 * Helper class to recognize if the function/method return type is void.
 
	 */
 
	template <typename Tfunc> struct HasVoidReturnT;
 
	/* functions */
 
	template <typename Tretval> struct HasVoidReturnT<Tretval (*)()> : IsVoidT<Tretval> {};
 
	template <typename Tretval, typename Targ1> struct HasVoidReturnT<Tretval (*)(Targ1)> : IsVoidT<Tretval> {};
 
@@ -111,49 +111,49 @@ namespace SQConvert {
 
	template <> inline const char *GetParam(ForceType<const char *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr)
 
	{
 
		/* Convert what-ever there is as parameter to a string */
 
		sq_tostring(vm, index);
 

	
 
		const SQChar *tmp;
 
		sq_getstring(vm, -1, &tmp);
 
		char *tmp_str = stredup(tmp);
 
		sq_poptop(vm);
 
		ptr->push_back((void *)tmp_str);
 
		str_validate(tmp_str, tmp_str + strlen(tmp_str));
 
		return tmp_str;
 
	}
 

	
 
	template <> inline Array      *GetParam(ForceType<Array *>,      HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr)
 
	{
 
		/* Sanity check of the size. */
 
		if (sq_getsize(vm, index) > UINT16_MAX) throw sq_throwerror(vm, "an array used as parameter to a function is too large");
 

	
 
		SQObject obj;
 
		sq_getstackobj(vm, index, &obj);
 
		sq_pushobject(vm, obj);
 
		sq_pushnull(vm);
 

	
 
		SmallVector<int32, 2> data;
 
		std::vector<int32> data;
 

	
 
		while (SQ_SUCCEEDED(sq_next(vm, -2))) {
 
			SQInteger tmp;
 
			if (SQ_SUCCEEDED(sq_getinteger(vm, -1, &tmp))) {
 
				data.push_back((int32)tmp);
 
			} else {
 
				sq_pop(vm, 4);
 
				throw sq_throwerror(vm, "a member of an array used as parameter to a function is not numeric");
 
			}
 

	
 
			sq_pop(vm, 2);
 
		}
 
		sq_pop(vm, 2);
 

	
 
		Array *arr = (Array*)MallocT<byte>(sizeof(Array) + sizeof(int32) * data.size());
 
		arr->size = data.size();
 
		memcpy(arr->array, data.data(), sizeof(int32) * data.size());
 

	
 
		ptr->push_back(arr);
 
		return arr;
 
	}
 

	
 
	/**
 
	 * Helper class to recognize the function type (retval type, args) and use the proper specialization
src/settingsgen/settingsgen.cpp
Show inline comments
 
@@ -131,49 +131,49 @@ public:
 
	}
 

	
 
	/**
 
	 * Write all stored output to the output stream.
 
	 * @param out_fp Stream to write the \a data to.
 
	 */
 
	void Write(FILE *out_fp) const
 
	{
 
		for (const OutputBuffer &out_data : output_buffer) {
 
			out_data.Write(out_fp);
 
		}
 
	}
 

	
 
private:
 
	/**
 
	 * Does the buffer have room without adding a new #OutputBuffer block?
 
	 * @return \c true if room is available, else \c false.
 
	 */
 
	bool BufferHasRoom() const
 
	{
 
		uint num_blocks = this->output_buffer.size();
 
		return num_blocks > 0 && this->output_buffer[num_blocks - 1].HasRoom();
 
	}
 

	
 
	typedef SmallVector<OutputBuffer, 2> OutputBufferVector; ///< Vector type for output buffers.
 
	typedef std::vector<OutputBuffer> OutputBufferVector; ///< Vector type for output buffers.
 
	OutputBufferVector output_buffer; ///< Vector of blocks containing the stored output.
 
};
 

	
 

	
 
/** Derived class for loading INI files without going through Fio stuff. */
 
struct SettingsIniFile : IniLoadFile {
 
	/**
 
	 * Construct a new ini loader.
 
	 * @param list_group_names A \c NULL terminated list with group names that should be loaded as lists instead of variables. @see IGT_LIST
 
	 * @param seq_group_names  A \c NULL terminated list with group names that should be loaded as lists of names. @see IGT_SEQUENCE
 
	 */
 
	SettingsIniFile(const char * const *list_group_names = NULL, const char * const *seq_group_names = NULL) :
 
			IniLoadFile(list_group_names, seq_group_names)
 
	{
 
	}
 

	
 
	virtual FILE *OpenFile(const char *filename, Subdirectory subdir, size_t *size)
 
	{
 
		/* Open the text file in binary mode to prevent end-of-line translations
 
		 * done by ftell() and friends, as defined by K&R. */
 
		FILE *in = fopen(filename, "rb");
 
		if (in == NULL) return NULL;
 

	
 
		fseek(in, 0L, SEEK_END);
src/sortlist_type.h
Show inline comments
 
@@ -26,49 +26,49 @@ enum SortListFlags {
 
	VL_REBUILD    = 1 << 2, ///< rebuild the sort list
 
	VL_FIRST_SORT = 1 << 3, ///< sort with quick sort first
 
	VL_FILTER     = 1 << 4, ///< filter disabled/enabled
 
	VL_END        = 1 << 5,
 
};
 
DECLARE_ENUM_AS_BIT_SET(SortListFlags)
 

	
 
/** Data structure describing how to show the list (what sort direction and criteria). */
 
struct Listing {
 
	bool order;    ///< Ascending/descending
 
	byte criteria; ///< Sorting criteria
 
};
 
/** Data structure describing what to show in the list (filter criteria). */
 
struct Filtering {
 
	bool state;    ///< Filter on/off
 
	byte criteria; ///< Filtering criteria
 
};
 

	
 
/**
 
 * List template of 'things' \p T to sort in a GUI.
 
 * @tparam T Type of data stored in the list to represent each item.
 
 * @tparam F Type of data fed as additional value to the filter function. @see FilterFunction
 
 */
 
template <typename T, typename F = const char*>
 
class GUIList : public SmallVector<T, 32> {
 
class GUIList : public std::vector<T> {
 
public:
 
	typedef int CDECL SortFunction(const T*, const T*); ///< Signature of sort function.
 
	typedef bool CDECL FilterFunction(const T*, F);     ///< Signature of filter function.
 

	
 
protected:
 
	SortFunction * const *sort_func_list;     ///< the sort criteria functions
 
	FilterFunction * const *filter_func_list; ///< the filter criteria functions
 
	SortListFlags flags;                      ///< used to control sorting/resorting/etc.
 
	uint8 sort_type;                          ///< what criteria to sort on
 
	uint8 filter_type;                        ///< what criteria to filter on
 
	uint16 resort_timer;                      ///< resort list after a given amount of ticks if set
 

	
 
	/**
 
	 * Check if the list is sortable
 
	 *
 
	 * @return true if we can sort the list
 
	 */
 
	bool IsSortable() const
 
	{
 
		return std::vector<T>::size() >= 2;
 
	}
 

	
 
	/**
 
	 * Reset the resort timer
src/station_cmd.cpp
Show inline comments
 
@@ -866,49 +866,49 @@ static CommandCost CheckFlatLandAirport(
 
		cost.AddCost(ret);
 

	
 
		ret = DoCommand(tile_iter, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
		if (ret.Failed()) return ret;
 
		cost.AddCost(ret);
 
	}
 

	
 
	return cost;
 
}
 

	
 
/**
 
 * Checks if a rail station can be built at the given area.
 
 * @param tile_area Area to check.
 
 * @param flags Operation to perform.
 
 * @param axis Rail station axis.
 
 * @param station StationID to be queried and returned if available.
 
 * @param rt The rail type to check for (overbuilding rail stations over rail).
 
 * @param affected_vehicles List of trains with PBS reservations on the tiles
 
 * @param spec_class Station class.
 
 * @param spec_index Index into the station class.
 
 * @param plat_len Platform length.
 
 * @param numtracks Number of platforms.
 
 * @return The cost in case of success, or an error code if it failed.
 
 */
 
static CommandCost CheckFlatLandRailStation(TileArea tile_area, DoCommandFlag flags, Axis axis, StationID *station, RailType rt, SmallVector<Train *, 4> &affected_vehicles, StationClassID spec_class, byte spec_index, byte plat_len, byte numtracks)
 
static CommandCost CheckFlatLandRailStation(TileArea tile_area, DoCommandFlag flags, Axis axis, StationID *station, RailType rt, std::vector<Train *> &affected_vehicles, StationClassID spec_class, byte spec_index, byte plat_len, byte numtracks)
 
{
 
	CommandCost cost(EXPENSES_CONSTRUCTION);
 
	int allowed_z = -1;
 
	uint invalid_dirs = 5 << axis;
 

	
 
	const StationSpec *statspec = StationClass::Get(spec_class)->GetSpec(spec_index);
 
	bool slope_cb = statspec != NULL && HasBit(statspec->callback_mask, CBM_STATION_SLOPE_CHECK);
 

	
 
	TILE_AREA_LOOP(tile_cur, tile_area) {
 
		CommandCost ret = CheckBuildableTile(tile_cur, invalid_dirs, allowed_z, false);
 
		if (ret.Failed()) return ret;
 
		cost.AddCost(ret);
 

	
 
		if (slope_cb) {
 
			/* Do slope check if requested. */
 
			ret = PerformStationTileSlopeCheck(tile_area.tile, tile_cur, statspec, axis, plat_len, numtracks);
 
			if (ret.Failed()) return ret;
 
		}
 

	
 
		/* if station is set, then we have special handling to allow building on top of already existing stations.
 
		 * so station points to INVALID_STATION if we can build on any station.
 
		 * Or it points to a station if we're only allowed to build on exactly that station. */
 
		if (station != NULL && IsTileType(tile_cur, MP_STATION)) {
 
			if (!IsRailStation(tile_cur)) {
 
@@ -1289,49 +1289,49 @@ CommandCost CmdBuildRailStation(TileInde
 
	if (plat_len == 0 || numtracks == 0) return CMD_ERROR;
 

	
 
	int w_org, h_org;
 
	if (axis == AXIS_X) {
 
		w_org = plat_len;
 
		h_org = numtracks;
 
	} else {
 
		h_org = plat_len;
 
		w_org = numtracks;
 
	}
 

	
 
	bool reuse = (station_to_join != NEW_STATION);
 
	if (!reuse) station_to_join = INVALID_STATION;
 
	bool distant_join = (station_to_join != INVALID_STATION);
 

	
 
	if (distant_join && (!_settings_game.station.distant_join_stations || !Station::IsValidID(station_to_join))) return CMD_ERROR;
 

	
 
	if (h_org > _settings_game.station.station_spread || w_org > _settings_game.station.station_spread) return CMD_ERROR;
 

	
 
	/* these values are those that will be stored in train_tile and station_platforms */
 
	TileArea new_location(tile_org, w_org, h_org);
 

	
 
	/* Make sure the area below consists of clear tiles. (OR tiles belonging to a certain rail station) */
 
	StationID est = INVALID_STATION;
 
	SmallVector<Train *, 4> affected_vehicles;
 
	std::vector<Train *> affected_vehicles;
 
	/* Clear the land below the station. */
 
	CommandCost cost = CheckFlatLandRailStation(new_location, flags, axis, &est, rt, affected_vehicles, spec_class, spec_index, plat_len, numtracks);
 
	if (cost.Failed()) return cost;
 
	/* Add construction expenses. */
 
	cost.AddCost((numtracks * _price[PR_BUILD_STATION_RAIL] + _price[PR_BUILD_STATION_RAIL_LENGTH]) * plat_len);
 
	cost.AddCost(numtracks * plat_len * RailBuildCost(rt));
 

	
 
	Station *st = NULL;
 
	ret = FindJoiningStation(est, station_to_join, adjacent, new_location, &st);
 
	if (ret.Failed()) return ret;
 

	
 
	ret = BuildStationPart(&st, flags, reuse, new_location, STATIONNAMING_RAIL);
 
	if (ret.Failed()) return ret;
 

	
 
	if (st != NULL && st->train_station.tile != INVALID_TILE) {
 
		CommandCost ret = CanExpandRailStation(st, new_location, axis);
 
		if (ret.Failed()) return ret;
 
	}
 

	
 
	/* Check if we can allocate a custom stationspec to this station */
 
	const StationSpec *statspec = StationClass::Get(spec_class)->GetSpec(spec_index);
 
	int specindex = AllocateSpecToStation(statspec, st, (flags & DC_EXEC) != 0);
 
	if (specindex == -1) return_cmd_error(STR_ERROR_TOO_MANY_STATION_SPECS);
 

	
 
@@ -1526,49 +1526,49 @@ restart:
 
			/* the left side is unused? */
 
			if (++i == ta.w) {
 
				ta.h--;
 
				goto restart;
 
			}
 
		}
 
	} else {
 
		ta.Clear();
 
	}
 

	
 
	st->train_station = ta;
 
}
 

	
 
/**
 
 * Remove a number of tiles from any rail station within the area.
 
 * @param ta the area to clear station tile from.
 
 * @param affected_stations the stations affected.
 
 * @param flags the command flags.
 
 * @param removal_cost the cost for removing the tile, including the rail.
 
 * @param keep_rail whether to keep the rail of the station.
 
 * @tparam T the type of station to remove.
 
 * @return the number of cleared tiles or an error.
 
 */
 
template <class T>
 
CommandCost RemoveFromRailBaseStation(TileArea ta, SmallVector<T *, 4> &affected_stations, DoCommandFlag flags, Money removal_cost, bool keep_rail)
 
CommandCost RemoveFromRailBaseStation(TileArea ta, std::vector<T *> &affected_stations, DoCommandFlag flags, Money removal_cost, bool keep_rail)
 
{
 
	/* Count of the number of tiles removed */
 
	int quantity = 0;
 
	CommandCost total_cost(EXPENSES_CONSTRUCTION);
 
	/* Accumulator for the errors seen during clearing. If no errors happen,
 
	 * and the quantity is 0 there is no station. Otherwise it will be one
 
	 * of the other error that got accumulated. */
 
	CommandCost error;
 

	
 
	/* Do the action for every tile into the area */
 
	TILE_AREA_LOOP(tile, ta) {
 
		/* Make sure the specified tile is a rail station */
 
		if (!HasStationTileRail(tile)) continue;
 

	
 
		/* If there is a vehicle on ground, do not allow to remove (flood) the tile */
 
		CommandCost ret = EnsureNoVehicleOnGround(tile);
 
		error.AddCost(ret);
 
		if (ret.Failed()) continue;
 

	
 
		/* Check ownership of station */
 
		T *st = T::GetByTile(tile);
 
		if (st == NULL) continue;
 

	
 
		if (_current_company != OWNER_WATER) {
 
@@ -1639,116 +1639,116 @@ CommandCost RemoveFromRailBaseStation(Ti
 
		}
 
	}
 

	
 
	total_cost.AddCost(quantity * removal_cost);
 
	return total_cost;
 
}
 

	
 
/**
 
 * Remove a single tile from a rail station.
 
 * This allows for custom-built station with holes and weird layouts
 
 * @param start tile of station piece to remove
 
 * @param flags operation to perform
 
 * @param p1 start_tile
 
 * @param p2 various bitstuffed elements
 
 * - p2 = bit 0 - if set keep the rail
 
 * @param text unused
 
 * @return the cost of this operation or an error
 
 */
 
CommandCost CmdRemoveFromRailStation(TileIndex start, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
 
{
 
	TileIndex end = p1 == 0 ? start : p1;
 
	if (start >= MapSize() || end >= MapSize()) return CMD_ERROR;
 

	
 
	TileArea ta(start, end);
 
	SmallVector<Station *, 4> affected_stations;
 
	std::vector<Station *> affected_stations;
 

	
 
	CommandCost ret = RemoveFromRailBaseStation(ta, affected_stations, flags, _price[PR_CLEAR_STATION_RAIL], HasBit(p2, 0));
 
	if (ret.Failed()) return ret;
 

	
 
	/* Do all station specific functions here. */
 
	for (Station *st : affected_stations) {
 

	
 
		if (st->train_station.tile == INVALID_TILE) SetWindowWidgetDirty(WC_STATION_VIEW, st->index, WID_SV_TRAINS);
 
		st->MarkTilesDirty(false);
 
		st->RecomputeCatchment();
 
	}
 

	
 
	/* Now apply the rail cost to the number that we deleted */
 
	return ret;
 
}
 

	
 
/**
 
 * Remove a single tile from a waypoint.
 
 * This allows for custom-built waypoint with holes and weird layouts
 
 * @param start tile of waypoint piece to remove
 
 * @param flags operation to perform
 
 * @param p1 start_tile
 
 * @param p2 various bitstuffed elements
 
 * - p2 = bit 0 - if set keep the rail
 
 * @param text unused
 
 * @return the cost of this operation or an error
 
 */
 
CommandCost CmdRemoveFromRailWaypoint(TileIndex start, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
 
{
 
	TileIndex end = p1 == 0 ? start : p1;
 
	if (start >= MapSize() || end >= MapSize()) return CMD_ERROR;
 

	
 
	TileArea ta(start, end);
 
	SmallVector<Waypoint *, 4> affected_stations;
 
	std::vector<Waypoint *> affected_stations;
 

	
 
	return RemoveFromRailBaseStation(ta, affected_stations, flags, _price[PR_CLEAR_WAYPOINT_RAIL], HasBit(p2, 0));
 
}
 

	
 

	
 
/**
 
 * Remove a rail station/waypoint
 
 * @param st The station/waypoint to remove the rail part from
 
 * @param flags operation to perform
 
 * @param removal_cost the cost for removing a tile
 
 * @tparam T the type of station to remove
 
 * @return cost or failure of operation
 
 */
 
template <class T>
 
CommandCost RemoveRailStation(T *st, DoCommandFlag flags, Money removal_cost)
 
{
 
	/* Current company owns the station? */
 
	if (_current_company != OWNER_WATER) {
 
		CommandCost ret = CheckOwnership(st->owner);
 
		if (ret.Failed()) return ret;
 
	}
 

	
 
	/* determine width and height of platforms */
 
	TileArea ta = st->train_station;
 

	
 
	assert(ta.w != 0 && ta.h != 0);
 

	
 
	CommandCost cost(EXPENSES_CONSTRUCTION);
 
	/* clear all areas of the station */
 
	TILE_AREA_LOOP(tile, ta) {
 
		/* only remove tiles that are actually train station tiles */
 
		if (st->TileBelongsToRailStation(tile)) {
 
			SmallVector<T*, 4> affected_stations; // dummy
 
			std::vector<T*> affected_stations; // dummy
 
			CommandCost ret = RemoveFromRailBaseStation(TileArea(tile, 1, 1), affected_stations, flags, removal_cost, false);
 
			if (ret.Failed()) return ret;
 
			cost.AddCost(ret);
 
		}
 
	}
 

	
 
	return cost;
 
}
 

	
 
/**
 
 * Remove a rail station
 
 * @param tile Tile of the station.
 
 * @param flags operation to perform
 
 * @return cost or failure of operation
 
 */
 
static CommandCost RemoveRailStation(TileIndex tile, DoCommandFlag flags)
 
{
 
	/* if there is flooding, remove platforms tile by tile */
 
	if (_current_company == OWNER_WATER) {
 
		return DoCommand(tile, 0, 0, DC_EXEC, CMD_REMOVE_FROM_RAIL_STATION);
 
	}
 

	
 
	Station *st = Station::GetByTile(tile);
 
	CommandCost cost = RemoveRailStation(st, flags, _price[PR_CLEAR_STATION_RAIL]);
 
@@ -3500,49 +3500,49 @@ void RerouteCargo(Station *st, CargoID c
 
 * @param from Station to check.
 
 */
 
void DeleteStaleLinks(Station *from)
 
{
 
	for (CargoID c = 0; c < NUM_CARGO; ++c) {
 
		const bool auto_distributed = (_settings_game.linkgraph.GetDistributionType(c) != DT_MANUAL);
 
		GoodsEntry &ge = from->goods[c];
 
		LinkGraph *lg = LinkGraph::GetIfValid(ge.link_graph);
 
		if (lg == NULL) continue;
 
		Node node = (*lg)[ge.node];
 
		for (EdgeIterator it(node.Begin()); it != node.End();) {
 
			Edge edge = it->second;
 
			Station *to = Station::Get((*lg)[it->first].Station());
 
			assert(to->goods[c].node == it->first);
 
			++it; // Do that before removing the edge. Anything else may crash.
 
			assert(_date >= edge.LastUpdate());
 
			uint timeout = LinkGraph::MIN_TIMEOUT_DISTANCE + (DistanceManhattan(from->xy, to->xy) >> 3);
 
			if ((uint)(_date - edge.LastUpdate()) > timeout) {
 
				bool updated = false;
 

	
 
				if (auto_distributed) {
 
					/* Have all vehicles refresh their next hops before deciding to
 
					 * remove the node. */
 
					OrderList *l;
 
					SmallVector<Vehicle *, 32> vehicles;
 
					std::vector<Vehicle *> vehicles;
 
					FOR_ALL_ORDER_LISTS(l) {
 
						bool found_from = false;
 
						bool found_to = false;
 
						for (Order *order = l->GetFirstOrder(); order != NULL; order = order->next) {
 
							if (!order->IsType(OT_GOTO_STATION) && !order->IsType(OT_IMPLICIT)) continue;
 
							if (order->GetDestination() == from->index) {
 
								found_from = true;
 
								if (found_to) break;
 
							} else if (order->GetDestination() == to->index) {
 
								found_to = true;
 
								if (found_from) break;
 
							}
 
						}
 
						if (!found_to || !found_from) continue;
 
						vehicles.push_back(l->GetFirstSharedVehicle());
 
					}
 

	
 
					auto iter = vehicles.begin();
 
					while (iter != vehicles.end()) {
 
						Vehicle *v = *iter;
 

	
 
						LinkRefresher::Run(v, false); // Don't allow merging. Otherwise lg might get deleted.
 
						if (edge.LastUpdate() == _date) {
 
							updated = true;
src/station_gui.cpp
Show inline comments
 
@@ -2095,50 +2095,50 @@ const StringID StationViewWindow::_group
 

	
 
static WindowDesc _station_view_desc(
 
	WDP_AUTO, "view_station", 249, 117,
 
	WC_STATION_VIEW, WC_NONE,
 
	0,
 
	_nested_station_view_widgets, lengthof(_nested_station_view_widgets)
 
);
 

	
 
/**
 
 * Opens StationViewWindow for given station
 
 *
 
 * @param station station which window should be opened
 
 */
 
void ShowStationViewWindow(StationID station)
 
{
 
	AllocateWindowDescFront<StationViewWindow>(&_station_view_desc, station);
 
}
 

	
 
/** Struct containing TileIndex and StationID */
 
struct TileAndStation {
 
	TileIndex tile;    ///< TileIndex
 
	StationID station; ///< StationID
 
};
 

	
 
static SmallVector<TileAndStation, 8> _deleted_stations_nearby;
 
static SmallVector<StationID, 8> _stations_nearby_list;
 
static std::vector<TileAndStation> _deleted_stations_nearby;
 
static std::vector<StationID> _stations_nearby_list;
 

	
 
/**
 
 * Add station on this tile to _stations_nearby_list if it's fully within the
 
 * station spread.
 
 * @param tile Tile just being checked
 
 * @param user_data Pointer to TileArea context
 
 * @tparam T the type of station to look for
 
 */
 
template <class T>
 
static bool AddNearbyStation(TileIndex tile, void *user_data)
 
{
 
	TileArea *ctx = (TileArea *)user_data;
 

	
 
	/* First check if there were deleted stations here */
 
	for (uint i = 0; i < _deleted_stations_nearby.size(); i++) {
 
		auto ts = _deleted_stations_nearby.begin() + i;
 
		if (ts->tile == tile) {
 
			_stations_nearby_list.push_back(_deleted_stations_nearby[i].station);
 
			_deleted_stations_nearby.erase(ts);
 
			i--;
 
		}
 
	}
 

	
 
	/* Check if own station and if we stay within station spread */
src/strgen/strgen_base.cpp
Show inline comments
 
@@ -214,49 +214,49 @@ uint StringData::CountInUse(uint tab) co
 
{
 
	int i;
 
	for (i = TAB_SIZE; --i >= 0;) if (this->strings[(tab * TAB_SIZE) + i] != NULL) break;
 
	return i + 1;
 
}
 

	
 
static const char *_cur_ident;
 

	
 
struct CmdPair {
 
	const CmdStruct *a;
 
	const char *v;
 
};
 

	
 
struct ParsedCommandStruct {
 
	uint np;
 
	CmdPair pairs[32];
 
	const CmdStruct *cmd[32]; // ordered by param #
 
};
 

	
 
/* Used when generating some advanced commands. */
 
static ParsedCommandStruct _cur_pcs;
 
static int _cur_argidx;
 

	
 
/** The buffer for writing a single string. */
 
struct Buffer : SmallVector<byte, 256> {
 
struct Buffer : std::vector<byte> {
 
	/**
 
	 * Convenience method for adding a byte.
 
	 * @param value The value to add.
 
	 */
 
	void AppendByte(byte value)
 
	{
 
		this->push_back(value);
 
	}
 

	
 
	/**
 
	 * Add an Unicode character encoded in UTF-8 to the buffer.
 
	 * @param value The character to add.
 
	 */
 
	void AppendUtf8(uint32 value)
 
	{
 
		if (value < 0x80) {
 
			this->push_back(value);
 
		} else if (value < 0x800) {
 
			this->push_back(0xC0 + GB(value,  6, 5));
 
			this->push_back(0x80 + GB(value,  0, 6));
 
		} else if (value < 0x10000) {
 
			this->push_back(0xE0 + GB(value, 12, 4));
 
			this->push_back(0x80 + GB(value,  6, 6));
 
			this->push_back(0x80 + GB(value,  0, 6));
src/string.cpp
Show inline comments
 
@@ -603,50 +603,50 @@ int strnatcmp(const char *s1, const char
 
#endif
 

	
 
	/* Do a normal comparison if ICU is missing or if we cannot create a collator. */
 
	return strcasecmp(s1, s2);
 
}
 

	
 
#ifdef WITH_UNISCRIBE
 

	
 
/* static */ StringIterator *StringIterator::Create()
 
{
 
	return new UniscribeStringIterator();
 
}
 

	
 
#elif defined(WITH_ICU_I18N)
 

	
 
#include <unicode/utext.h>
 
#include <unicode/brkiter.h>
 

	
 
/** String iterator using ICU as a backend. */
 
class IcuStringIterator : public StringIterator
 
{
 
	icu::BreakIterator *char_itr; ///< ICU iterator for characters.
 
	icu::BreakIterator *word_itr; ///< ICU iterator for words.
 

	
 
	SmallVector<UChar, 32> utf16_str;      ///< UTF-16 copy of the string.
 
	SmallVector<size_t, 32> utf16_to_utf8; ///< Mapping from UTF-16 code point position to index in the UTF-8 source string.
 
	std::vector<UChar> utf16_str;      ///< UTF-16 copy of the string.
 
	std::vector<size_t> utf16_to_utf8; ///< Mapping from UTF-16 code point position to index in the UTF-8 source string.
 

	
 
public:
 
	IcuStringIterator() : char_itr(NULL), word_itr(NULL)
 
	{
 
		UErrorCode status = U_ZERO_ERROR;
 
		this->char_itr = icu::BreakIterator::createCharacterInstance(icu::Locale(_current_language != NULL ? _current_language->isocode : "en"), status);
 
		this->word_itr = icu::BreakIterator::createWordInstance(icu::Locale(_current_language != NULL ? _current_language->isocode : "en"), status);
 

	
 
		this->utf16_str.push_back('\0');
 
		this->utf16_to_utf8.push_back(0);
 
	}
 

	
 
	virtual ~IcuStringIterator()
 
	{
 
		delete this->char_itr;
 
		delete this->word_itr;
 
	}
 

	
 
	virtual void SetString(const char *s)
 
	{
 
		const char *string_base = s;
 

	
 
		/* Unfortunately current ICU versions only provide rudimentary support
 
		 * for word break iterators (especially for CJK languages) in combination
src/stringfilter_type.h
Show inline comments
 
@@ -18,49 +18,49 @@
 
/**
 
 * String filter and state.
 
 *
 
 * The filter takes a stringterm and parses it into words separated by whitespace.
 
 * The whitespace-separation can be avoided by quoting words in the searchterm using " or '.
 
 * The quotation characters can be nested or concatenated in a unix-shell style.
 
 *
 
 * When filtering an item, all words are checked for matches, and the filter matches if every word
 
 * matched. So, effectively this is a AND search for all entered words.
 
 *
 
 * Once the filter is set up using SetFilterTerm, multiple items can be filtered consecutively.
 
 *  1. For every item first call ResetState() which resets the matching-state.
 
 *  2. Pass all lines of the item via AddLine() to the filter.
 
 *  3. Check the matching-result for the item via GetState().
 
 */
 
struct StringFilter {
 
private:
 
	/** State of a single filter word */
 
	struct WordState {
 
		const char *start;                         ///< Word to filter for.
 
		bool match;                                ///< Already matched?
 
	};
 

	
 
	const char *filter_buffer;                     ///< Parsed filter string. Words separated by 0.
 
	SmallVector<WordState, 4> word_index;          ///< Word index and filter state.
 
	std::vector<WordState> word_index;          ///< Word index and filter state.
 
	uint word_matches;                             ///< Summary of filter state: Number of words matched.
 

	
 
	const bool *case_sensitive;                    ///< Match case-sensitively (usually a static variable).
 

	
 
public:
 
	/**
 
	 * Constructor for filter.
 
	 * @param case_sensitive Pointer to a (usually static) variable controlling the case-sensitivity. NULL means always case-insensitive.
 
	 */
 
	StringFilter(const bool *case_sensitive = NULL) : filter_buffer(NULL), word_matches(0), case_sensitive(case_sensitive) {}
 
	~StringFilter() { free(this->filter_buffer); }
 

	
 
	void SetFilterTerm(const char *str);
 

	
 
	/**
 
	 * Check whether any filter words were entered.
 
	 * @return true if no words were entered.
 
	 */
 
	bool IsEmpty() const { return this->word_index.size() == 0; }
 

	
 
	void ResetState();
 
	void AddLine(const char *str);
 
	void AddLine(StringID str);
 

	
src/subsidy.cpp
Show inline comments
 
@@ -543,49 +543,49 @@ void SubsidyMonthlyLoop()
 
 * Tests whether given delivery is subsidised and possibly awards the subsidy to delivering company
 
 * @param cargo_type type of cargo
 
 * @param company company delivering the cargo
 
 * @param src_type type of \a src
 
 * @param src index of source
 
 * @param st station where the cargo is delivered to
 
 * @return is the delivery subsidised?
 
 */
 
bool CheckSubsidised(CargoID cargo_type, CompanyID company, SourceType src_type, SourceID src, const Station *st)
 
{
 
	/* If the source isn't subsidised, don't continue */
 
	if (src == INVALID_SOURCE) return false;
 
	switch (src_type) {
 
		case ST_INDUSTRY:
 
			if (!(Industry::Get(src)->part_of_subsidy & POS_SRC)) return false;
 
			break;
 
		case ST_TOWN:
 
			if (!(Town::Get(src)->cache.part_of_subsidy & POS_SRC)) return false;
 
			break;
 
		default: return false;
 
	}
 

	
 
	/* Remember all towns near this station (at least one house in its catchment radius)
 
	 * which are destination of subsidised path. Do that only if needed */
 
	SmallVector<const Town *, 2> towns_near;
 
	std::vector<const Town *> towns_near;
 
	if (!st->rect.IsEmpty()) {
 
		Subsidy *s;
 
		FOR_ALL_SUBSIDIES(s) {
 
			/* Don't create the cache if there is no applicable subsidy with town as destination */
 
			if (s->dst_type != ST_TOWN) continue;
 
			if (s->cargo_type != cargo_type || s->src_type != src_type || s->src != src) continue;
 
			if (s->IsAwarded() && s->awarded != company) continue;
 

	
 
			BitmapTileIterator it(st->catchment_tiles);
 
			for (TileIndex tile = it; tile != INVALID_TILE; tile = ++it) {
 
				if (!IsTileType(tile, MP_HOUSE)) continue;
 
				const Town *t = Town::GetByTile(tile);
 
				if (t->cache.part_of_subsidy & POS_DST) include(towns_near, t);
 
			}
 
			break;
 
		}
 
	}
 

	
 
	bool subsidised = false;
 

	
 
	/* Check if there's a (new) subsidy that applies. There can be more subsidies triggered by this delivery!
 
	 * Think about the case that subsidies are A->B and A->C and station has both B and C in its catchment area */
 
	Subsidy *s;
 
	FOR_ALL_SUBSIDIES(s) {
src/texteff.cpp
Show inline comments
 
@@ -16,49 +16,49 @@
 
#include "core/smallvec_type.hpp"
 
#include "viewport_func.h"
 
#include "settings_type.h"
 
#include "guitimer_func.h"
 

	
 
#include "safeguards.h"
 

	
 
/** Container for all information about a text effect */
 
struct TextEffect : public ViewportSign {
 
	uint64 params_1;     ///< DParam parameter
 
	uint64 params_2;     ///< second DParam parameter
 
	StringID string_id;  ///< String to draw for the text effect, if INVALID_STRING_ID then it's not valid
 
	uint8 duration;      ///< How long the text effect should stay, in ticks (applies only when mode == TE_RISING)
 
	TextEffectMode mode; ///< Type of text effect
 

	
 
	/** Reset the text effect */
 
	void Reset()
 
	{
 
		this->MarkDirty();
 
		this->width_normal = 0;
 
		this->string_id = INVALID_STRING_ID;
 
	}
 
};
 

	
 
static SmallVector<struct TextEffect, 32> _text_effects; ///< Text effects are stored there
 
static std::vector<struct TextEffect> _text_effects; ///< Text effects are stored there
 

	
 
/* Text Effects */
 
TextEffectID AddTextEffect(StringID msg, int center, int y, uint8 duration, TextEffectMode mode)
 
{
 
	if (_game_mode == GM_MENU) return INVALID_TE_ID;
 

	
 
	TextEffectID i;
 
	for (i = 0; i < _text_effects.size(); i++) {
 
		if (_text_effects[i].string_id == INVALID_STRING_ID) break;
 
	}
 
	if (i == _text_effects.size()) _text_effects.emplace_back();
 

	
 
	TextEffect &te = _text_effects[i];
 

	
 
	/* Start defining this object */
 
	te.string_id = msg;
 
	te.duration = duration;
 
	te.params_1 = GetDParam(0);
 
	te.params_2 = GetDParam(1);
 
	te.mode = mode;
 

	
 
	/* Make sure we only dirty the new area */
 
	te.width_normal = 0;
 
	te.UpdatePosition(center, y, msg);
src/textfile_gui.h
Show inline comments
 
/* $Id$ */
 

	
 
/*
 
 * This file is part of OpenTTD.
 
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/** @file textfile_gui.h GUI functions related to textfiles. */
 

	
 
#ifndef TEXTFILE_GUI_H
 
#define TEXTFILE_GUI_H
 

	
 
#include "fileio_type.h"
 
#include "strings_func.h"
 
#include "textfile_type.h"
 
#include "window_gui.h"
 

	
 
const char *GetTextfile(TextfileType type, Subdirectory dir, const char *filename);
 

	
 
/** Window for displaying a textfile */
 
struct TextfileWindow : public Window, MissingGlyphSearcher {
 
	TextfileType file_type;              ///< Type of textfile to view.
 
	Scrollbar *vscroll;                  ///< Vertical scrollbar.
 
	Scrollbar *hscroll;                  ///< Horizontal scrollbar.
 
	char *text;                          ///< Lines of text from the NewGRF's textfile.
 
	SmallVector<const char *, 64> lines; ///< #text, split into lines in a table with lines.
 
	uint search_iterator;                ///< Iterator for the font check search.
 
	TextfileType file_type;          ///< Type of textfile to view.
 
	Scrollbar *vscroll;              ///< Vertical scrollbar.
 
	Scrollbar *hscroll;              ///< Horizontal scrollbar.
 
	char *text;                      ///< Lines of text from the NewGRF's textfile.
 
	std::vector<const char *> lines; ///< #text, split into lines in a table with lines.
 
	uint search_iterator;            ///< Iterator for the font check search.
 

	
 
	static const int TOP_SPACING    = WD_FRAMETEXT_TOP;    ///< Additional spacing at the top of the #WID_TF_BACKGROUND widget.
 
	static const int BOTTOM_SPACING = WD_FRAMETEXT_BOTTOM; ///< Additional spacing at the bottom of the #WID_TF_BACKGROUND widget.
 

	
 
	TextfileWindow(TextfileType file_type);
 
	~TextfileWindow();
 

	
 
	void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override;
 
	void OnClick(Point pt, int widget, int click_count) override;
 
	void DrawWidget(const Rect &r, int widget) const override;
 
	void OnResize() override;
 

	
 
	void Reset() override;
 
	FontSize DefaultSize() override;
 
	const char *NextString() override;
 
	bool Monospace() override;
 
	void SetFontNames(FreeTypeSettings *settings, const char *font_name) override;
 

	
 
	virtual void LoadTextfile(const char *textfile, Subdirectory dir);
 

	
 
private:
 
	uint GetContentHeight();
 
	void SetupScrollbars();
 
};
src/timetable_cmd.cpp
Show inline comments
 
@@ -260,49 +260,49 @@ static int CDECL VehicleTimetableSorter(
 
 * @param p2 Various bitstuffed elements
 
 * - p2 = (bit 0-19) - Vehicle ID.
 
 * - p2 = (bit 20)   - Set to 1 to set timetable start for all vehicles sharing this order
 
 * @param p2 The timetable start date.
 
 * @param text Not used.
 
 * @return The error or cost of the operation.
 
 */
 
CommandCost CmdSetTimetableStart(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
 
{
 
	bool timetable_all = HasBit(p1, 20);
 
	Vehicle *v = Vehicle::GetIfValid(GB(p1, 0, 20));
 
	if (v == NULL || !v->IsPrimaryVehicle() || v->orders.list == NULL) return CMD_ERROR;
 

	
 
	CommandCost ret = CheckOwnership(v->owner);
 
	if (ret.Failed()) return ret;
 

	
 
	/* Don't let a timetable start more than 15 years into the future or 1 year in the past. */
 
	Date start_date = (Date)p2;
 
	if (start_date < 0 || start_date > MAX_DAY) return CMD_ERROR;
 
	if (start_date - _date > 15 * DAYS_IN_LEAP_YEAR) return CMD_ERROR;
 
	if (_date - start_date > DAYS_IN_LEAP_YEAR) return CMD_ERROR;
 
	if (timetable_all && !v->orders.list->IsCompleteTimetable()) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
 
		SmallVector<Vehicle *, 8> vehs;
 
		std::vector<Vehicle *> vehs;
 

	
 
		if (timetable_all) {
 
			for (Vehicle *w = v->orders.list->GetFirstSharedVehicle(); w != NULL; w = w->NextShared()) {
 
				vehs.push_back(w);
 
			}
 
		} else {
 
			vehs.push_back(v);
 
		}
 

	
 
		int total_duration = v->orders.list->GetTimetableTotalDuration();
 
		int num_vehs = vehs.size();
 

	
 
		if (num_vehs >= 2) {
 
			QSortT(vehs.data(), vehs.size(), &VehicleTimetableSorter);
 
		}
 

	
 
		int idx = vehs.begin() - std::find(vehs.begin(), vehs.end(), v);
 

	
 
		for (Vehicle *w : vehs) {
 

	
 
			w->lateness_counter = 0;
 
			ClrBit(w->vehicle_flags, VF_TIMETABLE_STARTED);
 
			/* Do multiplication, then division to reduce rounding errors. */
 
			w->timetable_start = start_date + idx * total_duration / num_vehs / DAY_TICKS;
src/train_cmd.cpp
Show inline comments
 
@@ -793,49 +793,49 @@ CommandCost CmdBuildRailVehicle(TileInde
 
	return CommandCost();
 
}
 

	
 
static Train *FindGoodVehiclePos(const Train *src)
 
{
 
	EngineID eng = src->engine_type;
 
	TileIndex tile = src->tile;
 

	
 
	Train *dst;
 
	FOR_ALL_TRAINS(dst) {
 
		if (dst->IsFreeWagon() && dst->tile == tile && !(dst->vehstatus & VS_CRASHED)) {
 
			/* check so all vehicles in the line have the same engine. */
 
			Train *t = dst;
 
			while (t->engine_type == eng) {
 
				t = t->Next();
 
				if (t == NULL) return dst;
 
			}
 
		}
 
	}
 

	
 
	return NULL;
 
}
 

	
 
/** Helper type for lists/vectors of trains */
 
typedef SmallVector<Train *, 16> TrainList;
 
typedef std::vector<Train *> TrainList;
 

	
 
/**
 
 * Make a backup of a train into a train list.
 
 * @param list to make the backup in
 
 * @param t    the train to make the backup of
 
 */
 
static void MakeTrainBackup(TrainList &list, Train *t)
 
{
 
	for (; t != NULL; t = t->Next()) list.push_back(t);
 
}
 

	
 
/**
 
 * Restore the train from the backup list.
 
 * @param list the train to restore.
 
 */
 
static void RestoreTrainBackup(TrainList &list)
 
{
 
	/* No train, nothing to do. */
 
	if (list.size() == 0) return;
 

	
 
	Train *prev = NULL;
 
	/* Iterate over the list and rebuild it. */
 
	for (Train *t : list) {
 
		if (prev != NULL) {
src/train_gui.cpp
Show inline comments
 
@@ -165,49 +165,49 @@ void DrawTrainImage(const Train *v, int 
 
struct CargoSummaryItem {
 
	CargoID cargo;    ///< The cargo that is carried
 
	StringID subtype; ///< STR_EMPTY if none
 
	uint capacity;    ///< Amount that can be carried
 
	uint amount;      ///< Amount that is carried
 
	StationID source; ///< One of the source stations
 

	
 
	/** Used by CargoSummary::Find() and similar functions */
 
	inline bool operator != (const CargoSummaryItem &other) const
 
	{
 
		return this->cargo != other.cargo || this->subtype != other.subtype;
 
	}
 

	
 
	/** Used by std::find() and similar functions */
 
	inline bool operator == (const CargoSummaryItem &other) const
 
	{
 
		return !(this->cargo != other.cargo);
 
	}
 
};
 

	
 
static const uint TRAIN_DETAILS_MIN_INDENT = 32; ///< Minimum indent level in the train details window
 
static const uint TRAIN_DETAILS_MAX_INDENT = 72; ///< Maximum indent level in the train details window; wider than this and we start on a new line
 

	
 
/** Container for the cargo summary information. */
 
typedef SmallVector<CargoSummaryItem, 2> CargoSummary;
 
typedef std::vector<CargoSummaryItem> CargoSummary;
 
/** Reused container of cargo details */
 
static CargoSummary _cargo_summary;
 

	
 
/**
 
 * Draw the details cargo tab for the given vehicle at the given position
 
 *
 
 * @param item  Data to draw
 
 * @param left  The left most coordinate to draw
 
 * @param right The right most coordinate to draw
 
 * @param y     The y coordinate
 
 */
 
static void TrainDetailsCargoTab(const CargoSummaryItem *item, int left, int right, int y)
 
{
 
	StringID str;
 
	if (item->amount > 0) {
 
		SetDParam(0, item->cargo);
 
		SetDParam(1, item->amount);
 
		SetDParam(2, item->source);
 
		SetDParam(3, _settings_game.vehicle.freight_trains);
 
		str = FreightWagonMult(item->cargo) > 1 ? STR_VEHICLE_DETAILS_CARGO_FROM_MULT : STR_VEHICLE_DETAILS_CARGO_FROM;
 
	} else {
 
		SetDParam(0, STR_QUANTITY_N_A);
 
		str = item->cargo == INVALID_CARGO ? STR_LTBLUE_STRING : STR_VEHICLE_DETAILS_CARGO_EMPTY;
 
	}
src/vehicle_cmd.cpp
Show inline comments
 
@@ -325,50 +325,49 @@ struct RefitResult {
 
 * This is the vehicle-type independent part of the CmdRefitXXX functions.
 
 * @param v            The vehicle to refit.
 
 * @param only_this    Whether to only refit this vehicle, or to check the rest of them.
 
 * @param num_vehicles Number of vehicles to refit (not counting articulated parts). Zero means the whole chain.
 
 * @param new_cid      Cargotype to refit to
 
 * @param new_subtype  Cargo subtype to refit to. 0xFF means to try keeping the same subtype according to GetBestFittingSubType().
 
 * @param flags        Command flags
 
 * @param auto_refit   Refitting is done as automatic refitting outside a depot.
 
 * @return Refit cost.
 
 */
 
static CommandCost RefitVehicle(Vehicle *v, bool only_this, uint8 num_vehicles, CargoID new_cid, byte new_subtype, DoCommandFlag flags, bool auto_refit)
 
{
 
	CommandCost cost(v->GetExpenseType(false));
 
	uint total_capacity = 0;
 
	uint total_mail_capacity = 0;
 
	num_vehicles = num_vehicles == 0 ? UINT8_MAX : num_vehicles;
 

	
 
	VehicleSet vehicles_to_refit;
 
	if (!only_this) {
 
		GetVehicleSet(vehicles_to_refit, v, num_vehicles);
 
		/* In this case, we need to check the whole chain. */
 
		v = v->First();
 
	}
 

	
 
	static SmallVector<RefitResult, 16> refit_result;
 
	refit_result.clear();
 
	std::vector<RefitResult> refit_result;
 

	
 
	v->InvalidateNewGRFCacheOfChain();
 
	byte actual_subtype = new_subtype;
 
	for (; v != NULL; v = (only_this ? NULL : v->Next())) {
 
		/* Reset actual_subtype for every new vehicle */
 
		if (!v->IsArticulatedPart()) actual_subtype = new_subtype;
 

	
 
		if (v->type == VEH_TRAIN && std::find(vehicles_to_refit.begin(), vehicles_to_refit.end(), v->index) == vehicles_to_refit.end() && !only_this) continue;
 

	
 
		const Engine *e = v->GetEngine();
 
		if (!e->CanCarryCargo()) continue;
 

	
 
		/* If the vehicle is not refittable, or does not allow automatic refitting,
 
		 * count its capacity nevertheless if the cargo matches */
 
		bool refittable = HasBit(e->info.refit_mask, new_cid) && (!auto_refit || HasBit(e->info.misc_flags, EF_AUTO_REFIT));
 
		if (!refittable && v->cargo_type != new_cid) continue;
 

	
 
		/* Determine best fitting subtype if requested */
 
		if (actual_subtype == 0xFF) {
 
			actual_subtype = GetBestFittingSubType(v, v, new_cid);
 
		}
 

	
 
		/* Back up the vehicle's cargo type */
 
		CargoID temp_cid = v->cargo_type;
src/vehicle_func.h
Show inline comments
 
@@ -154,30 +154,30 @@ static inline uint32 GetCmdRefitVeh(cons
 
}
 

	
 
static inline uint32 GetCmdSendToDepot(VehicleType type)
 
{
 
	return _send_to_depot_proc_table[type];
 
}
 

	
 
static inline uint32 GetCmdSendToDepot(const BaseVehicle *v)
 
{
 
	return GetCmdSendToDepot(v->type);
 
}
 

	
 
CommandCost EnsureNoVehicleOnGround(TileIndex tile);
 
CommandCost EnsureNoTrainOnTrackBits(TileIndex tile, TrackBits track_bits);
 

	
 
extern VehicleID _new_vehicle_id;
 
extern uint16 _returned_refit_capacity;
 
extern uint16 _returned_mail_refit_capacity;
 

	
 
bool CanVehicleUseStation(EngineID engine_type, const struct Station *st);
 
bool CanVehicleUseStation(const Vehicle *v, const struct Station *st);
 

	
 
void ReleaseDisastersTargetingVehicle(VehicleID vehicle);
 

	
 
typedef SmallVector<VehicleID, 2> VehicleSet;
 
typedef std::vector<VehicleID> VehicleSet;
 
void GetVehicleSet(VehicleSet &set, Vehicle *v, uint8 num_vehicles);
 

	
 
void CheckCargoCapacity(Vehicle *v);
 

	
 
#endif /* VEHICLE_FUNC_H */
src/vehicle_gui.cpp
Show inline comments
 
@@ -212,49 +212,49 @@ static void DrawVehicleProfitButton(cons
 
	} else {
 
		spr = SPR_PROFIT_LOT;
 
	}
 
	DrawSprite(spr, PAL_NONE, x, y);
 
}
 

	
 
/** Maximum number of refit cycles we try, to prevent infinite loops. And we store only a byte anyway */
 
static const uint MAX_REFIT_CYCLE = 256;
 

	
 
/**
 
 * Get the best fitting subtype when 'cloning'/'replacing' \a v_from with \a v_for.
 
 * All articulated parts of both vehicles are tested to find a possibly shared subtype.
 
 * For \a v_for only vehicle refittable to \a dest_cargo_type are considered.
 
 * @param v_from the vehicle to match the subtype from
 
 * @param v_for  the vehicle to get the subtype for
 
 * @param dest_cargo_type Destination cargo type.
 
 * @return the best sub type
 
 */
 
byte GetBestFittingSubType(Vehicle *v_from, Vehicle *v_for, CargoID dest_cargo_type)
 
{
 
	v_from = v_from->GetFirstEnginePart();
 
	v_for = v_for->GetFirstEnginePart();
 

	
 
	/* Create a list of subtypes used by the various parts of v_for */
 
	static SmallVector<StringID, 4> subtypes;
 
	static std::vector<StringID> subtypes;
 
	subtypes.clear();
 
	for (; v_from != NULL; v_from = v_from->HasArticulatedPart() ? v_from->GetNextArticulatedPart() : NULL) {
 
		const Engine *e_from = v_from->GetEngine();
 
		if (!e_from->CanCarryCargo() || !HasBit(e_from->info.callback_mask, CBM_VEHICLE_CARGO_SUFFIX)) continue;
 
		include(subtypes, GetCargoSubtypeText(v_from));
 
	}
 

	
 
	byte ret_refit_cyc = 0;
 
	bool success = false;
 
	if (subtypes.size() > 0) {
 
		/* Check whether any articulated part is refittable to 'dest_cargo_type' with a subtype listed in 'subtypes' */
 
		for (Vehicle *v = v_for; v != NULL; v = v->HasArticulatedPart() ? v->GetNextArticulatedPart() : NULL) {
 
			const Engine *e = v->GetEngine();
 
			if (!e->CanCarryCargo() || !HasBit(e->info.callback_mask, CBM_VEHICLE_CARGO_SUFFIX)) continue;
 
			if (!HasBit(e->info.refit_mask, dest_cargo_type) && v->cargo_type != dest_cargo_type) continue;
 

	
 
			CargoID old_cargo_type = v->cargo_type;
 
			byte old_cargo_subtype = v->cargo_subtype;
 

	
 
			/* Set the 'destination' cargo */
 
			v->cargo_type = dest_cargo_type;
 

	
 
			/* Cycle through the refits */
 
			for (uint refit_cyc = 0; refit_cyc < MAX_REFIT_CYCLE; refit_cyc++) {
 
@@ -296,49 +296,49 @@ struct RefitOption {
 
	byte subtype;     ///< Subcargo to use
 
	StringID string;  ///< GRF-local String to display for the cargo
 

	
 
	/**
 
	 * Inequality operator for #RefitOption.
 
	 * @param other Compare to this #RefitOption.
 
	 * @return True if both #RefitOption are different.
 
	 */
 
	inline bool operator != (const RefitOption &other) const
 
	{
 
		return other.cargo != this->cargo || other.string != this->string;
 
	}
 

	
 
	/**
 
	 * Equality operator for #RefitOption.
 
	 * @param other Compare to this #RefitOption.
 
	 * @return True if both #RefitOption are equal.
 
	 */
 
	inline bool operator == (const RefitOption &other) const
 
	{
 
		return other.cargo == this->cargo && other.string == this->string;
 
	}
 
};
 

	
 
typedef SmallVector<RefitOption, 32> SubtypeList; ///< List of refit subtypes associated to a cargo.
 
typedef std::vector<RefitOption> SubtypeList; ///< List of refit subtypes associated to a cargo.
 

	
 
/**
 
 * Draw the list of available refit options for a consist and highlight the selected refit option (if any).
 
 * @param list  List of subtype options for each (sorted) cargo.
 
 * @param sel   Selected refit cargo-type in the window
 
 * @param pos   Position of the selected item in caller widow
 
 * @param rows  Number of rows(capacity) in caller window
 
 * @param delta Step height in caller window
 
 * @param r     Rectangle of the matrix widget.
 
 */
 
static void DrawVehicleRefitWindow(const SubtypeList list[NUM_CARGO], const int sel[2], uint pos, uint rows, uint delta, const Rect &r)
 
{
 
	uint y = r.top + WD_MATRIX_TOP;
 
	uint current = 0;
 

	
 
	bool rtl = _current_text_dir == TD_RTL;
 
	uint iconwidth = max(GetSpriteSize(SPR_CIRCLE_FOLDED).width, GetSpriteSize(SPR_CIRCLE_UNFOLDED).width);
 
	uint iconheight = GetSpriteSize(SPR_CIRCLE_FOLDED).height;
 
	int linecolour = _colour_gradient[COLOUR_ORANGE][4];
 

	
 
	int iconleft   = rtl ? r.right - WD_MATRIX_RIGHT - iconwidth     : r.left + WD_MATRIX_LEFT;
 
	int iconcenter = rtl ? r.right - WD_MATRIX_RIGHT - iconwidth / 2 : r.left + WD_MATRIX_LEFT + iconwidth / 2;
 
	int iconinner  = rtl ? r.right - WD_MATRIX_RIGHT - iconwidth     : r.left + WD_MATRIX_LEFT + iconwidth;
 

	
src/vehiclelist.h
Show inline comments
 
@@ -31,31 +31,31 @@ enum VehicleListType {
 
struct VehicleListIdentifier {
 
	VehicleListType type; ///< The type of vehicle list.
 
	VehicleType vtype;    ///< The vehicle type associated with this list.
 
	CompanyID company;    ///< The company associated with this list.
 
	uint32 index;         ///< A vehicle list type specific index.
 

	
 
	uint32 Pack() const;
 
	bool UnpackIfValid(uint32 data);
 
	static VehicleListIdentifier UnPack(uint32 data);
 

	
 
	/**
 
	 * Create a simple vehicle list.
 
	 * @param type    List type.
 
	 * @param vtype   Vehicle type associated with this list.
 
	 * @param company Company associated with this list.
 
	 * @param index   Optional type specific index.
 
	 */
 
	VehicleListIdentifier(VehicleListType type, VehicleType vtype, CompanyID company, uint index = 0) :
 
		type(type), vtype(vtype), company(company), index(index) {}
 

	
 
	VehicleListIdentifier() : type(), vtype(), company(), index() {}
 
};
 

	
 
/** A list of vehicles. */
 
typedef SmallVector<const Vehicle *, 32> VehicleList;
 
typedef std::vector<const Vehicle *> VehicleList;
 

	
 
bool GenerateVehicleSortList(VehicleList *list, const VehicleListIdentifier &identifier);
 
void BuildDepotVehicleList(VehicleType type, TileIndex tile, VehicleList *engine_list, VehicleList *wagon_list, bool individual_wagons = false);
 
uint GetUnitNumberDigits(VehicleList &vehicles);
 

	
 
#endif /* VEHICLELIST_H */
src/viewport.cpp
Show inline comments
 
@@ -132,52 +132,52 @@ struct ChildScreenSpriteToDraw {
 
	const SubSprite *sub;           ///< only draw a rectangular part of the sprite
 
	int32 x;
 
	int32 y;
 
	int next;                       ///< next child to draw (-1 at the end)
 
};
 

	
 
/** Enumeration of multi-part foundations */
 
enum FoundationPart {
 
	FOUNDATION_PART_NONE     = 0xFF,  ///< Neither foundation nor groundsprite drawn yet.
 
	FOUNDATION_PART_NORMAL   = 0,     ///< First part (normal foundation or no foundation)
 
	FOUNDATION_PART_HALFTILE = 1,     ///< Second part (halftile foundation)
 
	FOUNDATION_PART_END
 
};
 

	
 
/**
 
 * Mode of "sprite combining"
 
 * @see StartSpriteCombine
 
 */
 
enum SpriteCombineMode {
 
	SPRITE_COMBINE_NONE,     ///< Every #AddSortableSpriteToDraw start its own bounding box
 
	SPRITE_COMBINE_PENDING,  ///< %Sprite combining will start with the next unclipped sprite.
 
	SPRITE_COMBINE_ACTIVE,   ///< %Sprite combining is active. #AddSortableSpriteToDraw outputs child sprites.
 
};
 

	
 
typedef SmallVector<TileSpriteToDraw, 64> TileSpriteToDrawVector;
 
typedef SmallVector<StringSpriteToDraw, 4> StringSpriteToDrawVector;
 
typedef SmallVector<ParentSpriteToDraw, 64> ParentSpriteToDrawVector;
 
typedef SmallVector<ChildScreenSpriteToDraw, 16> ChildScreenSpriteToDrawVector;
 
typedef std::vector<TileSpriteToDraw> TileSpriteToDrawVector;
 
typedef std::vector<StringSpriteToDraw> StringSpriteToDrawVector;
 
typedef std::vector<ParentSpriteToDraw> ParentSpriteToDrawVector;
 
typedef std::vector<ChildScreenSpriteToDraw> ChildScreenSpriteToDrawVector;
 

	
 
/** Data structure storing rendering information */
 
struct ViewportDrawer {
 
	DrawPixelInfo dpi;
 

	
 
	StringSpriteToDrawVector string_sprites_to_draw;
 
	TileSpriteToDrawVector tile_sprites_to_draw;
 
	ParentSpriteToDrawVector parent_sprites_to_draw;
 
	ParentSpriteToSortVector parent_sprites_to_sort; ///< Parent sprite pointer array used for sorting
 
	ChildScreenSpriteToDrawVector child_screen_sprites_to_draw;
 

	
 
	int *last_child;
 

	
 
	SpriteCombineMode combine_sprites;               ///< Current mode of "sprite combining". @see StartSpriteCombine
 

	
 
	int foundation[FOUNDATION_PART_END];             ///< Foundation sprites (index into parent_sprites_to_draw).
 
	FoundationPart foundation_part;                  ///< Currently active foundation for ground sprite drawing.
 
	int *last_foundation_child[FOUNDATION_PART_END]; ///< Tail of ChildSprite list of the foundations. (index into child_screen_sprites_to_draw)
 
	Point foundation_offset[FOUNDATION_PART_END];    ///< Pixel offset for ground sprites on the foundations.
 
};
 

	
 
static void MarkViewportDirty(const ViewPort *vp, int left, int top, int right, int bottom);
 

	
 
static ViewportDrawer _vd;
src/viewport_sprite_sorter.h
Show inline comments
 
@@ -20,39 +20,39 @@
 
struct ParentSpriteToDraw {
 
	/* Block of 16B loadable in xmm register */
 
	int32 xmin;                     ///< minimal world X coordinate of bounding box
 
	int32 ymin;                     ///< minimal world Y coordinate of bounding box
 
	int32 zmin;                     ///< minimal world Z coordinate of bounding box
 
	int32 x;                        ///< screen X coordinate of sprite
 

	
 
	/* Second block of 16B loadable in xmm register */
 
	int32 xmax;                     ///< maximal world X coordinate of bounding box
 
	int32 ymax;                     ///< maximal world Y coordinate of bounding box
 
	int32 zmax;                     ///< maximal world Z coordinate of bounding box
 
	int32 y;                        ///< screen Y coordinate of sprite
 

	
 
	SpriteID image;                 ///< sprite to draw
 
	PaletteID pal;                  ///< palette to use
 
	const SubSprite *sub;           ///< only draw a rectangular part of the sprite
 

	
 
	int32 left;                     ///< minimal screen X coordinate of sprite (= x + sprite->x_offs), reference point for child sprites
 
	int32 top;                      ///< minimal screen Y coordinate of sprite (= y + sprite->y_offs), reference point for child sprites
 

	
 
	int32 first_child;              ///< the first child to draw.
 
	bool comparison_done;           ///< Used during sprite sorting: true if sprite has been compared with all other sprites
 
};
 

	
 
typedef SmallVector<ParentSpriteToDraw*, 64> ParentSpriteToSortVector;
 
typedef std::vector<ParentSpriteToDraw*> ParentSpriteToSortVector;
 

	
 
/** Type for method for checking whether a viewport sprite sorter exists. */
 
typedef bool (*VpSorterChecker)();
 
/** Type for the actual viewport sprite sorter. */
 
typedef void (*VpSpriteSorter)(ParentSpriteToSortVector *psd);
 

	
 
#ifdef WITH_SSE
 
bool ViewportSortParentSpritesSSE41Checker();
 
void ViewportSortParentSpritesSSE41(ParentSpriteToSortVector *psdv);
 
#endif
 

	
 
void InitializeSpriteSorter();
 

	
 
#endif /* VIEWPORT_SPRITE_SORTER_H */
src/window.cpp
Show inline comments
 
@@ -64,72 +64,72 @@ Window *_z_back_window  = NULL;
 
bool _window_highlight_colour = false;
 

	
 
/*
 
 * Window that currently has focus. - The main purpose is to generate
 
 * #FocusLost events, not to give next window in z-order focus when a
 
 * window is closed.
 
 */
 
Window *_focused_window;
 

	
 
Point _cursorpos_drag_start;
 

	
 
int _scrollbar_start_pos;
 
int _scrollbar_size;
 
byte _scroller_click_timeout = 0;
 

	
 
bool _scrolling_viewport;  ///< A viewport is being scrolled with the mouse.
 
bool _mouse_hovering;      ///< The mouse is hovering over the same point.
 

	
 
SpecialMouseMode _special_mouse_mode; ///< Mode of the mouse.
 

	
 
/**
 
 * List of all WindowDescs.
 
 * This is a pointer to ensure initialisation order with the various static WindowDesc instances.
 
 */
 
static SmallVector<WindowDesc*, 16> *_window_descs = NULL;
 
static std::vector<WindowDesc*> *_window_descs = NULL;
 

	
 
/** Config file to store WindowDesc */
 
char *_windows_file;
 

	
 
/** Window description constructor. */
 
WindowDesc::WindowDesc(WindowPosition def_pos, const char *ini_key, int16 def_width_trad, int16 def_height_trad,
 
			WindowClass window_class, WindowClass parent_class, uint32 flags,
 
			const NWidgetPart *nwid_parts, int16 nwid_length, HotkeyList *hotkeys) :
 
	default_pos(def_pos),
 
	cls(window_class),
 
	parent_cls(parent_class),
 
	ini_key(ini_key),
 
	flags(flags),
 
	nwid_parts(nwid_parts),
 
	nwid_length(nwid_length),
 
	hotkeys(hotkeys),
 
	pref_sticky(false),
 
	pref_width(0),
 
	pref_height(0),
 
	default_width_trad(def_width_trad),
 
	default_height_trad(def_height_trad)
 
{
 
	if (_window_descs == NULL) _window_descs = new SmallVector<WindowDesc*, 16>();
 
	if (_window_descs == NULL) _window_descs = new std::vector<WindowDesc*>();
 
	_window_descs->push_back(this);
 
}
 

	
 
WindowDesc::~WindowDesc()
 
{
 
	_window_descs->erase(std::find(_window_descs->begin(), _window_descs->end(), this));
 
}
 

	
 
/**
 
 * Determine default width of window.
 
 * This is either a stored user preferred size, or the build-in default.
 
 * @return Width in pixels.
 
 */
 
int16 WindowDesc::GetDefaultWidth() const
 
{
 
	return this->pref_width != 0 ? this->pref_width : ScaleGUITrad(this->default_width_trad);
 
}
 

	
 
/**
 
 * Determine default height of window.
 
 * This is either a stored user preferred size, or the build-in default.
 
 * @return Height in pixels.
 
 */
 
int16 WindowDesc::GetDefaultHeight() const
src/window_gui.h
Show inline comments
 
@@ -260,49 +260,49 @@ struct ViewportData : ViewPort {
 
	int32 scrollpos_x;        ///< Currently shown x coordinate (virtual screen coordinate of topleft corner of the viewport).
 
	int32 scrollpos_y;        ///< Currently shown y coordinate (virtual screen coordinate of topleft corner of the viewport).
 
	int32 dest_scrollpos_x;   ///< Current destination x coordinate to display (virtual screen coordinate of topleft corner of the viewport).
 
	int32 dest_scrollpos_y;   ///< Current destination y coordinate to display (virtual screen coordinate of topleft corner of the viewport).
 
};
 

	
 
struct QueryString;
 

	
 
/* misc_gui.cpp */
 
enum TooltipCloseCondition {
 
	TCC_RIGHT_CLICK,
 
	TCC_HOVER,
 
	TCC_NONE,
 
};
 

	
 
/**
 
 * Data structure for an opened window
 
 */
 
struct Window : ZeroedMemoryAllocator {
 
protected:
 
	void InitializeData(WindowNumber window_number);
 
	void InitializePositionSize(int x, int y, int min_width, int min_height);
 
	virtual void FindWindowPlacementAndResize(int def_width, int def_height);
 

	
 
	SmallVector<int, 4> scheduled_invalidation_data;  ///< Data of scheduled OnInvalidateData() calls.
 
	std::vector<int> scheduled_invalidation_data;  ///< Data of scheduled OnInvalidateData() calls.
 

	
 
public:
 
	Window(WindowDesc *desc);
 

	
 
	virtual ~Window();
 

	
 
	/**
 
	 * Helper allocation function to disallow something.
 
	 * Don't allow arrays; arrays of Windows are pointless as you need
 
	 * to destruct them all at the same time too, which is kinda hard.
 
	 * @param size the amount of space not to allocate
 
	 */
 
	inline void *operator new[](size_t size)
 
	{
 
		NOT_REACHED();
 
	}
 

	
 
	/**
 
	 * Helper allocation function to disallow something.
 
	 * Don't free the window directly; it corrupts the linked list when iterating
 
	 * @param ptr the pointer not to free
 
	 */
 
	inline void operator delete(void *ptr)
 
	{
0 comments (0 inline, 0 general)