00001
00002
00022 #include "stdafx.h"
00023 #include "openttd.h"
00024 #include "currency.h"
00025 #include "screenshot.h"
00026 #include "variables.h"
00027 #include "network/network.h"
00028 #include "network/network_func.h"
00029 #include "settings_internal.h"
00030 #include "command_func.h"
00031 #include "console_func.h"
00032 #include "npf.h"
00033 #include "yapf/yapf.h"
00034 #include "genworld.h"
00035 #include "train.h"
00036 #include "news_func.h"
00037 #include "window_func.h"
00038 #include "strings_func.h"
00039 #include "vehicle_func.h"
00040 #include "sound_func.h"
00041 #include "company_func.h"
00042 #include "rev.h"
00043 #ifdef WITH_FREETYPE
00044 #include "fontcache.h"
00045 #endif
00046 #include "textbuf_gui.h"
00047 #include "rail_gui.h"
00048 #include "elrail_func.h"
00049 #include "gui.h"
00050 #include "town.h"
00051 #include "video/video_driver.hpp"
00052 #include "sound/sound_driver.hpp"
00053 #include "music/music_driver.hpp"
00054 #include "blitter/factory.hpp"
00055 #include "gfxinit.h"
00056 #include "gamelog.h"
00057 #include "station_func.h"
00058 #include "settings_func.h"
00059 #include "ini_type.h"
00060 #include "ai/ai_config.hpp"
00061 #include "newgrf.h"
00062 #include "engine_base.h"
00063
00064 #include "void_map.h"
00065 #include "station_base.h"
00066
00067 #include "table/strings.h"
00068
00069 ClientSettings _settings_client;
00070 GameSettings _settings_game;
00071 GameSettings _settings_newgame;
00072
00073 typedef const char *SettingListCallbackProc(const IniItem *item, uint index);
00074 typedef void SettingDescProc(IniFile *ini, const SettingDesc *desc, const char *grpname, void *object);
00075 typedef void SettingDescProcList(IniFile *ini, const char *grpname, char **list, uint len, SettingListCallbackProc proc);
00076
00077 static bool IsSignedVarMemType(VarType vt);
00078
00082 static const char *_list_group_names[] = {
00083 "bans",
00084 "newgrf",
00085 "servers",
00086 NULL
00087 };
00088
00094 static int lookup_oneofmany(const char *many, const char *one, size_t onelen = 0)
00095 {
00096 const char *s;
00097 int idx;
00098
00099 if (onelen == 0) onelen = strlen(one);
00100
00101
00102 if (*one >= '0' && *one <= '9')
00103 return strtoul(one, NULL, 0);
00104
00105 idx = 0;
00106 for (;;) {
00107
00108 s = many;
00109 while (*s != '|' && *s != 0) s++;
00110 if ((size_t)(s - many) == onelen && !memcmp(one, many, onelen)) return idx;
00111 if (*s == 0) return -1;
00112 many = s + 1;
00113 idx++;
00114 }
00115 }
00116
00122 static uint32 lookup_manyofmany(const char *many, const char *str)
00123 {
00124 const char *s;
00125 int r;
00126 uint32 res = 0;
00127
00128 for (;;) {
00129
00130 while (*str == ' ' || *str == '\t' || *str == '|') str++;
00131 if (*str == 0) break;
00132
00133 s = str;
00134 while (*s != 0 && *s != ' ' && *s != '\t' && *s != '|') s++;
00135
00136 r = lookup_oneofmany(many, str, s - str);
00137 if (r == -1) return (uint32)-1;
00138
00139 SetBit(res, r);
00140 if (*s == 0) break;
00141 str = s + 1;
00142 }
00143 return res;
00144 }
00145
00152 static int parse_intlist(const char *p, int *items, int maxitems)
00153 {
00154 int n = 0, v;
00155 char *end;
00156
00157 for (;;) {
00158 v = strtol(p, &end, 0);
00159 if (p == end || n == maxitems) return -1;
00160 p = end;
00161 items[n++] = v;
00162 if (*p == '\0') break;
00163 if (*p != ',' && *p != ' ') return -1;
00164 p++;
00165 }
00166
00167 return n;
00168 }
00169
00176 static bool load_intlist(const char *str, void *array, int nelems, VarType type)
00177 {
00178 int items[64];
00179 int i, nitems;
00180
00181 if (str == NULL) {
00182 memset(items, 0, sizeof(items));
00183 nitems = nelems;
00184 } else {
00185 nitems = parse_intlist(str, items, lengthof(items));
00186 if (nitems != nelems) return false;
00187 }
00188
00189 switch (type) {
00190 case SLE_VAR_BL:
00191 case SLE_VAR_I8:
00192 case SLE_VAR_U8:
00193 for (i = 0; i != nitems; i++) ((byte*)array)[i] = items[i];
00194 break;
00195 case SLE_VAR_I16:
00196 case SLE_VAR_U16:
00197 for (i = 0; i != nitems; i++) ((uint16*)array)[i] = items[i];
00198 break;
00199 case SLE_VAR_I32:
00200 case SLE_VAR_U32:
00201 for (i = 0; i != nitems; i++) ((uint32*)array)[i] = items[i];
00202 break;
00203 default: NOT_REACHED();
00204 }
00205
00206 return true;
00207 }
00208
00216 static void make_intlist(char *buf, const char *last, const void *array, int nelems, VarType type)
00217 {
00218 int i, v = 0;
00219 const byte *p = (const byte*)array;
00220
00221 for (i = 0; i != nelems; i++) {
00222 switch (type) {
00223 case SLE_VAR_BL:
00224 case SLE_VAR_I8: v = *(int8*)p; p += 1; break;
00225 case SLE_VAR_U8: v = *(byte*)p; p += 1; break;
00226 case SLE_VAR_I16: v = *(int16*)p; p += 2; break;
00227 case SLE_VAR_U16: v = *(uint16*)p; p += 2; break;
00228 case SLE_VAR_I32: v = *(int32*)p; p += 4; break;
00229 case SLE_VAR_U32: v = *(uint32*)p; p += 4; break;
00230 default: NOT_REACHED();
00231 }
00232 buf += seprintf(buf, last, (i == 0) ? "%d" : ",%d", v);
00233 }
00234 }
00235
00241 static void make_oneofmany(char *buf, const char *last, const char *many, int id)
00242 {
00243 int orig_id = id;
00244
00245
00246 while (--id >= 0) {
00247 for (; *many != '|'; many++) {
00248 if (*many == '\0') {
00249 seprintf(buf, last, "%d", orig_id);
00250 return;
00251 }
00252 }
00253 many++;
00254 }
00255
00256
00257 while (*many != '\0' && *many != '|' && buf < last) *buf++ = *many++;
00258 *buf = '\0';
00259 }
00260
00267 static void make_manyofmany(char *buf, const char *last, const char *many, uint32 x)
00268 {
00269 const char *start;
00270 int i = 0;
00271 bool init = true;
00272
00273 for (; x != 0; x >>= 1, i++) {
00274 start = many;
00275 while (*many != 0 && *many != '|') many++;
00276
00277 if (HasBit(x, 0)) {
00278 if (!init) buf += seprintf(buf, last, "|");
00279 init = false;
00280 if (start == many) {
00281 buf += seprintf(buf, last, "%d", i);
00282 } else {
00283 memcpy(buf, start, many - start);
00284 buf += many - start;
00285 }
00286 }
00287
00288 if (*many == '|') many++;
00289 }
00290
00291 *buf = '\0';
00292 }
00293
00298 static const void *string_to_val(const SettingDescBase *desc, const char *str)
00299 {
00300 switch (desc->cmd) {
00301 case SDT_NUMX: {
00302 char *end;
00303 unsigned long val = strtoul(str, &end, 0);
00304 if (*end != '\0') ShowInfoF("ini: trailing characters at end of setting '%s'", desc->name);
00305 return (void*)val;
00306 }
00307 case SDT_ONEOFMANY: {
00308 long r = lookup_oneofmany(desc->many, str);
00309
00310
00311 if (r == -1 && desc->proc_cnvt != NULL) r = desc->proc_cnvt(str);
00312 if (r != -1) return (void*)r;
00313 ShowInfoF("ini: invalid value '%s' for '%s'", str, desc->name);
00314 return 0;
00315 }
00316 case SDT_MANYOFMANY: {
00317 unsigned long r = lookup_manyofmany(desc->many, str);
00318 if (r != (unsigned long)-1) return (void*)r;
00319 ShowInfoF("ini: invalid value '%s' for '%s'", str, desc->name);
00320 return 0;
00321 }
00322 case SDT_BOOLX:
00323 if (strcmp(str, "true") == 0 || strcmp(str, "on") == 0 || strcmp(str, "1") == 0)
00324 return (void*)true;
00325 if (strcmp(str, "false") == 0 || strcmp(str, "off") == 0 || strcmp(str, "0") == 0)
00326 return (void*)false;
00327 ShowInfoF("ini: invalid setting value '%s' for '%s'", str, desc->name);
00328 break;
00329
00330 case SDT_STRING:
00331 case SDT_INTLIST: return str;
00332 default: break;
00333 }
00334
00335 return NULL;
00336 }
00337
00345 static void Write_ValidateSetting(void *ptr, const SettingDesc *sd, int32 val)
00346 {
00347 const SettingDescBase *sdb = &sd->desc;
00348
00349 if (sdb->cmd != SDT_BOOLX &&
00350 sdb->cmd != SDT_NUMX &&
00351 sdb->cmd != SDT_ONEOFMANY &&
00352 sdb->cmd != SDT_MANYOFMANY) {
00353 return;
00354 }
00355
00356
00357 if (sdb->cmd != SDT_MANYOFMANY) {
00358
00359
00360
00361
00362
00363 switch (GetVarMemType(sd->save.conv)) {
00364 case SLE_VAR_NULL: return;
00365 case SLE_VAR_BL:
00366 case SLE_VAR_I8:
00367 case SLE_VAR_U8:
00368 case SLE_VAR_I16:
00369 case SLE_VAR_U16:
00370 case SLE_VAR_I32: {
00371
00372 if (!(sdb->flags & SGF_0ISDISABLED) || val != 0) val = Clamp(val, sdb->min, sdb->max);
00373 } break;
00374 case SLE_VAR_U32: {
00375
00376 uint min = ((sdb->flags & SGF_0ISDISABLED) && (uint)val <= (uint)sdb->min) ? 0 : sdb->min;
00377 WriteValue(ptr, SLE_VAR_U32, (int64)ClampU(val, min, sdb->max));
00378 return;
00379 }
00380 case SLE_VAR_I64:
00381 case SLE_VAR_U64:
00382 default: NOT_REACHED(); break;
00383 }
00384 }
00385
00386 WriteValue(ptr, sd->save.conv, (int64)val);
00387 }
00388
00395 static void ini_load_settings(IniFile *ini, const SettingDesc *sd, const char *grpname, void *object)
00396 {
00397 IniGroup *group;
00398 IniGroup *group_def = ini->GetGroup(grpname);
00399 IniItem *item;
00400 const void *p;
00401 void *ptr;
00402 const char *s;
00403
00404 for (; sd->save.cmd != SL_END; sd++) {
00405 const SettingDescBase *sdb = &sd->desc;
00406 const SaveLoad *sld = &sd->save;
00407
00408 if (!SlIsObjectCurrentlyValid(sld->version_from, sld->version_to)) continue;
00409
00410
00411 s = strchr(sdb->name, '.');
00412 if (s != NULL) {
00413 group = ini->GetGroup(sdb->name, s - sdb->name);
00414 s++;
00415 } else {
00416 s = sdb->name;
00417 group = group_def;
00418 }
00419
00420 item = group->GetItem(s, false);
00421 if (item == NULL && group != group_def) {
00422
00423
00424 item = group_def->GetItem(s, false);
00425 }
00426 if (item == NULL) {
00427
00428
00429 const char *sc = strchr(s, '.');
00430 if (sc != NULL) item = ini->GetGroup(s, sc - s)->GetItem(sc + 1, false);
00431 }
00432
00433 p = (item == NULL) ? sdb->def : string_to_val(sdb, item->value);
00434 ptr = GetVariableAddress(object, sld);
00435
00436 switch (sdb->cmd) {
00437 case SDT_BOOLX:
00438 case SDT_NUMX:
00439 case SDT_ONEOFMANY:
00440 case SDT_MANYOFMANY:
00441 Write_ValidateSetting(ptr, sd, (unsigned long)p); break;
00442
00443 case SDT_STRING:
00444 switch (GetVarMemType(sld->conv)) {
00445 case SLE_VAR_STRB:
00446 case SLE_VAR_STRBQ:
00447 if (p != NULL) ttd_strlcpy((char*)ptr, (const char*)p, sld->length);
00448 break;
00449 case SLE_VAR_STR:
00450 case SLE_VAR_STRQ:
00451 if (p != NULL) {
00452 free(*(char**)ptr);
00453 *(char**)ptr = strdup((const char*)p);
00454 }
00455 break;
00456 case SLE_VAR_CHAR: *(char*)ptr = *(char*)p; break;
00457 default: NOT_REACHED(); break;
00458 }
00459 break;
00460
00461 case SDT_INTLIST: {
00462 if (!load_intlist((const char*)p, ptr, sld->length, GetVarMemType(sld->conv))) {
00463 ShowInfoF("ini: error in array '%s'", sdb->name);
00464 } else if (sd->desc.proc_cnvt != NULL) {
00465 sd->desc.proc_cnvt((const char*)p);
00466 }
00467 break;
00468 }
00469 default: NOT_REACHED(); break;
00470 }
00471 }
00472 }
00473
00485 static void ini_save_settings(IniFile *ini, const SettingDesc *sd, const char *grpname, void *object)
00486 {
00487 IniGroup *group_def = NULL, *group;
00488 IniItem *item;
00489 char buf[512];
00490 const char *s;
00491 void *ptr;
00492
00493 for (; sd->save.cmd != SL_END; sd++) {
00494 const SettingDescBase *sdb = &sd->desc;
00495 const SaveLoad *sld = &sd->save;
00496
00497
00498
00499 if (!SlIsObjectCurrentlyValid(sld->version_from, sld->version_to)) continue;
00500 if (sld->conv & SLF_CONFIG_NO) continue;
00501
00502
00503 s = strchr(sdb->name, '.');
00504 if (s != NULL) {
00505 group = ini->GetGroup(sdb->name, s - sdb->name);
00506 s++;
00507 } else {
00508 if (group_def == NULL) group_def = ini->GetGroup(grpname);
00509 s = sdb->name;
00510 group = group_def;
00511 }
00512
00513 item = group->GetItem(s, true);
00514 ptr = GetVariableAddress(object, sld);
00515
00516 if (item->value != NULL) {
00517
00518 const void *p = string_to_val(sdb, item->value);
00519
00520
00521
00522 switch (sdb->cmd) {
00523 case SDT_BOOLX:
00524 case SDT_NUMX:
00525 case SDT_ONEOFMANY:
00526 case SDT_MANYOFMANY:
00527 switch (GetVarMemType(sld->conv)) {
00528 case SLE_VAR_BL:
00529 if (*(bool*)ptr == (p != NULL)) continue;
00530 break;
00531 case SLE_VAR_I8:
00532 case SLE_VAR_U8:
00533 if (*(byte*)ptr == (byte)(unsigned long)p) continue;
00534 break;
00535 case SLE_VAR_I16:
00536 case SLE_VAR_U16:
00537 if (*(uint16*)ptr == (uint16)(unsigned long)p) continue;
00538 break;
00539 case SLE_VAR_I32:
00540 case SLE_VAR_U32:
00541 if (*(uint32*)ptr == (uint32)(unsigned long)p) continue;
00542 break;
00543 default: NOT_REACHED();
00544 }
00545 break;
00546 default: break;
00547 }
00548 }
00549
00550
00551 switch (sdb->cmd) {
00552 case SDT_BOOLX:
00553 case SDT_NUMX:
00554 case SDT_ONEOFMANY:
00555 case SDT_MANYOFMANY: {
00556 uint32 i = (uint32)ReadValue(ptr, sld->conv);
00557
00558 switch (sdb->cmd) {
00559 case SDT_BOOLX: strecpy(buf, (i != 0) ? "true" : "false", lastof(buf)); break;
00560 case SDT_NUMX: seprintf(buf, lastof(buf), IsSignedVarMemType(sld->conv) ? "%d" : "%u", i); break;
00561 case SDT_ONEOFMANY: make_oneofmany(buf, lastof(buf), sdb->many, i); break;
00562 case SDT_MANYOFMANY: make_manyofmany(buf, lastof(buf), sdb->many, i); break;
00563 default: NOT_REACHED();
00564 }
00565 } break;
00566
00567 case SDT_STRING:
00568 switch (GetVarMemType(sld->conv)) {
00569 case SLE_VAR_STRB: strecpy(buf, (char*)ptr, lastof(buf)); break;
00570 case SLE_VAR_STRBQ:seprintf(buf, lastof(buf), "\"%s\"", (char*)ptr); break;
00571 case SLE_VAR_STR: strecpy(buf, *(char**)ptr, lastof(buf)); break;
00572 case SLE_VAR_STRQ:
00573 if (*(char**)ptr == NULL) {
00574 buf[0] = '\0';
00575 } else {
00576 seprintf(buf, lastof(buf), "\"%s\"", *(char**)ptr);
00577 }
00578 break;
00579 case SLE_VAR_CHAR: buf[0] = *(char*)ptr; buf[1] = '\0'; break;
00580 default: NOT_REACHED();
00581 }
00582 break;
00583
00584 case SDT_INTLIST:
00585 make_intlist(buf, lastof(buf), ptr, sld->length, GetVarMemType(sld->conv));
00586 break;
00587 default: NOT_REACHED();
00588 }
00589
00590
00591 free(item->value);
00592 item->value = strdup(buf);
00593 }
00594 }
00595
00608 static void ini_load_setting_list(IniFile *ini, const char *grpname, char **list, uint len, SettingListCallbackProc proc)
00609 {
00610 IniGroup *group = ini->GetGroup(grpname);
00611 IniItem *item;
00612 const char *entry;
00613 uint i, j;
00614
00615 if (group == NULL) return;
00616
00617 for (i = j = 0, item = group->item; item != NULL; item = item->next) {
00618 entry = (proc != NULL) ? proc(item, i++) : item->name;
00619
00620 if (entry == NULL || list == NULL) continue;
00621
00622 if (j == len) break;
00623 list[j++] = strdup(entry);
00624 }
00625 }
00626
00636 static void ini_save_setting_list(IniFile *ini, const char *grpname, char **list, uint len, SettingListCallbackProc proc)
00637 {
00638 IniGroup *group = ini->GetGroup(grpname);
00639 const char *entry;
00640 uint i;
00641
00642 if (proc == NULL && list == NULL) return;
00643 if (group == NULL) return;
00644 group->Clear();
00645
00646 for (i = 0; i != len; i++) {
00647 entry = (proc != NULL) ? proc(NULL, i) : list[i];
00648
00649 if (entry == NULL || *entry == '\0') continue;
00650
00651 group->GetItem(entry, true)->SetValue("");
00652 }
00653 }
00654
00655
00656
00657
00658
00695 #define NSD_GENERAL(name, def, cmd, guiflags, min, max, interval, many, str, proc, load)\
00696 {name, (const void*)(def), {cmd}, {guiflags}, min, max, interval, many, str, proc, load}
00697
00698
00699
00700 #define SDTG_GENERAL(name, sdt_cmd, sle_cmd, type, flags, guiflags, var, length, def, min, max, interval, full, str, proc, from, to)\
00701 {NSD_GENERAL(name, def, sdt_cmd, guiflags, min, max, interval, full, str, proc, NULL), SLEG_GENERAL(sle_cmd, var, type | flags, length, from, to)}
00702
00703 #define SDTG_CONDVAR(name, type, flags, guiflags, var, def, min, max, interval, str, proc, from, to)\
00704 SDTG_GENERAL(name, SDT_NUMX, SL_VAR, type, flags, guiflags, var, 0, def, min, max, interval, NULL, str, proc, from, to)
00705 #define SDTG_VAR(name, type, flags, guiflags, var, def, min, max, interval, str, proc)\
00706 SDTG_CONDVAR(name, type, flags, guiflags, var, def, min, max, interval, str, proc, 0, SL_MAX_VERSION)
00707
00708 #define SDTG_CONDBOOL(name, flags, guiflags, var, def, str, proc, from, to)\
00709 SDTG_GENERAL(name, SDT_BOOLX, SL_VAR, SLE_BOOL, flags, guiflags, var, 0, def, 0, 1, 0, NULL, str, proc, from, to)
00710 #define SDTG_BOOL(name, flags, guiflags, var, def, str, proc)\
00711 SDTG_CONDBOOL(name, flags, guiflags, var, def, str, proc, 0, SL_MAX_VERSION)
00712
00713 #define SDTG_CONDLIST(name, type, length, flags, guiflags, var, def, str, proc, from, to)\
00714 SDTG_GENERAL(name, SDT_INTLIST, SL_ARR, type, flags, guiflags, var, length, def, 0, 0, 0, NULL, str, proc, from, to)
00715 #define SDTG_LIST(name, type, flags, guiflags, var, def, str, proc)\
00716 SDTG_GENERAL(name, SDT_INTLIST, SL_ARR, type, flags, guiflags, var, lengthof(var), def, 0, 0, 0, NULL, str, proc, 0, SL_MAX_VERSION)
00717
00718 #define SDTG_CONDSTR(name, type, length, flags, guiflags, var, def, str, proc, from, to)\
00719 SDTG_GENERAL(name, SDT_STRING, SL_STR, type, flags, guiflags, var, length, def, 0, 0, 0, NULL, str, proc, from, to)
00720 #define SDTG_STR(name, type, flags, guiflags, var, def, str, proc)\
00721 SDTG_GENERAL(name, SDT_STRING, SL_STR, type, flags, guiflags, var, lengthof(var), def, 0, 0, 0, NULL, str, proc, 0, SL_MAX_VERSION)
00722
00723 #define SDTG_CONDOMANY(name, type, flags, guiflags, var, def, max, full, str, proc, from, to)\
00724 SDTG_GENERAL(name, SDT_ONEOFMANY, SL_VAR, type, flags, guiflags, var, 0, def, 0, max, 0, full, str, proc, from, to)
00725 #define SDTG_OMANY(name, type, flags, guiflags, var, def, max, full, str, proc)\
00726 SDTG_CONDOMANY(name, type, flags, guiflags, var, def, max, full, str, proc, 0, SL_MAX_VERSION)
00727
00728 #define SDTG_CONDMMANY(name, type, flags, guiflags, var, def, full, str, proc, from, to)\
00729 SDTG_GENERAL(name, SDT_MANYOFMANY, SL_VAR, type, flags, guiflags, var, 0, def, 0, 0, 0, full, str, proc, from, to)
00730 #define SDTG_MMANY(name, type, flags, guiflags, var, def, full, str, proc)\
00731 SDTG_CONDMMANY(name, type, flags, guiflags, var, def, full, str, proc, 0, SL_MAX_VERSION)
00732
00733 #define SDTG_CONDNULL(length, from, to)\
00734 {{"", NULL, {0}, {0}, 0, 0, 0, NULL, STR_NULL, NULL, NULL}, SLEG_CONDNULL(length, from, to)}
00735
00736 #define SDTG_END() {{NULL, NULL, {0}, {0}, 0, 0, 0, NULL, STR_NULL, NULL, NULL}, SLEG_END()}
00737
00738
00739
00740 #define SDT_GENERAL(name, sdt_cmd, sle_cmd, type, flags, guiflags, base, var, length, def, min, max, interval, full, str, proc, load, from, to)\
00741 {NSD_GENERAL(name, def, sdt_cmd, guiflags, min, max, interval, full, str, proc, load), SLE_GENERAL(sle_cmd, base, var, type | flags, length, from, to)}
00742
00743 #define SDT_CONDVAR(base, var, type, from, to, flags, guiflags, def, min, max, interval, str, proc)\
00744 SDT_GENERAL(#var, SDT_NUMX, SL_VAR, type, flags, guiflags, base, var, 1, def, min, max, interval, NULL, str, proc, NULL, from, to)
00745 #define SDT_VAR(base, var, type, flags, guiflags, def, min, max, interval, str, proc)\
00746 SDT_CONDVAR(base, var, type, 0, SL_MAX_VERSION, flags, guiflags, def, min, max, interval, str, proc)
00747
00748 #define SDT_CONDBOOL(base, var, from, to, flags, guiflags, def, str, proc)\
00749 SDT_GENERAL(#var, SDT_BOOLX, SL_VAR, SLE_BOOL, flags, guiflags, base, var, 1, def, 0, 1, 0, NULL, str, proc, NULL, from, to)
00750 #define SDT_BOOL(base, var, flags, guiflags, def, str, proc)\
00751 SDT_CONDBOOL(base, var, 0, SL_MAX_VERSION, flags, guiflags, def, str, proc)
00752
00753 #define SDT_CONDLIST(base, var, type, from, to, flags, guiflags, def, str, proc)\
00754 SDT_GENERAL(#var, SDT_INTLIST, SL_ARR, type, flags, guiflags, base, var, lengthof(((base*)8)->var), def, 0, 0, 0, NULL, str, proc, NULL, from, to)
00755 #define SDT_LIST(base, var, type, flags, guiflags, def, str, proc)\
00756 SDT_CONDLIST(base, var, type, 0, SL_MAX_VERSION, flags, guiflags, def, str, proc)
00757 #define SDT_CONDLISTO(base, var, length, type, from, to, flags, guiflags, def, str, proc, load)\
00758 SDT_GENERAL(#var, SDT_INTLIST, SL_ARR, type, flags, guiflags, base, var, length, def, 0, 0, 0, NULL, str, proc, load, from, to)
00759
00760 #define SDT_CONDSTR(base, var, type, from, to, flags, guiflags, def, str, proc)\
00761 SDT_GENERAL(#var, SDT_STRING, SL_STR, type, flags, guiflags, base, var, lengthof(((base*)8)->var), def, 0, 0, 0, NULL, str, proc, NULL, from, to)
00762 #define SDT_STR(base, var, type, flags, guiflags, def, str, proc)\
00763 SDT_CONDSTR(base, var, type, 0, SL_MAX_VERSION, flags, guiflags, def, str, proc)
00764 #define SDT_CONDSTRO(base, var, length, type, from, to, flags, def, str, proc)\
00765 SDT_GENERAL(#var, SDT_STRING, SL_STR, type, flags, 0, base, var, length, def, 0, 0, NULL, str, proc, from, to)
00766
00767 #define SDT_CONDCHR(base, var, from, to, flags, guiflags, def, str, proc)\
00768 SDT_GENERAL(#var, SDT_STRING, SL_VAR, SLE_CHAR, flags, guiflags, base, var, 1, def, 0, 0, 0, NULL, str, proc, NULL, from, to)
00769 #define SDT_CHR(base, var, flags, guiflags, def, str, proc)\
00770 SDT_CONDCHR(base, var, 0, SL_MAX_VERSION, flags, guiflags, def, str, proc)
00771
00772 #define SDT_CONDOMANY(base, var, type, from, to, flags, guiflags, def, max, full, str, proc, load)\
00773 SDT_GENERAL(#var, SDT_ONEOFMANY, SL_VAR, type, flags, guiflags, base, var, 1, def, 0, max, 0, full, str, proc, load, from, to)
00774 #define SDT_OMANY(base, var, type, flags, guiflags, def, max, full, str, proc, load)\
00775 SDT_CONDOMANY(base, var, type, 0, SL_MAX_VERSION, flags, guiflags, def, max, full, str, proc, load)
00776
00777 #define SDT_CONDMMANY(base, var, type, from, to, flags, guiflags, def, full, str, proc)\
00778 SDT_GENERAL(#var, SDT_MANYOFMANY, SL_VAR, type, flags, guiflags, base, var, 1, def, 0, 0, 0, full, str, proc, NULL, from, to)
00779 #define SDT_MMANY(base, var, type, flags, guiflags, def, full, str, proc)\
00780 SDT_CONDMMANY(base, var, type, 0, SL_MAX_VERSION, flags, guiflags, def, full, str, proc)
00781
00782 #define SDT_CONDNULL(length, from, to)\
00783 {{"", NULL, {0}, {0}, 0, 0, 0, NULL, STR_NULL, NULL, NULL}, SLE_CONDNULL(length, from, to)}
00784
00785
00786 #define SDTC_CONDVAR(var, type, from, to, flags, guiflags, def, min, max, interval, str, proc)\
00787 SDTG_GENERAL(#var, SDT_NUMX, SL_VAR, type, flags, guiflags, _settings_client.var, 1, def, min, max, interval, NULL, str, proc, from, to)
00788 #define SDTC_VAR(var, type, flags, guiflags, def, min, max, interval, str, proc)\
00789 SDTC_CONDVAR(var, type, 0, SL_MAX_VERSION, flags, guiflags, def, min, max, interval, str, proc)
00790
00791 #define SDTC_CONDBOOL(var, from, to, flags, guiflags, def, str, proc)\
00792 SDTG_GENERAL(#var, SDT_BOOLX, SL_VAR, SLE_BOOL, flags, guiflags, _settings_client.var, 1, def, 0, 1, 0, NULL, str, proc, from, to)
00793 #define SDTC_BOOL(var, flags, guiflags, def, str, proc)\
00794 SDTC_CONDBOOL(var, 0, SL_MAX_VERSION, flags, guiflags, def, str, proc)
00795
00796 #define SDTC_CONDLIST(var, type, length, flags, guiflags, def, str, proc, from, to)\
00797 SDTG_GENERAL(#var, SDT_INTLIST, SL_ARR, type, flags, guiflags, _settings_client.var, length, def, 0, 0, 0, NULL, str, proc, from, to)
00798 #define SDTC_LIST(var, type, flags, guiflags, def, str, proc)\
00799 SDTG_GENERAL(#var, SDT_INTLIST, SL_ARR, type, flags, guiflags, _settings_client.var, lengthof(_settings_client.var), def, 0, 0, 0, NULL, str, proc, 0, SL_MAX_VERSION)
00800
00801 #define SDTC_CONDSTR(var, type, length, flags, guiflags, def, str, proc, from, to)\
00802 SDTG_GENERAL(#var, SDT_STRING, SL_STR, type, flags, guiflags, _settings_client.var, length, def, 0, 0, 0, NULL, str, proc, from, to)
00803 #define SDTC_STR(var, type, flags, guiflags, def, str, proc)\
00804 SDTG_GENERAL(#var, SDT_STRING, SL_STR, type, flags, guiflags, _settings_client.var, lengthof(_settings_client.var), def, 0, 0, 0, NULL, str, proc, 0, SL_MAX_VERSION)
00805
00806 #define SDTC_CONDOMANY(var, type, from, to, flags, guiflags, def, max, full, str, proc)\
00807 SDTG_GENERAL(#var, SDT_ONEOFMANY, SL_VAR, type, flags, guiflags, _settings_client.var, 1, def, 0, max, 0, full, str, proc, from, to)
00808 #define SDTC_OMANY(var, type, flags, guiflags, def, max, full, str, proc)\
00809 SDTC_CONDOMANY(var, type, 0, SL_MAX_VERSION, flags, guiflags, def, max, full, str, proc)
00810
00811 #define SDT_END() {{NULL, NULL, {0}, {0}, 0, 0, 0, NULL, STR_NULL, NULL, NULL}, SLE_END()}
00812
00813
00814
00815 #define S SLF_SAVE_NO | SLF_NETWORK_NO
00816 #define C SLF_CONFIG_NO
00817 #define N SLF_NETWORK_NO
00818
00819 #define D0 SGF_0ISDISABLED
00820 #define NC SGF_NOCOMMA
00821 #define MS SGF_MULTISTRING
00822 #define NO SGF_NETWORK_ONLY
00823 #define CR SGF_CURRENCY
00824 #define NN SGF_NO_NETWORK
00825 #define NG SGF_NEWGAME_ONLY
00826
00827
00828
00829 static bool v_PositionMainToolbar(int32 p1)
00830 {
00831 if (_game_mode != GM_MENU) PositionMainToolbar(NULL);
00832 return true;
00833 }
00834
00835 static bool PopulationInLabelActive(int32 p1)
00836 {
00837 Town *t;
00838 FOR_ALL_TOWNS(t) UpdateTownVirtCoord(t);
00839
00840 return true;
00841 }
00842
00843 static bool RedrawScreen(int32 p1)
00844 {
00845 MarkWholeScreenDirty();
00846 return true;
00847 }
00848
00849 static bool InvalidateDetailsWindow(int32 p1)
00850 {
00851 InvalidateWindowClasses(WC_VEHICLE_DETAILS);
00852 return true;
00853 }
00854
00855 static bool InvalidateStationBuildWindow(int32 p1)
00856 {
00857 InvalidateWindow(WC_BUILD_STATION, 0);
00858 return true;
00859 }
00860
00861 static bool InvalidateBuildIndustryWindow(int32 p1)
00862 {
00863 InvalidateWindowData(WC_BUILD_INDUSTRY, 0);
00864 return true;
00865 }
00866
00867 static bool CloseSignalGUI(int32 p1)
00868 {
00869 if (p1 == 0) {
00870 DeleteWindowByClass(WC_BUILD_SIGNAL);
00871 }
00872 return true;
00873 }
00874
00875 static bool InvalidateTownViewWindow(int32 p1)
00876 {
00877 InvalidateWindowClassesData(WC_TOWN_VIEW, p1);
00878 return true;
00879 }
00880
00881 static bool DeleteSelectStationWindow(int32 p1)
00882 {
00883 DeleteWindowById(WC_SELECT_STATION, 0);
00884 return true;
00885 }
00886
00887 static bool UpdateConsists(int32 p1)
00888 {
00889 Vehicle *v;
00890 FOR_ALL_VEHICLES(v) {
00891
00892 if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) TrainConsistChanged(v, true);
00893 }
00894 return true;
00895 }
00896
00897
00898 static bool CheckInterval(int32 p1)
00899 {
00900 VehicleSettings *ptc = (_game_mode == GM_MENU) ? &_settings_newgame.vehicle : &_settings_game.vehicle;
00901
00902 if (p1) {
00903 ptc->servint_trains = 50;
00904 ptc->servint_roadveh = 50;
00905 ptc->servint_aircraft = 50;
00906 ptc->servint_ships = 50;
00907 } else {
00908 ptc->servint_trains = 150;
00909 ptc->servint_roadveh = 150;
00910 ptc->servint_aircraft = 360;
00911 ptc->servint_ships = 100;
00912 }
00913
00914 InvalidateDetailsWindow(0);
00915
00916 return true;
00917 }
00918
00919 static bool EngineRenewUpdate(int32 p1)
00920 {
00921 DoCommandP(0, 0, _settings_client.gui.autorenew, CMD_SET_AUTOREPLACE);
00922 return true;
00923 }
00924
00925 static bool EngineRenewMonthsUpdate(int32 p1)
00926 {
00927 DoCommandP(0, 1, _settings_client.gui.autorenew_months, CMD_SET_AUTOREPLACE);
00928 return true;
00929 }
00930
00931 static bool EngineRenewMoneyUpdate(int32 p1)
00932 {
00933 DoCommandP(0, 2, _settings_client.gui.autorenew_money, CMD_SET_AUTOREPLACE);
00934 return true;
00935 }
00936
00937 static bool TrainAccelerationModelChanged(int32 p1)
00938 {
00939 Vehicle *v;
00940
00941 FOR_ALL_VEHICLES(v) {
00942 if (v->type == VEH_TRAIN && IsFrontEngine(v)) UpdateTrainAcceleration(v);
00943 }
00944
00945 return true;
00946 }
00947
00948 static bool DragSignalsDensityChanged(int32)
00949 {
00950 SetWindowDirty(FindWindowById(WC_BUILD_SIGNAL, 0));
00951
00952 return true;
00953 }
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976 static const DifficultySettings _default_game_diff[3] = {
00977
00978 {2, 2, 4, 300000, 2, 0, 2, 1, 2, 0, 1, 0, 0, 0, 0, 0, 0},
00979 {4, 2, 3, 150000, 3, 1, 3, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1},
00980 {7, 3, 3, 100000, 4, 1, 3, 2, 0, 2, 3, 2, 1, 1, 1, 2, 2},
00981 };
00982
00983 void SetDifficultyLevel(int mode, DifficultySettings *gm_opt)
00984 {
00985 assert(mode <= 3);
00986
00987 if (mode != 3) {
00988 *gm_opt = _default_game_diff[mode];
00989 } else {
00990 gm_opt->diff_level = 3;
00991 }
00992 }
00993
00998 void CheckDifficultyLevels()
00999 {
01000 if (_settings_newgame.difficulty.diff_level != 3) {
01001 SetDifficultyLevel(_settings_newgame.difficulty.diff_level, &_settings_newgame.difficulty);
01002 }
01003 }
01004
01005 static bool DifficultyReset(int32 level)
01006 {
01007 SetDifficultyLevel(level, (_game_mode == GM_MENU) ? &_settings_newgame.difficulty : &_settings_game.difficulty);
01008 return true;
01009 }
01010
01011 static bool DifficultyChange(int32)
01012 {
01013 if (_game_mode == GM_MENU) {
01014 if (_settings_newgame.difficulty.diff_level != 3) {
01015 ShowErrorMessage(INVALID_STRING_ID, STR_DIFFICULTY_TO_CUSTOM, 0, 0);
01016 _settings_newgame.difficulty.diff_level = 3;
01017 }
01018 } else {
01019 _settings_game.difficulty.diff_level = 3;
01020 }
01021
01022
01023
01024
01025 if (_networking && FindWindowById(WC_GAME_OPTIONS, 0) != NULL) {
01026 ShowGameDifficulty();
01027 }
01028
01029 return true;
01030 }
01031
01032 static bool DifficultyNoiseChange(int32 i)
01033 {
01034 if (_game_mode == GM_NORMAL) {
01035 UpdateAirportsNoise();
01036 if (_settings_game.economy.station_noise_level) {
01037 InvalidateWindowClassesData(WC_TOWN_VIEW, 0);
01038 }
01039 }
01040
01041 return DifficultyChange(i);
01042 }
01043
01049 static bool CheckRoadSide(int p1)
01050 {
01051 extern bool RoadVehiclesAreBuilt();
01052 return _game_mode == GM_MENU || !RoadVehiclesAreBuilt();
01053 }
01054
01061 static int32 ConvertLandscape(const char *value)
01062 {
01063
01064 return lookup_oneofmany("normal|hilly|desert|candy", value);
01065 }
01066
01073 static int32 CheckNoiseToleranceLevel(const char *value)
01074 {
01075 GameSettings *s = (_game_mode == GM_MENU) ? &_settings_newgame : &_settings_game;
01076 for (uint16 i = 0; i < lengthof(s->economy.town_noise_population); i++) {
01077 s->economy.town_noise_population[i] = max(uint16(200 * (i + 1)), s->economy.town_noise_population[i]);
01078 }
01079 return 0;
01080 }
01081
01082 static bool CheckFreeformEdges(int32 p1)
01083 {
01084 if (_game_mode == GM_MENU) return true;
01085 if (p1 != 0) {
01086 Vehicle *v;
01087 FOR_ALL_VEHICLES(v) {
01088 if (v->type == VEH_SHIP && (TileX(v->tile) == 0 || TileY(v->tile) == 0)) {
01089 ShowErrorMessage(INVALID_STRING_ID, STR_CONFIG_SETTING_EDGES_NOT_EMPTY, 0, 0);
01090 return false;
01091 }
01092 }
01093 Station *st;
01094 FOR_ALL_STATIONS(st) {
01095 if (TileX(st->xy) == 0 || TileY(st->xy) == 0) {
01096 ShowErrorMessage(INVALID_STRING_ID, STR_CONFIG_SETTING_EDGES_NOT_EMPTY, 0, 0);
01097 return false;
01098 }
01099 }
01100 for (uint i = 0; i < MapSizeX(); i++) MakeVoid(TileXY(i, 0));
01101 for (uint i = 0; i < MapSizeY(); i++) MakeVoid(TileXY(0, i));
01102 } else {
01103 for (uint i = 0; i < MapMaxX(); i++) {
01104 if (TileHeight(TileXY(i, 1)) != 0) {
01105 ShowErrorMessage(INVALID_STRING_ID, STR_CONFIG_SETTING_EDGES_NOT_WATER, 0, 0);
01106 return false;
01107 }
01108 }
01109 for (uint i = 1; i < MapMaxX(); i++) {
01110 if (!IsTileType(TileXY(i, MapMaxY() - 1), MP_WATER) || TileHeight(TileXY(1, MapMaxY())) != 0) {
01111 ShowErrorMessage(INVALID_STRING_ID, STR_CONFIG_SETTING_EDGES_NOT_WATER, 0, 0);
01112 return false;
01113 }
01114 }
01115 for (uint i = 0; i < MapMaxY(); i++) {
01116 if (TileHeight(TileXY(1, i)) != 0) {
01117 ShowErrorMessage(INVALID_STRING_ID, STR_CONFIG_SETTING_EDGES_NOT_WATER, 0, 0);
01118 return false;
01119 }
01120 }
01121 for (uint i = 1; i < MapMaxY(); i++) {
01122 if (!IsTileType(TileXY(MapMaxX() - 1, i), MP_WATER) || TileHeight(TileXY(MapMaxX(), i)) != 0) {
01123 ShowErrorMessage(INVALID_STRING_ID, STR_CONFIG_SETTING_EDGES_NOT_WATER, 0, 0);
01124 return false;
01125 }
01126 }
01127
01128 for (uint i = 0; i < MapMaxX(); i++) {
01129 SetTileHeight(TileXY(i, 0), 0);
01130 SetTileType(TileXY(i, 0), MP_WATER);
01131 }
01132 for (uint i = 0; i < MapMaxY(); i++) {
01133 SetTileHeight(TileXY(0, i), 0);
01134 SetTileType(TileXY(0, i), MP_WATER);
01135 }
01136 }
01137 MarkWholeScreenDirty();
01138 return true;
01139 }
01140
01145 static bool ChangeDynamicEngines(int32 p1)
01146 {
01147 if (_game_mode == GM_MENU) return true;
01148
01149 const Vehicle *v;
01150 FOR_ALL_VEHICLES(v) {
01151 if (IsCompanyBuildableVehicleType(v)) {
01152 ShowErrorMessage(INVALID_STRING_ID, STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES, 0, 0);
01153 return false;
01154 }
01155 }
01156
01157
01158 _engine_mngr.ResetToDefaultMapping();
01159 ReloadNewGRFData();
01160
01161 return true;
01162 }
01163
01164 #ifdef ENABLE_NETWORK
01165
01166 static bool UpdateClientName(int32 p1)
01167 {
01168 NetworkUpdateClientName();
01169 return true;
01170 }
01171
01172 static bool UpdateServerPassword(int32 p1)
01173 {
01174 if (strcmp(_settings_client.network.server_password, "*") == 0) {
01175 _settings_client.network.server_password[0] = '\0';
01176 }
01177
01178 return true;
01179 }
01180
01181 static bool UpdateRconPassword(int32 p1)
01182 {
01183 if (strcmp(_settings_client.network.rcon_password, "*") == 0) {
01184 _settings_client.network.rcon_password[0] = '\0';
01185 }
01186
01187 return true;
01188 }
01189
01190 static bool UpdateClientConfigValues(int32 p1)
01191 {
01192 if (_network_server) NetworkServerSendConfigUpdate();
01193
01194 return true;
01195 }
01196
01197 #endif
01198
01199
01200
01201
01202 static const SettingDesc _music_settings[] = {
01203 SDT_VAR(MusicFileSettings, playlist, SLE_UINT8, S, 0, 0, 0, 5, 1, STR_NULL, NULL),
01204 SDT_VAR(MusicFileSettings, music_vol, SLE_UINT8, S, 0, 127, 0, 127, 1, STR_NULL, NULL),
01205 SDT_VAR(MusicFileSettings, effect_vol, SLE_UINT8, S, 0, 127, 0, 127, 1, STR_NULL, NULL),
01206 SDT_LIST(MusicFileSettings, custom_1, SLE_UINT8, S, 0, NULL, STR_NULL, NULL),
01207 SDT_LIST(MusicFileSettings, custom_2, SLE_UINT8, S, 0, NULL, STR_NULL, NULL),
01208 SDT_BOOL(MusicFileSettings, playing, S, 0, true, STR_NULL, NULL),
01209 SDT_BOOL(MusicFileSettings, shuffle, S, 0, false, STR_NULL, NULL),
01210 SDT_END()
01211 };
01212
01213
01214 #if defined(WIN32) && !defined(DEDICATED)
01215 extern bool _force_full_redraw, _window_maximize;
01216 extern uint _display_hz, _fullscreen_bpp;
01217
01218 static const SettingDescGlobVarList _win32_settings[] = {
01219 SDTG_VAR("display_hz", SLE_UINT, S, 0, _display_hz, 0, 0, 120, 0, STR_NULL, NULL),
01220 SDTG_BOOL("force_full_redraw", S, 0, _force_full_redraw,false, STR_NULL, NULL),
01221 SDTG_VAR("fullscreen_bpp", SLE_UINT, S, 0, _fullscreen_bpp, 8, 8, 32, 0, STR_NULL, NULL),
01222 SDTG_BOOL("window_maximize", S, 0, _window_maximize, false, STR_NULL, NULL),
01223 SDTG_END()
01224 };
01225 #endif
01226
01227 static const SettingDescGlobVarList _misc_settings[] = {
01228 SDTG_MMANY("display_opt", SLE_UINT8, S, 0, _display_opt, (1 << DO_SHOW_TOWN_NAMES | 1 << DO_SHOW_STATION_NAMES | 1 << DO_SHOW_SIGNS | 1 << DO_FULL_ANIMATION | 1 << DO_FULL_DETAIL | 1 << DO_WAYPOINTS), "SHOW_TOWN_NAMES|SHOW_STATION_NAMES|SHOW_SIGNS|FULL_ANIMATION||FULL_DETAIL|WAYPOINTS", STR_NULL, NULL),
01229 SDTG_BOOL("news_ticker_sound", S, 0, _news_ticker_sound, true, STR_NULL, NULL),
01230 SDTG_BOOL("fullscreen", S, 0, _fullscreen, false, STR_NULL, NULL),
01231 SDTG_STR("graphicsset", SLE_STRQ, S, 0, _ini_graphics_set, NULL, STR_NULL, NULL),
01232 SDTG_STR("videodriver", SLE_STRQ, S, 0, _ini_videodriver, NULL, STR_NULL, NULL),
01233 SDTG_STR("musicdriver", SLE_STRQ, S, 0, _ini_musicdriver, NULL, STR_NULL, NULL),
01234 SDTG_STR("sounddriver", SLE_STRQ, S, 0, _ini_sounddriver, NULL, STR_NULL, NULL),
01235 SDTG_STR("blitter", SLE_STRQ, S, 0, _ini_blitter, NULL, STR_NULL, NULL),
01236 SDTG_STR("language", SLE_STRB, S, 0, _dynlang.curr_file, NULL, STR_NULL, NULL),
01237 SDTG_CONDLIST("resolution", SLE_INT, 2, S, 0, _cur_resolution, "640,480", STR_NULL, NULL, 0, SL_MAX_VERSION),
01238 SDTG_STR("screenshot_format",SLE_STRB, S, 0, _screenshot_format_name,NULL, STR_NULL, NULL),
01239 SDTG_STR("savegame_format", SLE_STRB, S, 0, _savegame_format, NULL, STR_NULL, NULL),
01240 SDTG_BOOL("rightclick_emulate", S, 0, _rightclick_emulate, false, STR_NULL, NULL),
01241 #ifdef WITH_FREETYPE
01242 SDTG_STR("small_font", SLE_STRB, S, 0, _freetype.small_font, NULL, STR_NULL, NULL),
01243 SDTG_STR("medium_font", SLE_STRB, S, 0, _freetype.medium_font, NULL, STR_NULL, NULL),
01244 SDTG_STR("large_font", SLE_STRB, S, 0, _freetype.large_font, NULL, STR_NULL, NULL),
01245 SDTG_VAR("small_size", SLE_UINT, S, 0, _freetype.small_size, 6, 0, 72, 0, STR_NULL, NULL),
01246 SDTG_VAR("medium_size", SLE_UINT, S, 0, _freetype.medium_size, 10, 0, 72, 0, STR_NULL, NULL),
01247 SDTG_VAR("large_size", SLE_UINT, S, 0, _freetype.large_size, 16, 0, 72, 0, STR_NULL, NULL),
01248 SDTG_BOOL("small_aa", S, 0, _freetype.small_aa, false, STR_NULL, NULL),
01249 SDTG_BOOL("medium_aa", S, 0, _freetype.medium_aa, false, STR_NULL, NULL),
01250 SDTG_BOOL("large_aa", S, 0, _freetype.large_aa, false, STR_NULL, NULL),
01251 #endif
01252 SDTG_VAR("sprite_cache_size",SLE_UINT, S, 0, _sprite_cache_size, 4, 1, 64, 0, STR_NULL, NULL),
01253 SDTG_VAR("player_face", SLE_UINT32, S, 0, _company_manager_face,0,0,0xFFFFFFFF,0, STR_NULL, NULL),
01254 SDTG_VAR("transparency_options", SLE_UINT, S, 0, _transparency_opt, 0,0,0x1FF,0, STR_NULL, NULL),
01255 SDTG_VAR("transparency_locks", SLE_UINT, S, 0, _transparency_lock, 0,0,0x1FF,0, STR_NULL, NULL),
01256 SDTG_VAR("invisibility_options", SLE_UINT, S, 0, _invisibility_opt, 0,0, 0xFF,0, STR_NULL, NULL),
01257 SDTG_STR("keyboard", SLE_STRB, S, 0, _keyboard_opt[0], NULL, STR_NULL, NULL),
01258 SDTG_STR("keyboard_caps", SLE_STRB, S, 0, _keyboard_opt[1], NULL, STR_NULL, NULL),
01259 SDTG_END()
01260 };
01261
01262 static const uint GAME_DIFFICULTY_NUM = 18;
01263 uint16 _old_diff_custom[GAME_DIFFICULTY_NUM];
01264
01265
01266
01267 static const char *_locale_currencies = "GBP|USD|EUR|YEN|ATS|BEF|CHF|CZK|DEM|DKK|ESP|FIM|FRF|GRD|HUF|ISK|ITL|NLG|NOK|PLN|RON|RUR|SIT|SEK|YTL|SKK|BRL|EEK|custom";
01268 static const char *_locale_units = "imperial|metric|si";
01269 static const char *_town_names = "english|french|german|american|latin|silly|swedish|dutch|finnish|polish|slovak|norwegian|hungarian|austrian|romanian|czech|swiss|danish|turkish|italian|catalan";
01270 static const char *_climates = "temperate|arctic|tropic|toyland";
01271 static const char *_autosave_interval = "off|monthly|quarterly|half year|yearly";
01272 static const char *_roadsides = "left|right";
01273 static const char *_savegame_date = "long|short|iso";
01274 #ifdef ENABLE_NETWORK
01275 static const char *_server_langs = "ANY|ENGLISH|GERMAN|FRENCH|BRAZILIAN|BULGARIAN|CHINESE|CZECH|DANISH|DUTCH|ESPERANTO|FINNISH|HUNGARIAN|ICELANDIC|ITALIAN|JAPANESE|KOREAN|LITHUANIAN|NORWEGIAN|POLISH|PORTUGUESE|ROMANIAN|RUSSIAN|SLOVAK|SLOVENIAN|SPANISH|SWEDISH|TURKISH|UKRAINIAN|AFRIKAANS|CROATIAN|CATALAN|ESTONIAN|GALICIAN|GREEK|LATVIAN";
01276 #endif
01277
01278 static const SettingDesc _gameopt_settings[] = {
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288 SDTG_GENERAL("diff_custom", SDT_INTLIST, SL_ARR, SLE_FILE_I16 | SLE_VAR_U16, C, 0, _old_diff_custom, 17, 0, 0, 0, 0, NULL, STR_NULL, NULL, 0, 3),
01289 SDTG_GENERAL("diff_custom", SDT_INTLIST, SL_ARR, SLE_UINT16, C, 0, _old_diff_custom, 18, 0, 0, 0, 0, NULL, STR_NULL, NULL, 4, SL_MAX_VERSION),
01290
01291 SDT_VAR(GameSettings, difficulty.diff_level, SLE_UINT8, 0, 0, 0, 0, 3, 0, STR_NULL, NULL),
01292 SDT_OMANY(GameSettings, locale.currency, SLE_UINT8, N, 0, 0, CUSTOM_CURRENCY_ID, _locale_currencies, STR_NULL, NULL, NULL),
01293 SDT_OMANY(GameSettings, locale.units, SLE_UINT8, N, 0, 1, 2, _locale_units, STR_NULL, NULL, NULL),
01294
01295 SDT_OMANY(GameSettings, game_creation.town_name, SLE_UINT8, 0, 0, 0, 255, _town_names, STR_NULL, NULL, NULL),
01296 SDT_OMANY(GameSettings, game_creation.landscape, SLE_UINT8, 0, 0, 0, 3, _climates, STR_NULL, NULL, ConvertLandscape),
01297 SDT_VAR(GameSettings, game_creation.snow_line, SLE_UINT8, 0, 0, 7 * TILE_HEIGHT, 2 * TILE_HEIGHT, 13 * TILE_HEIGHT, 0, STR_NULL, NULL),
01298 SDT_CONDNULL( 1, 0, 22),
01299 SDTC_CONDOMANY( gui.autosave, SLE_UINT8, 23, SL_MAX_VERSION, S, 0, 1, 4, _autosave_interval, STR_NULL, NULL),
01300 SDT_OMANY(GameSettings, vehicle.road_side, SLE_UINT8, 0, 0, 1, 1, _roadsides, STR_NULL, NULL, NULL),
01301 SDT_END()
01302 };
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313 const SettingDesc _settings[] = {
01314
01315
01316
01317 SDT_CONDVAR(GameSettings, difficulty.max_no_competitors, SLE_UINT8, 97, SL_MAX_VERSION, 0, 0, 2,0,MAX_COMPANIES-1,1,STR_NULL, DifficultyChange),
01318 SDT_CONDNULL( 1, 97, 109),
01319 SDT_CONDVAR(GameSettings, difficulty.number_towns, SLE_UINT8, 97, SL_MAX_VERSION, 0,NG, 2, 0, 4, 1, STR_NUM_VERY_LOW, DifficultyChange),
01320 SDT_CONDVAR(GameSettings, difficulty.number_industries, SLE_UINT8, 97, SL_MAX_VERSION, 0,NG, 4, 0, 4, 1, STR_NONE, DifficultyChange),
01321 SDT_CONDVAR(GameSettings, difficulty.max_loan, SLE_UINT32, 97, SL_MAX_VERSION, 0,NG|CR,300000,100000,500000,50000,STR_NULL, DifficultyChange),
01322 SDT_CONDVAR(GameSettings, difficulty.initial_interest, SLE_UINT8, 97, SL_MAX_VERSION, 0,NG, 2, 2, 4, 1, STR_NULL, DifficultyChange),
01323 SDT_CONDVAR(GameSettings, difficulty.vehicle_costs, SLE_UINT8, 97, SL_MAX_VERSION, 0, 0, 0, 0, 2, 1, STR_6820_LOW, DifficultyChange),
01324 SDT_CONDVAR(GameSettings, difficulty.competitor_speed, SLE_UINT8, 97, SL_MAX_VERSION, 0, 0, 2, 0, 4, 1, STR_681B_VERY_SLOW, DifficultyChange),
01325 SDT_CONDNULL( 1, 97, 109),
01326 SDT_CONDVAR(GameSettings, difficulty.vehicle_breakdowns, SLE_UINT8, 97, SL_MAX_VERSION, 0, 0, 1, 0, 2, 1, STR_6823_NONE, DifficultyChange),
01327 SDT_CONDVAR(GameSettings, difficulty.subsidy_multiplier, SLE_UINT8, 97, SL_MAX_VERSION, 0, 0, 2, 0, 3, 1, STR_6826_X1_5, DifficultyChange),
01328 SDT_CONDVAR(GameSettings, difficulty.construction_cost, SLE_UINT8, 97, SL_MAX_VERSION, 0,NG, 0, 0, 2, 1, STR_6820_LOW, DifficultyChange),
01329 SDT_CONDVAR(GameSettings, difficulty.terrain_type, SLE_UINT8, 97, SL_MAX_VERSION, 0,NG, 1, 0, 3, 1, STR_682A_VERY_FLAT, DifficultyChange),
01330 SDT_CONDVAR(GameSettings, difficulty.quantity_sea_lakes, SLE_UINT8, 97, SL_MAX_VERSION, 0,NG, 0, 0, 3, 1, STR_VERY_LOW, DifficultyChange),
01331 SDT_CONDVAR(GameSettings, difficulty.economy, SLE_UINT8, 97, SL_MAX_VERSION, 0, 0, 0, 0, 1, 1, STR_682E_STEADY, DifficultyChange),
01332 SDT_CONDVAR(GameSettings, difficulty.line_reverse_mode, SLE_UINT8, 97, SL_MAX_VERSION, 0, 0, 0, 0, 1, 1, STR_6834_AT_END_OF_LINE_AND_AT_STATIONS, DifficultyChange),
01333 SDT_CONDVAR(GameSettings, difficulty.disasters, SLE_UINT8, 97, SL_MAX_VERSION, 0, 0, 0, 0, 1, 1, STR_6836_OFF, DifficultyChange),
01334 SDT_CONDVAR(GameSettings, difficulty.town_council_tolerance, SLE_UINT8, 97, SL_MAX_VERSION, 0, 0, 0, 0, 2, 1, STR_PERMISSIVE, DifficultyNoiseChange),
01335 SDT_CONDVAR(GameSettings, difficulty.diff_level, SLE_UINT8, 97, SL_MAX_VERSION, 0,NG, 0, 0, 3, 0, STR_NULL, DifficultyReset),
01336
01337
01338 SDT_CONDOMANY(GameSettings, game_creation.town_name, SLE_UINT8, 97, SL_MAX_VERSION, 0,NN, 0, 255, _town_names, STR_NULL, NULL, NULL),
01339 SDT_CONDOMANY(GameSettings, game_creation.landscape, SLE_UINT8, 97, SL_MAX_VERSION, 0,NN, 0, 3, _climates, STR_NULL, NULL, ConvertLandscape),
01340 SDT_CONDVAR(GameSettings, game_creation.snow_line, SLE_UINT8, 97, SL_MAX_VERSION, 0,NN, 7 * TILE_HEIGHT, 2 * TILE_HEIGHT, 13 * TILE_HEIGHT, 0, STR_NULL, NULL),
01341 SDT_CONDOMANY(GameSettings, vehicle.road_side, SLE_UINT8, 97, SL_MAX_VERSION, 0,NN, 1, 1, _roadsides, STR_NULL, CheckRoadSide, NULL),
01342
01343 SDT_BOOL(GameSettings, construction.build_on_slopes, 0,NN, true, STR_CONFIG_SETTING_BUILDONSLOPES, NULL),
01344 SDT_CONDBOOL(GameSettings, construction.autoslope, 75, SL_MAX_VERSION, 0, 0, true, STR_CONFIG_SETTING_AUTOSLOPE, NULL),
01345 SDT_BOOL(GameSettings, construction.extra_dynamite, 0, 0, false, STR_CONFIG_SETTING_EXTRADYNAMITE, NULL),
01346 SDT_BOOL(GameSettings, construction.longbridges, 0,NN, true, STR_CONFIG_SETTING_LONGBRIDGES, NULL),
01347 SDT_BOOL(GameSettings, construction.signal_side, N,NN, true, STR_CONFIG_SETTING_SIGNALSIDE, RedrawScreen),
01348 SDT_BOOL(GameSettings, station.always_small_airport, 0,NN, false, STR_CONFIG_SETTING_SMALL_AIRPORTS, NULL),
01349 SDT_CONDVAR(GameSettings, economy.town_layout, SLE_UINT8, 59, SL_MAX_VERSION, 0,MS,TL_ORIGINAL,TL_BEGIN,NUM_TLS-1,1, STR_CONFIG_SETTING_TOWN_LAYOUT, NULL),
01350 SDT_CONDBOOL(GameSettings, economy.allow_town_roads, 113, SL_MAX_VERSION, 0, 0, true, STR_CONFIG_SETTING_ALLOW_TOWN_ROADS, NULL),
01351
01352 SDT_VAR(GameSettings, vehicle.train_acceleration_model, SLE_UINT8, 0,MS, 0, 0, 1, 1, STR_CONFIG_SETTING_TRAIN_ACCELERATION_MODEL, TrainAccelerationModelChanged),
01353 SDT_BOOL(GameSettings, pf.forbid_90_deg, 0, 0, false, STR_CONFIG_SETTING_FORBID_90_DEG, NULL),
01354 SDT_BOOL(GameSettings, vehicle.mammoth_trains, 0,NN, true, STR_CONFIG_SETTING_MAMMOTHTRAINS, NULL),
01355 SDT_BOOL(GameSettings, order.gotodepot, 0, 0, true, STR_CONFIG_SETTING_GOTODEPOT, NULL),
01356 SDT_BOOL(GameSettings, pf.roadveh_queue, 0, 0, true, STR_CONFIG_SETTING_ROADVEH_QUEUE, NULL),
01357
01358 SDT_CONDBOOL(GameSettings, pf.new_pathfinding_all, 0, 86, 0, 0, false, STR_NULL, NULL),
01359 SDT_CONDBOOL(GameSettings, pf.yapf.ship_use_yapf, 28, 86, 0, 0, false, STR_NULL, NULL),
01360 SDT_CONDBOOL(GameSettings, pf.yapf.road_use_yapf, 28, 86, 0, 0, true, STR_NULL, NULL),
01361 SDT_CONDBOOL(GameSettings, pf.yapf.rail_use_yapf, 28, 86, 0, 0, true, STR_NULL, NULL),
01362
01363 SDT_CONDVAR(GameSettings, pf.pathfinder_for_trains, SLE_UINT8, 87, SL_MAX_VERSION, 0, MS, 2, 0, 2, 1, STR_CONFIG_SETTING_PATHFINDER_FOR_TRAINS, NULL),
01364 SDT_CONDVAR(GameSettings, pf.pathfinder_for_roadvehs, SLE_UINT8, 87, SL_MAX_VERSION, 0, MS, 2, 0, 2, 1, STR_CONFIG_SETTING_PATHFINDER_FOR_ROADVEH, NULL),
01365 SDT_CONDVAR(GameSettings, pf.pathfinder_for_ships, SLE_UINT8, 87, SL_MAX_VERSION, 0, MS, 0, 0, 2, 1, STR_CONFIG_SETTING_PATHFINDER_FOR_SHIPS, NULL),
01366
01367 SDT_BOOL(GameSettings, vehicle.never_expire_vehicles, 0,NN, false, STR_CONFIG_SETTING_NEVER_EXPIRE_VEHICLES, NULL),
01368 SDT_VAR(GameSettings, vehicle.max_trains, SLE_UINT16, 0, 0, 500, 0, 5000, 0, STR_CONFIG_SETTING_MAX_TRAINS, RedrawScreen),
01369 SDT_VAR(GameSettings, vehicle.max_roadveh, SLE_UINT16, 0, 0, 500, 0, 5000, 0, STR_CONFIG_SETTING_MAX_ROADVEH, RedrawScreen),
01370 SDT_VAR(GameSettings, vehicle.max_aircraft, SLE_UINT16, 0, 0, 200, 0, 5000, 0, STR_CONFIG_SETTING_MAX_AIRCRAFT, RedrawScreen),
01371 SDT_VAR(GameSettings, vehicle.max_ships, SLE_UINT16, 0, 0, 300, 0, 5000, 0, STR_CONFIG_SETTING_MAX_SHIPS, RedrawScreen),
01372 SDT_BOOL(GameSettings, vehicle.servint_ispercent, 0,NN, false, STR_CONFIG_SETTING_SERVINT_ISPERCENT, CheckInterval),
01373 SDT_VAR(GameSettings, vehicle.servint_trains, SLE_UINT16, 0,D0, 150, 5, 800, 0, STR_CONFIG_SETTING_SERVINT_TRAINS, InvalidateDetailsWindow),
01374 SDT_VAR(GameSettings, vehicle.servint_roadveh, SLE_UINT16, 0,D0, 150, 5, 800, 0, STR_CONFIG_SETTING_SERVINT_ROADVEH, InvalidateDetailsWindow),
01375 SDT_VAR(GameSettings, vehicle.servint_ships, SLE_UINT16, 0,D0, 360, 5, 800, 0, STR_CONFIG_SETTING_SERVINT_SHIPS, InvalidateDetailsWindow),
01376 SDT_VAR(GameSettings, vehicle.servint_aircraft, SLE_UINT16, 0,D0, 100, 5, 800, 0, STR_CONFIG_SETTING_SERVINT_AIRCRAFT, InvalidateDetailsWindow),
01377 SDT_BOOL(GameSettings, order.no_servicing_if_no_breakdowns, 0, 0, false, STR_CONFIG_SETTING_NOSERVICE, NULL),
01378 SDT_BOOL(GameSettings, vehicle.wagon_speed_limits, 0,NN, true, STR_CONFIG_SETTING_WAGONSPEEDLIMITS, UpdateConsists),
01379 SDT_CONDBOOL(GameSettings, vehicle.disable_elrails, 38, SL_MAX_VERSION, 0,NN, false, STR_CONFIG_SETTING_DISABLE_ELRAILS, SettingsDisableElrail),
01380 SDT_CONDVAR(GameSettings, vehicle.freight_trains, SLE_UINT8, 39, SL_MAX_VERSION, 0,NN, 1, 1, 255, 1, STR_CONFIG_SETTING_FREIGHT_TRAINS, NULL),
01381 SDT_CONDBOOL(GameSettings, order.timetabling, 67, SL_MAX_VERSION, 0, 0, true, STR_CONFIG_SETTING_TIMETABLE_ALLOW, NULL),
01382 SDT_CONDVAR(GameSettings, vehicle.plane_speed, SLE_UINT8, 90, SL_MAX_VERSION, 0, 0, 4, 1, 4, 0, STR_CONFIG_SETTING_PLANE_SPEED, NULL),
01383 SDT_CONDBOOL(GameSettings, vehicle.dynamic_engines, 95, SL_MAX_VERSION, 0,NN, false, STR_CONFIG_SETTING_DYNAMIC_ENGINES, ChangeDynamicEngines),
01384
01385 SDT_BOOL(GameSettings, station.join_stations, 0, 0, true, STR_CONFIG_SETTING_JOINSTATIONS, NULL),
01386 SDTC_CONDBOOL( gui.sg_full_load_any, 22, 92, 0, 0, true, STR_NULL, NULL),
01387 SDT_BOOL(GameSettings, order.improved_load, 0,NN, true, STR_CONFIG_SETTING_IMPROVEDLOAD, NULL),
01388 SDT_BOOL(GameSettings, order.selectgoods, 0, 0, true, STR_CONFIG_SETTING_SELECTGOODS, NULL),
01389 SDTC_CONDBOOL( gui.sg_new_nonstop, 22, 92, 0, 0, false, STR_NULL, NULL),
01390 SDT_BOOL(GameSettings, station.nonuniform_stations, 0,NN, true, STR_CONFIG_SETTING_NONUNIFORM_STATIONS, NULL),
01391 SDT_VAR(GameSettings, station.station_spread, SLE_UINT8, 0, 0, 12, 4, 64, 0, STR_CONFIG_SETTING_STATION_SPREAD, InvalidateStationBuildWindow),
01392 SDT_BOOL(GameSettings, order.serviceathelipad, 0, 0, true, STR_CONFIG_SETTING_SERVICEATHELIPAD, NULL),
01393 SDT_BOOL(GameSettings, station.modified_catchment, 0, 0, true, STR_CONFIG_SETTING_CATCHMENT, NULL),
01394 SDT_CONDBOOL(GameSettings, order.gradual_loading, 40, SL_MAX_VERSION, 0, 0, true, STR_CONFIG_SETTING_GRADUAL_LOADING, NULL),
01395 SDT_CONDBOOL(GameSettings, construction.road_stop_on_town_road, 47, SL_MAX_VERSION, 0, 0, true, STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD, NULL),
01396 SDT_CONDBOOL(GameSettings, construction.road_stop_on_competitor_road, 114, SL_MAX_VERSION, 0, 0, true, STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD,NULL),
01397 SDT_CONDBOOL(GameSettings, station.adjacent_stations, 62, SL_MAX_VERSION, 0, 0, true, STR_CONFIG_SETTING_ADJACENT_STATIONS, NULL),
01398 SDT_CONDBOOL(GameSettings, economy.station_noise_level, 96, SL_MAX_VERSION, 0, 0, false, STR_CONFIG_SETTING_NOISE_LEVEL, InvalidateTownViewWindow),
01399 SDT_CONDBOOL(GameSettings, station.distant_join_stations, 106, SL_MAX_VERSION, 0, 0, true, STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS, DeleteSelectStationWindow),
01400
01401 SDT_BOOL(GameSettings, economy.inflation, 0, 0, true, STR_CONFIG_SETTING_INFLATION, NULL),
01402 SDT_VAR(GameSettings, construction.raw_industry_construction, SLE_UINT8, 0,MS, 0, 0, 2, 0, STR_CONFIG_SETTING_RAW_INDUSTRY_CONSTRUCTION_METHOD, InvalidateBuildIndustryWindow),
01403 SDT_BOOL(GameSettings, economy.multiple_industry_per_town, 0, 0, false, STR_CONFIG_SETTING_MULTIPINDTOWN, NULL),
01404 SDT_BOOL(GameSettings, economy.same_industry_close, 0, 0, false, STR_CONFIG_SETTING_SAMEINDCLOSE, NULL),
01405 SDT_BOOL(GameSettings, economy.bribe, 0, 0, true, STR_CONFIG_SETTING_BRIBE, NULL),
01406 SDT_CONDBOOL(GameSettings, economy.exclusive_rights, 79, SL_MAX_VERSION, 0, 0, true, STR_CONFIG_SETTING_ALLOW_EXCLUSIVE, NULL),
01407 SDT_CONDBOOL(GameSettings, economy.give_money, 79, SL_MAX_VERSION, 0, 0, true, STR_CONFIG_SETTING_ALLOW_GIVE_MONEY, NULL),
01408 SDT_VAR(GameSettings, game_creation.snow_line_height, SLE_UINT8, 0, 0, 7, 2, 13, 0, STR_CONFIG_SETTING_SNOWLINE_HEIGHT, NULL),
01409 SDTC_VAR( gui.coloured_news_year, SLE_INT32, 0,NC, 2000,MIN_YEAR,MAX_YEAR,1,STR_CONFIG_SETTING_COLOURED_NEWS_YEAR, NULL),
01410 SDT_VAR(GameSettings, game_creation.starting_year, SLE_INT32, 0,NC, 1950,MIN_YEAR,MAX_YEAR,1,STR_CONFIG_SETTING_STARTING_YEAR, NULL),
01411 SDT_CONDNULL( 4, 0, 104),
01412 SDT_BOOL(GameSettings, economy.smooth_economy, 0, 0, true, STR_CONFIG_SETTING_SMOOTH_ECONOMY, NULL),
01413 SDT_BOOL(GameSettings, economy.allow_shares, 0, 0, false, STR_CONFIG_SETTING_ALLOW_SHARES, NULL),
01414 SDT_CONDVAR(GameSettings, economy.town_growth_rate, SLE_UINT8, 54, SL_MAX_VERSION, 0, MS, 2, 0, 4, 0, STR_CONFIG_SETTING_TOWN_GROWTH, NULL),
01415 SDT_CONDVAR(GameSettings, economy.larger_towns, SLE_UINT8, 54, SL_MAX_VERSION, 0, D0, 4, 0, 255, 1, STR_CONFIG_SETTING_LARGER_TOWNS, NULL),
01416 SDT_CONDVAR(GameSettings, economy.initial_city_size, SLE_UINT8, 56, SL_MAX_VERSION, 0, 0, 2, 1, 10, 1, STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER, NULL),
01417 SDT_CONDBOOL(GameSettings, economy.mod_road_rebuild, 77, SL_MAX_VERSION, 0, 0, false, STR_CONFIG_SETTING_MODIFIED_ROAD_REBUILD, NULL),
01418
01419 SDT_CONDNULL(1, 0, 106),
01420 SDT_BOOL(GameSettings, ai.ai_in_multiplayer, 0, 0, true, STR_CONFIG_SETTING_AI_IN_MULTIPLAYER, NULL),
01421 SDT_BOOL(GameSettings, ai.ai_disable_veh_train, 0, 0, false, STR_CONFIG_SETTING_AI_BUILDS_TRAINS, NULL),
01422 SDT_BOOL(GameSettings, ai.ai_disable_veh_roadveh, 0, 0, false, STR_CONFIG_SETTING_AI_BUILDS_ROADVEH, NULL),
01423 SDT_BOOL(GameSettings, ai.ai_disable_veh_aircraft, 0, 0, false, STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT, NULL),
01424 SDT_BOOL(GameSettings, ai.ai_disable_veh_ship, 0, 0, false, STR_CONFIG_SETTING_AI_BUILDS_SHIPS, NULL),
01425 SDT_CONDVAR(GameSettings, ai.ai_max_opcode_till_suspend, SLE_UINT32,107, SL_MAX_VERSION, 0, NG, 10000, 5000,250000,2500, STR_CONFIG_SETTING_AI_MAX_OPCODES, NULL),
01426
01427 SDT_VAR(GameSettings, vehicle.extend_vehicle_life, SLE_UINT8, 0, 0, 0, 0, 100, 0, STR_NULL, NULL),
01428 SDT_VAR(GameSettings, economy.dist_local_authority, SLE_UINT8, 0, 0, 20, 5, 60, 0, STR_NULL, NULL),
01429 SDT_VAR(GameSettings, pf.wait_oneway_signal, SLE_UINT8, 0, 0, 15, 2, 255, 0, STR_NULL, NULL),
01430 SDT_VAR(GameSettings, pf.wait_twoway_signal, SLE_UINT8, 0, 0, 41, 2, 255, 0, STR_NULL, NULL),
01431 SDT_CONDLISTO(GameSettings, economy.town_noise_population, 3, SLE_UINT16, 96, SL_MAX_VERSION, 0,D0, "800,2000,4000", STR_NULL, NULL, CheckNoiseToleranceLevel),
01432
01433 SDT_CONDVAR(GameSettings, pf.wait_for_pbs_path, SLE_UINT8,100, SL_MAX_VERSION, 0, 0, 30, 2, 255, 0, STR_NULL, NULL),
01434 SDT_CONDBOOL(GameSettings, pf.reserve_paths, 100, SL_MAX_VERSION, 0, 0, false, STR_NULL, NULL),
01435 SDT_CONDVAR(GameSettings, pf.path_backoff_interval, SLE_UINT8,100, SL_MAX_VERSION, 0, 0, 20, 1, 255, 0, STR_NULL, NULL),
01436
01437 SDT_VAR(GameSettings, pf.opf.pf_maxlength, SLE_UINT16, 0, 0, 4096, 64, 65535, 0, STR_NULL, NULL),
01438 SDT_VAR(GameSettings, pf.opf.pf_maxdepth, SLE_UINT8, 0, 0, 48, 4, 255, 0, STR_NULL, NULL),
01439
01440 SDT_VAR(GameSettings, pf.npf.npf_max_search_nodes, SLE_UINT, 0, 0, 10000, 500, 100000, 0, STR_NULL, NULL),
01441 SDT_VAR(GameSettings, pf.npf.npf_rail_firstred_penalty, SLE_UINT, 0, 0, ( 10 * NPF_TILE_LENGTH), 0, 100000, 0, STR_NULL, NULL),
01442 SDT_VAR(GameSettings, pf.npf.npf_rail_firstred_exit_penalty, SLE_UINT, 0, 0, (100 * NPF_TILE_LENGTH), 0, 100000, 0, STR_NULL, NULL),
01443 SDT_VAR(GameSettings, pf.npf.npf_rail_lastred_penalty, SLE_UINT, 0, 0, ( 10 * NPF_TILE_LENGTH), 0, 100000, 0, STR_NULL, NULL),
01444 SDT_VAR(GameSettings, pf.npf.npf_rail_station_penalty, SLE_UINT, 0, 0, ( 1 * NPF_TILE_LENGTH), 0, 100000, 0, STR_NULL, NULL),
01445 SDT_VAR(GameSettings, pf.npf.npf_rail_slope_penalty, SLE_UINT, 0, 0, ( 1 * NPF_TILE_LENGTH), 0, 100000, 0, STR_NULL, NULL),
01446 SDT_VAR(GameSettings, pf.npf.npf_rail_curve_penalty, SLE_UINT, 0, 0, 1, 0, 100000, 0, STR_NULL, NULL),
01447 SDT_VAR(GameSettings, pf.npf.npf_rail_depot_reverse_penalty, SLE_UINT, 0, 0, ( 50 * NPF_TILE_LENGTH), 0, 100000, 0, STR_NULL, NULL),
01448 SDT_CONDVAR(GameSettings, pf.npf.npf_rail_pbs_cross_penalty, SLE_UINT,100, SL_MAX_VERSION, 0, 0, ( 3 * NPF_TILE_LENGTH), 0, 100000, 0, STR_NULL, NULL),
01449 SDT_CONDVAR(GameSettings, pf.npf.npf_rail_pbs_signal_back_penalty, SLE_UINT,100, SL_MAX_VERSION, 0, 0, ( 15 * NPF_TILE_LENGTH), 0, 100000, 0, STR_NULL, NULL),
01450 SDT_VAR(GameSettings, pf.npf.npf_buoy_penalty, SLE_UINT, 0, 0, ( 2 * NPF_TILE_LENGTH), 0, 100000, 0, STR_NULL, NULL),
01451 SDT_VAR(GameSettings, pf.npf.npf_water_curve_penalty, SLE_UINT, 0, 0, (NPF_TILE_LENGTH / 4), 0, 100000, 0, STR_NULL, NULL),
01452 SDT_VAR(GameSettings, pf.npf.npf_road_curve_penalty, SLE_UINT, 0, 0, 1, 0, 100000, 0, STR_NULL, NULL),
01453 SDT_VAR(GameSettings, pf.npf.npf_crossing_penalty, SLE_UINT, 0, 0, ( 3 * NPF_TILE_LENGTH), 0, 100000, 0, STR_NULL, NULL),
01454 SDT_CONDVAR(GameSettings, pf.npf.npf_road_drive_through_penalty, SLE_UINT, 47, SL_MAX_VERSION, 0, 0, ( 8 * NPF_TILE_LENGTH), 0, 100000, 0, STR_NULL, NULL),
01455
01456
01457 SDT_CONDBOOL(GameSettings, pf.yapf.disable_node_optimization, 28, SL_MAX_VERSION, 0, 0, false, STR_NULL, NULL),
01458 SDT_CONDVAR(GameSettings, pf.yapf.max_search_nodes, SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 10000, 500, 1000000, 0, STR_NULL, NULL),
01459 SDT_CONDBOOL(GameSettings, pf.yapf.rail_firstred_twoway_eol, 28, SL_MAX_VERSION, 0, 0, true, STR_NULL, NULL),
01460 SDT_CONDVAR(GameSettings, pf.yapf.rail_firstred_penalty, SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 10 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
01461 SDT_CONDVAR(GameSettings, pf.yapf.rail_firstred_exit_penalty, SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 100 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
01462 SDT_CONDVAR(GameSettings, pf.yapf.rail_lastred_penalty, SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 10 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
01463 SDT_CONDVAR(GameSettings, pf.yapf.rail_lastred_exit_penalty, SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 100 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
01464 SDT_CONDVAR(GameSettings, pf.yapf.rail_station_penalty, SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 10 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
01465 SDT_CONDVAR(GameSettings, pf.yapf.rail_slope_penalty, SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 2 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
01466 SDT_CONDVAR(GameSettings, pf.yapf.rail_curve45_penalty, SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 3 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
01467 SDT_CONDVAR(GameSettings, pf.yapf.rail_curve90_penalty, SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 6 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
01468 SDT_CONDVAR(GameSettings, pf.yapf.rail_depot_reverse_penalty, SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 50 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
01469 SDT_CONDVAR(GameSettings, pf.yapf.rail_crossing_penalty, SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 3 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
01470 SDT_CONDVAR(GameSettings, pf.yapf.rail_look_ahead_max_signals, SLE_UINT, 28, SL_MAX_VERSION, 0, 0, 10, 1, 100, 0, STR_NULL, NULL),
01471 SDT_CONDVAR(GameSettings, pf.yapf.rail_look_ahead_signal_p0, SLE_INT, 28, SL_MAX_VERSION, 0, 0, 500, -1000000, 1000000, 0, STR_NULL, NULL),
01472 SDT_CONDVAR(GameSettings, pf.yapf.rail_look_ahead_signal_p1, SLE_INT, 28, SL_MAX_VERSION, 0, 0, -100, -1000000, 1000000, 0, STR_NULL, NULL),
01473 SDT_CONDVAR(GameSettings, pf.yapf.rail_look_ahead_signal_p2, SLE_INT, 28, SL_MAX_VERSION, 0, 0, 5, -1000000, 1000000, 0, STR_NULL, NULL),
01474 SDT_CONDVAR(GameSettings, pf.yapf.rail_pbs_cross_penalty, SLE_UINT,100, SL_MAX_VERSION, 0, 0, 3 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
01475 SDT_CONDVAR(GameSettings, pf.yapf.rail_pbs_station_penalty, SLE_UINT,100, SL_MAX_VERSION, 0, 0, 8 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
01476 SDT_CONDVAR(GameSettings, pf.yapf.rail_pbs_signal_back_penalty, SLE_UINT,100, SL_MAX_VERSION, 0, 0, 15 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
01477 SDT_CONDVAR(GameSettings, pf.yapf.rail_doubleslip_penalty, SLE_UINT,100, SL_MAX_VERSION, 0, 0, 1 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
01478 SDT_CONDVAR(GameSettings, pf.yapf.rail_longer_platform_penalty, SLE_UINT, 33, SL_MAX_VERSION, 0, 0, 8 * YAPF_TILE_LENGTH, 0, 20000, 0, STR_NULL, NULL),
01479 SDT_CONDVAR(GameSettings, pf.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),
01480 SDT_CONDVAR(GameSettings, pf.yapf.rail_shorter_platform_penalty, SLE_UINT, 33, SL_MAX_VERSION, 0, 0, 40 * YAPF_TILE_LENGTH, 0, 20000, 0, STR_NULL, NULL),
01481 SDT_CONDVAR(GameSettings, pf.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),
01482 SDT_CONDVAR(GameSettings, pf.yapf.road_slope_penalty, SLE_UINT, 33, SL_MAX_VERSION, 0, 0, 2 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
01483 SDT_CONDVAR(GameSettings, pf.yapf.road_curve_penalty, SLE_UINT, 33, SL_MAX_VERSION, 0, 0, 1 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
01484 SDT_CONDVAR(GameSettings, pf.yapf.road_crossing_penalty, SLE_UINT, 33, SL_MAX_VERSION, 0, 0, 3 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
01485 SDT_CONDVAR(GameSettings, pf.yapf.road_stop_penalty, SLE_UINT, 47, SL_MAX_VERSION, 0, 0, 8 * YAPF_TILE_LENGTH, 0, 1000000, 0, STR_NULL, NULL),
01486
01487 SDT_CONDVAR(GameSettings, game_creation.land_generator, SLE_UINT8, 30, SL_MAX_VERSION, 0,MS, 1, 0, 1, 0, STR_CONFIG_SETTING_LAND_GENERATOR, NULL),
01488 SDT_CONDVAR(GameSettings, game_creation.oil_refinery_limit, SLE_UINT8, 30, SL_MAX_VERSION, 0, 0, 32, 12, 48, 0, STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE, NULL),
01489 SDT_CONDVAR(GameSettings, game_creation.tgen_smoothness, SLE_UINT8, 30, SL_MAX_VERSION, 0,MS, 1, 0, 3, 0, STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN, NULL),
01490 SDT_CONDVAR(GameSettings, game_creation.generation_seed, SLE_UINT32, 30, SL_MAX_VERSION, 0, 0, GENERATE_NEW_SEED, 0, UINT32_MAX, 0, STR_NULL, NULL),
01491 SDT_CONDVAR(GameSettings, game_creation.tree_placer, SLE_UINT8, 30, SL_MAX_VERSION, 0,MS, 2, 0, 2, 0, STR_CONFIG_SETTING_TREE_PLACER, NULL),
01492 SDT_VAR(GameSettings, game_creation.heightmap_rotation, SLE_UINT8, S,MS, 0, 0, 1, 0, STR_CONFIG_SETTING_HEIGHTMAP_ROTATION, NULL),
01493 SDT_VAR(GameSettings, game_creation.se_flat_world_height, SLE_UINT8, S, 0, 1, 0, 15, 0, STR_CONFIG_SETTING_SE_FLAT_WORLD_HEIGHT, NULL),
01494
01495 SDT_VAR(GameSettings, game_creation.map_x, SLE_UINT8, S, 0, 8, 6, 11, 0, STR_CONFIG_SETTING_MAP_X, NULL),
01496 SDT_VAR(GameSettings, game_creation.map_y, SLE_UINT8, S, 0, 8, 6, 11, 0, STR_CONFIG_SETTING_MAP_Y, NULL),
01497 SDT_CONDBOOL(GameSettings, construction.freeform_edges, 111, SL_MAX_VERSION, 0, 0, true, STR_CONFIG_SETTING_ENABLE_FREEFORM_EDGES, CheckFreeformEdges),
01498 SDT_CONDVAR(GameSettings, game_creation.water_borders, SLE_UINT8,111, SL_MAX_VERSION, 0, 0, 15, 0, 16, 0, STR_NULL, NULL),
01499 SDT_CONDVAR(GameSettings, game_creation.custom_town_number, SLE_UINT16,115, SL_MAX_VERSION, 0, 0, 1, 1, 5000, 0, STR_NULL, NULL),
01500
01501 SDT_CONDOMANY(GameSettings, locale.currency, SLE_UINT8, 97, SL_MAX_VERSION, N, 0, 0, CUSTOM_CURRENCY_ID, _locale_currencies, STR_NULL, NULL, NULL),
01502 SDT_CONDOMANY(GameSettings, locale.units, SLE_UINT8, 97, SL_MAX_VERSION, N, 0, 1, 2, _locale_units, STR_NULL, NULL, NULL),
01503
01504
01505
01506 SDTC_OMANY(gui.autosave, SLE_UINT8, S, 0, 1, 4, _autosave_interval, STR_NULL, NULL),
01507 SDTC_OMANY(gui.date_format_in_default_names,SLE_UINT8,S,MS, 0, 2, _savegame_date, STR_CONFIG_SETTING_DATE_FORMAT_IN_SAVE_NAMES, NULL),
01508 SDTC_BOOL(gui.vehicle_speed, S, 0, true, STR_CONFIG_SETTING_VEHICLESPEED, NULL),
01509 SDTC_BOOL(gui.status_long_date, S, 0, true, STR_CONFIG_SETTING_LONGDATE, NULL),
01510 SDTC_BOOL(gui.show_finances, S, 0, true, STR_CONFIG_SETTING_SHOWFINANCES, NULL),
01511 SDTC_BOOL(gui.autoscroll, S, 0, false, STR_CONFIG_SETTING_AUTOSCROLL, NULL),
01512 SDTC_BOOL(gui.reverse_scroll, S, 0, false, STR_CONFIG_SETTING_REVERSE_SCROLLING, NULL),
01513 SDTC_BOOL(gui.smooth_scroll, S, 0, false, STR_CONFIG_SETTING_SMOOTH_SCROLLING, NULL),
01514 SDTC_BOOL(gui.left_mouse_btn_scrolling, S, 0, false, STR_CONFIG_SETTING_LEFT_MOUSE_BTN_SCROLLING, NULL),
01515 SDTC_BOOL(gui.measure_tooltip, S, 0, true, STR_CONFIG_SETTING_MEASURE_TOOLTIP, NULL),
01516 SDTC_VAR(gui.errmsg_duration, SLE_UINT8, S, 0, 5, 0, 20, 0, STR_CONFIG_SETTING_ERRMSG_DURATION, NULL),
01517 SDTC_VAR(gui.toolbar_pos, SLE_UINT8, S, MS, 0, 0, 2, 0, STR_CONFIG_SETTING_TOOLBAR_POS, v_PositionMainToolbar),
01518 SDTC_VAR(gui.window_snap_radius, SLE_UINT8, S, D0, 10, 1, 32, 0, STR_CONFIG_SETTING_SNAP_RADIUS, NULL),
01519 SDTC_VAR(gui.window_soft_limit, SLE_UINT8, S, D0, 20, 5, 255, 1, STR_CONFIG_SETTING_SOFT_LIMIT, NULL),
01520 SDTC_BOOL(gui.population_in_label, S, 0, true, STR_CONFIG_SETTING_POPULATION_IN_LABEL, PopulationInLabelActive),
01521 SDTC_BOOL(gui.link_terraform_toolbar, S, 0, false, STR_CONFIG_SETTING_LINK_TERRAFORM_TOOLBAR, NULL),
01522 SDTC_VAR(gui.liveries, SLE_UINT8, S, MS, 2, 0, 2, 0, STR_CONFIG_SETTING_LIVERIES, RedrawScreen),
01523 SDTC_BOOL(gui.prefer_teamchat, S, 0, false, STR_CONFIG_SETTING_PREFER_TEAMCHAT, NULL),
01524 SDTC_VAR(gui.scrollwheel_scrolling, SLE_UINT8, S, MS, 0, 0, 2, 0, STR_CONFIG_SETTING_SCROLLWHEEL_SCROLLING, NULL),
01525 SDTC_VAR(gui.scrollwheel_multiplier, SLE_UINT8, S, 0, 5, 1, 15, 1, STR_CONFIG_SETTING_SCROLLWHEEL_MULTIPLIER, NULL),
01526 SDTC_BOOL(gui.pause_on_newgame, S, 0, false, STR_CONFIG_SETTING_PAUSE_ON_NEW_GAME, NULL),
01527 SDTC_VAR(gui.advanced_vehicle_list, SLE_UINT8, S, MS, 1, 0, 2, 0, STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS, NULL),
01528 SDTC_BOOL(gui.timetable_in_ticks, S, 0, false, STR_CONFIG_SETTING_TIMETABLE_IN_TICKS, NULL),
01529 SDTC_BOOL(gui.quick_goto, S, 0, false, STR_CONFIG_SETTING_QUICKGOTO, NULL),
01530 SDTC_VAR(gui.loading_indicators, SLE_UINT8, S, MS, 1, 0, 2, 0, STR_CONFIG_SETTING_LOADING_INDICATORS, RedrawScreen),
01531 SDTC_VAR(gui.default_rail_type, SLE_UINT8, S, MS, 4, 0, 6, 0, STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE, NULL),
01532 SDTC_BOOL(gui.enable_signal_gui, S, 0, true, STR_CONFIG_SETTING_ENABLE_SIGNAL_GUI, CloseSignalGUI),
01533 SDTC_VAR(gui.drag_signals_density, SLE_UINT8, S, 0, 4, 1, 20, 0, STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY, DragSignalsDensityChanged),
01534 SDTC_VAR(gui.semaphore_build_before, SLE_INT32, S, NC, 1975, MIN_YEAR, MAX_YEAR, 1, STR_CONFIG_SETTING_SEMAPHORE_BUILD_BEFORE_DATE, ResetSignalVariant),
01535 SDTC_BOOL(gui.vehicle_income_warn, S, 0, true, STR_CONFIG_SETTING_WARN_INCOME_LESS, NULL),
01536 SDTC_VAR(gui.order_review_system, SLE_UINT8, S, MS, 2, 0, 2, 0, STR_CONFIG_SETTING_ORDER_REVIEW, NULL),
01537 SDTC_BOOL(gui.lost_train_warn, S, 0, true, STR_CONFIG_SETTING_WARN_LOST_TRAIN, NULL),
01538 SDTC_BOOL(gui.autorenew, S, 0, false, STR_CONFIG_SETTING_AUTORENEW_VEHICLE, EngineRenewUpdate),
01539 SDTC_VAR(gui.autorenew_months, SLE_INT16, S, 0, 6, -12, 12, 0, STR_CONFIG_SETTING_AUTORENEW_MONTHS, EngineRenewMonthsUpdate),
01540 SDTC_VAR(gui.autorenew_money, SLE_UINT, S, CR,100000, 0, 2000000, 0, STR_CONFIG_SETTING_AUTORENEW_MONEY, EngineRenewMoneyUpdate),
01541 SDTC_BOOL(gui.always_build_infrastructure, S, 0, false, STR_CONFIG_SETTING_ALWAYS_BUILD_INFRASTRUCTURE, RedrawScreen),
01542 SDTC_BOOL(gui.new_nonstop, S, 0, false, STR_CONFIG_SETTING_NONSTOP_BY_DEFAULT, NULL),
01543 SDTC_BOOL(gui.keep_all_autosave, S, 0, false, STR_NULL, NULL),
01544 SDTC_BOOL(gui.autosave_on_exit, S, 0, false, STR_NULL, NULL),
01545 SDTC_VAR(gui.max_num_autosaves, SLE_UINT8, S, 0, 16, 0, 255, 0, STR_NULL, NULL),
01546 SDTC_BOOL(gui.bridge_pillars, S, 0, true, STR_NULL, NULL),
01547 SDTC_BOOL(gui.auto_euro, S, 0, true, STR_NULL, NULL),
01548 SDTC_VAR(gui.news_message_timeout, SLE_UINT8, S, 0, 2, 1, 255, 0, STR_NULL, NULL),
01549 SDTC_BOOL(gui.show_track_reservation, S, 0, false, STR_CONFIG_SETTING_SHOW_TRACK_RESERVATION, RedrawScreen),
01550 SDTC_VAR(gui.default_signal_type, SLE_UINT8, S, MS, 0, 0, 2, 1, STR_CONFIG_SETTING_DEFAULT_SIGNAL_TYPE, NULL),
01551 SDTC_VAR(gui.cycle_signal_types, SLE_UINT8, S, MS, 2, 0, 2, 1, STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES, NULL),
01552 SDTC_VAR(gui.station_numtracks, SLE_UINT8, S, 0, 1, 1, 7, 0, STR_NULL, NULL),
01553 SDTC_VAR(gui.station_platlength, SLE_UINT8, S, 0, 5, 1, 7, 0, STR_NULL, NULL),
01554 SDTC_BOOL(gui.station_dragdrop, S, 0, true, STR_NULL, NULL),
01555 SDTC_BOOL(gui.station_show_coverage, S, 0, false, STR_NULL, NULL),
01556 SDTC_BOOL(gui.persistent_buildingtools, S, 0, false, STR_CONFIG_SETTING_PERSISTENT_BUILDINGTOOLS, NULL),
01557 SDTC_BOOL(gui.expenses_layout, S, 0, false, STR_CONFIG_SETTING_EXPENSES_LAYOUT, RedrawScreen),
01558
01559 SDTC_VAR(gui.console_backlog_timeout, SLE_UINT16, S, 0, 100, 10, 65500, 0, STR_NULL, NULL),
01560 SDTC_VAR(gui.console_backlog_length, SLE_UINT16, S, 0, 100, 10, 65500, 0, STR_NULL, NULL),
01561 #ifdef ENABLE_NETWORK
01562 SDTC_VAR(gui.network_chat_box_width, SLE_UINT16, S, 0, 700, 200, 65535, 0, STR_NULL, NULL),
01563 SDTC_VAR(gui.network_chat_box_height, SLE_UINT8, S, 0, 25, 5, 255, 0, STR_NULL, NULL),
01564
01565 SDTC_VAR(network.sync_freq, SLE_UINT16,C|S,NO, 100, 0, 100, 0, STR_NULL, NULL),
01566 SDTC_VAR(network.frame_freq, SLE_UINT8,C|S,NO, 0, 0, 100, 0, STR_NULL, NULL),
01567 SDTC_VAR(network.max_join_time, SLE_UINT16, S, NO, 500, 0, 32000, 0, STR_NULL, NULL),
01568 SDTC_BOOL(network.pause_on_join, S, NO, true, STR_NULL, NULL),
01569 SDTC_STR(network.server_bind_ip, SLE_STRB, S, NO, "0.0.0.0", STR_NULL, NULL),
01570 SDTC_VAR(network.server_port, SLE_UINT16, S, NO,NETWORK_DEFAULT_PORT,0,65535,0,STR_NULL, NULL),
01571 SDTC_BOOL(network.server_advertise, S, NO, false, STR_NULL, NULL),
01572 SDTC_VAR(network.lan_internet, SLE_UINT8, S, NO, 0, 0, 1, 0, STR_NULL, NULL),
01573 SDTC_STR(network.client_name, SLE_STRB, S, 0, NULL, STR_NULL, UpdateClientName),
01574 SDTC_STR(network.server_password, SLE_STRB, S, NO, NULL, STR_NULL, UpdateServerPassword),
01575 SDTC_STR(network.rcon_password, SLE_STRB, S, NO, NULL, STR_NULL, UpdateRconPassword),
01576 SDTC_STR(network.default_company_pass, SLE_STRB, S, 0, NULL, STR_NULL, NULL),
01577 SDTC_STR(network.server_name, SLE_STRB, S, NO, NULL, STR_NULL, NULL),
01578 SDTC_STR(network.connect_to_ip, SLE_STRB, S, 0, NULL, STR_NULL, NULL),
01579 SDTC_STR(network.network_id, SLE_STRB, S, NO, NULL, STR_NULL, NULL),
01580 SDTC_BOOL(network.autoclean_companies, S, NO, false, STR_NULL, NULL),
01581 SDTC_VAR(network.autoclean_unprotected, SLE_UINT8, S,D0|NO, 12, 0, 240, 0, STR_NULL, NULL),
01582 SDTC_VAR(network.autoclean_protected, SLE_UINT8, S,D0|NO, 36, 0, 240, 0, STR_NULL, NULL),
01583 SDTC_VAR(network.autoclean_novehicles, SLE_UINT8, S,D0|NO, 0, 0, 240, 0, STR_NULL, NULL),
01584 SDTC_VAR(network.max_companies, SLE_UINT8, S, NO, 8, 1,MAX_COMPANIES,0, STR_NULL, UpdateClientConfigValues),
01585 SDTC_VAR(network.max_clients, SLE_UINT8, S, NO, 16, 2, MAX_CLIENTS, 0, STR_NULL, NULL),
01586 SDTC_VAR(network.max_spectators, SLE_UINT8, S, NO, 8, 0, MAX_CLIENTS, 0, STR_NULL, UpdateClientConfigValues),
01587 SDTC_VAR(network.restart_game_year, SLE_INT32, S,D0|NO|NC,0, MIN_YEAR, MAX_YEAR, 1, STR_NULL, NULL),
01588 SDTC_VAR(network.min_active_clients, SLE_UINT8, S, NO, 0, 0, MAX_CLIENTS, 0, STR_NULL, NULL),
01589 SDTC_OMANY(network.server_lang, SLE_UINT8, S, NO, 0, 35, _server_langs, STR_NULL, NULL),
01590 SDTC_BOOL(network.reload_cfg, S, NO, false, STR_NULL, NULL),
01591 SDTC_STR(network.last_host, SLE_STRB, S, 0, "0.0.0.0", STR_NULL, NULL),
01592 SDTC_VAR(network.last_port, SLE_UINT16, S, 0, 0, 0, UINT16_MAX, 0, STR_NULL, NULL),
01593 #endif
01594
01595
01596
01597
01598
01599
01600
01601
01602 #ifdef __APPLE__
01603
01604 SDTC_VAR(gui.right_mouse_btn_emulation, SLE_UINT8, S, MS, 0, 0, 2, 0, STR_CONFIG_SETTING_RIGHT_MOUSE_BTN_EMU, NULL),
01605 #endif
01606
01607 SDT_END()
01608 };
01609
01610 static const SettingDesc _currency_settings[] = {
01611 SDT_VAR(CurrencySpec, rate, SLE_UINT16, S, 0, 1, 0, UINT16_MAX, 0, STR_NULL, NULL),
01612 SDT_CHR(CurrencySpec, separator, S, 0, ".", STR_NULL, NULL),
01613 SDT_VAR(CurrencySpec, to_euro, SLE_INT32, S, 0, 0, MIN_YEAR, MAX_YEAR, 0, STR_NULL, NULL),
01614 SDT_STR(CurrencySpec, prefix, SLE_STRBQ, S, 0, NULL, STR_NULL, NULL),
01615 SDT_STR(CurrencySpec, suffix, SLE_STRBQ, S, 0, " credits", STR_NULL, NULL),
01616 SDT_END()
01617 };
01618
01619
01620 #undef S
01621 #undef C
01622 #undef N
01623
01624 #undef D0
01625 #undef NC
01626 #undef MS
01627 #undef NO
01628 #undef CR
01629
01633 static void PrepareOldDiffCustom()
01634 {
01635 memset(_old_diff_custom, 0, sizeof(_old_diff_custom));
01636 }
01637
01644 static void HandleOldDiffCustom(bool savegame)
01645 {
01646 uint options_to_load = GAME_DIFFICULTY_NUM - ((savegame && CheckSavegameVersion(4)) ? 1 : 0);
01647
01648 if (!savegame) {
01649
01650 bool old_diff_custom_used = false;
01651 for (uint i = 0; i < options_to_load && !old_diff_custom_used; i++) {
01652 old_diff_custom_used = (_old_diff_custom[i] != 0);
01653 }
01654
01655 if (!old_diff_custom_used) return;
01656 }
01657
01658 for (uint i = 0; i < options_to_load; i++) {
01659 const SettingDesc *sd = &_settings[i];
01660
01661 if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue;
01662 void *var = GetVariableAddress(savegame ? &_settings_game : &_settings_newgame, &sd->save);
01663 Write_ValidateSetting(var, sd, (int32)((i == 4 ? 1000 : 1) * _old_diff_custom[i]));
01664 }
01665 }
01666
01671 bool ConvertOldNewsSetting(const char *name, const char *value)
01672 {
01673 if (strcasecmp(name, "openclose") == 0) {
01674
01675
01676
01677
01678 NewsDisplay display = ND_OFF;
01679 if (strcasecmp(value, "full") == 0) {
01680 display = ND_FULL;
01681 } else if (strcasecmp(value, "summarized") == 0) {
01682 display = ND_SUMMARY;
01683 }
01684
01685 _news_type_data[NT_INDUSTRY_OPEN].display = display;
01686 _news_type_data[NT_INDUSTRY_CLOSE].display = display;
01687 return true;
01688 }
01689 return false;
01690 }
01691
01692 static void NewsDisplayLoadConfig(IniFile *ini, const char *grpname)
01693 {
01694 IniGroup *group = ini->GetGroup(grpname);
01695 IniItem *item;
01696
01697
01698 if (group == NULL) return;
01699
01700 for (item = group->item; item != NULL; item = item->next) {
01701 int news_item = -1;
01702 for (int i = 0; i < NT_END; i++) {
01703 if (strcasecmp(item->name, _news_type_data[i].name) == 0) {
01704 news_item = i;
01705 break;
01706 }
01707 }
01708
01709
01710 if (news_item == -1) {
01711
01712 if (!ConvertOldNewsSetting(item->name, item->value)) {
01713 DEBUG(misc, 0, "Invalid display option: %s", item->name);
01714 }
01715
01716 continue;
01717 }
01718
01719 if (strcasecmp(item->value, "full") == 0) {
01720 _news_type_data[news_item].display = ND_FULL;
01721 } else if (strcasecmp(item->value, "off") == 0) {
01722 _news_type_data[news_item].display = ND_OFF;
01723 } else if (strcasecmp(item->value, "summarized") == 0) {
01724 _news_type_data[news_item].display = ND_SUMMARY;
01725 } else {
01726 DEBUG(misc, 0, "Invalid display value: %s", item->value);
01727 continue;
01728 }
01729 }
01730 }
01731
01732 static void AILoadConfig(IniFile *ini, const char *grpname)
01733 {
01734 IniGroup *group = ini->GetGroup(grpname);
01735 IniItem *item;
01736
01737
01738 for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
01739 AIConfig::GetConfig(c, true)->ChangeAI(NULL);
01740 }
01741
01742
01743 if (group == NULL) return;
01744
01745 CompanyID c = COMPANY_FIRST;
01746 for (item = group->item; c < MAX_COMPANIES && item != NULL; c++, item = item->next) {
01747 AIConfig *config = AIConfig::GetConfig(c, true);
01748
01749 config->ChangeAI(item->name);
01750 if (!config->HasAI()) {
01751 if (strcmp(item->name, "none") != 0) {
01752 DEBUG(ai, 0, "The AI by the name '%s' was no longer found, and removed from the list.", item->name);
01753 continue;
01754 }
01755 }
01756 config->StringToSettings(item->value);
01757 }
01758 }
01759
01760
01761 static GRFConfig *GRFLoadConfig(IniFile *ini, const char *grpname, bool is_static)
01762 {
01763 IniGroup *group = ini->GetGroup(grpname);
01764 IniItem *item;
01765 GRFConfig *first = NULL;
01766 GRFConfig **curr = &first;
01767
01768 if (group == NULL) return NULL;
01769
01770 for (item = group->item; item != NULL; item = item->next) {
01771 GRFConfig *c = CallocT<GRFConfig>(1);
01772 c->filename = strdup(item->name);
01773
01774
01775 if (!StrEmpty(item->value)) {
01776 c->num_params = parse_intlist(item->value, (int*)c->param, lengthof(c->param));
01777 if (c->num_params == (byte)-1) {
01778 ShowInfoF("ini: error in array '%s'", item->name);
01779 c->num_params = 0;
01780 }
01781 }
01782
01783
01784 if (!FillGRFDetails(c, is_static)) {
01785 const char *msg;
01786
01787 if (c->status == GCS_NOT_FOUND) {
01788 msg = "not found";
01789 } else if (HasBit(c->flags, GCF_UNSAFE)) {
01790 msg = "unsafe for static use";
01791 } else if (HasBit(c->flags, GCF_SYSTEM)) {
01792 msg = "system NewGRF";
01793 } else {
01794 msg = "unknown";
01795 }
01796
01797 ShowInfoF("ini: ignoring invalid NewGRF '%s': %s", item->name, msg);
01798 ClearGRFConfig(&c);
01799 continue;
01800 }
01801
01802
01803 bool duplicate = false;
01804 for (const GRFConfig *gc = first; gc != NULL; gc = gc->next) {
01805 if (gc->grfid == c->grfid) {
01806 ShowInfoF("ini: ignoring NewGRF '%s': duplicate GRF ID with '%s'", item->name, gc->filename);
01807 duplicate = true;
01808 break;
01809 }
01810 }
01811 if (duplicate) {
01812 ClearGRFConfig(&c);
01813 continue;
01814 }
01815
01816
01817 if (is_static) SetBit(c->flags, GCF_STATIC);
01818
01819
01820 *curr = c;
01821 curr = &c->next;
01822 }
01823
01824 return first;
01825 }
01826
01827 static void NewsDisplaySaveConfig(IniFile *ini, const char *grpname)
01828 {
01829 IniGroup *group = ini->GetGroup(grpname);
01830
01831 for (int i = 0; i < NT_END; i++) {
01832 const char *value;
01833 int v = _news_type_data[i].display;
01834
01835 value = (v == ND_OFF ? "off" : (v == ND_SUMMARY ? "summarized" : "full"));
01836
01837 group->GetItem(_news_type_data[i].name, true)->SetValue(value);
01838 }
01839 }
01840
01841 static void AISaveConfig(IniFile *ini, const char *grpname)
01842 {
01843 IniGroup *group = ini->GetGroup(grpname);
01844
01845 if (group == NULL) return;
01846 group->Clear();
01847
01848 for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
01849 AIConfig *config = AIConfig::GetConfig(c, true);
01850 const char *name;
01851 char value[1024];
01852 config->SettingsToString(value, lengthof(value));
01853
01854 if (config->HasAI()) {
01855 name = config->GetName();
01856 } else {
01857 name = "none";
01858 }
01859
01860 IniItem *item = new IniItem(group, name, strlen(name));
01861 item->SetValue(value);
01862 }
01863 }
01864
01869 static void SaveVersionInConfig(IniFile *ini)
01870 {
01871 IniGroup *group = ini->GetGroup("version");
01872
01873 char version[9];
01874 snprintf(version, lengthof(version), "%08X", _openttd_newgrf_version);
01875
01876 const char *versions[][2] = {
01877 { "version_string", _openttd_revision },
01878 { "version_number", version }
01879 };
01880
01881 for (uint i = 0; i < lengthof(versions); i++) {
01882 group->GetItem(versions[i][0], true)->SetValue(versions[i][1]);
01883 }
01884 }
01885
01886
01887 static void GRFSaveConfig(IniFile *ini, const char *grpname, const GRFConfig *list)
01888 {
01889 ini->RemoveGroup(grpname);
01890 IniGroup *group = ini->GetGroup(grpname);
01891 const GRFConfig *c;
01892
01893 for (c = list; c != NULL; c = c->next) {
01894 char params[512];
01895 GRFBuildParamList(params, c, lastof(params));
01896
01897 group->GetItem(c->filename, true)->SetValue(params);
01898 }
01899 }
01900
01901
01902 static void HandleSettingDescs(IniFile *ini, SettingDescProc *proc, SettingDescProcList *proc_list)
01903 {
01904 proc(ini, (const SettingDesc*)_misc_settings, "misc", NULL);
01905 proc(ini, (const SettingDesc*)_music_settings, "music", &msf);
01906 #if defined(WIN32) && !defined(DEDICATED)
01907 proc(ini, (const SettingDesc*)_win32_settings, "win32", NULL);
01908 #endif
01909
01910 proc(ini, _settings, "patches", &_settings_newgame);
01911 proc(ini, _currency_settings,"currency", &_custom_currency);
01912
01913 #ifdef ENABLE_NETWORK
01914 proc_list(ini, "servers", _network_host_list, lengthof(_network_host_list), NULL);
01915 proc_list(ini, "bans", _network_ban_list, lengthof(_network_ban_list), NULL);
01916 #endif
01917 }
01918
01919 static IniFile *IniLoadConfig()
01920 {
01921 IniFile *ini = new IniFile(_list_group_names);
01922 ini->LoadFromDisk(_config_file);
01923 return ini;
01924 }
01925
01927 void LoadFromConfig()
01928 {
01929 IniFile *ini = IniLoadConfig();
01930 ResetCurrencies(false);
01931
01932 HandleSettingDescs(ini, ini_load_settings, ini_load_setting_list);
01933 _grfconfig_newgame = GRFLoadConfig(ini, "newgrf", false);
01934 _grfconfig_static = GRFLoadConfig(ini, "newgrf-static", true);
01935 NewsDisplayLoadConfig(ini, "news_display");
01936 AILoadConfig(ini, "ai_players");
01937
01938 PrepareOldDiffCustom();
01939 ini_load_settings(ini, _gameopt_settings, "gameopt", &_settings_newgame);
01940 HandleOldDiffCustom(false);
01941
01942 CheckDifficultyLevels();
01943 delete ini;
01944 }
01945
01947 void SaveToConfig()
01948 {
01949 IniFile *ini = IniLoadConfig();
01950
01951
01952 ini->RemoveGroup("patches");
01953 ini->RemoveGroup("yapf");
01954 ini->RemoveGroup("gameopt");
01955
01956 HandleSettingDescs(ini, ini_save_settings, ini_save_setting_list);
01957 GRFSaveConfig(ini, "newgrf", _grfconfig_newgame);
01958 GRFSaveConfig(ini, "newgrf-static", _grfconfig_static);
01959 NewsDisplaySaveConfig(ini, "news_display");
01960 AISaveConfig(ini, "ai_players");
01961 SaveVersionInConfig(ini);
01962 ini->SaveToDisk(_config_file);
01963 delete ini;
01964 }
01965
01966 void GetGRFPresetList(GRFPresetList *list)
01967 {
01968 list->Clear();
01969
01970 IniFile *ini = IniLoadConfig();
01971 IniGroup *group;
01972 for (group = ini->group; group != NULL; group = group->next) {
01973 if (strncmp(group->name, "preset-", 7) == 0) {
01974 *list->Append() = strdup(group->name + 7);
01975 }
01976 }
01977
01978 delete ini;
01979 }
01980
01981 GRFConfig *LoadGRFPresetFromConfig(const char *config_name)
01982 {
01983 char *section = (char*)alloca(strlen(config_name) + 8);
01984 sprintf(section, "preset-%s", config_name);
01985
01986 IniFile *ini = IniLoadConfig();
01987 GRFConfig *config = GRFLoadConfig(ini, section, false);
01988 delete ini;
01989
01990 return config;
01991 }
01992
01993 void SaveGRFPresetToConfig(const char *config_name, GRFConfig *config)
01994 {
01995 char *section = (char*)alloca(strlen(config_name) + 8);
01996 sprintf(section, "preset-%s", config_name);
01997
01998 IniFile *ini = IniLoadConfig();
01999 GRFSaveConfig(ini, section, config);
02000 ini->SaveToDisk(_config_file);
02001 delete ini;
02002 }
02003
02004 void DeleteGRFPresetFromConfig(const char *config_name)
02005 {
02006 char *section = (char*)alloca(strlen(config_name) + 8);
02007 sprintf(section, "preset-%s", config_name);
02008
02009 IniFile *ini = IniLoadConfig();
02010 ini->RemoveGroup(section);
02011 ini->SaveToDisk(_config_file);
02012 delete ini;
02013 }
02014
02015 static const SettingDesc *GetSettingDescription(uint index)
02016 {
02017 if (index >= lengthof(_settings)) return NULL;
02018 return &_settings[index];
02019 }
02020
02029 CommandCost CmdChangeSetting(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
02030 {
02031 const SettingDesc *sd = GetSettingDescription(p1);
02032
02033 if (sd == NULL) return CMD_ERROR;
02034 if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) return CMD_ERROR;
02035
02036 if ((sd->desc.flags & SGF_NETWORK_ONLY) && !_networking && _game_mode != GM_MENU) return CMD_ERROR;
02037 if ((sd->desc.flags & SGF_NO_NETWORK) && _networking) return CMD_ERROR;
02038 if ((sd->desc.flags & SGF_NEWGAME_ONLY) && _game_mode != GM_MENU) return CMD_ERROR;
02039
02040 if (flags & DC_EXEC) {
02041 GameSettings *s = (_game_mode == GM_MENU) ? &_settings_newgame : &_settings_game;
02042 void *var = GetVariableAddress(s, &sd->save);
02043
02044 int32 oldval = (int32)ReadValue(var, sd->save.conv);
02045 int32 newval = (int32)p2;
02046
02047 Write_ValidateSetting(var, sd, newval);
02048 newval = (int32)ReadValue(var, sd->save.conv);
02049
02050 if (oldval == newval) return CommandCost();
02051
02052 if (sd->desc.proc != NULL && !sd->desc.proc(newval)) {
02053 WriteValue(var, sd->save.conv, (int64)oldval);
02054 return CommandCost();
02055 }
02056
02057 if (sd->desc.flags & SGF_NO_NETWORK) {
02058 GamelogStartAction(GLAT_SETTING);
02059 GamelogSetting(sd->desc.name, oldval, newval);
02060 GamelogStopAction();
02061 }
02062
02063 InvalidateWindow(WC_GAME_OPTIONS, 0);
02064 }
02065
02066 return CommandCost();
02067 }
02068
02076 bool SetSettingValue(uint index, int32 value)
02077 {
02078 const SettingDesc *sd = &_settings[index];
02079
02080
02081
02082
02083 if (sd->save.conv & SLF_NETWORK_NO) {
02084 void *var = GetVariableAddress((_game_mode == GM_MENU) ? &_settings_newgame : &_settings_game, &sd->save);
02085 Write_ValidateSetting(var, sd, value);
02086
02087 if (_game_mode != GM_MENU) {
02088 void *var2 = GetVariableAddress(&_settings_newgame, &sd->save);
02089 Write_ValidateSetting(var2, sd, value);
02090 }
02091 if (sd->desc.proc != NULL) sd->desc.proc((int32)ReadValue(var, sd->save.conv));
02092 InvalidateWindow(WC_GAME_OPTIONS, 0);
02093 return true;
02094 }
02095
02096
02097 if (!_networking || (_networking && _network_server)) {
02098 return DoCommandP(0, index, value, CMD_CHANGE_SETTING);
02099 }
02100 return false;
02101 }
02102
02109 bool SetSettingValue(uint index, const char *value)
02110 {
02111 const SettingDesc *sd = &_settings[index];
02112 assert(sd->save.conv & SLF_NETWORK_NO);
02113
02114 char *var = (char*)GetVariableAddress(NULL, &sd->save);
02115 ttd_strlcpy(var, value, sd->save.length);
02116 if (sd->desc.proc != NULL) sd->desc.proc(0);
02117
02118 return true;
02119 }
02120
02128 const SettingDesc *GetSettingFromName(const char *name, uint *i)
02129 {
02130 const SettingDesc *sd;
02131
02132
02133 for (*i = 0, sd = _settings; sd->save.cmd != SL_END; sd++, (*i)++) {
02134 if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue;
02135 if (strcmp(sd->desc.name, name) == 0) return sd;
02136 }
02137
02138
02139 for (*i = 0, sd = _settings; sd->save.cmd != SL_END; sd++, (*i)++) {
02140 if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue;
02141 const char *short_name = strchr(sd->desc.name, '.');
02142 if (short_name != NULL) {
02143 short_name++;
02144 if (strcmp(short_name, name) == 0) return sd;
02145 }
02146 }
02147
02148 return NULL;
02149 }
02150
02151
02152
02153 void IConsoleSetSetting(const char *name, const char *value)
02154 {
02155 uint index;
02156 const SettingDesc *sd = GetSettingFromName(name, &index);
02157
02158 if (sd == NULL) {
02159 IConsolePrintF(CC_WARNING, "'%s' is an unknown setting.", name);
02160 return;
02161 }
02162
02163 bool success;
02164 if (sd->desc.cmd == SDT_STRING) {
02165 success = SetSettingValue(index, value);
02166 } else {
02167 uint32 val;
02168 extern bool GetArgumentInteger(uint32 *value, const char *arg);
02169 success = GetArgumentInteger(&val, value);
02170 if (!success) {
02171 IConsolePrintF(CC_ERROR, "'%s' is not an integer.", value);
02172 return;
02173 }
02174
02175 success = SetSettingValue(index, val);
02176 }
02177
02178 if (!success) {
02179 if (_network_server) {
02180 IConsoleError("This command/variable is not available during network games.");
02181 } else {
02182 IConsoleError("This command/variable is only available to a network server.");
02183 }
02184 }
02185 }
02186
02187 void IConsoleSetSetting(const char *name, int value)
02188 {
02189 uint index;
02190 const SettingDesc *sd = GetSettingFromName(name, &index);
02191 assert(sd != NULL);
02192 SetSettingValue(index, value);
02193 }
02194
02199 void IConsoleGetSetting(const char *name)
02200 {
02201 char value[20];
02202 uint index;
02203 const SettingDesc *sd = GetSettingFromName(name, &index);
02204 const void *ptr;
02205
02206 if (sd == NULL) {
02207 IConsolePrintF(CC_WARNING, "'%s' is an unknown setting.", name);
02208 return;
02209 }
02210
02211 ptr = GetVariableAddress((_game_mode == GM_MENU) ? &_settings_newgame : &_settings_game, &sd->save);
02212
02213 if (sd->desc.cmd == SDT_STRING) {
02214 IConsolePrintF(CC_WARNING, "Current value for '%s' is: '%s'", name, (const char *)ptr);
02215 } else {
02216 if (sd->desc.cmd == SDT_BOOLX) {
02217 snprintf(value, sizeof(value), (*(bool*)ptr == 1) ? "on" : "off");
02218 } else {
02219 snprintf(value, sizeof(value), "%d", (int32)ReadValue(ptr, sd->save.conv));
02220 }
02221
02222 IConsolePrintF(CC_WARNING, "Current value for '%s' is: '%s' (min: %s%d, max: %d)",
02223 name, value, (sd->desc.flags & SGF_0ISDISABLED) ? "(0) " : "", sd->desc.min, sd->desc.max);
02224 }
02225 }
02226
02232 void IConsoleListSettings(const char *prefilter)
02233 {
02234 IConsolePrintF(CC_WARNING, "All settings with their current value:");
02235
02236 for (const SettingDesc *sd = _settings; sd->save.cmd != SL_END; sd++) {
02237 if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue;
02238 if (prefilter != NULL) {
02239 if (strncmp(sd->desc.name, prefilter, min(strlen(sd->desc.name), strlen(prefilter))) != 0) continue;
02240 }
02241 char value[80];
02242 const void *ptr = GetVariableAddress((_game_mode == GM_MENU) ? &_settings_newgame : &_settings_game, &sd->save);
02243
02244 if (sd->desc.cmd == SDT_BOOLX) {
02245 snprintf(value, lengthof(value), (*(bool*)ptr == 1) ? "on" : "off");
02246 } else if (sd->desc.cmd == SDT_STRING) {
02247 snprintf(value, sizeof(value), "%s", (const char *)ptr);
02248 } else {
02249 snprintf(value, lengthof(value), "%d", (uint32)ReadValue(ptr, sd->save.conv));
02250 }
02251 IConsolePrintF(CC_DEFAULT, "%s = %s", sd->desc.name, value);
02252 }
02253
02254 IConsolePrintF(CC_WARNING, "Use 'setting' command to change a value");
02255 }
02256
02261 static void LoadSettings(const SettingDesc *osd, void *object)
02262 {
02263 for (; osd->save.cmd != SL_END; osd++) {
02264 const SaveLoad *sld = &osd->save;
02265 void *ptr = GetVariableAddress(object, sld);
02266
02267 if (!SlObjectMember(ptr, sld)) continue;
02268 }
02269 }
02270
02275 static inline void LoadSettingsGlobList(const SettingDescGlobVarList *sdg)
02276 {
02277 LoadSettings((const SettingDesc*)sdg, NULL);
02278 }
02279
02284 static void SaveSettings(const SettingDesc *sd, void *object)
02285 {
02286
02287
02288 const SettingDesc *i;
02289 size_t length = 0;
02290 for (i = sd; i->save.cmd != SL_END; i++) {
02291 const void *ptr = GetVariableAddress(object, &i->save);
02292 length += SlCalcObjMemberLength(ptr, &i->save);
02293 }
02294 SlSetLength(length);
02295
02296 for (i = sd; i->save.cmd != SL_END; i++) {
02297 void *ptr = GetVariableAddress(object, &i->save);
02298 SlObjectMember(ptr, &i->save);
02299 }
02300 }
02301
02305 static inline void SaveSettingsGlobList(const SettingDescGlobVarList *sdg)
02306 {
02307 SaveSettings((const SettingDesc*)sdg, NULL);
02308 }
02309
02310 static void Load_OPTS()
02311 {
02312
02313
02314
02315 PrepareOldDiffCustom();
02316 LoadSettings(_gameopt_settings, &_settings_game);
02317 HandleOldDiffCustom(true);
02318 }
02319
02320 static void Load_PATS()
02321 {
02322
02323
02324
02325 LoadSettings(_settings, &_settings_game);
02326 }
02327
02328 static void Save_PATS()
02329 {
02330 SaveSettings(_settings, &_settings_game);
02331 }
02332
02333 void CheckConfig()
02334 {
02335
02336
02337
02338
02339 if (_settings_newgame.pf.opf.pf_maxdepth == 16 && _settings_newgame.pf.opf.pf_maxlength == 512) {
02340 _settings_newgame.pf.opf.pf_maxdepth = 48;
02341 _settings_newgame.pf.opf.pf_maxlength = 4096;
02342 }
02343 }
02344
02345 extern const ChunkHandler _setting_chunk_handlers[] = {
02346 { 'OPTS', NULL, Load_OPTS, CH_RIFF},
02347 { 'PATS', Save_PATS, Load_PATS, CH_RIFF | CH_LAST},
02348 };
02349
02350 static bool IsSignedVarMemType(VarType vt)
02351 {
02352 switch (GetVarMemType(vt)) {
02353 case SLE_VAR_I8:
02354 case SLE_VAR_I16:
02355 case SLE_VAR_I32:
02356 case SLE_VAR_I64:
02357 return true;
02358 }
02359 return false;
02360 }