+
+
+/* ========================================================================= */
+/* setup file functions */
+/* ========================================================================= */
+
+#define TOKEN_STR_PLAYER_PREFIX "player_"
+
+/* global setup */
+#define SETUP_TOKEN_PLAYER_NAME 0
+#define SETUP_TOKEN_SOUND 1
+#define SETUP_TOKEN_SOUND_LOOPS 2
+#define SETUP_TOKEN_SOUND_MUSIC 3
+#define SETUP_TOKEN_SOUND_SIMPLE 4
+#define SETUP_TOKEN_TOONS 5
+#define SETUP_TOKEN_SCROLL_DELAY 6
+#define SETUP_TOKEN_SOFT_SCROLLING 7
+#define SETUP_TOKEN_FADING 8
+#define SETUP_TOKEN_AUTORECORD 9
+#define SETUP_TOKEN_QUICK_DOORS 10
+#define SETUP_TOKEN_TEAM_MODE 11
+#define SETUP_TOKEN_HANDICAP 12
+#define SETUP_TOKEN_TIME_LIMIT 13
+#define SETUP_TOKEN_FULLSCREEN 14
+#define SETUP_TOKEN_ASK_ON_ESCAPE 15
+#define SETUP_TOKEN_GRAPHICS_SET 16
+#define SETUP_TOKEN_SOUNDS_SET 17
+#define SETUP_TOKEN_MUSIC_SET 18
+#define SETUP_TOKEN_OVERRIDE_LEVEL_GRAPHICS 19
+#define SETUP_TOKEN_OVERRIDE_LEVEL_SOUNDS 20
+#define SETUP_TOKEN_OVERRIDE_LEVEL_MUSIC 21
+
+#define NUM_GLOBAL_SETUP_TOKENS 22
+
+/* editor setup */
+#define SETUP_TOKEN_EDITOR_EL_BOULDERDASH 0
+#define SETUP_TOKEN_EDITOR_EL_EMERALD_MINE 1
+#define SETUP_TOKEN_EDITOR_EL_MORE 2
+#define SETUP_TOKEN_EDITOR_EL_SOKOBAN 3
+#define SETUP_TOKEN_EDITOR_EL_SUPAPLEX 4
+#define SETUP_TOKEN_EDITOR_EL_DIAMOND_CAVES 5
+#define SETUP_TOKEN_EDITOR_EL_DX_BOULDERDASH 6
+#define SETUP_TOKEN_EDITOR_EL_CHARS 7
+#define SETUP_TOKEN_EDITOR_EL_CUSTOM 8
+
+#define NUM_EDITOR_SETUP_TOKENS 9
+
+/* shortcut setup */
+#define SETUP_TOKEN_SHORTCUT_SAVE_GAME 0
+#define SETUP_TOKEN_SHORTCUT_LOAD_GAME 1
+#define SETUP_TOKEN_SHORTCUT_TOGGLE_PAUSE 2
+
+#define NUM_SHORTCUT_SETUP_TOKENS 3
+
+/* player setup */
+#define SETUP_TOKEN_PLAYER_USE_JOYSTICK 0
+#define SETUP_TOKEN_PLAYER_JOY_DEVICE_NAME 1
+#define SETUP_TOKEN_PLAYER_JOY_XLEFT 2
+#define SETUP_TOKEN_PLAYER_JOY_XMIDDLE 3
+#define SETUP_TOKEN_PLAYER_JOY_XRIGHT 4
+#define SETUP_TOKEN_PLAYER_JOY_YUPPER 5
+#define SETUP_TOKEN_PLAYER_JOY_YMIDDLE 6
+#define SETUP_TOKEN_PLAYER_JOY_YLOWER 7
+#define SETUP_TOKEN_PLAYER_JOY_SNAP 8
+#define SETUP_TOKEN_PLAYER_JOY_BOMB 9
+#define SETUP_TOKEN_PLAYER_KEY_LEFT 10
+#define SETUP_TOKEN_PLAYER_KEY_RIGHT 11
+#define SETUP_TOKEN_PLAYER_KEY_UP 12
+#define SETUP_TOKEN_PLAYER_KEY_DOWN 13
+#define SETUP_TOKEN_PLAYER_KEY_SNAP 14
+#define SETUP_TOKEN_PLAYER_KEY_BOMB 15
+
+#define NUM_PLAYER_SETUP_TOKENS 16
+
+static struct SetupInfo si;
+static struct SetupEditorInfo sei;
+static struct SetupShortcutInfo ssi;
+static struct SetupInputInfo sii;
+
+static struct TokenInfo global_setup_tokens[] =
+{
+ /* global setup */
+ { TYPE_STRING, &si.player_name, "player_name" },
+ { TYPE_SWITCH, &si.sound, "sound" },
+ { TYPE_SWITCH, &si.sound_loops, "repeating_sound_loops" },
+ { TYPE_SWITCH, &si.sound_music, "background_music" },
+ { TYPE_SWITCH, &si.sound_simple, "simple_sound_effects" },
+ { TYPE_SWITCH, &si.toons, "toons" },
+ { TYPE_SWITCH, &si.scroll_delay, "scroll_delay" },
+ { TYPE_SWITCH, &si.soft_scrolling, "soft_scrolling" },
+ { TYPE_SWITCH, &si.fading, "screen_fading" },
+ { TYPE_SWITCH, &si.autorecord, "automatic_tape_recording" },
+ { TYPE_SWITCH, &si.quick_doors, "quick_doors" },
+ { TYPE_SWITCH, &si.team_mode, "team_mode" },
+ { TYPE_SWITCH, &si.handicap, "handicap" },
+ { TYPE_SWITCH, &si.time_limit, "time_limit" },
+ { TYPE_SWITCH, &si.fullscreen, "fullscreen" },
+ { TYPE_SWITCH, &si.ask_on_escape, "ask_on_escape" },
+ { TYPE_STRING, &si.graphics_set, "graphics_set" },
+ { TYPE_STRING, &si.sounds_set, "sounds_set" },
+ { TYPE_STRING, &si.music_set, "music_set" },
+ { TYPE_SWITCH, &si.override_level_graphics, "override_level_graphics" },
+ { TYPE_SWITCH, &si.override_level_sounds, "override_level_sounds" },
+ { TYPE_SWITCH, &si.override_level_music, "override_level_music" },
+};
+
+static struct TokenInfo editor_setup_tokens[] =
+{
+ /* shortcut setup */
+ { TYPE_SWITCH, &sei.el_boulderdash, "editor.el_boulderdash" },
+ { TYPE_SWITCH, &sei.el_emerald_mine, "editor.el_emerald_mine" },
+ { TYPE_SWITCH, &sei.el_more, "editor.el_more" },
+ { TYPE_SWITCH, &sei.el_sokoban, "editor.el_sokoban" },
+ { TYPE_SWITCH, &sei.el_supaplex, "editor.el_supaplex" },
+ { TYPE_SWITCH, &sei.el_diamond_caves, "editor.el_diamond_caves" },
+ { TYPE_SWITCH, &sei.el_dx_boulderdash,"editor.el_dx_boulderdash" },
+ { TYPE_SWITCH, &sei.el_chars, "editor.el_chars" },
+ { TYPE_SWITCH, &sei.el_custom, "editor.el_custom" },
+};
+
+static struct TokenInfo shortcut_setup_tokens[] =
+{
+ /* shortcut setup */
+ { TYPE_KEY_X11, &ssi.save_game, "shortcut.save_game" },
+ { TYPE_KEY_X11, &ssi.load_game, "shortcut.load_game" },
+ { TYPE_KEY_X11, &ssi.toggle_pause, "shortcut.toggle_pause" }
+};
+
+static struct TokenInfo player_setup_tokens[] =
+{
+ /* player setup */
+ { TYPE_BOOLEAN, &sii.use_joystick, ".use_joystick" },
+ { TYPE_STRING, &sii.joy.device_name, ".joy.device_name" },
+ { TYPE_INTEGER, &sii.joy.xleft, ".joy.xleft" },
+ { TYPE_INTEGER, &sii.joy.xmiddle, ".joy.xmiddle" },
+ { TYPE_INTEGER, &sii.joy.xright, ".joy.xright" },
+ { TYPE_INTEGER, &sii.joy.yupper, ".joy.yupper" },
+ { TYPE_INTEGER, &sii.joy.ymiddle, ".joy.ymiddle" },
+ { TYPE_INTEGER, &sii.joy.ylower, ".joy.ylower" },
+ { TYPE_INTEGER, &sii.joy.snap, ".joy.snap_field" },
+ { TYPE_INTEGER, &sii.joy.bomb, ".joy.place_bomb" },
+ { TYPE_KEY_X11, &sii.key.left, ".key.move_left" },
+ { TYPE_KEY_X11, &sii.key.right, ".key.move_right" },
+ { TYPE_KEY_X11, &sii.key.up, ".key.move_up" },
+ { TYPE_KEY_X11, &sii.key.down, ".key.move_down" },
+ { TYPE_KEY_X11, &sii.key.snap, ".key.snap_field" },
+ { TYPE_KEY_X11, &sii.key.bomb, ".key.place_bomb" }
+};
+
+static void setSetupInfoToDefaults(struct SetupInfo *si)
+{
+ int i;
+
+ si->player_name = getStringCopy(getLoginName());
+
+ si->sound = TRUE;
+ si->sound_loops = TRUE;
+ si->sound_music = TRUE;
+ si->sound_simple = TRUE;
+ si->toons = TRUE;
+ si->double_buffering = TRUE;
+ si->direct_draw = !si->double_buffering;
+ si->scroll_delay = TRUE;
+ si->soft_scrolling = TRUE;
+ si->fading = FALSE;
+ si->autorecord = TRUE;
+ si->quick_doors = FALSE;
+ si->team_mode = FALSE;
+ si->handicap = TRUE;
+ si->time_limit = TRUE;
+ si->fullscreen = FALSE;
+ si->ask_on_escape = TRUE;
+
+ si->graphics_set = getStringCopy(GRAPHICS_SUBDIR);
+ si->sounds_set = getStringCopy(SOUNDS_SUBDIR);
+ si->music_set = getStringCopy(MUSIC_SUBDIR);
+ si->override_level_graphics = FALSE;
+ si->override_level_sounds = FALSE;
+ si->override_level_music = FALSE;
+
+ si->editor.el_boulderdash = TRUE;
+ si->editor.el_emerald_mine = TRUE;
+ si->editor.el_more = TRUE;
+ si->editor.el_sokoban = TRUE;
+ si->editor.el_supaplex = TRUE;
+ si->editor.el_diamond_caves = TRUE;
+ si->editor.el_dx_boulderdash = TRUE;
+ si->editor.el_chars = TRUE;
+ si->editor.el_custom = FALSE;
+
+ si->shortcut.save_game = DEFAULT_KEY_SAVE_GAME;
+ si->shortcut.load_game = DEFAULT_KEY_LOAD_GAME;
+ si->shortcut.toggle_pause = DEFAULT_KEY_TOGGLE_PAUSE;
+
+ for (i=0; i<MAX_PLAYERS; i++)
+ {
+ si->input[i].use_joystick = FALSE;
+ si->input[i].joy.device_name=getStringCopy(getDeviceNameFromJoystickNr(i));
+ si->input[i].joy.xleft = JOYSTICK_XLEFT;
+ si->input[i].joy.xmiddle = JOYSTICK_XMIDDLE;
+ si->input[i].joy.xright = JOYSTICK_XRIGHT;
+ si->input[i].joy.yupper = JOYSTICK_YUPPER;
+ si->input[i].joy.ymiddle = JOYSTICK_YMIDDLE;
+ si->input[i].joy.ylower = JOYSTICK_YLOWER;
+ si->input[i].joy.snap = (i == 0 ? JOY_BUTTON_1 : 0);
+ si->input[i].joy.bomb = (i == 0 ? JOY_BUTTON_2 : 0);
+ si->input[i].key.left = (i == 0 ? DEFAULT_KEY_LEFT : KSYM_UNDEFINED);
+ si->input[i].key.right = (i == 0 ? DEFAULT_KEY_RIGHT : KSYM_UNDEFINED);
+ si->input[i].key.up = (i == 0 ? DEFAULT_KEY_UP : KSYM_UNDEFINED);
+ si->input[i].key.down = (i == 0 ? DEFAULT_KEY_DOWN : KSYM_UNDEFINED);
+ si->input[i].key.snap = (i == 0 ? DEFAULT_KEY_SNAP : KSYM_UNDEFINED);
+ si->input[i].key.bomb = (i == 0 ? DEFAULT_KEY_BOMB : KSYM_UNDEFINED);
+ }
+}
+
+static void decodeSetupFileList(struct SetupFileList *setup_file_list)
+{
+ int i, pnr;
+
+ if (!setup_file_list)
+ return;
+
+ /* global setup */
+ si = setup;
+ for (i=0; i<NUM_GLOBAL_SETUP_TOKENS; i++)
+ setSetupInfo(global_setup_tokens, i,
+ getTokenValue(setup_file_list, global_setup_tokens[i].text));
+ setup = si;
+
+ /* editor setup */
+ sei = setup.editor;
+ for (i=0; i<NUM_EDITOR_SETUP_TOKENS; i++)
+ setSetupInfo(editor_setup_tokens, i,
+ getTokenValue(setup_file_list,editor_setup_tokens[i].text));
+ setup.editor = sei;
+
+ /* shortcut setup */
+ ssi = setup.shortcut;
+ for (i=0; i<NUM_SHORTCUT_SETUP_TOKENS; i++)
+ setSetupInfo(shortcut_setup_tokens, i,
+ getTokenValue(setup_file_list,shortcut_setup_tokens[i].text));
+ setup.shortcut = ssi;
+
+ /* player setup */
+ for (pnr=0; pnr<MAX_PLAYERS; pnr++)
+ {
+ char prefix[30];
+
+ sprintf(prefix, "%s%d", TOKEN_STR_PLAYER_PREFIX, pnr + 1);
+
+ sii = setup.input[pnr];
+ for (i=0; i<NUM_PLAYER_SETUP_TOKENS; i++)
+ {
+ char full_token[100];
+
+ sprintf(full_token, "%s%s", prefix, player_setup_tokens[i].text);
+ setSetupInfo(player_setup_tokens, i,
+ getTokenValue(setup_file_list, full_token));
+ }
+ setup.input[pnr] = sii;
+ }
+}
+
+void LoadSetup()
+{
+ char *filename = getSetupFilename();
+ struct SetupFileList *setup_file_list = NULL;
+
+ /* always start with reliable default values */
+ setSetupInfoToDefaults(&setup);
+
+ setup_file_list = loadSetupFileList(filename);
+
+ if (setup_file_list)
+ {
+ checkSetupFileListIdentifier(setup_file_list, getCookie("SETUP"));
+ decodeSetupFileList(setup_file_list);
+
+ setup.direct_draw = !setup.double_buffering;
+
+ freeSetupFileList(setup_file_list);
+
+ /* needed to work around problems with fixed length strings */
+ if (strlen(setup.player_name) > MAX_PLAYER_NAME_LEN)
+ setup.player_name[MAX_PLAYER_NAME_LEN] = '\0';
+ else if (strlen(setup.player_name) < MAX_PLAYER_NAME_LEN)
+ {
+ char *new_name = checked_malloc(MAX_PLAYER_NAME_LEN + 1);
+
+ strcpy(new_name, setup.player_name);
+ free(setup.player_name);
+ setup.player_name = new_name;
+ }
+ }
+ else
+ Error(ERR_WARN, "using default setup values");
+}
+
+void SaveSetup()
+{
+ char *filename = getSetupFilename();
+ FILE *file;
+ int i, pnr;
+
+ InitUserDataDirectory();
+
+ if (!(file = fopen(filename, MODE_WRITE)))
+ {
+ Error(ERR_WARN, "cannot write setup file '%s'", filename);
+ return;
+ }
+
+ fprintf(file, "%s\n", getFormattedSetupEntry(TOKEN_STR_FILE_IDENTIFIER,
+ getCookie("SETUP")));
+ fprintf(file, "\n");
+
+ /* global setup */
+ si = setup;
+ for (i=0; i<NUM_GLOBAL_SETUP_TOKENS; i++)
+ {
+ /* just to make things nicer :) */
+ if (i == SETUP_TOKEN_PLAYER_NAME + 1 ||
+ i == SETUP_TOKEN_GRAPHICS_SET)
+ fprintf(file, "\n");
+
+ fprintf(file, "%s\n", getSetupLine(global_setup_tokens, "", i));
+ }
+
+ /* editor setup */
+ sei = setup.editor;
+ fprintf(file, "\n");
+ for (i=0; i<NUM_EDITOR_SETUP_TOKENS; i++)
+ fprintf(file, "%s\n", getSetupLine(editor_setup_tokens, "", i));
+
+ /* shortcut setup */
+ ssi = setup.shortcut;
+ fprintf(file, "\n");
+ for (i=0; i<NUM_SHORTCUT_SETUP_TOKENS; i++)
+ fprintf(file, "%s\n", getSetupLine(shortcut_setup_tokens, "", i));
+
+ /* player setup */
+ for (pnr=0; pnr<MAX_PLAYERS; pnr++)
+ {
+ char prefix[30];
+
+ sprintf(prefix, "%s%d", TOKEN_STR_PLAYER_PREFIX, pnr + 1);
+ fprintf(file, "\n");
+
+ sii = setup.input[pnr];
+ for (i=0; i<NUM_PLAYER_SETUP_TOKENS; i++)
+ fprintf(file, "%s\n", getSetupLine(player_setup_tokens, prefix, i));
+ }
+
+ fclose(file);
+
+ SetFilePermissions(filename, PERMS_PRIVATE);
+}
+
+void LoadCustomElementDescriptions()
+{
+ char *filename = getCustomArtworkConfigFilename(ARTWORK_TYPE_GRAPHICS);
+ struct SetupFileList *setup_file_list;
+ int i;
+
+ for (i=0; i<NUM_FILE_ELEMENTS; i++)
+ {
+ if (element_info[i].custom_description != NULL)
+ {
+ free(element_info[i].custom_description);
+ element_info[i].custom_description = NULL;
+ }
+ }
+
+ if ((setup_file_list = loadSetupFileList(filename)) == NULL)
+ return;
+
+ for (i=0; i<NUM_FILE_ELEMENTS; i++)
+ {
+ char *token = getStringCat2(element_info[i].token_name, ".name");
+ char *value = getTokenValue(setup_file_list, token);
+
+ if (value != NULL)
+ element_info[i].custom_description = getStringCopy(value);
+
+ free(token);
+ }
+
+ freeSetupFileList(setup_file_list);
+}