1 /*
2 Copyright (C) 2003 - 2018 by David White <dave@whitevine.net>
3 Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY.
11
12 See the COPYING file for more details.
13 */
14
15 /**
16 * @file
17 * Get and set user-preferences.
18 */
19
20 #define GETTEXT_DOMAIN "wesnoth-lib"
21
22 #include "preferences/general.hpp"
23
24 #include "config.hpp"
25 #include "credentials.hpp"
26 #include "filesystem.hpp"
27 #include "game_config.hpp"
28 #include "hotkey/hotkey_item.hpp"
29 #include "lexical_cast.hpp"
30 #include "log.hpp"
31 #include "sdl/point.hpp"
32 #include "serialization/parser.hpp"
33 #include "sound.hpp"
34 #include "utils/general.hpp"
35 #include "video.hpp" // non_interactive()
36
37 #include <sys/stat.h> // for setting the permissions of the preferences file
38 #ifndef _WIN32
39 #include <unistd.h>
40 #endif
41
42 static lg::log_domain log_config("config");
43 #define ERR_CFG LOG_STREAM(err , log_config)
44
45 static lg::log_domain log_filesystem("filesystem");
46 #define ERR_FS LOG_STREAM(err, log_filesystem)
47
48 namespace {
49
50 bool no_preferences_save = false;
51
52 bool fps = false;
53
54 config prefs;
55 }
56
57 namespace preferences {
58
59 /*
60 * Stores all the static, default values for certain game preferences. The values
61 * are kept here for easy modification without a lengthy rebuild.
62 *
63 * Add any variables of similar type here.
64 */
65 const int min_window_width = 800;
66 const int min_window_height = 600;
67
68 const int def_window_width = 1280;
69 const int def_window_height = 720;
70
71 const int min_font_scaling = 80;
72 const int max_font_scaling = 150;
73
74 const SCALING_ALGORITHM default_scaling_algorithm = SCALING_ALGORITHM::XBRZ_NN;
75
76 class prefs_event_handler : public events::sdl_handler {
77 public:
handle_event(const SDL_Event &)78 virtual void handle_event(const SDL_Event &) {}
79 virtual void handle_window_event(const SDL_Event &event);
prefs_event_handler()80 prefs_event_handler() : sdl_handler(false) {}
81 };
82
83 prefs_event_handler event_handler_;
84
base_manager()85 base_manager::base_manager()
86 {
87 event_handler_.join_global();
88
89 try{
90 #ifdef DEFAULT_PREFS_PATH
91 filesystem::scoped_istream stream = filesystem::istream_file(filesystem::get_default_prefs_file(),false);
92 read(prefs, *stream);
93
94 config user_prefs;
95 stream = filesystem::istream_file(filesystem::get_prefs_file());
96 read(user_prefs, *stream);
97
98 prefs.merge_with(user_prefs);
99 #else
100 filesystem::scoped_istream stream = filesystem::istream_file(filesystem::get_prefs_file(),false);
101 read(prefs, *stream);
102 #endif
103 } catch(const config::error& e) {
104 ERR_CFG << "Error loading preference, message: "
105 << e.what()
106 << std::endl;
107 }
108 preferences::load_credentials();
109 }
110
~base_manager()111 base_manager::~base_manager()
112 {
113 event_handler_.leave_global();
114
115 try {
116 if (no_preferences_save) return;
117
118 // Set the 'hidden' preferences.
119 prefs["scroll_threshold"] = mouse_scroll_threshold();
120
121 write_preferences();
122 } catch (...) {}
123 }
124
125 /*
126 * Hook for setting window state variables on window resize and maximize
127 * events. Since there is no fullscreen window event, that setter is called
128 * from the CVideo function instead.
129 */
handle_window_event(const SDL_Event & event)130 void prefs_event_handler::handle_window_event(const SDL_Event& event)
131 {
132
133 // Safety check to make sure this is a window event
134 if (event.type != SDL_WINDOWEVENT) return;
135
136 switch(event.window.event) {
137 case SDL_WINDOWEVENT_RESIZED:
138 _set_resolution(point(event.window.data1,event.window.data2));
139
140 break;
141
142 case SDL_WINDOWEVENT_MAXIMIZED:
143 _set_maximized(true);
144
145 break;
146
147 case SDL_WINDOWEVENT_RESTORED:
148 _set_maximized(fullscreen() || false);
149
150 break;
151 }
152 }
153
write_preferences()154 void write_preferences()
155 {
156 #ifndef _WIN32
157 bool prefs_file_existed = access(filesystem::get_prefs_file().c_str(), F_OK) == 0;
158 #endif
159
160 try {
161 filesystem::scoped_ostream prefs_file = filesystem::ostream_file(filesystem::get_prefs_file());
162 write(*prefs_file, prefs);
163 } catch(const filesystem::io_exception&) {
164 ERR_FS << "error writing to preferences file '" << filesystem::get_prefs_file() << "'" << std::endl;
165 }
166
167 preferences::save_credentials();
168
169 #ifndef _WIN32
170 if(!prefs_file_existed) {
171
172 if(chmod(filesystem::get_prefs_file().c_str(), 0600) == -1) {
173 ERR_FS << "error setting permissions of preferences file '" << filesystem::get_prefs_file() << "'" << std::endl;
174 }
175
176 }
177 #endif
178 }
179
set(const std::string & key,bool value)180 void set(const std::string &key, bool value)
181 {
182 prefs[key] = value;
183 }
184
set(const std::string & key,int value)185 void set(const std::string &key, int value)
186 {
187 prefs[key] = value;
188 }
189
set(const std::string & key,char const * value)190 void set(const std::string &key, char const *value)
191 {
192 prefs[key] = value;
193 }
194
set(const std::string & key,const std::string & value)195 void set(const std::string &key, const std::string &value)
196 {
197 prefs[key] = value;
198 }
199
set(const std::string & key,const config::attribute_value & value)200 void set(const std::string &key, const config::attribute_value &value)
201 {
202 prefs[key] = value;
203 }
204
clear(const std::string & key)205 void clear(const std::string& key)
206 {
207 prefs.recursive_clear_value(key);
208 }
209
set_child(const std::string & key,const config & val)210 void set_child(const std::string& key, const config& val) {
211 prefs.clear_children(key);
212 prefs.add_child(key, val);
213 }
214
get_child(const std::string & key)215 const config &get_child(const std::string& key)
216 {
217 return prefs.child(key);
218 }
219
erase(const std::string & key)220 void erase(const std::string& key) {
221 prefs.remove_attribute(key);
222 }
223
have_setting(const std::string & key)224 bool have_setting(const std::string& key) {
225 return prefs.has_attribute(key);
226 }
227
get(const std::string & key)228 std::string get(const std::string& key) {
229 return prefs[key];
230 }
231
get(const std::string & key,const std::string & def)232 std::string get(const std::string& key, const std::string& def) {
233 return prefs[key].empty() ? def : prefs[key];
234 }
235
get(const std::string & key,bool def)236 bool get(const std::string &key, bool def)
237 {
238 return prefs[key].to_bool(def);
239 }
240
get_as_attribute(const std::string & key)241 config::attribute_value get_as_attribute(const std::string &key)
242 {
243 return prefs[key];
244 }
245
disable_preferences_save()246 void disable_preferences_save() {
247 no_preferences_save = true;
248 }
249
get_prefs()250 config* get_prefs(){
251 config* pointer = &prefs;
252 return pointer;
253 }
254
255
show_allied_orb()256 bool show_allied_orb() {
257 return get("show_ally_orb", game_config::show_ally_orb);
258 }
set_show_allied_orb(bool show_orb)259 void set_show_allied_orb(bool show_orb) {
260 prefs["show_ally_orb"] = show_orb;
261 }
262
show_enemy_orb()263 bool show_enemy_orb() {
264 return get("show_enemy_orb", game_config::show_enemy_orb);
265 }
set_show_enemy_orb(bool show_orb)266 void set_show_enemy_orb(bool show_orb) {
267 prefs["show_enemy_orb"] = show_orb;
268 }
269
show_moved_orb()270 bool show_moved_orb() {
271 return get("show_moved_orb", game_config::show_moved_orb);
272 }
set_show_moved_orb(bool show_orb)273 void set_show_moved_orb(bool show_orb) {
274 prefs["show_moved_orb"] = show_orb;
275 }
276
show_unmoved_orb()277 bool show_unmoved_orb() {
278 return get("show_unmoved_orb", game_config::show_unmoved_orb);
279 }
set_show_unmoved_orb(bool show_orb)280 void set_show_unmoved_orb(bool show_orb) {
281 prefs["show_unmoved_orb"] = show_orb;
282 }
283
show_partial_orb()284 bool show_partial_orb() {
285 return get("show_partial_orb", game_config::show_partial_orb);
286 }
set_show_partial_orb(bool show_orb)287 void set_show_partial_orb(bool show_orb) {
288 prefs["show_partial_orb"] = show_orb;
289 }
290
291
fix_orb_color_name(const std::string & color)292 static std::string fix_orb_color_name(const std::string& color) {
293 if (color.substr(0,4) == "orb_") {
294 if(color[4] >= '0' && color[4] <= '9') {
295 return color.substr(5);
296 } else {
297 return color.substr(4);
298 }
299 }
300 return color;
301 }
302
allied_color()303 std::string allied_color() {
304 std::string ally_color = get("ally_orb_color");
305 if (ally_color.empty())
306 return game_config::colors::ally_orb_color;
307 return fix_orb_color_name(ally_color);
308 }
set_allied_color(const std::string & color_id)309 void set_allied_color(const std::string& color_id) {
310 prefs["ally_orb_color"] = color_id;
311 }
312
core_id()313 std::string core_id() {
314 std::string core_id = get("core");
315 if (core_id.empty())
316 return "default";
317 return core_id;
318 }
set_core_id(const std::string & core_id)319 void set_core_id(const std::string& core_id) {
320 prefs["core"] = core_id;
321 }
322
enemy_color()323 std::string enemy_color() {
324 std::string enemy_color = get("enemy_orb_color");
325 if (enemy_color.empty())
326 return game_config::colors::enemy_orb_color;
327 return fix_orb_color_name(enemy_color);
328 }
set_enemy_color(const std::string & color_id)329 void set_enemy_color(const std::string& color_id) {
330 prefs["enemy_orb_color"] = color_id;
331 }
332
moved_color()333 std::string moved_color() {
334 std::string moved_color = get("moved_orb_color");
335 if (moved_color.empty())
336 return game_config::colors::moved_orb_color;
337 return fix_orb_color_name(moved_color);
338 }
set_moved_color(const std::string & color_id)339 void set_moved_color(const std::string& color_id) {
340 prefs["moved_orb_color"] = color_id;
341 }
342
unmoved_color()343 std::string unmoved_color() {
344 std::string unmoved_color = get("unmoved_orb_color");
345 if (unmoved_color.empty())
346 return game_config::colors::unmoved_orb_color;
347 return fix_orb_color_name(unmoved_color);
348 }
set_unmoved_color(const std::string & color_id)349 void set_unmoved_color(const std::string& color_id) {
350 prefs["unmoved_orb_color"] = color_id;
351 }
352
partial_color()353 std::string partial_color() {
354 std::string partmoved_color = get("partial_orb_color");
355 if (partmoved_color.empty())
356 return game_config::colors::partial_orb_color;
357 return fix_orb_color_name(partmoved_color);
358 }
set_partial_color(const std::string & color_id)359 void set_partial_color(const std::string& color_id) {
360 prefs["partial_orb_color"] = color_id;
361 }
362
scroll_to_action()363 bool scroll_to_action()
364 {
365 return get("scroll_to_action", true);
366 }
367
set_scroll_to_action(bool ison)368 void set_scroll_to_action(bool ison)
369 {
370 prefs["scroll_to_action"] = ison;
371 }
372
resolution()373 point resolution()
374 {
375 const unsigned x_res = prefs["xresolution"].to_unsigned();
376 const unsigned y_res = prefs["yresolution"].to_unsigned();
377
378 // Either resolution was unspecified, return default.
379 if(x_res == 0 || y_res == 0) {
380 return point(def_window_width, def_window_height);
381 }
382
383 return point(
384 std::max<unsigned>(x_res, min_window_width),
385 std::max<unsigned>(y_res, min_window_height)
386 );
387 }
388
maximized()389 bool maximized()
390 {
391 return get("maximized", !fullscreen());
392 }
393
fullscreen()394 bool fullscreen()
395 {
396 return get("fullscreen", true);
397 }
398
_set_resolution(const point & res)399 void _set_resolution(const point& res)
400 {
401 preferences::set("xresolution", std::to_string(res.x));
402 preferences::set("yresolution", std::to_string(res.y));
403 }
404
_set_maximized(bool ison)405 void _set_maximized(bool ison)
406 {
407 prefs["maximized"] = ison;
408 }
409
_set_fullscreen(bool ison)410 void _set_fullscreen(bool ison)
411 {
412 prefs["fullscreen"] = ison;
413 }
414
turbo()415 bool turbo()
416 {
417 if(CVideo::get_singleton().non_interactive()) {
418 return true;
419 }
420
421 return get("turbo", false);
422 }
423
_set_turbo(bool ison)424 void _set_turbo(bool ison)
425 {
426 prefs["turbo"] = ison;
427 }
428
turbo_speed()429 double turbo_speed()
430 {
431 return prefs["turbo_speed"].to_double(2.0);
432 }
433
save_turbo_speed(const double speed)434 void save_turbo_speed(const double speed)
435 {
436 prefs["turbo_speed"] = speed;
437 }
438
font_scaling()439 int font_scaling()
440 {
441 // Clip at 80 because if it's too low it'll cause crashes
442 return std::max<int>(std::min<int>(prefs["font_scale"].to_int(100), max_font_scaling), min_font_scaling);
443 }
444
set_font_scaling(int scale)445 void set_font_scaling(int scale)
446 {
447 prefs["font_scale"] = utils::clamp(scale, min_font_scaling, max_font_scaling);
448 }
449
font_scaled(int size)450 int font_scaled(int size)
451 {
452 return (size * font_scaling()) / 100;
453 }
454
idle_anim()455 bool idle_anim()
456 {
457 return get("idle_anim", true);
458 }
459
_set_idle_anim(const bool ison)460 void _set_idle_anim(const bool ison)
461 {
462 prefs["idle_anim"] = ison;
463 }
464
idle_anim_rate()465 int idle_anim_rate()
466 {
467 return prefs["idle_anim_rate"];
468 }
469
_set_idle_anim_rate(const int rate)470 void _set_idle_anim_rate(const int rate)
471 {
472 prefs["idle_anim_rate"] = rate;
473 }
474
language()475 std::string language()
476 {
477 return prefs["locale"];
478 }
479
set_language(const std::string & s)480 void set_language(const std::string& s)
481 {
482 preferences::set("locale", s);
483 }
484
gui_theme()485 std::string gui_theme()
486 {
487 return prefs["gui2_theme"];
488 }
489
set_gui_theme(const std::string & s)490 void set_gui_theme(const std::string& s)
491 {
492 preferences::set("gui2_theme", s);
493 }
494
ellipses()495 bool ellipses()
496 {
497 return get("show_side_colors", false);
498 }
499
set_ellipses(bool ison)500 void set_ellipses(bool ison)
501 {
502 preferences::set("show_side_colors", ison);
503 }
504
grid()505 bool grid()
506 {
507 return get("grid", false);
508 }
509
_set_grid(bool ison)510 void _set_grid(bool ison)
511 {
512 preferences::set("grid", ison);
513 }
514
sound_buffer_size()515 size_t sound_buffer_size()
516 {
517 // Sounds don't sound good on Windows unless the buffer size is 4k,
518 // but this seems to cause crashes on other systems...
519 #ifdef _WIN32
520 const size_t buf_size = 4096;
521 #else
522 const size_t buf_size = 1024;
523 #endif
524
525 return prefs["sound_buffer_size"].to_int(buf_size);
526 }
527
save_sound_buffer_size(const size_t size)528 void save_sound_buffer_size(const size_t size)
529 {
530 #ifdef _WIN32
531 const char* buf_size = "4096";
532 #else
533 const char* buf_size = "1024";
534 #endif
535
536 const std::string new_size = lexical_cast_default<std::string>(size, buf_size);
537 if (get("sound_buffer_size") == new_size)
538 return;
539
540 preferences::set("sound_buffer_size", new_size);
541
542 sound::reset_sound();
543 }
544
music_volume()545 int music_volume()
546 {
547 return prefs["music_volume"].to_int(100);
548 }
549
set_music_volume(int vol)550 void set_music_volume(int vol)
551 {
552 if(music_volume() == vol) {
553 return;
554 }
555
556 prefs["music_volume"] = vol;
557 sound::set_music_volume(music_volume());
558 }
559
sound_volume()560 int sound_volume()
561 {
562 return prefs["sound_volume"].to_int(100);
563 }
564
set_sound_volume(int vol)565 void set_sound_volume(int vol)
566 {
567 if(sound_volume() == vol) {
568 return;
569 }
570
571 prefs["sound_volume"] = vol;
572 sound::set_sound_volume(sound_volume());
573 }
574
bell_volume()575 int bell_volume()
576 {
577 return prefs["bell_volume"].to_int(100);
578 }
579
set_bell_volume(int vol)580 void set_bell_volume(int vol)
581 {
582 if(bell_volume() == vol) {
583 return;
584 }
585
586 prefs["bell_volume"] = vol;
587 sound::set_bell_volume(bell_volume());
588 }
589
UI_volume()590 int UI_volume()
591 {
592 return prefs["UI_volume"].to_int(100);
593 }
594
set_UI_volume(int vol)595 void set_UI_volume(int vol)
596 {
597 if(UI_volume() == vol) {
598 return;
599 }
600
601 prefs["UI_volume"] = vol;
602 sound::set_UI_volume(UI_volume());
603 }
604
turn_bell()605 bool turn_bell()
606 {
607 return get("turn_bell", true);
608 }
609
set_turn_bell(bool ison)610 bool set_turn_bell(bool ison)
611 {
612 if(!turn_bell() && ison) {
613 preferences::set("turn_bell", true);
614 if(!music_on() && !sound_on() && !UI_sound_on()) {
615 if(!sound::init_sound()) {
616 preferences::set("turn_bell", false);
617 return false;
618 }
619 }
620 } else if(turn_bell() && !ison) {
621 preferences::set("turn_bell", false);
622 sound::stop_bell();
623 if(!music_on() && !sound_on() && !UI_sound_on())
624 sound::close_sound();
625 }
626 return true;
627 }
628
UI_sound_on()629 bool UI_sound_on()
630 {
631 return get("UI_sound", true);
632 }
633
set_UI_sound(bool ison)634 bool set_UI_sound(bool ison)
635 {
636 if(!UI_sound_on() && ison) {
637 preferences::set("UI_sound", true);
638 if(!music_on() && !sound_on() && !turn_bell()) {
639 if(!sound::init_sound()) {
640 preferences::set("UI_sound", false);
641 return false;
642 }
643 }
644 } else if(UI_sound_on() && !ison) {
645 preferences::set("UI_sound", false);
646 sound::stop_UI_sound();
647 if(!music_on() && !sound_on() && !turn_bell())
648 sound::close_sound();
649 }
650 return true;
651 }
652
message_bell()653 bool message_bell()
654 {
655 return get("message_bell", true);
656 }
657
sound_on()658 bool sound_on()
659 {
660 return get("sound", true);
661 }
662
set_sound(bool ison)663 bool set_sound(bool ison) {
664 if(!sound_on() && ison) {
665 preferences::set("sound", true);
666 if(!music_on() && !turn_bell() && !UI_sound_on()) {
667 if(!sound::init_sound()) {
668 preferences::set("sound", false);
669 return false;
670 }
671 }
672 } else if(sound_on() && !ison) {
673 preferences::set("sound", false);
674 sound::stop_sound();
675 if(!music_on() && !turn_bell() && !UI_sound_on())
676 sound::close_sound();
677 }
678 return true;
679 }
680
music_on()681 bool music_on()
682 {
683 return get("music", true);
684 }
685
set_music(bool ison)686 bool set_music(bool ison) {
687 if(!music_on() && ison) {
688 preferences::set("music", true);
689 if(!sound_on() && !turn_bell() && !UI_sound_on()) {
690 if(!sound::init_sound()) {
691 preferences::set("music", false);
692 return false;
693 }
694 }
695 else
696 sound::play_music();
697 } else if(music_on() && !ison) {
698 preferences::set("music", false);
699 if(!sound_on() && !turn_bell() && !UI_sound_on())
700 sound::close_sound();
701 else
702 sound::stop_music();
703 }
704 return true;
705 }
706
stop_music_in_background()707 bool stop_music_in_background()
708 {
709 return get("stop_music_in_background", false);
710 }
711
set_stop_music_in_background(bool ison)712 void set_stop_music_in_background(bool ison)
713 {
714 preferences::set("stop_music_in_background", ison);
715 }
716
717 namespace {
718 double scroll = 0.2;
719 }
720
joystick_support_enabled()721 bool joystick_support_enabled()
722 {
723 return get("joystick_support_enabled", false);
724 }
725
joystick_mouse_deadzone()726 int joystick_mouse_deadzone()
727 {
728 const int value = utils::clamp<int>(lexical_cast_default<int>(get("joystick_scroll_deadzone"), 1500), 0, 16000);
729 return value;
730 }
731
joystick_num_mouse_xaxis()732 int joystick_num_mouse_xaxis()
733 {
734 const int value = utils::clamp<int>(lexical_cast_default<int>(get("joystick_num_scroll_xaxis"), 0), -1, 3);
735 return value;
736 }
737
joystick_mouse_xaxis_num()738 int joystick_mouse_xaxis_num()
739 {
740 const int value = utils::clamp<int>(lexical_cast_default<int>(get("joystick_scroll_xaxis_num"), 0), 0, 7);
741 return value;
742 }
743
joystick_num_mouse_yaxis()744 int joystick_num_mouse_yaxis()
745 {
746 const int value = utils::clamp<int>(lexical_cast_default<int>(get("joystick_num_scroll_yaxis"), 0), -1, 3);
747 return value;
748 }
749
joystick_mouse_yaxis_num()750 int joystick_mouse_yaxis_num()
751 {
752 const int value = utils::clamp<int>(lexical_cast_default<int>(get("joystick_scroll_yaxis_num"), 1), 0, 7);
753 return value;
754 }
755
joystick_scroll_deadzone()756 int joystick_scroll_deadzone()
757 {
758 const int value = utils::clamp<int>(lexical_cast_default<int>(get("joystick_scroll_deadzone"), 1500), 0, 16000);
759 return value;
760 }
761
joystick_cursor_deadzone()762 int joystick_cursor_deadzone()
763 {
764 const int value = utils::clamp<int>(lexical_cast_default<int>(get("joystick_cursor_deadzone"), 1500), 0, 16000);
765 return value;
766 }
767
joystick_thrusta_deadzone()768 int joystick_thrusta_deadzone()
769 {
770 const int value = utils::clamp<int>(lexical_cast_default<int>(get("joystick_thrusta_deadzone"), 1500), 0, 16000);
771 return value;
772 }
773
joystick_thrustb_deadzone()774 int joystick_thrustb_deadzone()
775 {
776 const int value = utils::clamp<int>(lexical_cast_default<int>(get("joystick_thrustb_deadzone"), 1500), 0, 16000);
777 return value;
778 }
779
joystick_cursor_threshold()780 int joystick_cursor_threshold()
781 {
782 const int value = utils::clamp<int>(lexical_cast_default<int>(get("joystick_cursor_threshold"), 10000), 0, 16000);
783 return value;
784 }
785
joystick_num_scroll_xaxis()786 int joystick_num_scroll_xaxis()
787 {
788 const int value = utils::clamp<int>(lexical_cast_default<int>(get("joystick_num_scroll_xaxis"), 0), -1, 3);
789 return value;
790 }
791
joystick_scroll_xaxis_num()792 int joystick_scroll_xaxis_num()
793 {
794 const int value = utils::clamp<int>(lexical_cast_default<int>(get("joystick_scroll_xaxis_num"), 0), 0, 7);
795 return value;
796 }
797
joystick_num_scroll_yaxis()798 int joystick_num_scroll_yaxis()
799 {
800 const int value = utils::clamp<int>(lexical_cast_default<int>(get("joystick_num_scroll_yaxis"), 0), -1, 3);
801 return value;
802 }
803
joystick_scroll_yaxis_num()804 int joystick_scroll_yaxis_num()
805 {
806 const int value = utils::clamp<int>(lexical_cast_default<int>(get("joystick_scroll_yaxis_num"), 1), 0, 7);
807 return value;
808 }
809
joystick_num_cursor_xaxis()810 int joystick_num_cursor_xaxis()
811 {
812 const int value = utils::clamp<int>(lexical_cast_default<int>(get("joystick_num_cursor_xaxis"), 0), -1, 3);
813 return value;
814 }
815
joystick_cursor_xaxis_num()816 int joystick_cursor_xaxis_num()
817 {
818 const int value = utils::clamp<int>(lexical_cast_default<int>(get("joystick_cursor_xaxis_num"), 3), 0, 7);
819 return value;
820 }
821
joystick_num_cursor_yaxis()822 int joystick_num_cursor_yaxis()
823 {
824 const int value = utils::clamp<int>(lexical_cast_default<int>(get("joystick_num_cursor_yaxis"), 0), -1, 3);
825 return value;
826 }
827
joystick_cursor_yaxis_num()828 int joystick_cursor_yaxis_num()
829 {
830 const int value = utils::clamp<int>(lexical_cast_default<int>(get("joystick_cursor_yaxis_num"), 4), 0, 7);
831 return value;
832 }
833
joystick_num_thrusta_axis()834 int joystick_num_thrusta_axis()
835 {
836 const int value = utils::clamp<int>(lexical_cast_default<int>(get("joystick_num_thrusta_axis"), 0), -1, 3);
837 return value;
838 }
839
joystick_thrusta_axis_num()840 int joystick_thrusta_axis_num()
841 {
842 const int value = utils::clamp<int>(lexical_cast_default<int>(get("joystick_thrusta_axis_num"), 2), 0, 7);
843 return value;
844 }
845
joystick_num_thrustb_axis()846 int joystick_num_thrustb_axis()
847 {
848 const int value = utils::clamp<int>(lexical_cast_default<int>(get("joystick_num_thrustb_axis"), 0), -1, 3);
849 return value;
850 }
851
joystick_thrustb_axis_num()852 int joystick_thrustb_axis_num()
853 {
854 const int value = utils::clamp<int>(lexical_cast_default<int>(get("joystick_thrustb_axis_num"), 2), 0, 7);
855 return value;
856 }
857
858
scroll_speed()859 int scroll_speed()
860 {
861 const int value = utils::clamp<int>(lexical_cast_default<int>(get("scroll"), 50), 1, 100);
862 scroll = value/100.0;
863
864 return value;
865 }
866
set_scroll_speed(const int new_speed)867 void set_scroll_speed(const int new_speed)
868 {
869 prefs["scroll"] = new_speed;
870 scroll = new_speed / 100.0;
871 }
872
middle_click_scrolls()873 bool middle_click_scrolls()
874 {
875 return get("middle_click_scrolls", true);
876 }
877
mouse_scroll_enabled()878 bool mouse_scroll_enabled()
879 {
880 return get("mouse_scrolling", true);
881 }
882
enable_mouse_scroll(bool value)883 void enable_mouse_scroll(bool value)
884 {
885 set("mouse_scrolling", value);
886 }
887
mouse_scroll_threshold()888 int mouse_scroll_threshold()
889 {
890 return prefs["scroll_threshold"].to_int(10);
891 }
892
animate_map()893 bool animate_map()
894 {
895 return preferences::get("animate_map", true);
896 }
897
animate_water()898 bool animate_water()
899 {
900 return preferences::get("animate_water", true);
901 }
902
minimap_movement_coding()903 bool minimap_movement_coding()
904 {
905 return preferences::get("minimap_movement_coding", true);
906 }
907
toggle_minimap_movement_coding()908 void toggle_minimap_movement_coding()
909 {
910 set("minimap_movement_coding", !minimap_movement_coding());
911 }
912
minimap_terrain_coding()913 bool minimap_terrain_coding()
914 {
915 return preferences::get("minimap_terrain_coding", true);
916 }
917
toggle_minimap_terrain_coding()918 void toggle_minimap_terrain_coding()
919 {
920 set("minimap_terrain_coding", !minimap_terrain_coding());
921 }
922
minimap_draw_units()923 bool minimap_draw_units()
924 {
925 return preferences::get("minimap_draw_units", true);
926 }
927
toggle_minimap_draw_units()928 void toggle_minimap_draw_units()
929 {
930 set("minimap_draw_units", !minimap_draw_units());
931 }
932
minimap_draw_villages()933 bool minimap_draw_villages()
934 {
935 return preferences::get("minimap_draw_villages", true);
936 }
937
toggle_minimap_draw_villages()938 void toggle_minimap_draw_villages()
939 {
940 set("minimap_draw_villages", !minimap_draw_villages());
941 }
942
minimap_draw_terrain()943 bool minimap_draw_terrain()
944 {
945 return preferences::get("minimap_draw_terrain", true);
946 }
947
toggle_minimap_draw_terrain()948 void toggle_minimap_draw_terrain()
949 {
950 set("minimap_draw_terrain", !minimap_draw_terrain());
951 }
952
set_animate_map(bool value)953 void set_animate_map(bool value)
954 {
955 set("animate_map", value);
956 }
957
set_animate_water(bool value)958 void set_animate_water(bool value)
959 {
960 set("animate_water", value);
961 }
962
show_fps()963 bool show_fps()
964 {
965 return fps;
966 }
967
set_show_fps(bool value)968 void set_show_fps(bool value)
969 {
970 fps = value;
971 }
972
draw_delay()973 int draw_delay()
974 {
975 return prefs["draw_delay"].to_int(-1);
976 }
977
set_draw_delay(int value)978 void set_draw_delay(int value)
979 {
980 prefs["draw_delay"] = value;
981 }
982
use_color_cursors()983 bool use_color_cursors()
984 {
985 return get("color_cursors", true);
986 }
987
_set_color_cursors(bool value)988 void _set_color_cursors(bool value)
989 {
990 preferences::set("color_cursors", value);
991 }
992
load_hotkeys()993 void load_hotkeys()
994 {
995 hotkey::load_hotkeys(prefs, false);
996 }
997
save_hotkeys()998 void save_hotkeys()
999 {
1000 hotkey::save_hotkeys(prefs);
1001 }
1002
clear_hotkeys()1003 void clear_hotkeys()
1004 {
1005 hotkey::reset_default_hotkeys();
1006 prefs.clear_children("hotkey");
1007 }
1008
add_alias(const std::string & alias,const std::string & command)1009 void add_alias(const std::string &alias, const std::string &command)
1010 {
1011 config &alias_list = prefs.child_or_add("alias");
1012 alias_list[alias] = command;
1013 }
1014
1015
get_alias()1016 const config &get_alias()
1017 {
1018 return get_child("alias");
1019 }
1020
sample_rate()1021 unsigned int sample_rate()
1022 {
1023 return prefs["sample_rate"].to_int(44100);
1024 }
1025
save_sample_rate(const unsigned int rate)1026 void save_sample_rate(const unsigned int rate)
1027 {
1028 if (sample_rate() == rate)
1029 return;
1030
1031 prefs["sample_rate"] = static_cast<int>(rate);
1032
1033 // If audio is open, we have to re set sample rate
1034 sound::reset_sound();
1035 }
1036
confirm_load_save_from_different_version()1037 bool confirm_load_save_from_different_version()
1038 {
1039 return get("confirm_load_save_from_different_version", true);
1040 }
1041
use_twelve_hour_clock_format()1042 bool use_twelve_hour_clock_format()
1043 {
1044 return get("use_twelve_hour_clock_format", false);
1045 }
1046
disable_auto_moves()1047 bool disable_auto_moves()
1048 {
1049 return get("disable_auto_moves", false);
1050 }
1051
set_disable_auto_moves(bool value)1052 void set_disable_auto_moves(bool value)
1053 {
1054 preferences::set("disable_auto_moves", value);
1055 }
1056
disable_loadingscreen_animation()1057 bool disable_loadingscreen_animation()
1058 {
1059 return get("disable_loadingscreen_animation", false);
1060 }
1061
set_disable_loadingscreen_animation(bool value)1062 void set_disable_loadingscreen_animation(bool value)
1063 {
1064 set("disable_loadingscreen_animation", value);
1065 }
1066
damage_prediction_allow_monte_carlo_simulation()1067 bool damage_prediction_allow_monte_carlo_simulation()
1068 {
1069 return get("damage_prediction_allow_monte_carlo_simulation", true);
1070 }
1071
set_damage_prediction_allow_monte_carlo_simulation(bool value)1072 void set_damage_prediction_allow_monte_carlo_simulation(bool value)
1073 {
1074 set("damage_prediction_allow_monte_carlo_simulation", value);
1075 }
1076
1077 } // end namespace preferences
1078