Changeset - r15589:fd456a62bb1c
[Not reviewed]
master
0 7 0
rubidium - 14 years ago 2010-07-31 14:40:50
rubidium@openttd.org
(svn r20259) -Add: allow NewGRFs to specify their version and use that to hide old NewGRFs / to choose the newest when loading compatible NewGRFs
7 files changed with 55 insertions and 7 deletions:
0 comments (0 inline, 0 general)
src/lang/english.txt
Show inline comments
 
@@ -2352,48 +2352,49 @@ STR_NEWGRF_SETTINGS_PRESET_SAVE_QUERY   
 
STR_NEWGRF_SETTINGS_PRESET_DELETE                               :{BLACK}Delete preset
 
STR_NEWGRF_SETTINGS_PRESET_DELETE_TOOLTIP                       :{BLACK}Delete the currently selected preset
 
STR_NEWGRF_SETTINGS_ADD                                         :{BLACK}Add
 
STR_NEWGRF_SETTINGS_ADD_FILE_TOOLTIP                            :{BLACK}Add the selected NewGRF file to your configuration
 
STR_NEWGRF_SETTINGS_RESCAN_FILES                                :{BLACK}Rescan files
 
STR_NEWGRF_SETTINGS_RESCAN_FILES_TOOLTIP                        :{BLACK}Update the list of available NewGRF files
 
STR_NEWGRF_SETTINGS_REMOVE                                      :{BLACK}Remove
 
STR_NEWGRF_SETTINGS_REMOVE_TOOLTIP                              :{BLACK}Remove the selected NewGRF file from the list
 
STR_NEWGRF_SETTINGS_MOVEUP                                      :{BLACK}Move Up
 
STR_NEWGRF_SETTINGS_MOVEUP_TOOLTIP                              :{BLACK}Move the selected NewGRF file up the list
 
STR_NEWGRF_SETTINGS_MOVEDOWN                                    :{BLACK}Move Down
 
STR_NEWGRF_SETTINGS_MOVEDOWN_TOOLTIP                            :{BLACK}Move the selected NewGRF file down the list
 
STR_NEWGRF_SETTINGS_FILE_TOOLTIP                                :{BLACK}A list of the NewGRF files that are installed. Click a file to change its parameters
 

	
 
STR_NEWGRF_SETTINGS_SET_PARAMETERS                              :{BLACK}Set parameters
 
STR_NEWGRF_SETTINGS_TOGGLE_PALETTE                              :{BLACK}Toggle palette
 
STR_NEWGRF_SETTINGS_TOGGLE_PALETTE_TOOLTIP                      :{BLACK}Toggle the palette of the selected NewGRF.{}Do this when the graphics from this NewGRF look pink in-game
 
STR_NEWGRF_SETTINGS_APPLY_CHANGES                               :{BLACK}Apply changes
 

	
 
STR_NEWGRF_SETTINGS_FIND_MISSING_CONTENT_BUTTON                 :{BLACK}Find missing content online
 
STR_NEWGRF_SETTINGS_FIND_MISSING_CONTENT_TOOLTIP                :{BLACK}Check whether the missing content can be found online
 

	
 
STR_NEWGRF_SETTINGS_FILENAME                                    :{BLACK}Filename: {SILVER}{RAW_STRING}
 
STR_NEWGRF_SETTINGS_GRF_ID                                      :{BLACK}GRF ID: {SILVER}{RAW_STRING}
 
STR_NEWGRF_SETTINGS_VERSION                                     :{BLACK}Version: {SILVER}{NUM}
 
STR_NEWGRF_SETTINGS_MD5SUM                                      :{BLACK}MD5sum: {SILVER}{RAW_STRING}
 
STR_NEWGRF_SETTINGS_PALETTE                                     :{BLACK}Palette: {SILVER}{RAW_STRING}
 
STR_NEWGRF_SETTINGS_PARAMETER                                   :{BLACK}Parameters: {SILVER}{STRING1}
 

	
 
STR_NEWGRF_SETTINGS_NO_INFO                                     :{BLACK}No information available
 
STR_NEWGRF_SETTINGS_NOT_FOUND                                   :{RED}Matching file not found
 
STR_NEWGRF_SETTINGS_DISABLED                                    :{RED}Disabled
 

	
 
STR_NEWGRF_SETTINGS_PARAMETER_QUERY                             :{BLACK}Enter NewGRF parameters
 

	
 
# NewGRF parameters window
 
STR_NEWGRF_PARAMETERS_CAPTION                                   :{WHITE}Change NewGRF parameters
 
STR_NEWGRF_PARAMETERS_CLOSE                                     :{BLACK}Close
 
STR_NEWGRF_PARAMETERS_DEFAULT_NAME                              :Parameter {NUM}
 

	
 
# NewGRF inspect window
 
STR_NEWGRF_INSPECT_CAPTION                                      :{WHITE}Inspect - {STRING5}
 
STR_NEWGRF_INSPECT_PARENT_BUTTON                                :{BLACK}Parent
 
STR_NEWGRF_INSPECT_PARENT_TOOLTIP                               :{BLACK}Inspect the object of the parent scope
 

	
 
STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT                            :{STRING1} at {HEX}
 
STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_RAIL_TYPE                  :Rail type
 

	
 
STR_NEWGRF_INSPECT_QUERY_CAPTION                                :{WHITE}NewGRF variable 60+x parameter (hexadecimal)
src/newgrf.cpp
Show inline comments
 
@@ -4848,49 +4848,49 @@ static void GRFInfo(ByteReader *buf)
 
	 *
 
	 * B version       newgrf version, currently 06
 
	 * 4*B grf-id      globally unique ID of this .grf file
 
	 * S name          name of this .grf set
 
	 * S info          string describing the set, and e.g. author and copyright */
 

	
 
	uint8 version    = buf->ReadByte();
 
	uint32 grfid     = buf->ReadDWord();
 
	const char *name = buf->ReadString();
 

	
 
	if (_cur_stage < GLS_RESERVE && _cur_grfconfig->status != GCS_UNKNOWN) {
 
		_cur_grfconfig->status = GCS_DISABLED;
 
		delete _cur_grfconfig->error;
 
		_cur_grfconfig->error  = new GRFError(STR_NEWGRF_ERROR_MSG_FATAL, STR_NEWGRF_ERROR_MULTIPLE_ACTION_8);
 

	
 
		_skip_sprites = -1;
 
		return;
 
	}
 

	
 
	_cur_grffile->grfid = grfid;
 
	_cur_grffile->grf_version = version;
 
	_cur_grfconfig->status = _cur_stage < GLS_RESERVE ? GCS_INITIALISED : GCS_ACTIVATED;
 

	
 
	/* Do swap the GRFID for displaying purposes since people expect that */
 
	DEBUG(grf, 1, "GRFInfo: Loaded GRFv%d set %08X - %s (palette: %s)", version, BSWAP32(grfid), name, (_cur_grfconfig->palette & GRFP_USE_MASK) ? "Windows" : "DOS");
 
	DEBUG(grf, 1, "GRFInfo: Loaded GRFv%d set %08X - %s (palette: %s, version: %i)", version, BSWAP32(grfid), name, (_cur_grfconfig->palette & GRFP_USE_MASK) ? "Windows" : "DOS", _cur_grfconfig->version);
 
}
 

	
 
/* Action 0x0A */
 
static void SpriteReplace(ByteReader *buf)
 
{
 
	/* <0A> <num-sets> <set1> [<set2> ...]
 
	 * <set>: <num-sprites> <first-sprite>
 
	 *
 
	 * B num-sets      How many sets of sprites to replace.
 
	 * Each set:
 
	 * B num-sprites   How many sprites are in this set
 
	 * W first-sprite  First sprite number to replace */
 

	
 
	uint8 num_sets = buf->ReadByte();
 

	
 
	for (uint i = 0; i < num_sets; i++) {
 
		uint8 num_sprites = buf->ReadByte();
 
		uint16 first_sprite = buf->ReadWord();
 

	
 
		grfmsg(2, "SpriteReplace: [Set %d] Changing %d sprites, beginning with %d",
 
			i, num_sprites, first_sprite
 
		);
 

	
 
		for (uint j = 0; j < num_sprites; j++) {
 
@@ -5931,48 +5931,60 @@ static bool ChangeGRFNumUsedParams(size_
 
	return true;
 
}
 

	
 
/** Callback function for 'INFO'->'PALS' to set the number of valid parameters. */
 
static bool ChangeGRFPalette(size_t len, ByteReader *buf)
 
{
 
	if (len != 1) {
 
		grfmsg(2, "StaticGRFInfo: expected only 1 byte for 'INFO'->'PALS' but got " PRINTF_SIZE ", ignoring this field", len);
 
		buf->Skip(len);
 
	} else {
 
		char data = buf->ReadByte();
 
		switch (data) {
 
			case '*':
 
			case 'A': _cur_grfconfig->palette |= GRFP_GRF_ANY;     break;
 
			case 'W': _cur_grfconfig->palette |= GRFP_GRF_WINDOWS; break;
 
			case 'D': _cur_grfconfig->palette |= GRFP_GRF_DOS;     break;
 
			default:
 
				grfmsg(2, "StaticGRFInfo: unexpected value '%02x' for 'INFO'->'PALS', ignoring this field", data);
 
				break;
 
		}
 
	}
 
	return true;
 
}
 

	
 
/** Callback function for 'INFO'->'VRSN' to the version of the NewGRF. */
 
static bool ChangeGRFVersion(size_t len, ByteReader *buf)
 
{
 
	if (len != 4) {
 
		grfmsg(2, "StaticGRFInfo: expected 4 bytes for 'INFO'->'VRSN' but got " PRINTF_SIZE ", ignoring this field", len);
 
		buf->Skip(len);
 
	} else {
 
		_cur_grfconfig->version = buf->ReadDWord();
 
	}
 
	return true;
 
}
 

	
 

	
 
static GRFParameterInfo *_cur_parameter; ///< The parameter which info is currently changed by the newgrf.
 

	
 
/** Callback function for 'INFO'->'PARAM'->param_num->'NAME' to set the name of a parameter. */
 
static bool ChangeGRFParamName(byte langid, const char *str)
 
{
 
	AddGRFTextToList(&_cur_parameter->name, langid, _cur_grfconfig->ident.grfid, str);
 
	return true;
 
}
 

	
 
/** Callback function for 'INFO'->'PARAM'->param_num->'DESC' to set the description of a parameter. */
 
static bool ChangeGRFParamDescription(byte langid, const char *str)
 
{
 
	AddGRFTextToList(&_cur_parameter->desc, langid, _cur_grfconfig->ident.grfid, str);
 
	return true;
 
}
 

	
 
/** Callback function for 'INFO'->'PARAM'->param_num->'TYPE' to set the typeof a parameter. */
 
static bool ChangeGRFParamType(size_t len, ByteReader *buf)
 
{
 
	if (len != 1) {
 
		grfmsg(2, "StaticGRFInfo: expected 1 byte for 'INFO'->'PARA'->'TYPE' but got " PRINTF_SIZE ", ignoring this field", len);
 
		buf->Skip(len);
 
	} else {
 
@@ -6169,48 +6181,49 @@ static bool HandleParameterInfo(ByteRead
 
			if (!SkipUnknownInfo(buf, type)) return false;
 
		}
 

	
 
		if (id >= _cur_grfconfig->param_info.Length()) {
 
			uint num_to_add = id - _cur_grfconfig->param_info.Length() + 1;
 
			GRFParameterInfo **newdata = _cur_grfconfig->param_info.Append(num_to_add);
 
			MemSetT<GRFParameterInfo *>(newdata, 0, num_to_add);
 
		}
 
		if (_cur_grfconfig->param_info[id] == NULL) {
 
			_cur_grfconfig->param_info[id] = new GRFParameterInfo(id);
 
		}
 
		_cur_parameter = _cur_grfconfig->param_info[id];
 
		/* Read all parameter-data and process each node. */
 
		if (!HandleNodes(buf, _tags_parameters)) return false;
 
		type = buf->ReadByte();
 
	}
 
	return true;
 
}
 

	
 
AllowedSubtags _tags_info[] = {
 
	AllowedSubtags('NAME', ChangeGRFName),
 
	AllowedSubtags('DESC', ChangeGRFDescription),
 
	AllowedSubtags('NPAR', ChangeGRFNumUsedParams),
 
	AllowedSubtags('PALS', ChangeGRFPalette),
 
	AllowedSubtags('VRSN', ChangeGRFVersion),
 
	AllowedSubtags('PARA', HandleParameterInfo),
 
	AllowedSubtags()
 
};
 

	
 
AllowedSubtags _tags_root[] = {
 
	AllowedSubtags('INFO', _tags_info),
 
	AllowedSubtags()
 
};
 

	
 

	
 
/**
 
 * Try to skip the current node and all subnodes (if it's a branch node).
 
 * @return True if we could skip the node, false if an error occured.
 
 */
 
static bool SkipUnknownInfo(ByteReader *buf, byte type)
 
{
 
	/* type and id are already read */
 
	switch (type) {
 
		case 'C': {
 
			byte new_type = buf->ReadByte();
 
			while (new_type != 0) {
 
				buf->ReadDWord(); // skip the id
 
				if (!SkipUnknownInfo(buf, new_type)) return false;
 
				new_type = buf->ReadByte();
src/newgrf_config.cpp
Show inline comments
 
@@ -18,48 +18,49 @@
 
#include "gfx_func.h"
 
#include "newgrf_text.h"
 
#include "window_func.h"
 

	
 
#include "fileio_func.h"
 
#include "fios.h"
 

	
 
/**
 
 * Create a new GRFConfig.
 
 * @param filename Set the filename of this GRFConfig to filename. The argument
 
 *   is copied so the original string isn't needed after the constructor.
 
 */
 
GRFConfig::GRFConfig(const char *filename) :
 
	num_valid_params(lengthof(param))
 
{
 
	if (filename != NULL) this->filename = strdup(filename);
 
}
 

	
 
/**
 
 * Create a new GRFConfig that is a deep copy of an existing config.
 
 * @param config The GRFConfig object to make a copy of.
 
 */
 
GRFConfig::GRFConfig(const GRFConfig &config) :
 
	ident(config.ident),
 
	version(config.version),
 
	flags(config.flags & ~GCF_COPY),
 
	status(config.status),
 
	grf_bugs(config.grf_bugs),
 
	num_params(config.num_params),
 
	num_valid_params(config.num_valid_params),
 
	palette(config.palette)
 
{
 
	MemCpyT<uint8>(this->original_md5sum, config.original_md5sum, lengthof(this->original_md5sum));
 
	MemCpyT<uint32>(this->param, config.param, lengthof(this->param));
 
	if (config.filename != NULL) this->filename = strdup(config.filename);
 
	this->name = DuplicateGRFText(config.name);
 
	this->info = DuplicateGRFText(config.info);
 
	if (config.error    != NULL) this->error    = new GRFError(*config.error);
 
	for (uint i = 0; i < config.param_info.Length(); i++) {
 
		if (config.param_info[i] == NULL) {
 
			*this->param_info.Append() = NULL;
 
		} else {
 
			*this->param_info.Append() = new GRFParameterInfo(*config.param_info[i]);
 
		}
 
	}
 
}
 

	
 
/** Cleanup a GRFConfig object. */
 
GRFConfig::~GRFConfig()
 
@@ -558,53 +559,56 @@ void ScanNewGRFFiles()
 

	
 
	QSortT(to_sort, num, &GRFSorter);
 

	
 
	for (i = 1; i < num; i++) {
 
		to_sort[i - 1]->next = to_sort[i];
 
	}
 
	to_sort[num - 1]->next = NULL;
 
	_all_grfs = to_sort[0];
 

	
 
	free(to_sort);
 

	
 
#ifdef ENABLE_NETWORK
 
	NetworkAfterNewGRFScan();
 
#endif
 
}
 

	
 

	
 
/** Find a NewGRF in the scanned list.
 
 * @param grfid GRFID to look for,
 
 * @param md5sum Expected MD5 sum (set to \c NULL if not relevant).
 
 * @return The matching grf, if it exists in #_all_grfs, else \c NULL.
 
 */
 
const GRFConfig *FindGRFConfig(uint32 grfid, const uint8 *md5sum)
 
{
 
	const GRFConfig *best = NULL;
 
	for (const GRFConfig *c = _all_grfs; c != NULL; c = c->next) {
 
		if (c->ident.HasGrfIdentifier(grfid, md5sum)) return c;
 
		if (!c->ident.HasGrfIdentifier(grfid, md5sum)) continue;
 
		if (md5sum != NULL) return c;
 
		if (best == NULL || c->version > best->version) best = c;
 
	}
 

	
 
	return NULL;
 
	return best;
 
}
 

	
 
#ifdef ENABLE_NETWORK
 

	
 
/** Structure for UnknownGRFs; this is a lightweight variant of GRFConfig */
 
struct UnknownGRF : public GRFIdentifier {
 
	UnknownGRF *next;
 
	char   name[NETWORK_GRF_NAME_LENGTH];
 
};
 

	
 
/**
 
 * Finds the name of a NewGRF in the list of names for unknown GRFs. An
 
 * unknown GRF is a GRF where the .grf is not found during scanning.
 
 *
 
 * The names are resolved via UDP calls to servers that should know the name,
 
 * though the replies may not come. This leaves "<Unknown>" as name, though
 
 * that shouldn't matter _very_ much as they need GRF crawler or so to look
 
 * up the GRF anyway and that works better with the GRF ID.
 
 *
 
 * @param grfid  the GRF ID part of the 'unique' GRF identifier
 
 * @param md5sum the MD5 checksum part of the 'unique' GRF identifier
 
 * @param create whether to create a new GRFConfig if the GRFConfig did not
 
 *               exist in the fake list of GRFConfigs.
 
 * @return the GRFConfig with the given GRF ID and MD5 checksum or NULL when
src/newgrf_config.h
Show inline comments
 
@@ -118,48 +118,49 @@ struct GRFParameterInfo {
 
	uint32 min_value;      ///< The minimal value this parameter can have
 
	uint32 max_value;      ///< The maximal value of this parameter
 
	byte param_nr;         ///< GRF parameter to store content in
 
	byte first_bit;        ///< First bit to use in the GRF parameter
 
	byte num_bit;          ///< Number of bits to use for this parameter
 
	SmallMap<uint32, struct GRFText *, 8> value_names; ///< Names for each value.
 

	
 
	uint32 GetValue(struct GRFConfig *config) const;
 
	void SetValue(struct GRFConfig *config, uint32 value);
 
};
 

	
 
/** 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
 
	struct GRFText *name;      ///< NOSAVE: GRF name (Action 0x08)
 
	struct GRFText *info;      ///< NOSAVE: GRF info (author, copyright, ...) (Action 0x08)
 
	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
 
	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
 

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

	
 
	bool IsOpenTTDBaseGRF() const;
 

	
 
	const char *GetName() const;
 
	const char *GetDescription() const;
 

	
 
	void SetSuitablePalette();
 
};
 

	
 
extern GRFConfig *_all_grfs;          ///< First item in list of all scanned NewGRFs
 
extern GRFConfig *_grfconfig;         ///< First item in list of current GRF set up
 
extern GRFConfig *_grfconfig_newgame; ///< First item in list of default GRF set up
 
extern GRFConfig *_grfconfig_static;  ///< First item in list of static GRF set up
 

	
src/newgrf_gui.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_gui.cpp GUI to change NewGRF settings. */
 

	
 
#include "stdafx.h"
 
#include "gui.h"
 
#include "newgrf.h"
 
#include "strings_func.h"
 
#include "window_func.h"
 
#include "gamelog.h"
 
#include "settings_type.h"
 
#include "settings_func.h"
 
#include "widgets/dropdown_type.h"
 
#include "network/network.h"
 
#include "network/network_content.h"
 
#include "sortlist_type.h"
 
#include "querystring_gui.h"
 
#include "core/geometry_func.hpp"
 
#include "newgrf_text.h"
 

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

	
 
/**
 
 * Show the first NewGRF error we can find.
 
 */
 
void ShowNewGRFError()
 
{
 
	for (const GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
 
		/* We only want to show fatal errors */
 
		if (c->error == NULL || c->error->severity != STR_NEWGRF_ERROR_MSG_FATAL) continue;
 

	
 
		SetDParam   (0, c->error->custom_message == NULL ? c->error->message : STR_JUST_RAW_STRING);
 
		SetDParamStr(1, c->error->custom_message);
 
		SetDParam   (2, STR_JUST_RAW_STRING);
 
@@ -59,48 +60,53 @@ static void ShowNewGRFInfo(const GRFConf
 
		SetDParamStr(2, c->filename);
 
		SetDParam   (3, STR_JUST_RAW_STRING);
 
		SetDParamStr(4, c->error->data);
 
		for (uint i = 0; i < c->error->num_params; i++) {
 
			SetDParam(5 + i, c->error->param_value[i]);
 
		}
 
		GetString(message, c->error->custom_message == NULL ? c->error->message : STR_JUST_RAW_STRING, lastof(message));
 

	
 
		SetDParamStr(0, message);
 
		y = DrawStringMultiLine(x, right, y, bottom, c->error->severity);
 
	}
 

	
 
	/* Draw filename or not if it is not known (GRF sent over internet) */
 
	if (c->filename != NULL) {
 
		SetDParamStr(0, c->filename);
 
		y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_FILENAME);
 
	}
 

	
 
	/* Prepare and draw GRF ID */
 
	char buff[256];
 
	snprintf(buff, lengthof(buff), "%08X", BSWAP32(c->ident.grfid));
 
	SetDParamStr(0, buff);
 
	y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_GRF_ID);
 

	
 
	if (c->version != 0) {
 
		SetDParam(0, c->version);
 
		y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_VERSION);
 
	}
 

	
 
	/* Prepare and draw MD5 sum */
 
	md5sumToString(buff, lastof(buff), c->ident.md5sum);
 
	SetDParamStr(0, buff);
 
	y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_MD5SUM);
 

	
 
	/* Show GRF parameter list */
 
	if (show_params) {
 
		if (c->num_params > 0) {
 
			GRFBuildParamList(buff, c, lastof(buff));
 
			SetDParam(0, STR_JUST_RAW_STRING);
 
			SetDParamStr(1, buff);
 
		} else {
 
			SetDParam(0, STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE);
 
		}
 
		y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_PARAMETER);
 

	
 
		/* Draw the palette of the NewGRF */
 
		SetDParamStr(0, (c->palette & GRFP_USE_WINDOWS) ? "Windows" : "DOS");
 
		y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_PALETTE);
 
	}
 

	
 
	/* Show flags */
 
	if (c->status == GCS_NOT_FOUND)       y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_NOT_FOUND);
 
	if (c->status == GCS_DISABLED)        y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_DISABLED);
 
@@ -596,50 +602,49 @@ struct NewGRFWindow : public QueryString
 
					if (this->vscroll.IsVisible(i)) {
 
						const char *text = c->GetName();
 
						bool h = (this->active_sel == c);
 
						PaletteID pal = this->GetPalette(c);
 

	
 
						if (h) GfxFillRect(r.left + 1, y, r.right - 1, y + step_height - 1, 156);
 
						DrawSprite(SPR_SQUARE, pal, square_left, y + sprite_offset_y);
 
						if (c->error != NULL) DrawSprite(SPR_WARNING_SIGN, 0, warning_left, y + sprite_offset_y);
 
						uint txtoffset = c->error == NULL ? 0 : 10;
 
						DrawString(text_left + (rtl ? 0 : txtoffset), text_right - (rtl ? txtoffset : 0), y + offset_y, text, h ? TC_WHITE : TC_ORANGE);
 
						y += step_height;
 
					}
 
				}
 
			} break;
 

	
 
			case SNGRFS_AVAIL_LIST: {
 
				GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, 0xD7);
 

	
 
				uint step_height = this->GetWidget<NWidgetBase>(SNGRFS_AVAIL_LIST)->resize_y;
 
				int offset_y = (step_height - FONT_HEIGHT_NORMAL) / 2;
 
				uint y = r.top + WD_FRAMERECT_TOP;
 
				uint min_index = this->vscroll2.GetPosition();
 
				uint max_index = min(min_index + this->vscroll2.GetCapacity(), this->avails.Length());
 

	
 
				for (uint i = min_index; i < max_index; i++)
 
				{
 
				for (uint i = min_index; i < max_index; i++) {
 
					const GRFConfig *c = this->avails[i];
 
					bool h = (c == this->avail_sel);
 
					const char *text = c->GetName();
 

	
 
					if (h) GfxFillRect(r.left + 1, y, r.right - 1, y + step_height - 1, 156);
 
					DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y + offset_y, text, h ? TC_WHITE : TC_SILVER);
 
					y += step_height;
 
				}
 
				break;
 
			}
 

	
 
			case SNGRFS_NEWGRF_INFO_TITLE:
 
				/* Create the nice grayish rectangle at the details top. */
 
				GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, 157);
 
				DrawString(r.left, r.right, (r.top + r.bottom - FONT_HEIGHT_NORMAL) / 2, STR_NEWGRF_SETTINGS_INFO_TITLE, TC_FROMSTRING, SA_HOR_CENTER);
 
				break;
 

	
 
			case SNGRFS_NEWGRF_INFO: {
 
				const GRFConfig *selected = this->active_sel;
 
				if (selected == NULL) selected = this->avail_sel;
 
				if (selected != NULL) {
 
					ShowNewGRFInfo(selected, r.left + WD_FRAMERECT_LEFT, r.top + WD_FRAMERECT_TOP, r.right - WD_FRAMERECT_RIGHT, r.bottom - WD_FRAMERECT_BOTTOM, this->show_params);
 
				}
 
				break;
 
@@ -1051,70 +1056,92 @@ struct NewGRFWindow : public QueryString
 
			}
 
		}
 

	
 
		if (this->avails.Length() == 0) this->avail_pos = -1;
 
		if (this->avail_pos >= 0) {
 
			this->avail_sel = this->avails[this->avail_pos];
 
			this->vscroll2.ScrollTowards(this->avail_pos);
 
			this->InvalidateData(0);
 
		}
 

	
 
		return ES_HANDLED;
 
	}
 

	
 
	virtual void OnOSKInput(int wid)
 
	{
 
		this->avails.SetFilterState(!StrEmpty(this->edit_str_buf));
 
		this->avails.ForceRebuild();
 
		this->InvalidateData(0);
 
	}
 

	
 
private:
 
	/** Sort grfs by name. */
 
	static int CDECL NameSorter(const GRFConfig * const *a, const GRFConfig * const *b)
 
	{
 
		return strcasecmp((*a)->GetName(), (*b)->GetName());
 
		int i = strcasecmp((*a)->GetName(), (*b)->GetName());
 
		if (i != 0) return i;
 

	
 
		i = (*a)->version - (*b)->version;
 
		if (i != 0) return i;
 

	
 
		return memcmp((*a)->ident.md5sum, (*b)->ident.md5sum, lengthof((*b)->ident.md5sum));
 
	}
 

	
 
	/** Filter grfs by tags/name */
 
	static bool CDECL TagNameFilter(const GRFConfig * const *a, const char *filter_string)
 
	{
 
		if (strcasestr((*a)->GetName(), filter_string) != NULL) return true;
 
		if ((*a)->filename != NULL && strcasestr((*a)->filename, filter_string) != NULL) return true;
 
		if ((*a)->GetDescription() != NULL && strcasestr((*a)->GetDescription(), filter_string) != NULL) return true;
 
		return false;
 
	}
 

	
 
	void BuildAvailables()
 
	{
 
		if (!this->avails.NeedRebuild()) return;
 

	
 
		this->avails.Clear();
 

	
 
		for (const GRFConfig *c = _all_grfs; c != NULL; c = c->next) {
 
			bool found = false;
 
			for (const GRFConfig *grf = this->actives; grf != NULL && !found; grf = grf->next) found = grf->ident.HasGrfIdentifier(c->ident.grfid, c->ident.md5sum);
 
			if (!found) *this->avails.Append() = c;
 
			if (found) continue;
 

	
 
			if (_settings_client.gui.newgrf_show_old_versions) {
 
				*this->avails.Append() = c;
 
			} else {
 
				const GRFConfig *best = FindGRFConfig(c->ident.grfid, NULL);
 
				/*
 
				 * If the best version is 0, then all NewGRF with this GRF ID
 
				 * have version 0, so for backward compatability reasons we
 
				 * want to show them all.
 
				 * If we are the best version, then we definitely want to
 
				 * show that NewGRF!.
 
				 */
 
				if (best->version == 0 || best->ident.HasGrfIdentifier(c->ident.grfid, c->ident.md5sum)) {
 
					*this->avails.Append() = c;
 
				}
 
			}
 
		}
 

	
 
		this->avails.Filter(this->edit_str_buf);
 
		this->avails.Compact();
 
		this->avails.RebuildDone();
 
		this->avails.Sort();
 

	
 
		if (this->avail_sel != NULL) {
 
			this->avail_pos = this->avails.FindIndex(this->avail_sel);
 
			if (this->avail_pos < 0) this->avail_sel = NULL;
 
		}
 

	
 
		this->vscroll2.SetCount(this->avails.Length()); // Update the scrollbar
 
	}
 
};
 

	
 
Listing NewGRFWindow::last_sorting     = {false, 0};
 
Filtering NewGRFWindow::last_filtering = {false, 0};
 

	
 
NewGRFWindow::GUIGRFConfigList::SortFunction * const NewGRFWindow::sorter_funcs[] = {
 
	&NameSorter,
 
};
 

	
 
NewGRFWindow::GUIGRFConfigList::FilterFunction * const NewGRFWindow::filter_funcs[] = {
src/settings_type.h
Show inline comments
 
@@ -90,48 +90,49 @@ struct GUISettings {
 
	byte   drag_signals_density;             ///< many signals density
 
	Year   semaphore_build_before;           ///< build semaphore signals automatically before this year
 
	byte   news_message_timeout;             ///< how much longer than the news message "age" should we keep the message in the history
 
	bool   show_track_reservation;           ///< highlight reserved tracks.
 
	uint8  default_signal_type;              ///< the signal type to build by default.
 
	uint8  cycle_signal_types;               ///< what signal types to cycle with the build signal tool.
 
	byte   station_numtracks;                ///< the number of platforms to default on for rail stations
 
	byte   station_platlength;               ///< the platform length, in tiles, for rail stations
 
	bool   station_dragdrop;                 ///< whether drag and drop is enabled for stations
 
	bool   station_show_coverage;            ///< whether to highlight coverage area
 
	bool   persistent_buildingtools;         ///< keep the building tools active after usage
 
	uint8  expenses_layout;                  ///< layout of expenses window
 

	
 
	uint16 console_backlog_timeout;          ///< the minimum amount of time items should be in the console backlog before they will be removed in ~3 seconds granularity.
 
	uint16 console_backlog_length;           ///< the minimum amount of items in the console backlog before items will be removed.
 
#ifdef ENABLE_NETWORK
 
	uint16 network_chat_box_width;           ///< width of the chat box in pixels
 
	uint8  network_chat_box_height;          ///< height of the chat box in lines
 
#endif
 

	
 
	uint8  developer;                        ///< print non-fatal warnings in console (>= 1), copy debug output to console (== 2)
 
	bool   show_date_in_logs;                ///< whether to show dates in console logs
 
	bool   newgrf_developer_tools;           ///< activate NewGRF developer tools
 
	bool   ai_developer_tools;               ///< activate AI developer tools
 
	bool   newgrf_show_old_versions;         ///< whether to show old versions in the NewGRF list
 
};
 

	
 
/** Settings related to currency/unit systems. */
 
struct LocaleSettings {
 
	byte   currency;                         ///< currency we currently use
 
	byte   units;                            ///< unit system we show everything
 
	char  *digit_group_separator;            ///< thousand separator for non-currencies
 
	char  *digit_group_separator_currency;   ///< thousand separator for currencies
 
	char  *digit_decimal_separator;          ///< decimal separator
 
};
 

	
 
/** All settings related to the network. */
 
struct NetworkSettings {
 
#ifdef ENABLE_NETWORK
 
	uint16 sync_freq;                                     ///< how often do we check whether we are still in-sync
 
	uint8  frame_freq;                                    ///< how often do we send commands to the clients
 
	uint16 max_join_time;                                 ///< maximum amount of time, in game ticks, a client may take to join
 
	bool   pause_on_join;                                 ///< pause the game when people join
 
	uint16 server_port;                                   ///< port the server listens on
 
	char   server_name[NETWORK_NAME_LENGTH];              ///< name of the server
 
	char   server_password[NETWORK_PASSWORD_LENGTH];      ///< passowrd for joining this server
 
	char   rcon_password[NETWORK_PASSWORD_LENGTH];        ///< passowrd for rconsole (server side)
 
	bool   server_advertise;                              ///< advertise the server to the masterserver
 
	uint8  lan_internet;                                  ///< search on the LAN or internet for servers
src/table/settings.h
Show inline comments
 
@@ -590,48 +590,49 @@ const SettingDesc _settings[] = {
 
	 SDTC_BOOL(gui.autosave_on_exit,                     S,  0, false,                        STR_NULL,                                       NULL),
 
	  SDTC_VAR(gui.max_num_autosaves,         SLE_UINT8, S,  0,    16,        0,      255, 0, STR_NULL,                                       NULL),
 
	 SDTC_BOOL(gui.bridge_pillars,                       S,  0,  true,                        STR_NULL,                                       NULL),
 
	 SDTC_BOOL(gui.auto_euro,                            S,  0,  true,                        STR_NULL,                                       NULL),
 
	  SDTC_VAR(gui.news_message_timeout,      SLE_UINT8, S,  0,     2,        1,      255, 0, STR_NULL,                                       NULL),
 
	 SDTC_BOOL(gui.show_track_reservation,               S,  0, false,                        STR_CONFIG_SETTING_SHOW_TRACK_RESERVATION,      RedrawScreen),
 
	  SDTC_VAR(gui.default_signal_type,       SLE_UINT8, S, MS,     1,        0,        2, 1, STR_CONFIG_SETTING_DEFAULT_SIGNAL_TYPE,         NULL),
 
	  SDTC_VAR(gui.cycle_signal_types,        SLE_UINT8, S, MS,     2,        0,        2, 1, STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES,          NULL),
 
	  SDTC_VAR(gui.station_numtracks,         SLE_UINT8, S,  0,     1,        1,        7, 0, STR_NULL,                                       NULL),
 
	  SDTC_VAR(gui.station_platlength,        SLE_UINT8, S,  0,     5,        1,        7, 0, STR_NULL,                                       NULL),
 
	 SDTC_BOOL(gui.station_dragdrop,                     S,  0,  true,                        STR_NULL,                                       NULL),
 
	 SDTC_BOOL(gui.station_show_coverage,                S,  0, false,                        STR_NULL,                                       NULL),
 
	 SDTC_BOOL(gui.persistent_buildingtools,             S,  0,  true,                        STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS,    NULL),
 
	 SDTC_BOOL(gui.expenses_layout,                      S,  0, false,                        STR_CONFIG_SETTING_EXPENSES_LAYOUT,             RedrawScreen),
 

	
 
/* For the dedicated build we'll enable dates in logs by default. */
 
#ifdef DEDICATED
 
	 SDTC_BOOL(gui.show_date_in_logs,                    S,  0,  true,                        STR_NULL,                                       NULL),
 
#else
 
	 SDTC_BOOL(gui.show_date_in_logs,                    S,  0, false,                        STR_NULL,                                       NULL),
 
#endif
 
	  SDTC_VAR(gui.developer,                 SLE_UINT8, S,  0,     1,        0,        2, 0, STR_NULL,                                       NULL),
 
	 SDTC_BOOL(gui.newgrf_developer_tools,               S,  0, false,                        STR_NULL,                                       ReinitWindows),
 
	 SDTC_BOOL(gui.ai_developer_tools,                   S,  0, false,                        STR_NULL,                                       NULL),
 
	 SDTC_BOOL(gui.newgrf_show_old_versions,             S,  0, false,                        STR_NULL,                                       NULL),
 
	  SDTC_VAR(gui.console_backlog_timeout,  SLE_UINT16, S,  0,   100,       10,    65500, 0, STR_NULL,                                       NULL),
 
	  SDTC_VAR(gui.console_backlog_length,   SLE_UINT16, S,  0,   100,       10,    65500, 0, STR_NULL,                                       NULL),
 
#ifdef ENABLE_NETWORK
 
	  SDTC_VAR(gui.network_chat_box_width,   SLE_UINT16, S,  0,   620,      200,    65535, 0, STR_NULL,                                       NULL),
 
	  SDTC_VAR(gui.network_chat_box_height,   SLE_UINT8, S,  0,    25,        5,      255, 0, STR_NULL,                                       NULL),
 

	
 
	  SDTC_VAR(network.sync_freq,            SLE_UINT16,C|S,NO,   100,        0,      100, 0, STR_NULL,                                       NULL),
 
	  SDTC_VAR(network.frame_freq,            SLE_UINT8,C|S,NO,     0,        0,      100, 0, STR_NULL,                                       NULL),
 
	  SDTC_VAR(network.max_join_time,        SLE_UINT16, S, NO,   500,        0,    32000, 0, STR_NULL,                                       NULL),
 
	 SDTC_BOOL(network.pause_on_join,                    S, NO,  true,                        STR_NULL,                                       NULL),
 
	  SDTC_VAR(network.server_port,          SLE_UINT16, S, NO,NETWORK_DEFAULT_PORT,0,65535,0,STR_NULL,                                       NULL),
 
	 SDTC_BOOL(network.server_advertise,                 S, NO, false,                        STR_NULL,                                       NULL),
 
	  SDTC_VAR(network.lan_internet,          SLE_UINT8, S, NO,     0,        0,        1, 0, STR_NULL,                                       NULL),
 
	  SDTC_STR(network.client_name,            SLE_STRB, S,  0,  NULL,                        STR_NULL,                                       UpdateClientName),
 
	  SDTC_STR(network.server_password,        SLE_STRB, S, NO,  NULL,                        STR_NULL,                                       UpdateServerPassword),
 
	  SDTC_STR(network.rcon_password,          SLE_STRB, S, NO,  NULL,                        STR_NULL,                                       UpdateRconPassword),
 
	  SDTC_STR(network.default_company_pass,   SLE_STRB, S,  0,  NULL,                        STR_NULL,                                       NULL),
 
	  SDTC_STR(network.server_name,            SLE_STRB, S, NO,  NULL,                        STR_NULL,                                       NULL),
 
	  SDTC_STR(network.connect_to_ip,          SLE_STRB, S,  0,  NULL,                        STR_NULL,                                       NULL),
 
	  SDTC_STR(network.network_id,             SLE_STRB, S, NO,  NULL,                        STR_NULL,                                       NULL),
 
	 SDTC_BOOL(network.autoclean_companies,              S, NO, false,                        STR_NULL,                                       NULL),
 
	  SDTC_VAR(network.autoclean_unprotected, SLE_UINT8, S,D0|NO,  12,     0,         240, 0, STR_NULL,                                       NULL),
 
	  SDTC_VAR(network.autoclean_protected,   SLE_UINT8, S,D0|NO,  36,     0,         240, 0, STR_NULL,                                       NULL),
 
	  SDTC_VAR(network.autoclean_novehicles,  SLE_UINT8, S,D0|NO,   0,     0,         240, 0, STR_NULL,                                       NULL),
0 comments (0 inline, 0 general)