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