Add weapon cycling bindings for mouse and joystick buttons. Add weapon cycling bindi...
[chocolate-doom.git] / setup / configfile.c
blob2a3cb8452ccfcee052c2a77723547b0a09710fce
1 // Emacs style mode select -*- C++ -*-
2 //-----------------------------------------------------------------------------
3 //
4 // Copyright(C) 1993-1996 Id Software, Inc.
5 // Copyright(C) 2005 Simon Howard
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 // 02111-1307, USA.
23 // DESCRIPTION:
24 // Configuration file load/save code.
26 //-----------------------------------------------------------------------------
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <ctype.h>
32 #include <string.h>
34 // for mkdir:
36 #ifdef _WIN32
37 #include <io.h>
38 #define WIN32_LEAN_AND_MEAN
39 #include <windows.h>
40 #else
41 #include <sys/stat.h>
42 #include <sys/types.h>
43 #endif
45 #include "SDL_mixer.h"
47 #include "config.h"
49 #include "doomfeatures.h"
50 #include "doomkeys.h"
51 #include "doomtype.h"
52 #include "d_englsh.h"
54 #include "m_argv.h"
56 #include "compatibility.h"
57 #include "display.h"
58 #include "joystick.h"
59 #include "keyboard.h"
60 #include "mouse.h"
61 #include "multiplayer.h"
62 #include "sound.h"
64 char *configdir;
67 // Create a directory
70 void M_MakeDirectory(char *path)
72 #ifdef _WIN32
73 mkdir(path);
74 #else
75 mkdir(path, 0755);
76 #endif
80 //
81 // M_SetConfigDir:
83 // Sets the location of the configuration directory, where configuration
84 // files are stored - default.cfg, chocolate-doom.cfg, savegames, etc.
87 void M_SetConfigDir(void)
89 #if !defined(_WIN32) || defined(_WIN32_WCE)
91 // Configuration settings are stored in ~/.chocolate-doom/,
92 // except on Windows, where we behave like Vanilla Doom and
93 // save in the current directory.
95 char *homedir;
97 homedir = getenv("HOME");
99 if (homedir != NULL)
101 // put all configuration in a config directory off the
102 // homedir
104 configdir = malloc(strlen(homedir) + strlen(PACKAGE_TARNAME) + 5);
106 sprintf(configdir, "%s%c.%s%c", homedir, DIR_SEPARATOR,
107 PACKAGE_TARNAME, DIR_SEPARATOR);
109 // make the directory if it doesnt already exist
111 M_MakeDirectory(configdir);
113 else
114 #endif /* #ifndef _WIN32 */
116 #if defined(_WIN32) && !defined(_WIN32_WCE)
117 // when given the -cdrom option, save config+savegames in
118 // c:\doomdata. This only applies under Windows.
120 if (M_CheckParm("-cdrom") > 0)
122 printf(D_CDROM);
123 configdir = strdup("c:\\doomdata\\");
125 M_MakeDirectory(configdir);
127 else
128 #endif
130 configdir = strdup("");
138 // DEFAULTS
141 // These are options that are not controlled by setup.
143 static int showMessages = 1;
144 static int screenblocks = 9;
145 static int detailLevel = 0;
146 static int usegamma = 0;
148 // dos specific options: these are unused but should be maintained
149 // so that the config file can be shared between chocolate
150 // doom and doom.exe
152 static int snd_sbport = 0;
153 static int snd_sbirq = 0;
154 static int snd_sbdma = 0;
155 static int snd_mport = 0;
157 typedef enum
159 DEFAULT_INT,
160 DEFAULT_INT_HEX,
161 DEFAULT_STRING,
162 DEFAULT_FLOAT,
163 DEFAULT_KEY,
164 } default_type_t;
166 typedef struct
168 // Name of the variable
169 char * name;
171 // Pointer to the location in memory of the variable
172 void * location;
174 // Type of the variable
175 default_type_t type;
177 // If this is a key value, the original integer scancode we read from
178 // the config file before translating it to the internal key value.
179 // If zero, we didn't read this value from a config file.
180 int untranslated;
182 // The value we translated the scancode into when we read the
183 // config file on startup. If the variable value is different from
184 // this, it has been changed and needs to be converted; otherwise,
185 // use the 'untranslated' value.
186 int original_translated;
187 } default_t;
189 typedef struct
191 default_t *defaults;
192 int numdefaults;
193 char *filename;
194 } default_collection_t;
196 static default_t doom_defaults_list[] =
198 {"mouse_sensitivity", &mouseSensitivity, DEFAULT_INT, 0, 0},
199 {"sfx_volume",&sfxVolume, DEFAULT_INT, 0, 0},
200 {"music_volume",&musicVolume, DEFAULT_INT, 0, 0},
201 {"show_messages",&showMessages, DEFAULT_INT, 0, 0},
203 {"key_right",&key_right, DEFAULT_KEY, 0, 0},
204 {"key_left",&key_left, DEFAULT_KEY, 0, 0},
205 {"key_up",&key_up, DEFAULT_KEY, 0, 0},
206 {"key_down",&key_down, DEFAULT_KEY, 0, 0},
207 {"key_strafeleft",&key_strafeleft, DEFAULT_KEY, 0, 0},
208 {"key_straferight",&key_straferight, DEFAULT_KEY, 0, 0},
210 {"key_fire",&key_fire, DEFAULT_KEY, 0, 0},
211 {"key_use",&key_use, DEFAULT_KEY, 0, 0},
212 {"key_strafe",&key_strafe, DEFAULT_KEY, 0, 0},
213 {"key_speed",&key_speed, DEFAULT_KEY, 0, 0},
215 {"use_mouse",&usemouse, DEFAULT_INT, 0, 0},
216 {"mouseb_fire",&mousebfire, DEFAULT_INT, 0, 0},
217 {"mouseb_strafe",&mousebstrafe, DEFAULT_INT, 0, 0},
218 {"mouseb_forward",&mousebforward, DEFAULT_INT, 0, 0},
220 {"use_joystick",&usejoystick, DEFAULT_INT, 0, 0},
221 {"joyb_fire",&joybfire, DEFAULT_INT, 0, 0},
222 {"joyb_strafe",&joybstrafe, DEFAULT_INT, 0, 0},
223 {"joyb_use",&joybuse, DEFAULT_INT, 0, 0},
224 {"joyb_speed",&joybspeed, DEFAULT_INT, 0, 0},
226 {"screenblocks",&screenblocks, DEFAULT_INT, 0, 0},
227 {"detaillevel",&detailLevel, DEFAULT_INT, 0, 0},
229 {"snd_channels",&numChannels, DEFAULT_INT, 0, 0},
231 {"snd_musicdevice", &snd_musicdevice, DEFAULT_INT, 0, 0},
232 {"snd_sfxdevice", &snd_sfxdevice, DEFAULT_INT, 0, 0},
233 {"snd_sbport", &snd_sbport, DEFAULT_INT, 0, 0},
234 {"snd_sbirq", &snd_sbirq, DEFAULT_INT, 0, 0},
235 {"snd_sbdma", &snd_sbdma, DEFAULT_INT, 0, 0},
236 {"snd_mport", &snd_mport, DEFAULT_INT, 0, 0},
238 {"usegamma", &usegamma, DEFAULT_INT, 0, 0},
240 {"chatmacro0", &chat_macros[0], DEFAULT_STRING, 0, 0 },
241 {"chatmacro1", &chat_macros[1], DEFAULT_STRING, 0, 0 },
242 {"chatmacro2", &chat_macros[2], DEFAULT_STRING, 0, 0 },
243 {"chatmacro3", &chat_macros[3], DEFAULT_STRING, 0, 0 },
244 {"chatmacro4", &chat_macros[4], DEFAULT_STRING, 0, 0 },
245 {"chatmacro5", &chat_macros[5], DEFAULT_STRING, 0, 0 },
246 {"chatmacro6", &chat_macros[6], DEFAULT_STRING, 0, 0 },
247 {"chatmacro7", &chat_macros[7], DEFAULT_STRING, 0, 0 },
248 {"chatmacro8", &chat_macros[8], DEFAULT_STRING, 0, 0 },
249 {"chatmacro9", &chat_macros[9], DEFAULT_STRING, 0, 0 },
253 static default_collection_t doom_defaults =
255 doom_defaults_list,
256 arrlen(doom_defaults_list),
257 NULL,
260 static default_t extra_defaults_list[] =
262 {"autoadjust_video_settings", &autoadjust_video_settings, DEFAULT_INT, 0, 0},
263 {"fullscreen", &fullscreen, DEFAULT_INT, 0, 0},
264 {"aspect_ratio_correct", &aspect_ratio_correct, DEFAULT_INT, 0, 0},
265 {"startup_delay", &startup_delay, DEFAULT_INT, 0, 0},
266 {"screen_width", &screen_width, DEFAULT_INT, 0, 0},
267 {"screen_height", &screen_height, DEFAULT_INT, 0, 0},
268 {"grabmouse", &grabmouse, DEFAULT_INT, 0, 0},
269 {"novert", &novert, DEFAULT_INT, 0, 0},
270 {"mouse_acceleration", &mouse_acceleration, DEFAULT_FLOAT, 0, 0},
271 {"mouse_threshold", &mouse_threshold, DEFAULT_INT, 0, 0},
272 {"snd_samplerate", &snd_samplerate, DEFAULT_INT, 0, 0},
273 {"opl_io_port", &opl_io_port, DEFAULT_INT_HEX, 0, 0},
274 {"show_endoom", &show_endoom, DEFAULT_INT, 0, 0},
275 {"vanilla_savegame_limit", &vanilla_savegame_limit, DEFAULT_INT, 0, 0},
276 {"vanilla_demo_limit", &vanilla_demo_limit, DEFAULT_INT, 0, 0},
277 {"vanilla_keyboard_mapping", &vanilla_keyboard_mapping, DEFAULT_INT, 0, 0},
278 #ifdef FEATURE_MULTIPLAYER
279 {"player_name", &net_player_name, DEFAULT_STRING, 0, 0},
280 #endif
281 {"video_driver", &video_driver, DEFAULT_STRING, 0, 0},
282 {"joystick_index", &joystick_index, DEFAULT_INT, 0, 0},
283 {"joystick_x_axis", &joystick_x_axis, DEFAULT_INT, 0, 0},
284 {"joystick_x_invert", &joystick_x_invert, DEFAULT_INT, 0, 0},
285 {"joystick_y_axis", &joystick_y_axis, DEFAULT_INT, 0, 0},
286 {"joystick_y_invert", &joystick_y_invert, DEFAULT_INT, 0, 0},
287 {"joyb_strafeleft", &joybstrafeleft, DEFAULT_INT, 0, 0},
288 {"joyb_straferight", &joybstraferight, DEFAULT_INT, 0, 0},
289 {"joyb_prevweapon", &joybprevweapon, DEFAULT_INT, 0, 0},
290 {"joyb_nextweapon", &joybnextweapon, DEFAULT_INT, 0, 0},
291 {"dclick_use", &dclick_use, DEFAULT_INT, 0, 0},
292 {"mouseb_strafeleft", &mousebstrafeleft, DEFAULT_INT, 0, 0},
293 {"mouseb_straferight", &mousebstraferight, DEFAULT_INT, 0, 0},
294 {"mouseb_use", &mousebuse, DEFAULT_INT, 0, 0},
295 {"mouseb_backward", &mousebbackward, DEFAULT_INT, 0, 0},
296 {"mouseb_prevweapon", &mousebprevweapon, DEFAULT_INT, 0, 0},
297 {"mouseb_nextweapon", &mousebnextweapon, DEFAULT_INT, 0, 0},
298 {"use_libsamplerate", &use_libsamplerate, DEFAULT_INT, 0, 0},
300 {"key_pause", &key_pause, DEFAULT_KEY, 0, 0},
301 {"key_menu_activate", &key_menu_activate, DEFAULT_KEY, 0, 0},
302 {"key_menu_up", &key_menu_up, DEFAULT_KEY, 0, 0},
303 {"key_menu_down", &key_menu_down, DEFAULT_KEY, 0, 0},
304 {"key_menu_left", &key_menu_left, DEFAULT_KEY, 0, 0},
305 {"key_menu_right", &key_menu_right, DEFAULT_KEY, 0, 0},
306 {"key_menu_back", &key_menu_back, DEFAULT_KEY, 0, 0},
307 {"key_menu_forward", &key_menu_forward, DEFAULT_KEY, 0, 0},
308 {"key_menu_confirm", &key_menu_confirm, DEFAULT_KEY, 0, 0},
309 {"key_menu_abort", &key_menu_abort, DEFAULT_KEY, 0, 0},
310 {"key_menu_help", &key_menu_help, DEFAULT_KEY, 0, 0},
311 {"key_menu_save", &key_menu_save, DEFAULT_KEY, 0, 0},
312 {"key_menu_load", &key_menu_load, DEFAULT_KEY, 0, 0},
313 {"key_menu_volume", &key_menu_volume, DEFAULT_KEY, 0, 0},
314 {"key_menu_detail", &key_menu_detail, DEFAULT_KEY, 0, 0},
315 {"key_menu_qsave", &key_menu_qsave, DEFAULT_KEY, 0, 0},
316 {"key_menu_endgame", &key_menu_endgame, DEFAULT_KEY, 0, 0},
317 {"key_menu_messages", &key_menu_messages, DEFAULT_KEY, 0, 0},
318 {"key_menu_qload", &key_menu_qload, DEFAULT_KEY, 0, 0},
319 {"key_menu_quit", &key_menu_quit, DEFAULT_KEY, 0, 0},
320 {"key_menu_gamma", &key_menu_gamma, DEFAULT_KEY, 0, 0},
321 {"key_spy", &key_spy, DEFAULT_KEY, 0, 0},
322 {"key_menu_incscreen", &key_menu_incscreen, DEFAULT_KEY, 0, 0},
323 {"key_menu_decscreen", &key_menu_decscreen, DEFAULT_KEY, 0, 0},
325 {"key_map_toggle", &key_map_toggle, DEFAULT_KEY, 0, 0},
326 {"key_map_north", &key_map_north, DEFAULT_KEY, 0, 0},
327 {"key_map_south", &key_map_south, DEFAULT_KEY, 0, 0},
328 {"key_map_east", &key_map_east, DEFAULT_KEY, 0, 0},
329 {"key_map_west", &key_map_west, DEFAULT_KEY, 0, 0},
330 {"key_map_zoomin", &key_map_zoomin, DEFAULT_KEY, 0, 0},
331 {"key_map_zoomout", &key_map_zoomout, DEFAULT_KEY, 0, 0},
332 {"key_map_maxzoom", &key_map_maxzoom, DEFAULT_KEY, 0, 0},
333 {"key_map_follow", &key_map_follow, DEFAULT_KEY, 0, 0},
334 {"key_map_grid", &key_map_grid, DEFAULT_KEY, 0, 0},
335 {"key_map_mark", &key_map_mark, DEFAULT_KEY, 0, 0},
336 {"key_map_clearmark", &key_map_clearmark, DEFAULT_KEY, 0, 0},
337 {"key_weapon1", &key_weapon1, DEFAULT_KEY, 0, 0},
338 {"key_weapon2", &key_weapon2, DEFAULT_KEY, 0, 0},
339 {"key_weapon3", &key_weapon3, DEFAULT_KEY, 0, 0},
340 {"key_weapon4", &key_weapon4, DEFAULT_KEY, 0, 0},
341 {"key_weapon5", &key_weapon5, DEFAULT_KEY, 0, 0},
342 {"key_weapon6", &key_weapon6, DEFAULT_KEY, 0, 0},
343 {"key_weapon7", &key_weapon7, DEFAULT_KEY, 0, 0},
344 {"key_weapon8", &key_weapon8, DEFAULT_KEY, 0, 0},
345 {"key_prevweapon", &key_prevweapon, DEFAULT_KEY, 0, 0},
346 {"key_nextweapon", &key_nextweapon, DEFAULT_KEY, 0, 0},
347 {"key_message_refresh", &key_message_refresh, DEFAULT_KEY, 0, 0},
348 {"key_demo_quit", &key_demo_quit, DEFAULT_KEY, 0, 0},
349 {"key_multi_msg", &key_multi_msg, DEFAULT_KEY, 0, 0},
350 {"key_multi_msgplayer1", &key_multi_msgplayer[0], DEFAULT_KEY, 0, 0},
351 {"key_multi_msgplayer2", &key_multi_msgplayer[1], DEFAULT_KEY, 0, 0},
352 {"key_multi_msgplayer3", &key_multi_msgplayer[2], DEFAULT_KEY, 0, 0},
353 {"key_multi_msgplayer4", &key_multi_msgplayer[3], DEFAULT_KEY, 0, 0},
356 static default_collection_t extra_defaults =
358 extra_defaults_list,
359 arrlen(extra_defaults_list),
360 NULL,
363 static int scantokey[128] =
365 0 , 27, '1', '2', '3', '4', '5', '6',
366 '7', '8', '9', '0', '-', '=', KEY_BACKSPACE, 9,
367 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i',
368 'o', 'p', '[', ']', 13, KEY_RCTRL, 'a', 's',
369 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
370 '\'', '`', KEY_RSHIFT,'\\', 'z', 'x', 'c', 'v',
371 'b', 'n', 'm', ',', '.', '/', KEY_RSHIFT,KEYP_MULTIPLY,
372 KEY_RALT, ' ', KEY_CAPSLOCK,KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5,
373 KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_PAUSE,KEY_SCRLCK,KEY_HOME,
374 KEY_UPARROW,KEY_PGUP,KEYP_MINUS,KEY_LEFTARROW,KEYP_5,KEY_RIGHTARROW,KEYP_PLUS,KEY_END,
375 KEY_DOWNARROW,KEY_PGDN,KEY_INS,KEY_DEL,0, 0, 0, KEY_F11,
376 KEY_F12, 0, 0, 0, 0, 0, 0, 0,
377 0, 0, 0, 0, 0, 0, 0, 0,
378 0, 0, 0, 0, 0, 0, 0, 0,
379 0, 0, 0, 0, 0, 0, 0, 0,
380 0, 0, 0, 0, 0, 0, 0, 0
384 static void SaveDefaultCollection(default_collection_t *collection)
386 default_t *defaults;
387 int i, v;
388 FILE *f;
390 f = fopen (collection->filename, "w");
391 if (!f)
392 return; // can't write the file, but don't complain
394 defaults = collection->defaults;
396 for (i=0 ; i<collection->numdefaults ; i++)
398 int chars_written;
400 // Print the name and line up all values at 30 characters
402 chars_written = fprintf(f, "%s ", defaults[i].name);
404 for (; chars_written < 30; ++chars_written)
405 fprintf(f, " ");
407 // Print the value
409 switch (defaults[i].type)
411 case DEFAULT_KEY:
413 // use the untranslated version if we can, to reduce
414 // the possibility of screwing up the user's config
415 // file
417 v = * (int *) defaults[i].location;
419 if (defaults[i].untranslated
420 && v == defaults[i].original_translated)
422 // Has not been changed since the last time we
423 // read the config file.
425 v = defaults[i].untranslated;
427 else
429 // search for a reverse mapping back to a scancode
430 // in the scantokey table
432 int s;
434 for (s=0; s<128; ++s)
436 if (scantokey[s] == v)
438 v = s;
439 break;
444 fprintf(f, "%i", v);
445 break;
447 case DEFAULT_INT_HEX:
448 fprintf(f, "0x%x", * (int *) defaults[i].location);
449 break;
451 case DEFAULT_INT:
452 fprintf(f, "%i", * (int *) defaults[i].location);
453 break;
455 case DEFAULT_FLOAT:
456 fprintf(f, "%f", * (float *) defaults[i].location);
457 break;
459 case DEFAULT_STRING:
460 fprintf(f,"\"%s\"", * (char **) (defaults[i].location));
461 break;
464 fprintf(f, "\n");
467 fclose (f);
470 // Parses integer values in the configuration file
472 static int ParseIntParameter(char *strparm)
474 int parm;
476 if (strparm[0] == '0' && strparm[1] == 'x')
477 sscanf(strparm+2, "%x", &parm);
478 else
479 sscanf(strparm, "%i", &parm);
481 return parm;
484 static void LoadDefaultCollection(default_collection_t *collection)
486 default_t *defaults = collection->defaults;
487 int i;
488 FILE* f;
489 char defname[80];
490 char strparm[100];
492 // read the file in, overriding any set defaults
493 f = fopen(collection->filename, "r");
495 if (!f)
497 // File not opened, but don't complain
499 return;
502 while (!feof(f))
504 if (fscanf (f, "%79s %[^\n]\n", defname, strparm) != 2)
506 // This line doesn't match
508 continue;
511 // Strip off trailing non-printable characters (\r characters
512 // from DOS text files)
514 while (strlen(strparm) > 0 && !isprint(strparm[strlen(strparm)-1]))
516 strparm[strlen(strparm)-1] = '\0';
519 // Find the setting in the list
521 for (i=0; i<collection->numdefaults; ++i)
523 default_t *def = &collection->defaults[i];
524 char *s;
525 int intparm;
527 if (strcmp(defname, def->name) != 0)
529 // not this one
530 continue;
533 // parameter found
535 switch (def->type)
537 case DEFAULT_STRING:
538 s = strdup(strparm + 1);
539 s[strlen(s) - 1] = '\0';
540 * (char **) def->location = s;
541 break;
543 case DEFAULT_INT:
544 case DEFAULT_INT_HEX:
545 * (int *) def->location = ParseIntParameter(strparm);
546 break;
548 case DEFAULT_KEY:
550 // translate scancodes read from config
551 // file (save the old value in untranslated)
553 intparm = ParseIntParameter(strparm);
554 defaults[i].untranslated = intparm;
556 if (intparm >= 0 && intparm < 128)
558 intparm = scantokey[intparm];
560 else
562 intparm = 0;
565 defaults[i].original_translated = intparm;
566 * (int *) def->location = intparm;
567 break;
569 case DEFAULT_FLOAT:
570 * (float *) def->location = atof(strparm);
571 break;
574 // finish
576 break;
580 fclose (f);
584 // M_SaveDefaults
587 void M_SaveDefaults (void)
589 SaveDefaultCollection(&doom_defaults);
590 SaveDefaultCollection(&extra_defaults);
595 // M_LoadDefaults
598 void M_LoadDefaults (void)
600 int i;
602 // check for a custom default file
603 i = M_CheckParm ("-config");
605 if (i && i<myargc-1)
607 doom_defaults.filename = myargv[i+1];
608 printf (" default file: %s\n",doom_defaults.filename);
610 else
612 doom_defaults.filename = malloc(strlen(configdir) + 20);
613 sprintf(doom_defaults.filename, "%sdefault.cfg", configdir);
616 // printf("saving config in %s\n", doom_defaults.filename);
618 i = M_CheckParm("-extraconfig");
620 if (i && i<myargc-1)
622 extra_defaults.filename = myargv[i+1];
623 printf(" extra configuration file: %s\n",
624 extra_defaults.filename);
626 else
628 extra_defaults.filename
629 = malloc(strlen(configdir) + strlen(PACKAGE_TARNAME) + 10);
630 sprintf(extra_defaults.filename, "%s%s.cfg",
631 configdir, PACKAGE_TARNAME);
634 LoadDefaultCollection(&doom_defaults);
635 LoadDefaultCollection(&extra_defaults);
639 // Save normal (default.cfg) defaults to a given file
642 void M_SaveMainDefaults(char *filename)
644 char *main_filename;
646 // Save the normal filename and set this one
648 main_filename = doom_defaults.filename;
649 doom_defaults.filename = filename;
651 // Save the file
653 SaveDefaultCollection(&doom_defaults);
655 // Restore the normal filename
657 doom_defaults.filename = main_filename;
661 // Save extra (chocolate-doom.cfg) defaults to a given file
664 void M_SaveExtraDefaults(char *filename)
666 char *main_filename;
668 // Save the normal filename and set this one
670 main_filename = extra_defaults.filename;
671 extra_defaults.filename = filename;
673 // Save the file
675 SaveDefaultCollection(&extra_defaults);
677 // Restore the normal filename
679 extra_defaults.filename = main_filename;
682 #ifdef _WIN32_WCE
684 static int SystemHasKeyboard(void)
686 HKEY key;
687 DWORD valtype;
688 DWORD valsize;
689 DWORD result;
691 if (RegOpenKeyExW(HKEY_CURRENT_USER,
692 L"\\Software\\Microsoft\\Shell", 0,
693 KEY_READ, &key) != ERROR_SUCCESS)
695 return 0;
698 valtype = REG_SZ;
699 valsize = sizeof(DWORD);
701 if (RegQueryValueExW(key, L"HasKeyboard", NULL, &valtype,
702 (LPBYTE) &result, &valsize) != ERROR_SUCCESS)
704 result = 0;
707 // Close the key
709 RegCloseKey(key);
711 return result;
715 // Apply custom defaults for Windows CE.
718 static void M_ApplyWindowsCEDefaults(void)
720 // If the system doesn't have a keyboard, patch the default
721 // configuration to use the hardware keys.
723 if (!SystemHasKeyboard())
725 key_use = KEY_F1;
726 key_fire = KEY_F2;
727 key_menu_activate = KEY_F3;
728 key_map_toggle = KEY_F4;
730 key_menu_help = 0;
731 key_menu_save = 0;
732 key_menu_load = 0;
733 key_menu_volume = 0;
735 key_menu_confirm = KEY_ENTER;
736 key_menu_back = KEY_F2;
737 key_menu_abort = KEY_F2;
742 #endif
745 // Apply custom patches to the default values depending on the
746 // platform we are running on.
749 void M_ApplyPlatformDefaults(void)
751 #ifdef _WIN32_WCE
752 M_ApplyWindowsCEDefaults();
753 #endif
755 // Before SDL_mixer version 1.2.11, MIDI music caused the game
756 // to crash when it looped. If this is an old SDL_mixer version,
757 // disable MIDI.
759 #ifdef __MACOSX__
761 const SDL_version *v = Mix_Linked_Version();
763 if (SDL_VERSIONNUM(v->major, v->minor, v->patch)
764 < SDL_VERSIONNUM(1, 2, 11))
766 snd_musicdevice = SNDDEVICE_NONE;
769 #endif