src/settings.cpp
branchgamebalance
changeset 9895 7bd07f43b0e3
parent 6338 0fb4f452873c
child 9904 e7d15ae60d43
equal deleted inserted replaced
9894:70d78ac95d6c 9895:7bd07f43b0e3
    39 #include "newgrf_config.h"
    39 #include "newgrf_config.h"
    40 #include "genworld.h"
    40 #include "genworld.h"
    41 #include "date.h"
    41 #include "date.h"
    42 #include "rail.h"
    42 #include "rail.h"
    43 #include "helpers.hpp"
    43 #include "helpers.hpp"
       
    44 #include "news.h"
    44 #ifdef WITH_FREETYPE
    45 #ifdef WITH_FREETYPE
    45 #include "gfx.h"
    46 #include "gfx.h"
    46 #include "fontcache.h"
    47 #include "fontcache.h"
    47 #endif
    48 #endif
    48 
    49 
    49 /** The patch values that are used for new games and/or modified in config file */
    50 /** The patch values that are used for new games and/or modified in config file */
    50 Patches _patches_newgame;
    51 Patches _patches_newgame;
    51 
    52 
    52 typedef struct IniFile IniFile;
    53 struct IniFile;
    53 typedef struct IniItem IniItem;
    54 struct IniItem;
    54 typedef struct IniGroup IniGroup;
    55 struct IniGroup;
    55 typedef struct SettingsMemoryPool SettingsMemoryPool;
    56 struct SettingsMemoryPool;
    56 
    57 
    57 typedef const char *SettingListCallbackProc(const IniItem *item, uint index);
    58 typedef const char *SettingListCallbackProc(const IniItem *item, uint index);
    58 typedef void SettingDescProc(IniFile *ini, const SettingDesc *desc, const char *grpname, void *object);
    59 typedef void SettingDescProc(IniFile *ini, const SettingDesc *desc, const char *grpname, void *object);
    59 typedef void SettingDescProcList(IniFile *ini, const char *grpname, char **list, uint len, SettingListCallbackProc proc);
    60 typedef void SettingDescProcList(IniFile *ini, const char *grpname, char **list, uint len, SettingListCallbackProc proc);
    60 
    61 
   151 	IniGroup *group, **last_group;
   152 	IniGroup *group, **last_group;
   152 	char *comment; // last comment in file
   153 	char *comment; // last comment in file
   153 };
   154 };
   154 
   155 
   155 // allocate an inifile object
   156 // allocate an inifile object
   156 static IniFile *ini_alloc(void)
   157 static IniFile *ini_alloc()
   157 {
   158 {
   158 	IniFile *ini;
   159 	IniFile *ini;
   159 	SettingsMemoryPool *pool;
   160 	SettingsMemoryPool *pool;
   160 	pool_init(&pool);
   161 	pool_init(&pool);
   161 	ini = (IniFile*)pool_alloc(&pool, sizeof(IniFile));
   162 	ini = (IniFile*)pool_alloc(&pool, sizeof(IniFile));
  1181 };
  1182 };
  1182 #endif /* WIN32 */
  1183 #endif /* WIN32 */
  1183 
  1184 
  1184 static const SettingDescGlobVarList _misc_settings[] = {
  1185 static const SettingDescGlobVarList _misc_settings[] = {
  1185 	SDTG_MMANY("display_opt",     SLE_UINT8, S, 0, _display_opt,       (DO_SHOW_TOWN_NAMES|DO_SHOW_STATION_NAMES|DO_SHOW_SIGNS|DO_FULL_ANIMATION|DO_FULL_DETAIL|DO_TRANS_BUILDINGS|DO_WAYPOINTS), "SHOW_TOWN_NAMES|SHOW_STATION_NAMES|SHOW_SIGNS|FULL_ANIMATION|TRANS_BUILDINGS|FULL_DETAIL|WAYPOINTS", STR_NULL, NULL),
  1186 	SDTG_MMANY("display_opt",     SLE_UINT8, S, 0, _display_opt,       (DO_SHOW_TOWN_NAMES|DO_SHOW_STATION_NAMES|DO_SHOW_SIGNS|DO_FULL_ANIMATION|DO_FULL_DETAIL|DO_TRANS_BUILDINGS|DO_WAYPOINTS), "SHOW_TOWN_NAMES|SHOW_STATION_NAMES|SHOW_SIGNS|FULL_ANIMATION|TRANS_BUILDINGS|FULL_DETAIL|WAYPOINTS", STR_NULL, NULL),
  1186 	  SDTG_VAR("news_display_opt", SLE_UINT, S, 0, _news_display_opt,0xAAAAAAAA,0,0xAAAAAAAA,0,STR_NULL, NULL), // default to all full messages: 10101010101010101010 = 0xAAAAAAAA
       
  1187 	 SDTG_BOOL("news_ticker_sound",          S, 0, _news_ticker_sound,     true,    STR_NULL, NULL),
  1187 	 SDTG_BOOL("news_ticker_sound",          S, 0, _news_ticker_sound,     true,    STR_NULL, NULL),
  1188 	 SDTG_BOOL("fullscreen",                 S, 0, _fullscreen,           false,    STR_NULL, NULL),
  1188 	 SDTG_BOOL("fullscreen",                 S, 0, _fullscreen,           false,    STR_NULL, NULL),
  1189 	  SDTG_STR("videodriver",      SLE_STRB,C|S,0, _ini_videodriver,       NULL,    STR_NULL, NULL),
  1189 	  SDTG_STR("videodriver",      SLE_STRB,C|S,0, _ini_videodriver,       NULL,    STR_NULL, NULL),
  1190 	  SDTG_STR("musicdriver",      SLE_STRB,C|S,0, _ini_musicdriver,       NULL,    STR_NULL, NULL),
  1190 	  SDTG_STR("musicdriver",      SLE_STRB,C|S,0, _ini_musicdriver,       NULL,    STR_NULL, NULL),
  1191 	  SDTG_STR("sounddriver",      SLE_STRB,C|S,0, _ini_sounddriver,       NULL,    STR_NULL, NULL),
  1191 	  SDTG_STR("sounddriver",      SLE_STRB,C|S,0, _ini_sounddriver,       NULL,    STR_NULL, NULL),
  1281 	 SDT_VAR(Patches, map_x,              SLE_UINT8, S, 0,  8, 6, 11, 0, STR_CONFIG_PATCHES_MAP_X,                 NULL),
  1281 	 SDT_VAR(Patches, map_x,              SLE_UINT8, S, 0,  8, 6, 11, 0, STR_CONFIG_PATCHES_MAP_X,                 NULL),
  1282 	 SDT_VAR(Patches, map_y,              SLE_UINT8, S, 0,  8, 6, 11, 0, STR_CONFIG_PATCHES_MAP_Y,                 NULL),
  1282 	 SDT_VAR(Patches, map_y,              SLE_UINT8, S, 0,  8, 6, 11, 0, STR_CONFIG_PATCHES_MAP_Y,                 NULL),
  1283 	SDT_BOOL(Patches, link_terraform_toolbar,        S, 0, false,        STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR,NULL),
  1283 	SDT_BOOL(Patches, link_terraform_toolbar,        S, 0, false,        STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR,NULL),
  1284 	 SDT_VAR(Patches, liveries,           SLE_UINT8, S,MS,  2, 0,  2, 0, STR_CONFIG_PATCHES_LIVERIES,              RedrawScreen),
  1284 	 SDT_VAR(Patches, liveries,           SLE_UINT8, S,MS,  2, 0,  2, 0, STR_CONFIG_PATCHES_LIVERIES,              RedrawScreen),
  1285 	SDT_BOOL(Patches, prefer_teamchat,               S, 0, false,        STR_CONFIG_PATCHES_PREFER_TEAMCHAT,       NULL),
  1285 	SDT_BOOL(Patches, prefer_teamchat,               S, 0, false,        STR_CONFIG_PATCHES_PREFER_TEAMCHAT,       NULL),
       
  1286 	SDT_VAR(Patches, scrollwheel_scrolling,SLE_UINT8,S,MS, 0,  0,  2, 0, STR_CONFIG_PATCHES_SCROLLWHEEL_SCROLLING, NULL),
       
  1287 	SDT_VAR(Patches,scrollwheel_multiplier,SLE_UINT8,S, 0, 5,  1, 15, 1, STR_CONFIG_PATCHES_SCROLLWHEEL_MULTIPLIER,NULL),
  1286 
  1288 
  1287 	/***************************************************************************/
  1289 	/***************************************************************************/
  1288 	/* Construction section of the GUI-configure patches window */
  1290 	/* Construction section of the GUI-configure patches window */
  1289 	SDT_BOOL(Patches, build_on_slopes,               0, 0,  true,        STR_CONFIG_PATCHES_BUILDONSLOPES,       NULL),
  1291 	SDT_BOOL(Patches, build_on_slopes,               0, 0,  true,        STR_CONFIG_PATCHES_BUILDONSLOPES,       NULL),
  1290 	SDT_BOOL(Patches, extra_dynamite,                0, 0, false,        STR_CONFIG_PATCHES_EXTRADYNAMITE,       NULL),
  1292 	SDT_BOOL(Patches, extra_dynamite,                0, 0, false,        STR_CONFIG_PATCHES_EXTRADYNAMITE,       NULL),
  1500 #undef NC
  1502 #undef NC
  1501 #undef MS
  1503 #undef MS
  1502 #undef NO
  1504 #undef NO
  1503 #undef CR
  1505 #undef CR
  1504 
  1506 
       
  1507 static uint NewsDisplayLoadConfig(IniFile *ini, const char *grpname)
       
  1508 {
       
  1509 	IniGroup *group = ini_getgroup(ini, grpname, -1);
       
  1510 	IniItem *item;
       
  1511 	/* By default, set everything to full (0xAAAAAAAA = 1010101010101010) */
       
  1512 	uint res = 0xAAAAAAAA;
       
  1513 
       
  1514 	/* If no group exists, return everything full */
       
  1515 	if (group == NULL) return res;
       
  1516 
       
  1517 	for (item = group->item; item != NULL; item = item->next) {
       
  1518 		int news_item = -1;
       
  1519 		for (int i = 0; i < NT_END; i++) {
       
  1520 			if (strcasecmp(item->name, _news_display_name[i]) == 0) {
       
  1521 				news_item = i;
       
  1522 				break;
       
  1523 			}
       
  1524 		}
       
  1525 		if (news_item == -1) {
       
  1526 			DEBUG(misc, 0, "Invalid display option: %s", item->name);
       
  1527 			continue;
       
  1528 		}
       
  1529 
       
  1530 		if (strcasecmp(item->value, "full") == 0) {
       
  1531 			SB(res, news_item * 2, 2, 2);
       
  1532 		} else if (strcasecmp(item->value, "off") == 0) {
       
  1533 			SB(res, news_item * 2, 2, 0);
       
  1534 		} else if (strcasecmp(item->value, "summarized") == 0) {
       
  1535 			SB(res, news_item * 2, 2, 1);
       
  1536 		} else {
       
  1537 			DEBUG(misc, 0, "Invalid display value: %s", item->value);
       
  1538 			continue;
       
  1539 		}
       
  1540 	}
       
  1541 
       
  1542 	return res;
       
  1543 }
  1505 
  1544 
  1506 /* Load a GRF configuration from the given group name */
  1545 /* Load a GRF configuration from the given group name */
  1507 static GRFConfig *GRFLoadConfig(IniFile *ini, const char *grpname, bool is_static)
  1546 static GRFConfig *GRFLoadConfig(IniFile *ini, const char *grpname, bool is_static)
  1508 {
  1547 {
  1509 	IniGroup *group = ini_getgroup(ini, grpname, -1);
  1548 	IniGroup *group = ini_getgroup(ini, grpname, -1);
  1528 
  1567 
  1529 		/* Check if item is valid */
  1568 		/* Check if item is valid */
  1530 		if (!FillGRFDetails(c, is_static)) {
  1569 		if (!FillGRFDetails(c, is_static)) {
  1531 			const char *msg;
  1570 			const char *msg;
  1532 
  1571 
  1533 			if (HASBIT(c->flags, GCF_NOT_FOUND)) {
  1572 			if (c->status == GCS_NOT_FOUND) {
  1534 				msg = "not found";
  1573 				msg = "not found";
  1535 			} else if (HASBIT(c->flags, GCF_UNSAFE)) {
  1574 			} else if (HASBIT(c->flags, GCF_UNSAFE)) {
  1536 				msg = "unsafe for static use";
  1575 				msg = "unsafe for static use";
  1537 			} else if (HASBIT(c->flags, GCF_SYSTEM)) {
  1576 			} else if (HASBIT(c->flags, GCF_SYSTEM)) {
  1538 				msg = "system NewGRF";
  1577 				msg = "system NewGRF";
  1554 	}
  1593 	}
  1555 
  1594 
  1556 	return first;
  1595 	return first;
  1557 }
  1596 }
  1558 
  1597 
       
  1598 static void NewsDisplaySaveConfig(IniFile *ini, const char *grpname, uint news_display)
       
  1599 {
       
  1600 	IniGroup *group = ini_getgroup(ini, grpname, -1);
       
  1601 	IniItem **item;
       
  1602 
       
  1603 	if (group == NULL) return;
       
  1604 	group->item = NULL;
       
  1605 	item = &group->item;
       
  1606 
       
  1607 	for (int i = 0; i < NT_END; i++) {
       
  1608 		const char *value;
       
  1609 		int v = GB(news_display, i * 2, 2);
       
  1610 
       
  1611 		value = (v == 0 ? "off" : (v == 1 ? "summarized" : "full"));
       
  1612 
       
  1613 		*item = ini_item_alloc(group, _news_display_name[i], strlen(_news_display_name[i]));
       
  1614 		(*item)->value = (char*)pool_strdup(&ini->pool, value, strlen(value));
       
  1615 		item = &(*item)->next;
       
  1616 	}
       
  1617 }
  1559 
  1618 
  1560 /* Save a GRF configuration to the given group name */
  1619 /* Save a GRF configuration to the given group name */
  1561 static void GRFSaveConfig(IniFile *ini, const char *grpname, const GRFConfig *list)
  1620 static void GRFSaveConfig(IniFile *ini, const char *grpname, const GRFConfig *list)
  1562 {
  1621 {
  1563 	IniGroup *group = ini_getgroup(ini, grpname, -1);
  1622 	IniGroup *group = ini_getgroup(ini, grpname, -1);
  1597 	proc_list(ini, "bans",    _network_ban_list,  lengthof(_network_ban_list), NULL);
  1656 	proc_list(ini, "bans",    _network_ban_list,  lengthof(_network_ban_list), NULL);
  1598 #endif /* ENABLE_NETWORK */
  1657 #endif /* ENABLE_NETWORK */
  1599 }
  1658 }
  1600 
  1659 
  1601 /** Load the values from the configuration files */
  1660 /** Load the values from the configuration files */
  1602 void LoadFromConfig(void)
  1661 void LoadFromConfig()
  1603 {
  1662 {
  1604 	IniFile *ini = ini_load(_config_file);
  1663 	IniFile *ini = ini_load(_config_file);
  1605 	HandleSettingDescs(ini, ini_load_settings, ini_load_setting_list);
  1664 	HandleSettingDescs(ini, ini_load_settings, ini_load_setting_list);
  1606 	_grfconfig_newgame = GRFLoadConfig(ini, "newgrf", false);
  1665 	_grfconfig_newgame = GRFLoadConfig(ini, "newgrf", false);
  1607 	_grfconfig_static  = GRFLoadConfig(ini, "newgrf-static", true);
  1666 	_grfconfig_static  = GRFLoadConfig(ini, "newgrf-static", true);
       
  1667 	_news_display_opt  = NewsDisplayLoadConfig(ini, "news_display");
  1608 	ini_free(ini);
  1668 	ini_free(ini);
  1609 }
  1669 }
  1610 
  1670 
  1611 /** Save the values to the configuration file */
  1671 /** Save the values to the configuration file */
  1612 void SaveToConfig(void)
  1672 void SaveToConfig()
  1613 {
  1673 {
  1614 	IniFile *ini = ini_load(_config_file);
  1674 	IniFile *ini = ini_load(_config_file);
  1615 	HandleSettingDescs(ini, ini_save_settings, ini_save_setting_list);
  1675 	HandleSettingDescs(ini, ini_save_settings, ini_save_setting_list);
  1616 	GRFSaveConfig(ini, "newgrf", _grfconfig_newgame);
  1676 	GRFSaveConfig(ini, "newgrf", _grfconfig_newgame);
  1617 	GRFSaveConfig(ini, "newgrf-static", _grfconfig_static);
  1677 	GRFSaveConfig(ini, "newgrf-static", _grfconfig_static);
       
  1678 	NewsDisplaySaveConfig(ini, "news_display", _news_display_opt);
  1618 	ini_save(_config_file, ini);
  1679 	ini_save(_config_file, ini);
  1619 	ini_free(ini);
  1680 	ini_free(ini);
  1620 }
  1681 }
  1621 
  1682 
  1622 static const SettingDesc *GetSettingDescription(uint index)
  1683 static const SettingDesc *GetSettingDescription(uint index)
  1792 static inline void SaveSettingsGlobList(const SettingDescGlobVarList *sdg)
  1853 static inline void SaveSettingsGlobList(const SettingDescGlobVarList *sdg)
  1793 {
  1854 {
  1794 	SaveSettings((const SettingDesc*)sdg, NULL);
  1855 	SaveSettings((const SettingDesc*)sdg, NULL);
  1795 }
  1856 }
  1796 
  1857 
  1797 static void Load_OPTS(void)
  1858 static void Load_OPTS()
  1798 {
  1859 {
  1799 	/* Copy over default setting since some might not get loaded in
  1860 	/* Copy over default setting since some might not get loaded in
  1800 	 * a networking environment. This ensures for example that the local
  1861 	 * a networking environment. This ensures for example that the local
  1801 	 * autosave-frequency stays when joining a network-server */
  1862 	 * autosave-frequency stays when joining a network-server */
  1802 	_opt = _opt_newgame;
  1863 	_opt = _opt_newgame;
  1803 	LoadSettings(_gameopt_settings, &_opt);
  1864 	LoadSettings(_gameopt_settings, &_opt);
  1804 }
  1865 }
  1805 
  1866 
  1806 static void Save_OPTS(void)
  1867 static void Save_OPTS()
  1807 {
  1868 {
  1808 	SaveSettings(_gameopt_settings, &_opt);
  1869 	SaveSettings(_gameopt_settings, &_opt);
  1809 }
  1870 }
  1810 
  1871 
  1811 static void Load_PATS(void)
  1872 static void Load_PATS()
  1812 {
  1873 {
  1813 	/* Copy over default setting since some might not get loaded in
  1874 	/* Copy over default setting since some might not get loaded in
  1814 	 * a networking environment. This ensures for example that the local
  1875 	 * a networking environment. This ensures for example that the local
  1815 	 * signal_side stays when joining a network-server */
  1876 	 * signal_side stays when joining a network-server */
  1816 	_patches = _patches_newgame;
  1877 	_patches = _patches_newgame;
  1817 	LoadSettings(_patch_settings, &_patches);
  1878 	LoadSettings(_patch_settings, &_patches);
  1818 }
  1879 }
  1819 
  1880 
  1820 static void Save_PATS(void)
  1881 static void Save_PATS()
  1821 {
  1882 {
  1822 	SaveSettings(_patch_settings, &_patches);
  1883 	SaveSettings(_patch_settings, &_patches);
  1823 }
  1884 }
  1824 
  1885 
  1825 void CheckConfig(void)
  1886 void CheckConfig()
  1826 {
  1887 {
  1827 	// fix up news_display_opt from old to new
       
  1828 	int i;
       
  1829 	uint32 tmp;
       
  1830 	for (i = 0, tmp = _news_display_opt; i != 10; i++, tmp >>= 2) {
       
  1831 		if ((tmp & 0x3) == 0x3) { // old settings
       
  1832 			_news_display_opt = 0xAAAAAAAA; // set all news-messages to full 1010101010...
       
  1833 			break;
       
  1834 		}
       
  1835 	}
       
  1836 
       
  1837 	// Increase old default values for pf_maxdepth and pf_maxlength
  1888 	// Increase old default values for pf_maxdepth and pf_maxlength
  1838 	// to support big networks.
  1889 	// to support big networks.
  1839 	if (_patches_newgame.pf_maxdepth == 16 && _patches_newgame.pf_maxlength == 512) {
  1890 	if (_patches_newgame.pf_maxdepth == 16 && _patches_newgame.pf_maxlength == 512) {
  1840 		_patches_newgame.pf_maxdepth = 48;
  1891 		_patches_newgame.pf_maxdepth = 48;
  1841 		_patches_newgame.pf_maxlength = 4096;
  1892 		_patches_newgame.pf_maxlength = 4096;
  1842 	}
  1893 	}
  1843 }
  1894 }
  1844 
  1895 
  1845 void UpdatePatches(void)
  1896 void UpdatePatches()
  1846 {
  1897 {
  1847 	/* Since old(er) savegames don't have any patches saved, we initialise
  1898 	/* Since old(er) savegames don't have any patches saved, we initialise
  1848 	 * them with the default values just as it was in the old days.
  1899 	 * them with the default values just as it was in the old days.
  1849 	 * Also new games need this copying-over */
  1900 	 * Also new games need this copying-over */
  1850 	_patches = _patches_newgame; /* backwards compatibility */
  1901 	_patches = _patches_newgame; /* backwards compatibility */