rnd-20100616-1-src
[rocksndiamonds.git] / src / files.c
index 2e58ad30240e469571637a99b075a5267d87dd4d..8f018be001fcf4a7cd6b9bf5190e63874b505449 100644 (file)
@@ -6551,7 +6551,7 @@ static void LoadLevelFromFileInfo_SB(struct LevelInfo *level,
   boolean load_xsb_to_ces = check_special_flags("load_xsb_to_ces");
   int file_level_nr = 0;
   int line_nr = 0;
-  int x, y;
+  int x = 0, y = 0;            /* initialized to make compilers happy */
 
 #if 0
   printf("::: looking for level number %d [%d]\n",
@@ -8452,6 +8452,79 @@ static int LoadTape_BODY(FILE *file, int chunk_size, struct TapeInfo *tape)
   return chunk_size;
 }
 
+void LoadTape_SokobanSolution(char *filename)
+{
+  FILE *file;
+  int move_delay = TILESIZE / level.initial_player_stepsize[0];
+
+  if (!(file = fopen(filename, MODE_READ)))
+  {
+    tape.no_valid_file = TRUE;
+
+    return;
+  }
+
+  while (!feof(file))
+  {
+    unsigned char c = fgetc(file);
+
+    if (feof(file))
+      break;
+
+    switch (c)
+    {
+      case 'u':
+      case 'U':
+       tape.pos[tape.length].action[0] = MV_UP;
+       tape.pos[tape.length].delay = move_delay + (c < 'a' ? 2 : 0);
+       tape.length++;
+       break;
+
+      case 'd':
+      case 'D':
+       tape.pos[tape.length].action[0] = MV_DOWN;
+       tape.pos[tape.length].delay = move_delay + (c < 'a' ? 2 : 0);
+       tape.length++;
+       break;
+
+      case 'l':
+      case 'L':
+       tape.pos[tape.length].action[0] = MV_LEFT;
+       tape.pos[tape.length].delay = move_delay + (c < 'a' ? 2 : 0);
+       tape.length++;
+       break;
+
+      case 'r':
+      case 'R':
+       tape.pos[tape.length].action[0] = MV_RIGHT;
+       tape.pos[tape.length].delay = move_delay + (c < 'a' ? 2 : 0);
+       tape.length++;
+       break;
+
+      case '\n':
+      case '\r':
+      case '\t':
+      case ' ':
+       /* ignore white-space characters */
+       break;
+
+      default:
+       tape.no_valid_file = TRUE;
+
+       Error(ERR_WARN, "unsupported Sokoban solution file '%s' ['%d']", filename, c);
+
+       break;
+    }
+  }
+
+  fclose(file);
+
+  if (tape.no_valid_file)
+    return;
+
+  tape.length_seconds = GetTapeLength();
+}
+
 void LoadTapeFromFilename(char *filename)
 {
   char cookie[MAX_LINE_LEN];
@@ -8462,6 +8535,13 @@ void LoadTapeFromFilename(char *filename)
   /* always start with reliable default values */
   setTapeInfoToDefaults();
 
+  if (strSuffix(filename, ".sln"))
+  {
+    LoadTape_SokobanSolution(filename);
+
+    return;
+  }
+
   if (!(file = fopen(filename, MODE_READ)))
   {
     tape.no_valid_file = TRUE;
@@ -8506,6 +8586,7 @@ void LoadTapeFromFilename(char *filename)
 
       Error(ERR_WARN, "unsupported version of tape file '%s'", filename);
       fclose(file);
+
       return;
     }
 
@@ -8979,15 +9060,20 @@ void SaveScore(int nr)
 #define SETUP_TOKEN_SHORTCUT_FOCUS_PLAYER_4    6
 #define SETUP_TOKEN_SHORTCUT_FOCUS_PLAYER_ALL  7
 #define SETUP_TOKEN_SHORTCUT_TAPE_EJECT                8
-#define SETUP_TOKEN_SHORTCUT_TAPE_STOP         9
-#define SETUP_TOKEN_SHORTCUT_TAPE_PAUSE                10
-#define SETUP_TOKEN_SHORTCUT_TAPE_RECORD       11
-#define SETUP_TOKEN_SHORTCUT_TAPE_PLAY         12
-#define SETUP_TOKEN_SHORTCUT_SOUND_SIMPLE      13
-#define SETUP_TOKEN_SHORTCUT_SOUND_LOOPS       14
-#define SETUP_TOKEN_SHORTCUT_SOUND_MUSIC       15
-
-#define NUM_SHORTCUT_SETUP_TOKENS              16
+#define SETUP_TOKEN_SHORTCUT_TAPE_EXTRA                9
+#define SETUP_TOKEN_SHORTCUT_TAPE_STOP         10
+#define SETUP_TOKEN_SHORTCUT_TAPE_PAUSE                11
+#define SETUP_TOKEN_SHORTCUT_TAPE_RECORD       12
+#define SETUP_TOKEN_SHORTCUT_TAPE_PLAY         13
+#define SETUP_TOKEN_SHORTCUT_SOUND_SIMPLE      14
+#define SETUP_TOKEN_SHORTCUT_SOUND_LOOPS       15
+#define SETUP_TOKEN_SHORTCUT_SOUND_MUSIC       16
+#define SETUP_TOKEN_SHORTCUT_SNAP_LEFT         17
+#define SETUP_TOKEN_SHORTCUT_SNAP_RIGHT                18
+#define SETUP_TOKEN_SHORTCUT_SNAP_UP           19
+#define SETUP_TOKEN_SHORTCUT_SNAP_DOWN         20
+
+#define NUM_SHORTCUT_SETUP_TOKENS              21
 
 /* player setup */
 #define SETUP_TOKEN_PLAYER_USE_JOYSTICK                0
@@ -9133,6 +9219,7 @@ static struct TokenInfo shortcut_setup_tokens[] =
   { TYPE_KEY_X11, &ssi.focus_player[3],        "shortcut.focus_player_4"       },
   { TYPE_KEY_X11, &ssi.focus_player_all,"shortcut.focus_player_all"    },
   { TYPE_KEY_X11, &ssi.tape_eject,     "shortcut.tape_eject"           },
+  { TYPE_KEY_X11, &ssi.tape_extra,     "shortcut.tape_extra"           },
   { TYPE_KEY_X11, &ssi.tape_stop,      "shortcut.tape_stop"            },
   { TYPE_KEY_X11, &ssi.tape_pause,     "shortcut.tape_pause"           },
   { TYPE_KEY_X11, &ssi.tape_record,    "shortcut.tape_record"          },
@@ -9140,6 +9227,10 @@ static struct TokenInfo shortcut_setup_tokens[] =
   { TYPE_KEY_X11, &ssi.sound_simple,   "shortcut.sound_simple"         },
   { TYPE_KEY_X11, &ssi.sound_loops,    "shortcut.sound_loops"          },
   { TYPE_KEY_X11, &ssi.sound_music,    "shortcut.sound_music"          },
+  { TYPE_KEY_X11, &ssi.snap_left,      "shortcut.snap_left"            },
+  { TYPE_KEY_X11, &ssi.snap_right,     "shortcut.snap_right"           },
+  { TYPE_KEY_X11, &ssi.snap_up,                "shortcut.snap_up"              },
+  { TYPE_KEY_X11, &ssi.snap_down,      "shortcut.snap_down"            },
 };
 
 static struct TokenInfo player_setup_tokens[] =
@@ -9257,6 +9348,7 @@ static void setSetupInfoToDefaults(struct SetupInfo *si)
   si->shortcut.focus_player_all        = DEFAULT_KEY_FOCUS_PLAYER_ALL;
 
   si->shortcut.tape_eject      = DEFAULT_KEY_TAPE_EJECT;
+  si->shortcut.tape_extra      = DEFAULT_KEY_TAPE_EXTRA;
   si->shortcut.tape_stop       = DEFAULT_KEY_TAPE_STOP;
   si->shortcut.tape_pause      = DEFAULT_KEY_TAPE_PAUSE;
   si->shortcut.tape_record     = DEFAULT_KEY_TAPE_RECORD;
@@ -9266,6 +9358,11 @@ static void setSetupInfoToDefaults(struct SetupInfo *si)
   si->shortcut.sound_loops     = DEFAULT_KEY_SOUND_LOOPS;
   si->shortcut.sound_music     = DEFAULT_KEY_SOUND_MUSIC;
 
+  si->shortcut.snap_left       = DEFAULT_KEY_SNAP_LEFT;
+  si->shortcut.snap_right      = DEFAULT_KEY_SNAP_RIGHT;
+  si->shortcut.snap_up         = DEFAULT_KEY_SNAP_UP;
+  si->shortcut.snap_down       = DEFAULT_KEY_SNAP_DOWN;
+
   for (i = 0; i < MAX_PLAYERS; i++)
   {
     si->input[i].use_joystick = FALSE;
@@ -9293,6 +9390,7 @@ static void setSetupInfoToDefaults(struct SetupInfo *si)
   si->options.verbose = FALSE;
 
 #if defined(CREATE_SPECIAL_EDITION_RND_JUE)
+  si->toons = FALSE;
   si->handicap = FALSE;
   si->fullscreen = TRUE;
   si->override_level_graphics = AUTO;
@@ -9726,6 +9824,16 @@ static void InitMenuDesignSettings_SpecialPreProcessing()
     menu.enter_screen[i] = menu.enter_screen[GFX_SPECIAL_ARG_DEFAULT];
     menu.leave_screen[i] = menu.leave_screen[GFX_SPECIAL_ARG_DEFAULT];
   }
+
+  /* special case: initialize "ARG_DEFAULT" values in static default config */
+  /* (eg, init "viewport.door_1.MAIN.xyz" from "viewport.door_1.xyz") */
+  for (i = 0; i < NUM_SPECIAL_GFX_ARGS; i++)
+  {
+    viewport.playfield[i] = viewport.playfield[GFX_SPECIAL_ARG_DEFAULT];
+    viewport.door_1[i] = viewport.door_1[GFX_SPECIAL_ARG_DEFAULT];
+    if (i != GFX_SPECIAL_ARG_EDITOR)   /* editor value already initialized */
+      viewport.door_2[i] = viewport.door_2[GFX_SPECIAL_ARG_DEFAULT];
+  }
 }
 
 static void InitMenuDesignSettings_SpecialPostProcessing()
@@ -9863,6 +9971,50 @@ static void LoadMenuDesignSettingsFromFilename(char *filename)
                                                                  value_6);
   }
 
+  /* special case: initialize with default values that may be overwritten */
+  /* (eg, init "viewport.door_1.MAIN.xyz" from "viewport.door_1.xyz") */
+  for (i = 0; i < NUM_SPECIAL_GFX_ARGS; i++)
+  {
+    char *token_1 = "viewport.playfield.x";
+    char *token_2 = "viewport.playfield.y";
+    char *token_3 = "viewport.playfield.width";
+    char *token_4 = "viewport.playfield.height";
+    char *token_5 = "viewport.playfield.border_size";
+    char *token_6 = "viewport.door_1.x";
+    char *token_7 = "viewport.door_1.y";
+    char *token_8 = "viewport.door_2.x";
+    char *token_9 = "viewport.door_2.y";
+    char *value_1 = getHashEntry(setup_file_hash, token_1);
+    char *value_2 = getHashEntry(setup_file_hash, token_2);
+    char *value_3 = getHashEntry(setup_file_hash, token_3);
+    char *value_4 = getHashEntry(setup_file_hash, token_4);
+    char *value_5 = getHashEntry(setup_file_hash, token_5);
+    char *value_6 = getHashEntry(setup_file_hash, token_6);
+    char *value_7 = getHashEntry(setup_file_hash, token_7);
+    char *value_8 = getHashEntry(setup_file_hash, token_8);
+    char *value_9 = getHashEntry(setup_file_hash, token_9);
+
+    if (value_1 != NULL)
+      viewport.playfield[i].x = get_token_parameter_value(token_1, value_1);
+    if (value_2 != NULL)
+      viewport.playfield[i].y = get_token_parameter_value(token_2, value_2);
+    if (value_3 != NULL)
+      viewport.playfield[i].width = get_token_parameter_value(token_3, value_3);
+    if (value_4 != NULL)
+      viewport.playfield[i].height = get_token_parameter_value(token_4,value_4);
+    if (value_5 != NULL)
+      viewport.playfield[i].border_size = get_token_parameter_value(token_5,
+                                                                   value_5);
+    if (value_6 != NULL)
+      viewport.door_1[i].x = get_token_parameter_value(token_6, value_6);
+    if (value_7 != NULL)
+      viewport.door_1[i].y = get_token_parameter_value(token_7, value_7);
+    if (value_8 != NULL)
+      viewport.door_2[i].x = get_token_parameter_value(token_8, value_8);
+    if (value_9 != NULL)
+      viewport.door_2[i].y = get_token_parameter_value(token_9, value_9);
+  }
+
   /* special case: initialize with default values that may be overwritten */
   /* (e.g., init "titlemessage_1.fade_mode" from "[titlemessage].fade_mode") */
   for (i = 0; titlemessage_arrays[i].array != NULL; i++)
@@ -10199,6 +10351,10 @@ void LoadMusicInfo()
     if (!music_info_listed(music_file_info, music->filename))
     {
       *new = get_music_file_info(music->filename, i);
+#if 0
+      if (*new != NULL)
+       printf(":1: adding '%s' ['%s'] ...\n", (*new)->title, music->filename);
+#endif
       if (*new != NULL)
        new = &(*new)->next;
     }
@@ -10244,6 +10400,10 @@ void LoadMusicInfo()
     if (!music_info_listed(music_file_info, basename))
     {
       *new = get_music_file_info(basename, MAP_NOCONF_MUSIC(num_music_noconf));
+#if 0
+      if (*new != NULL)
+       printf(":2: adding '%s' ['%s'] ...\n", (*new)->title, basename);
+#endif
       if (*new != NULL)
        new = &(*new)->next;
     }