--- a/src/settings.cpp Thu Apr 19 14:48:10 2007 +0000
+++ b/src/settings.cpp Tue Jun 12 11:56:35 2007 +0000
@@ -1,6 +1,6 @@
/* $Id$ */
-/** @file
+/** @file settings.cpp
* All actions handling saving and loading of the settings/configuration goes on in this file.
* The file consists of four parts:
* <ol>
@@ -95,10 +95,10 @@
size = ALIGN(size, sizeof(void*));
- // first check if there's memory in the next pool
+ /* first check if there's memory in the next pool */
if (p->next && p->next->pos + size <= p->next->size) {
p = p->next;
- // then check if there's not memory in the cur pool
+ /* then check if there's not memory in the cur pool */
} else if (p->pos + size > p->size) {
SettingsMemoryPool *n = pool_new(size);
*pool = n;
@@ -130,7 +130,7 @@
}
}
-// structs describing the ini format.
+/** structs describing the ini format. */
struct IniItem {
char *name;
char *value;
@@ -139,21 +139,21 @@
};
struct IniGroup {
- char *name; // name of group
- char *comment; //comment for group
+ char *name; ///< name of group
+ char *comment; ///<comment for group
IniItem *item, **last_item;
IniGroup *next;
IniFile *ini;
- IniGroupType type; // type of group
+ IniGroupType type; ///< type of group
};
struct IniFile {
SettingsMemoryPool *pool;
IniGroup *group, **last_group;
- char *comment; // last comment in file
+ char *comment; ///< last comment in file
};
-// allocate an inifile object
+/** allocate an inifile object */
static IniFile *ini_alloc()
{
IniFile *ini;
@@ -167,7 +167,7 @@
return ini;
}
-// allocate an ini group object
+/** allocate an ini group object */
static IniGroup *ini_group_alloc(IniFile *ini, const char *grpt, int len)
{
IniGroup *grp = (IniGroup*)pool_alloc(&ini->pool, sizeof(IniGroup));
@@ -199,7 +199,7 @@
return item;
}
-// load an ini file into the "abstract" format
+/** load an ini file into the "abstract" format */
static IniFile *ini_load(const char *filename)
{
char buffer[1024], c, *s, *t, *e;
@@ -217,23 +217,23 @@
in = fopen(filename, "r");
if (in == NULL) return ini;
- // for each line in the file
+ /* for each line in the file */
while (fgets(buffer, sizeof(buffer), in)) {
- // trim whitespace from the left side
+ /* trim whitespace from the left side */
for (s = buffer; *s == ' ' || *s == '\t'; s++);
- // trim whitespace from right side.
+ /* trim whitespace from right side. */
e = s + strlen(s);
while (e > s && ((c=e[-1]) == '\n' || c == '\r' || c == ' ' || c == '\t')) e--;
*e = '\0';
- // skip comments and empty lines
+ /* skip comments and empty lines */
if (*s == '#' || *s == ';' || *s == '\0') {
uint ns = comment_size + (e - s + 1);
uint a = comment_alloc;
uint pos;
- // add to comment
+ /* add to comment */
if (ns > a) {
a = max(a, 128U);
do a*=2; while (a < ns);
@@ -246,7 +246,7 @@
continue;
}
- // it's a group?
+ /* it's a group? */
if (s[0] == '[') {
if (e[-1] != ']') {
ShowInfoF("ini: invalid group name '%s'", buffer);
@@ -260,30 +260,36 @@
comment_size = 0;
}
} else if (group) {
- // find end of keyname
- for (t = s; *t != '\0' && *t != '=' && *t != '\t' && *t != ' '; t++);
+ /* find end of keyname */
+ if (*s == '\"') {
+ s++;
+ for (t = s; *t != '\0' && *t != '\"'; t++);
+ if (*t == '\"') *t = ' ';
+ } else {
+ for (t = s; *t != '\0' && *t != '=' && *t != '\t' && *t != ' '; t++);
+ }
- // it's an item in an existing group
+ /* it's an item in an existing group */
item = ini_item_alloc(group, s, t-s);
if (comment_size) {
item->comment = (char*)pool_strdup(&ini->pool, comment, comment_size);
comment_size = 0;
}
- // find start of parameter
+ /* find start of parameter */
while (*t == '=' || *t == ' ' || *t == '\t') t++;
- // remove starting quotation marks
+ /* remove starting quotation marks */
if (*t == '\"') t++;
- // remove ending quotation marks
+ /* remove ending quotation marks */
e = t + strlen(t);
if (e > t && e[-1] == '\"') e--;
*e = '\0';
item->value = (char*)pool_strdup(&ini->pool, t, e - t);
} else {
- // it's an orphan item
+ /* it's an orphan item */
ShowInfoF("ini: '%s' outside of group", buffer);
}
}
@@ -299,25 +305,25 @@
return ini;
}
-// lookup a group or make a new one
+/** lookup a group or make a new one */
static IniGroup *ini_getgroup(IniFile *ini, const char *name, int len)
{
IniGroup *group;
if (len == -1) len = strlen(name);
- // does it exist already?
+ /* does it exist already? */
for (group = ini->group; group; group = group->next)
if (!memcmp(group->name, name, len) && group->name[len] == 0)
return group;
- // otherwise make a new one
+ /* otherwise make a new one */
group = ini_group_alloc(ini, name, len);
group->comment = (char*)pool_strdup(&ini->pool, "\n", 1);
return group;
}
-// lookup an item or make a new one
+/** lookup an item or make a new one */
static IniItem *ini_getitem(IniGroup *group, const char *name, bool create)
{
IniItem *item;
@@ -328,11 +334,11 @@
if (!create) return NULL;
- // otherwise make a new one
+ /* otherwise make a new one */
return ini_item_alloc(group, name, len);
}
-// save ini file from the "abstract" format.
+/** save ini file from the "abstract" format. */
static bool ini_save(const char *filename, IniFile *ini)
{
FILE *f;
@@ -349,11 +355,18 @@
assert(item->value != NULL);
if (item->comment != NULL) fputs(item->comment, f);
+ /* protect item->name with quotes if needed */
+ if (strchr(item->name, ' ') != NULL) {
+ fprintf(f, "\"%s\"", item->name);
+ } else {
+ fprintf(f, "%s", item->name);
+ }
+
/* Don't give an equal sign to list items that don't have a parameter */
if (group->type == IGT_LIST && *item->value == '\0') {
- fprintf(f, "%s\n", item->name);
+ fprintf(f, "\n");
} else {
- fprintf(f, "%s = %s\n", item->name, item->value);
+ fprintf(f, " = %s\n", item->value);
}
}
}
@@ -380,13 +393,13 @@
if (onelen == -1) onelen = strlen(one);
- // check if it's an integer
+ /* check if it's an integer */
if (*one >= '0' && *one <= '9')
return strtoul(one, NULL, 0);
idx = 0;
for (;;) {
- // find end of item
+ /* find end of item */
s = many;
while (*s != '|' && *s != 0) s++;
if (s - many == onelen && !memcmp(one, many, onelen)) return idx;
@@ -408,7 +421,7 @@
uint32 res = 0;
for (;;) {
- // skip "whitespace"
+ /* skip "whitespace" */
while (*str == ' ' || *str == '\t' || *str == '|') str++;
if (*str == 0) break;
@@ -522,7 +535,7 @@
{
int orig_id = id;
- // Look for the id'th element
+ /* Look for the id'th element */
while (--id >= 0) {
for (; *many != '|'; many++) {
if (*many == '\0') { // not found
@@ -533,7 +546,7 @@
many++; // pass the |-character
}
- // copy string until next item (|) or the end of the list if this is the last one
+ /* copy string until next item (|) or the end of the list if this is the last one */
while (*many != '\0' && *many != '|') *buf++ = *many++;
*buf = '\0';
}
@@ -685,7 +698,7 @@
if (!SlIsObjectCurrentlyValid(sld->version_from, sld->version_to)) continue;
- // XXX - wtf is this?? (group override?)
+ /* XXX - wtf is this?? (group override?) */
s = strchr(sdb->name, '.');
if (s != NULL) {
group = ini_getgroup(ini, sdb->name, s - sdb->name);
@@ -761,7 +774,7 @@
if (!SlIsObjectCurrentlyValid(sld->version_from, sld->version_to)) continue;
if (sld->conv & SLF_CONFIG_NO) continue;
- // XXX - wtf is this?? (group override?)
+ /* XXX - wtf is this?? (group override?) */
s = strchr(sdb->name, '.');
if (s != NULL) {
group = ini_getgroup(ini, sdb->name, s - sdb->name);
@@ -776,7 +789,7 @@
ptr = GetVariableAddress(object, sld);
if (item->value != NULL) {
- // check if the value is the same as the old value
+ /* check if the value is the same as the old value */
const void *p = string_to_val(sdb, item->value);
/* The main type of a variable/setting is in bytes 8-15
@@ -929,7 +942,8 @@
* 2. SDT_something
* The 'G' stands for global, so this is the one you will use for a
* SettingDescGlobVarList section meaning global variables. The other uses a
- * Base/Offset and runtime variable selection mechanism, known from the saveload * convention (it also has global so it should not be hard).
+ * Base/Offset and runtime variable selection mechanism, known from the saveload
+ * convention (it also has global so it should not be hard).
* Of each type there are again two versions, the normal one and one prefixed
* with 'COND'.
* COND means that the setting is only valid in certain savegame versions
@@ -1052,7 +1066,6 @@
/* Shortcuts for macros below. Logically if we don't save the value
* we also don't sync it in a network game */
#define S SLF_SAVE_NO | SLF_NETWORK_NO
-#define NS SLF_SAVE_NO
#define C SLF_CONFIG_NO
#define N SLF_NETWORK_NO
@@ -1069,7 +1082,7 @@
#include "gui.h"
#include "town.h"
#include "gfx.h"
-// virtual PositionMainToolbar function, calls the right one.
+/* virtual PositionMainToolbar function, calls the right one.*/
static int32 v_PositionMainToolbar(int32 p1)
{
if (_game_mode != GM_MENU) PositionMainToolbar(NULL);
@@ -1205,7 +1218,7 @@
#endif /* WIN32 */
static const SettingDescGlobVarList _misc_settings[] = {
- SDTG_MMANY("display_opt", SLE_UINT8, S, 0, _display_opt, (DO_SHOW_TOWN_NAMES|DO_SHOW_STATION_NAMES|DO_SHOW_SIGNS|DO_FULL_ANIMATION|DO_FULL_DETAIL|DO_TRANS_BUILDINGS|DO_WAYPOINTS), "SHOW_TOWN_NAMES|SHOW_STATION_NAMES|SHOW_SIGNS|FULL_ANIMATION|TRANS_BUILDINGS|FULL_DETAIL|WAYPOINTS", STR_NULL, NULL),
+ SDTG_MMANY("display_opt", SLE_UINT8, S, 0, _display_opt, (DO_SHOW_TOWN_NAMES|DO_SHOW_STATION_NAMES|DO_SHOW_SIGNS|DO_FULL_ANIMATION|DO_FULL_DETAIL|DO_WAYPOINTS), "SHOW_TOWN_NAMES|SHOW_STATION_NAMES|SHOW_SIGNS|FULL_ANIMATION|FULL_DETAIL|WAYPOINTS", STR_NULL, NULL),
SDTG_BOOL("news_ticker_sound", S, 0, _news_ticker_sound, true, STR_NULL, NULL),
SDTG_BOOL("fullscreen", S, 0, _fullscreen, false, STR_NULL, NULL),
SDTG_STR("videodriver", SLE_STRB,C|S,0, _ini_videodriver, NULL, STR_NULL, NULL),
@@ -1380,6 +1393,8 @@
SDT_VAR(Patches, ending_year, SLE_INT32,0,NC|NO,2051, MIN_YEAR, MAX_YEAR, 1, STR_CONFIG_PATCHES_ENDING_YEAR, NULL),
SDT_BOOL(Patches, smooth_economy, 0, 0, true, STR_CONFIG_PATCHES_SMOOTH_ECONOMY, NULL),
SDT_BOOL(Patches, allow_shares, 0, 0, false, STR_CONFIG_PATCHES_ALLOW_SHARES, NULL),
+ SDT_CONDVAR(Patches, town_growth_rate, SLE_UINT8, 54, SL_MAX_VERSION, 0, MS, 2, 0, 4, 0, STR_CONFIG_PATCHES_TOWN_GROWTH, NULL),
+ SDT_CONDVAR(Patches, larger_towns, SLE_UINT8, 54, SL_MAX_VERSION, 0, D0, 4, 0, 255, 1, STR_CONFIG_PATCHES_LARGER_TOWNS, NULL),
/***************************************************************************/
/* AI section of the GUI-configure patches window */
@@ -1461,7 +1476,7 @@
SDT_CONDVAR (Patches, npf_road_drive_through_penalty, SLE_UINT, 47, SL_MAX_VERSION, 0, 0, 8 * NPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
- // The maximum number of nodes to search
+ /* The maximum number of nodes to search */
SDT_CONDBOOL(Patches, yapf.disable_node_optimization , 28, SL_MAX_VERSION, 0, 0, false , STR_NULL, NULL),
SDT_CONDVAR (Patches, yapf.max_search_nodes , SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 10000 , 500, 1000000, 0, STR_NULL, NULL),
SDT_CONDBOOL(Patches, yapf.rail_firstred_twoway_eol , 28, SL_MAX_VERSION, 0, 0, true , STR_NULL, NULL),
@@ -1473,22 +1488,22 @@
SDT_CONDVAR (Patches, yapf.rail_slope_penalty , SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 2 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
SDT_CONDVAR (Patches, yapf.rail_curve45_penalty , SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 1 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
SDT_CONDVAR (Patches, yapf.rail_curve90_penalty , SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 6 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
- // This penalty is applied when a train reverses inside a depot
+ /* This penalty is applied when a train reverses inside a depot */
SDT_CONDVAR (Patches, yapf.rail_depot_reverse_penalty , SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 50 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
- // This is the penalty for level crossings (for trains only)
+ /* This is the penalty for level crossings (for trains only) */
SDT_CONDVAR (Patches, yapf.rail_crossing_penalty , SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 3 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
- // look-ahead how many signals are checked
+ /* look-ahead how many signals are checked */
SDT_CONDVAR (Patches, yapf.rail_look_ahead_max_signals, SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 10 , 1, 100, 0, STR_NULL, NULL),
- // look-ahead n-th red signal penalty polynomial: penalty = p2 * n^2 + p1 * n + p0
+ /* look-ahead n-th red signal penalty polynomial: penalty = p2 * n^2 + p1 * n + p0 */
SDT_CONDVAR (Patches, yapf.rail_look_ahead_signal_p0 , SLE_INT , 28, SL_MAX_VERSION, 0, 0, 500 , -1000000, 1000000, 0, STR_NULL, NULL),
SDT_CONDVAR (Patches, yapf.rail_look_ahead_signal_p1 , SLE_INT , 28, SL_MAX_VERSION, 0, 0, -100 , -1000000, 1000000, 0, STR_NULL, NULL),
SDT_CONDVAR (Patches, yapf.rail_look_ahead_signal_p2 , SLE_INT , 28, SL_MAX_VERSION, 0, 0, 5 , -1000000, 1000000, 0, STR_NULL, NULL),
- // penalties for too long or too short station platforms
+ /* penalties for too long or too short station platforms */
SDT_CONDVAR (Patches, yapf.rail_longer_platform_penalty, SLE_UINT, 33, SL_MAX_VERSION, 0, 0, 8 * YAPF_TILE_LENGTH, 0, 20000, 0, STR_NULL, NULL),
SDT_CONDVAR (Patches, yapf.rail_longer_platform_per_tile_penalty, SLE_UINT, 33, SL_MAX_VERSION, 0, 0, 0 * YAPF_TILE_LENGTH, 0, 20000, 0, STR_NULL, NULL),
SDT_CONDVAR (Patches, yapf.rail_shorter_platform_penalty, SLE_UINT, 33, SL_MAX_VERSION, 0, 0, 40 * YAPF_TILE_LENGTH, 0, 20000, 0, STR_NULL, NULL),
SDT_CONDVAR (Patches, yapf.rail_shorter_platform_per_tile_penalty, SLE_UINT, 33, SL_MAX_VERSION, 0, 0, 0 * YAPF_TILE_LENGTH, 0, 20000, 0, STR_NULL, NULL),
- // road vehicles - penalties
+ /* road vehicles - penalties */
SDT_CONDVAR (Patches, yapf.road_slope_penalty , SLE_UINT, 33, SL_MAX_VERSION, 0, 0, 2 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
SDT_CONDVAR (Patches, yapf.road_curve_penalty , SLE_UINT, 33, SL_MAX_VERSION, 0, 0, 1 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
SDT_CONDVAR (Patches, yapf.road_crossing_penalty , SLE_UINT, 33, SL_MAX_VERSION, 0, 0, 3 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
@@ -1577,7 +1592,7 @@
for (item = group->item; item != NULL; item = item->next) {
GRFConfig *c = CallocT<GRFConfig>(1);
- c->filename = strdup(item->name);
+ c->full_path = strdup(item->name);
/* Parse parameters */
if (*item->value != '\0') {
@@ -1654,7 +1669,7 @@
char params[512];
GRFBuildParamList(params, c, lastof(params));
- *item = ini_item_alloc(group, c->filename, strlen(c->filename));
+ *item = ini_item_alloc(group, c->full_path, strlen(c->full_path));
(*item)->value = (char*)pool_strdup(&ini->pool, params, strlen(params));
item = &(*item)->next;
}
@@ -1830,6 +1845,25 @@
name, value, (sd->desc.flags & SGF_0ISDISABLED) ? "(0) " : "", sd->desc.min, sd->desc.max);
}
+void IConsoleListPatches()
+{
+ IConsolePrintF(_icolour_warn, "All patches with their current value:");
+
+ for (const SettingDesc *sd = _patch_settings; sd->save.cmd != SL_END; sd++) {
+ char value[80];
+ const void *ptr = GetVariableAddress((_game_mode == GM_MENU) ? &_patches_newgame : &_patches, &sd->save);
+
+ if (sd->desc.cmd == SDT_BOOLX) {
+ snprintf(value, lengthof(value), (*(bool*)ptr == 1) ? "on" : "off");
+ } else {
+ snprintf(value, lengthof(value), "%d", (uint32)ReadValue(ptr, sd->save.conv));
+ }
+ IConsolePrintF(_icolour_def, "%s = %s", sd->desc.name, value);
+ }
+
+ IConsolePrintF(_icolour_warn, "Use 'patch' command to change a value");
+}
+
/** Save and load handler for patches/settings
* @param osd SettingDesc struct containing all information
* @param object can be either NULL in which case we load global variables or