2 * Copyright (c) 2007-2013, Czirkos Zoltan http://code.google.com/p/gdash/
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include <glib/gi18n.h>
23 #include "settings.hpp"
24 #include "misc/logger.hpp"
25 #include "misc/printf.hpp"
26 #include "misc/util.hpp"
27 #include "cave/gamerender.hpp"
28 #include "gfx/pixbuffactory.hpp"
29 #include "input/gameinputhandler.hpp"
36 #include <gdk/gdkkeysyms.h>
40 #define SETTINGS_INI_FILE "gdash.ini"
41 #define SETTINGS_GDASH_GROUP "GDash"
43 /* possible languages. */
44 /* they are not translated, so every language name is show in that language itself. */
45 const char *gd_languages_names
[]={N_("System default"), "English", "Deutsch", "Magyar", NULL
};
47 /* this should correspond to the above one. */
49 /* locale names used in windows. */
50 static const char *language_locale_default
[]= { "", NULL
, };
51 static const char *language_locale_en
[]= { "English", NULL
, };
52 static const char *language_locale_de
[]= { "German", NULL
, };
53 static const char *language_locale_hu
[]= { "Hungarian", NULL
, };
54 /* these will be used on windows for a putenv to trick gtk. */
55 /* on linux, the setlocale call works correctly, and this is not needed. */
56 static const char *languages_for_env
[]={ NULL
, "en", "de", "hu" };
58 /* locale names used in unix. */
59 /* anyone, a better solution for this? */
60 static const char *language_locale_default
[]=
62 static const char *language_locale_en
[]=
63 { "en_US.UTF-8", "en_US.UTF8", "en_US.ISO8859-15", "en_US.ISO8859-1", "en_US.US-ASCII", "en_US", "en", NULL
, };
64 static const char *language_locale_de
[]=
65 { "de_DE.UTF-8", "de_DE.UTF8", "de_DE.ISO8859-15", "de_DE.ISO8859-1", "de_DE",
66 "de_AT.UTF-8", "de_AT.UTF8", "de_AT.ISO8859-15", "de_AT.ISO8859-1", "de_AT",
67 "de_CH.UTF-8", "de_CH.UTF8", "de_CH.ISO8859-15", "de_CH.ISO8859-1", "de_CH",
69 static const char *language_locale_hu
[]=
70 { "hu_HU.UTF-8", "hu_HU.ISO8859-2", "hu_HU", "hu", NULL
, };
71 #endif /* ifdef g_os_win32 else */
73 /* put the locales to be tried in an array - same for windows and unix */
74 static const char **language_locale
[]={
75 language_locale_default
,
82 static std::map
<char const *, int *> settings_integers
;
83 static std::map
<char const *, bool *> settings_bools
;
84 static std::map
<char const *, std::string
*> settings_strings
;
87 /* universal settings */
88 std::string gd_username
;
90 bool gd_no_invisible_outbox
=false;
91 bool gd_all_caves_selectable
=false;
92 bool gd_import_as_all_caves_selectable
=false;
93 bool gd_use_bdcff_highscore
=false;
94 int gd_pal_emu_scanline_shade
=80;
95 bool gd_fine_scroll
=false;
96 bool gd_particle_effects
=true;
97 bool gd_show_story
=true;
98 bool gd_show_name_of_game
=true;
99 int gd_status_bar_colors
=GD_STATUS_BAR_ORIGINAL
;
101 /* palette settings */
102 int gd_c64_palette
=0;
103 int gd_c64dtv_palette
=0;
104 int gd_atari_palette
=0;
105 int gd_preferred_palette
=GdColor::TypeRGB
;
106 /* editor settings */
107 bool gd_game_view
=true; /* show animated cells instead of arrows & ... */
108 bool gd_colored_objects
=true; /* show objects with different color */
109 bool gd_show_object_list
=true; /* show object list */
110 bool gd_show_test_label
=true; /* show a label with some variables, for testing */
111 int gd_editor_window_width
=800; /* window size */
112 int gd_editor_window_height
=520; /* window size */
113 bool gd_fast_uncover_in_test
= true;
117 bool gd_show_preview
=true;
120 bool gd_fullscreen
= false;
121 int gd_cell_scale_game
=GD_SCALING_2X
;
122 bool gd_pal_emulation_game
=false;
123 int gd_cell_scale_editor
=GD_SCALING_ORIGINAL
;
124 bool gd_pal_emulation_editor
=false;
126 /* html output option */
127 /* CURRENTLY ONLY FROM THE COMMAND LINE */
128 char *gd_html_stylesheet_filename
=NULL
;
129 char *gd_html_favicon_filename
=NULL
;
131 /* GTK keyboard settings */
132 #ifdef HAVE_GTK /* only if having gtk */
133 int gd_gtk_key_left
=GDK_Left
;
134 int gd_gtk_key_right
=GDK_Right
;
135 int gd_gtk_key_up
=GDK_Up
;
136 int gd_gtk_key_down
=GDK_Down
;
137 int gd_gtk_key_fire_1
=GDK_Control_L
;
138 int gd_gtk_key_fire_2
=GDK_Control_R
;
139 int gd_gtk_key_suicide
=GDK_s
;
140 int gd_gtk_key_fast_forward
=GDK_f
;
141 int gd_gtk_key_status_bar
=GDK_Shift_L
;
142 int gd_gtk_key_restart_level
=GDK_Escape
;
143 #endif /* only if having gtk */
147 int gd_sdl_key_left
=SDLK_LEFT
;
148 int gd_sdl_key_right
=SDLK_RIGHT
;
149 int gd_sdl_key_up
=SDLK_UP
;
150 int gd_sdl_key_down
=SDLK_DOWN
;
151 int gd_sdl_key_fire_1
=SDLK_LCTRL
;
152 int gd_sdl_key_fire_2
=SDLK_RCTRL
;
153 int gd_sdl_key_suicide
=SDLK_s
;
154 int gd_sdl_key_fast_forward
=SDLK_f
;
155 int gd_sdl_key_status_bar
=SDLK_LSHIFT
;
156 int gd_sdl_key_restart_level
=SDLK_ESCAPE
;
161 bool gd_sound_enabled
=true;
162 bool gd_sound_16bit_mixing
=true;
163 bool gd_sound_44khz_mixing
=true;
164 bool gd_sound_stereo
=true;
165 bool gd_classic_sound
=false;
166 int gd_sound_chunks_volume_percent
=50;
167 int gd_sound_music_volume_percent
=50;
168 #endif /* if gd_sound */
171 /* some directories the game uses */
172 const char *gd_user_config_dir
;
173 const char *gd_system_data_dir
;
174 const char *gd_system_caves_dir
;
175 const char *gd_system_music_dir
;
177 std::vector
<std::string
> gd_sound_dirs
, gd_themes_dirs
, gd_fonts_dirs
;
179 /* command line parameters */
180 int gd_param_license
=0;
181 char **gd_param_cavenames
=NULL
;
184 static void set_page_numbers(Setting
*settings
) {
186 for (size_t i
= 0; settings
[i
].name
!= NULL
; ++i
) {
187 if (settings
[i
].type
== TypePage
)
189 settings
[i
].page
= page
;
194 Setting
*gd_get_game_settings_array() {
195 static Setting settings_static
[] = {
196 { TypePage
, _("Game") },
197 { TypeStringv
, _("Language"), &gd_language
, false, gd_languages_names
, _("The language of the application. Changing this setting requires a restart!") },
198 { TypeBoolean
, _("All caves selectable"), &gd_all_caves_selectable
, false, NULL
, _("All caves and intermissions can be selected at game start.") },
199 { TypeBoolean
, _("Import as all selectable"), &gd_import_as_all_caves_selectable
, false, NULL
, _("Original, C64 games are imported not with A, E, I, M caves selectable, but all caves (ABCD, EFGH... excluding intermissions). This does not affect BDCFF caves.") },
200 { TypeBoolean
, _("Use BDCFF highscore"), &gd_use_bdcff_highscore
, false, NULL
, _("Use BDCFF highscores. GDash saves highscores in its own configuration directory and also in the *.bd files. However, it prefers loading them from the configuration directory; as the *.bd files might be read-only. You can enable this setting to let GDash load them from the *.bd files. This can be selected for a specific file in the file open dialog, too.") },
201 { TypeBoolean
, _("Show story"), &gd_show_story
, false, NULL
, _("If the cave has a story, it will be shown when the cave is first started.") },
202 { TypeBoolean
, _("Game name at uncover"), &gd_show_name_of_game
, false, NULL
, _("Show the name of the game when uncovering a cave.") },
203 { TypeBoolean
, _("No invisible outbox"), &gd_no_invisible_outbox
, false, NULL
, _("Show invisible outboxes as visible (blinking) ones.") },
205 { TypePage
, _("Game graphics") },
206 { TypeTheme
, _("Theme"), NULL
, false },
207 { TypeStringv
, _("Scale"), &gd_cell_scale_game
, true, gd_scaling_name
, _("Scaling factor and method.") },
208 { TypeBoolean
, _("PAL emulation"), &gd_pal_emulation_game
, true, NULL
, _("Use PAL emulated graphics, i.e. lines are striped, and colors are distorted like on a TV.") },
209 { TypePercent
, _(" PAL scanline shade"), &gd_pal_emu_scanline_shade
, true, NULL
, _("Darker rows for PAL emulation.") },
210 { TypeBoolean
, _("Particle effects"), &gd_particle_effects
, false, NULL
, _("Particle effects during play.") },
211 { TypeBoolean
, _("Fine scrolling"), &gd_fine_scroll
, false, NULL
, _("50 frames per second scrolling.") },
212 { TypeStringv
, _("Status bar colors"), &gd_status_bar_colors
, false, gd_status_bar_colors_get_names(), _("Preferred status bar color scheme. Only affects the colors, not the status bar layout.") },
213 { TypeStringv
, _(" C64 palette"), &gd_c64_palette
, false, GdColor::get_c64_palette_names(), _("The color palette for games imported from C64 files.") },
214 { TypeStringv
, _(" C64DTV palette"), &gd_c64dtv_palette
, false, GdColor::get_c64dtv_palette_names(), _("The color palette for imported C64 DTV games.") },
215 { TypeStringv
, _(" Atari palette"), &gd_atari_palette
, false, GdColor::get_atari_palette_names(), _("The color palette for imported Atari games.") },
216 { TypeStringv
, _(" Preferred palette"), &gd_preferred_palette
, false, GdColor::get_palette_types_names(), _("New caves and random colored caves use this palette.") },
218 { TypePage
, _("Editor graphics") },
219 { TypeStringv
, _("Scale"), &gd_cell_scale_editor
, true, gd_scaling_name
, _("Scaling factor and method.") },
220 { TypeBoolean
, _("PAL emulation"), &gd_pal_emulation_editor
, true, NULL
, _("Use PAL emulated graphics, i.e. lines are striped, and colors are distorted like on a TV.") },
221 { TypeBoolean
, _("Animated view"), &gd_game_view
, false, NULL
, _("Show simplified view of cave in the editor.") },
222 { TypeBoolean
, _("Colored objects"), &gd_colored_objects
, false, NULL
, _("Cave objects are colored, to make them different from random cave elements.") },
223 { TypeBoolean
, _("Object list"), &gd_show_object_list
, false, NULL
, _("Show objects list sidebar in the editor.") },
224 { TypeBoolean
, _("Fast uncover"), &gd_fast_uncover_in_test
, false, NULL
, _("Fast uncovering and covering of cave in editor cave test.") },
227 { TypePage
, _("Sound") },
228 { TypeBoolean
, _("Sound"), &gd_sound_enabled
, true, NULL
, _("Play sounds and music in the program.") },
229 { TypeBoolean
, _("Classic sounds only"), &gd_classic_sound
, true, NULL
, _("Play only classic sounds taken from the original game.") },
230 { TypeBoolean
, _("Stereo sounds"), &gd_sound_stereo
, true, NULL
, _("If you enable stereo sounds, you will hear the direction of sounds in the caves.") },
231 { TypeBoolean
, _("16-bit mixing"), &gd_sound_16bit_mixing
, true, NULL
, _("Use 16-bit mixing of sounds. Try changing this setting if sound is clicky.") },
232 { TypeBoolean
, _("44kHz mixing"), &gd_sound_44khz_mixing
, true, NULL
, _("Use 44kHz mixing of sounds. Try changing this setting if sound is clicky.") },
236 { TypeBoolean
, NULL
},
239 set_page_numbers(settings_static
);
241 return settings_static
;
246 Setting
*gd_get_keyboard_settings_array(GameInputHandler
*gih
) {
247 static Setting settings_static
[] = {
248 { TypePage
, _("Keyboard") },
249 { TypeKey
, _("Key left"), &gih
->get_key_variable(GameInputHandler::KeyLeft
), false },
250 { TypeKey
, _("Key right"), &gih
->get_key_variable(GameInputHandler::KeyRight
), false },
251 { TypeKey
, _("Key up"), &gih
->get_key_variable(GameInputHandler::KeyUp
), false },
252 { TypeKey
, _("Key down"), &gih
->get_key_variable(GameInputHandler::KeyDown
), false },
253 { TypeKey
, _("Key snap"), &gih
->get_key_variable(GameInputHandler::KeyFire1
), false },
254 { TypeKey
, _("Key snap (alt.)"), &gih
->get_key_variable(GameInputHandler::KeyFire2
), false },
255 { TypeKey
, _("Key suicide"), &gih
->get_key_variable(GameInputHandler::KeySuicide
), false },
256 { TypeKey
, _("Key fast forward"), &gih
->get_key_variable(GameInputHandler::KeyFastForward
), false },
257 { TypeKey
, _("Key status bar"), &gih
->get_key_variable(GameInputHandler::KeyStatusBar
), false },
258 { TypeKey
, _("Key restart level"), &gih
->get_key_variable(GameInputHandler::KeyRestartLevel
), false },
260 { TypeBoolean
, NULL
},
263 set_page_numbers(settings_static
);
265 return settings_static
;
271 /* gets boolean value from key file; returns def if not found or unreadable */
272 static bool keyfile_get_bool_with_default(GKeyFile
*keyfile
, const char *group
, const char *key
, bool def
) {
276 result
=g_key_file_get_boolean(keyfile
, group
, key
, &error
);
278 return result
!=FALSE
;
279 gd_message(error
->message
);
284 /* gets integer value from key file; returns def if not found or unreadable */
285 static int keyfile_get_integer_with_default(GKeyFile
*keyfile
, const char *group
, const char *key
, int def
) {
287 int result
=g_key_file_get_integer(keyfile
, group
, key
, &error
);
290 gd_message(error
->message
);
295 static std::string
keyfile_get_string(GKeyFile
*keyfile
, const char *group
, const char *key
) {
296 if (!g_key_file_has_key(keyfile
, group
, key
, NULL
))
300 char *result
=g_key_file_get_string(keyfile
, group
, key
, &error
);
302 std::string
ret(result
);
306 gd_message(error
->message
);
312 void gd_settings_init() {
313 gd_username
= g_get_real_name();
314 settings_bools
["no_invisible_outbox"] = &gd_no_invisible_outbox
;
315 settings_bools
["all_caves_selectable"] = &gd_all_caves_selectable
;
316 settings_bools
["import_as_all_caves_selectable"] = &gd_import_as_all_caves_selectable
;
317 settings_bools
["use_bdcff_highscore"] = &gd_use_bdcff_highscore
;
318 settings_bools
["fine_scroll"] = &gd_fine_scroll
;
319 settings_bools
["particle_effects"] = &gd_particle_effects
;
320 settings_bools
["show_story"] = &gd_show_story
;
321 settings_bools
["show_name_of_game"] = &gd_show_name_of_game
;
322 settings_integers
["pal_emu_scanline_shade"] = &gd_pal_emu_scanline_shade
;
323 settings_integers
["status_bar_colors"] = &gd_status_bar_colors
;
324 settings_integers
["c64_palette"] = &gd_c64_palette
;
325 settings_integers
["c64dtv_palette"] = &gd_c64dtv_palette
;
326 settings_integers
["atari_palette"] = &gd_atari_palette
;
327 settings_integers
["preferred_palette"] = &gd_preferred_palette
;
328 settings_strings
["username"] = &gd_username
;
329 settings_strings
["theme"] = &gd_theme
;
331 settings_bools
["game_view"] = &gd_game_view
;
332 settings_bools
["colored_objects"] = &gd_colored_objects
;
333 settings_bools
["show_object_list"] = &gd_show_object_list
;
334 settings_bools
["show_test_label"] = &gd_show_test_label
;
335 settings_bools
["show_preview"] = &gd_show_preview
;
336 settings_bools
["pal_emulation_game"] = &gd_pal_emulation_game
;
337 settings_bools
["pal_emulation_editor"] = &gd_pal_emulation_editor
;
338 settings_bools
["fast_uncover_in_test"] = &gd_fast_uncover_in_test
;
339 settings_integers
["editor_window_width"] = &gd_editor_window_width
;
340 settings_integers
["editor_window_height"] = &gd_editor_window_height
;
341 settings_integers
["language"] = &gd_language
;
342 settings_integers
["cell_scale_game"] = &gd_cell_scale_game
;
343 settings_integers
["cell_scale_editor"] = &gd_cell_scale_editor
;
344 settings_bools
["fullscreen"] = &gd_fullscreen
;
347 settings_integers
["gtk_key_left"] = &gd_gtk_key_left
;
348 settings_integers
["gtk_key_right"] = &gd_gtk_key_right
;
349 settings_integers
["gtk_key_up"] = &gd_gtk_key_up
;
350 settings_integers
["gtk_key_down"] = &gd_gtk_key_down
;
351 settings_integers
["gtk_key_fire_1"] = &gd_gtk_key_fire_1
;
352 settings_integers
["gtk_key_fire_2"] = &gd_gtk_key_fire_2
;
353 settings_integers
["gtk_key_suicide"] = &gd_gtk_key_suicide
;
354 settings_integers
["gtk_key_fast_forward"] = &gd_gtk_key_fast_forward
;
355 settings_integers
["gtk_key_status_bar"] = &gd_gtk_key_status_bar
;
356 settings_integers
["gtk_key_restart_level"] = &gd_gtk_key_restart_level
;
359 #ifdef HAVE_SDL /* only if having sdl */
360 settings_integers
["sdl_key_left"] = &gd_sdl_key_left
;
361 settings_integers
["sdl_key_right"] = &gd_sdl_key_right
;
362 settings_integers
["sdl_key_up"] = &gd_sdl_key_up
;
363 settings_integers
["sdl_key_down"] = &gd_sdl_key_down
;
364 settings_integers
["sdl_key_fire_1"] = &gd_sdl_key_fire_1
;
365 settings_integers
["sdl_key_fire_2"] = &gd_sdl_key_fire_2
;
366 settings_integers
["sdl_key_suicide"] = &gd_sdl_key_suicide
;
367 settings_integers
["sdl_key_fast_forward"] = &gd_sdl_key_fast_forward
;
368 settings_integers
["sdl_key_status_bar"] = &gd_sdl_key_status_bar
;
369 settings_integers
["sdl_key_restart_level"] = &gd_sdl_key_restart_level
;
373 settings_bools
["sound"] = &gd_sound_enabled
;
374 settings_bools
["sound_16bit_mixing"] = &gd_sound_16bit_mixing
;
375 settings_bools
["sound_44khz_mixing"] = &gd_sound_44khz_mixing
;
376 settings_bools
["sound_stereo"] = &gd_sound_stereo
;
377 settings_bools
["classic_sound"] = &gd_classic_sound
;
378 settings_integers
["sound_chunks_volume_percent"] = &gd_sound_chunks_volume_percent
;
379 settings_integers
["sound_music_volume_percent"] = &gd_sound_music_volume_percent
;
384 static void add_dirs(std::vector
<std::string
>& dirs
, const char *specific
) {
386 dirs
.push_back(gd_tostring_free(g_build_path(G_DIR_SEPARATOR_S
, gd_user_config_dir
, specific
, NULL
)));
387 dirs
.push_back(gd_tostring_free(g_build_path(G_DIR_SEPARATOR_S
, gd_user_config_dir
, NULL
)));
388 // system-wide gdash config
389 dirs
.push_back(gd_tostring_free(g_build_path(G_DIR_SEPARATOR_S
, gd_system_data_dir
, specific
, NULL
)));
390 dirs
.push_back(gd_tostring_free(g_build_path(G_DIR_SEPARATOR_S
, gd_system_data_dir
, NULL
)));
391 // for testing: actual directory
392 dirs
.push_back(gd_tostring_free(g_build_path(G_DIR_SEPARATOR_S
, ".", specific
, NULL
)));
393 dirs
.push_back(gd_tostring_free(g_build_path(G_DIR_SEPARATOR_S
, ".", NULL
)));
396 /* sets up directiories and loads translations */
397 void gd_settings_init_dirs() {
399 /* on win32, use the glib function. */
400 gd_system_data_dir
=g_win32_get_package_installation_directory (NULL
, NULL
);
402 /* on linux, this is a defined, built-in string, $perfix/share/locale */
403 gd_system_data_dir
=PKGDATADIR
;
405 gd_system_caves_dir
=g_build_path(G_DIR_SEPARATOR_S
, gd_system_data_dir
, "caves", NULL
);
406 gd_system_music_dir
=g_build_path(G_DIR_SEPARATOR_S
, gd_system_data_dir
, "music", NULL
);
407 gd_user_config_dir
=g_build_path(G_DIR_SEPARATOR_S
, g_get_user_config_dir(), PACKAGE
, NULL
);
409 add_dirs(gd_sound_dirs
, "sound");
410 add_dirs(gd_themes_dirs
, "themes");
411 add_dirs(gd_fonts_dirs
, "fonts");
414 /* set locale from the gdash setting variable. */
415 /* only bother setting the locale cleverly when we are in the gtk version. */
416 /* for sdl version, not really matters. */
417 /* if no gtk, just set the system default locale. */
418 void gd_settings_set_locale() {
419 if (gd_language
<0 || gd_language
>=int(G_N_ELEMENTS(language_locale
)))
420 gd_language
=0; /* switch to default, if out of bounds. */
422 /* on windows, we put the LANGUAGE variable into the environment. that seems to be the only
423 thing gtk+ acts upon. we also set the locale below. */
425 g_assert(G_N_ELEMENTS(language_locale
)==G_N_ELEMENTS(languages_for_env
));
426 if (languages_for_env
[gd_language
]) {
427 g_setenv("LANGUAGE", languages_for_env
[gd_language
], TRUE
);
431 /* try to set the locale. */
434 while (result
==NULL
&& language_locale
[gd_language
][i
]!=NULL
) {
435 result
= setlocale(LC_ALL
, language_locale
[gd_language
][i
]);
438 if (result
== NULL
) {
440 gd_message(CPrintf("Failed to set language to '%s'. Switching to system default locale.") % gd_languages_names
[gd_language
]);
441 setlocale(LC_ALL
, "");
445 /* sets up directiories and loads translations */
446 /* also instructs gettext to give all strings as utf8, as gtk uses that */
447 void gd_settings_init_translation() {
448 /* different directories storing the translation files on unix and win32. */
449 /* gdash (and gtk) always uses utf8, so convert translated strings to utf8 if needed. */
451 bindtextdomain("gtk20-properties", gd_system_data_dir
);
452 bind_textdomain_codeset("gtk20-properties", "UTF-8");
453 bindtextdomain("gtk20", gd_system_data_dir
);
454 bind_textdomain_codeset("gtk20", "UTF-8");
455 bindtextdomain("glib20", gd_system_data_dir
);
456 bind_textdomain_codeset("glib20", "UTF-8");
457 bindtextdomain(PACKAGE
, gd_system_data_dir
); /* gdash */
458 bind_textdomain_codeset(PACKAGE
, "UTF-8");
460 bindtextdomain(PACKAGE
, LOCALEDIR
); /* gdash */
461 bind_textdomain_codeset(PACKAGE
, "UTF-8");
463 textdomain(PACKAGE
); /* set default textdomain to gdash */
467 /* load settings from .config/gdash/gdash.ini */
468 void gd_load_settings() {
473 char *filename
=g_build_path(G_DIR_SEPARATOR_S
, gd_user_config_dir
, SETTINGS_INI_FILE
, NULL
);
474 if (!g_file_get_contents(filename
, &data
, &length
, &error
)) {
475 /* no ini file found */
476 gd_message(CPrintf("%s: %s") % filename
% error
->message
);
482 /* if zero length file, also return */
486 GKeyFile
*ini
=g_key_file_new();
487 gboolean success
=g_key_file_load_from_data(ini
, data
, length
, G_KEY_FILE_NONE
, &error
);
490 gd_message(CPrintf("INI file contents error: %s") % error
->message
);
495 /* load the settings */
496 for (std::map
<char const *, int *>::const_iterator it
= settings_integers
.begin(); it
!= settings_integers
.end(); ++it
) {
497 char const *key
= it
->first
;
498 int &var
= *it
->second
;
499 var
= keyfile_get_integer_with_default(ini
, SETTINGS_GDASH_GROUP
, key
, var
);
501 for (std::map
<char const *, bool *>::const_iterator it
= settings_bools
.begin(); it
!= settings_bools
.end(); ++it
) {
502 char const *key
= it
->first
;
503 bool &var
= *it
->second
;
504 var
= keyfile_get_bool_with_default(ini
, SETTINGS_GDASH_GROUP
, key
, var
);
506 for (std::map
<char const *, std::string
*>::const_iterator it
= settings_strings
.begin(); it
!= settings_strings
.end(); ++it
) {
507 char const *key
= it
->first
;
508 std::string
&var
= *it
->second
;
509 var
= keyfile_get_string(ini
, SETTINGS_GDASH_GROUP
, key
);
513 if (gd_cell_scale_game
<0 || gd_cell_scale_game
>=GD_SCALING_MAX
)
514 gd_cell_scale_game
=GD_SCALING_ORIGINAL
;
515 if (gd_cell_scale_editor
<0 || gd_cell_scale_editor
>=GD_SCALING_MAX
)
516 gd_cell_scale_editor
=GD_SCALING_ORIGINAL
;
517 if (gd_preferred_palette
<0 || gd_preferred_palette
>=int(GdColor::Invalid
))
518 gd_preferred_palette
=GdColor::TypeRGB
;
519 if (gd_status_bar_colors
<0 || gd_status_bar_colors
> int(GD_STATUS_BAR_MAX
))
520 gd_status_bar_colors
=GD_STATUS_BAR_ORIGINAL
;
522 g_key_file_free(ini
);
526 /* save settings to .config/gdash.ini */
527 void gd_save_settings() {
528 GKeyFile
*ini
=g_key_file_new();
531 for (std::map
<char const *, int *>::const_iterator it
= settings_integers
.begin(); it
!= settings_integers
.end(); ++it
) {
532 char const *key
= it
->first
;
533 int &var
= *it
->second
;
534 g_key_file_set_integer(ini
, SETTINGS_GDASH_GROUP
, key
, var
);
536 for (std::map
<char const *, bool *>::const_iterator it
= settings_bools
.begin(); it
!= settings_bools
.end(); ++it
) {
537 char const *key
= it
->first
;
538 bool &var
= *it
->second
;
539 g_key_file_set_boolean(ini
, SETTINGS_GDASH_GROUP
, key
, (gboolean
) var
);
541 for (std::map
<char const *, std::string
*>::const_iterator it
= settings_strings
.begin(); it
!= settings_strings
.end(); ++it
) {
542 char const *key
= it
->first
;
543 std::string
&var
= *it
->second
;
544 g_key_file_set_string(ini
, SETTINGS_GDASH_GROUP
, key
, var
.c_str());
548 /* convert to string and free */
549 gchar
*data
=g_key_file_to_data(ini
, NULL
, &error
);
550 g_key_file_free(ini
);
552 /* this is highly unlikely - why would g_key_file_to_data report error? docs do not mention. */
553 gd_warning(CPrintf("Unable to save settings: %s") % error
->message
);
559 char *filename
=g_build_path(G_DIR_SEPARATOR_S
, gd_user_config_dir
, SETTINGS_INI_FILE
, NULL
);
560 g_mkdir_with_parents(gd_user_config_dir
, 0700);
561 g_file_set_contents(filename
, data
, -1, &error
);
564 /* error saving the file */
565 gd_warning(CPrintf("Unable to save settings: %s") % error
->message
);
573 GOptionContext
*gd_option_context_new() {
574 GOptionEntry
const entries
[]={
575 {"license", 'L', 0, G_OPTION_ARG_NONE
, &gd_param_license
, N_("Show license and quit")},
576 {G_OPTION_REMAINING
, 0, 0, G_OPTION_ARG_FILENAME_ARRAY
, &gd_param_cavenames
, N_("Cave names")},
579 GOptionContext
*context
=g_option_context_new(_("[FILE NAME]"));
580 g_option_context_set_help_enabled(context
, TRUE
);
581 g_option_context_add_main_entries(context
, entries
, PACKAGE
); /* gdash parameters */