fixed returning from function with incomplete list pointers
[rocksndiamonds.git] / src / files.c
index cdb890b92f52325e57ff16136f5696cadbbec4ae..676ebf8aa3d9db839d3921b76032c6fadd76e2f5 100644 (file)
@@ -904,11 +904,34 @@ static struct LevelFileConfigInfo chunk_config_ELEM[] =
     TYPE_INTEGER,                      CONF_VALUE_16_BIT(1),
     &li.mm_time_bomb,                  75
   },
+
   {
     EL_MM_GRAY_BALL,                   -1,
     TYPE_INTEGER,                      CONF_VALUE_16_BIT(1),
     &li.mm_time_ball,                  75
   },
+  {
+    EL_MM_GRAY_BALL,                   -1,
+    TYPE_INTEGER,                      CONF_VALUE_8_BIT(1),
+    &li.mm_ball_choice_mode,           ANIM_RANDOM
+  },
+  {
+    EL_MM_GRAY_BALL,                   -1,
+    TYPE_ELEMENT_LIST,                 CONF_VALUE_BYTES(1),
+    &li.mm_ball_content,               EL_EMPTY, NULL,
+    &li.num_mm_ball_contents,          8, MAX_MM_BALL_CONTENTS
+  },
+  {
+    EL_MM_GRAY_BALL,                   -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(1),
+    &li.rotate_mm_ball_content,                TRUE
+  },
+  {
+    EL_MM_GRAY_BALL,                   -1,
+    TYPE_BOOLEAN,                      CONF_VALUE_8_BIT(2),
+    &li.explode_mm_ball,               FALSE
+  },
+
   {
     EL_MM_STEEL_BLOCK,                 -1,
     TYPE_INTEGER,                      CONF_VALUE_16_BIT(1),
@@ -1841,6 +1864,16 @@ static void setLevelInfoToDefaults_Elements(struct LevelInfo *level)
     int element = i;
     struct ElementInfo *ei = &element_info[element];
 
+    if (element == EL_MM_GRAY_BALL)
+    {
+      struct LevelInfo_MM *level_mm = level->native_mm_level;
+      int j;
+
+      for (j = 0; j < level->num_mm_ball_contents; j++)
+       level->mm_ball_content[j] =
+         map_element_MM_to_RND(level_mm->ball_content[j]);
+    }
+
     // never initialize clipboard elements after the very first time
     // (to be able to use clipboard elements between several levels)
     if (IS_CLIPBOARD_ELEMENT(element) && clipboard_elements_initialized)
@@ -2848,7 +2881,7 @@ static int LoadLevel_CUS3(File *file, int chunk_size, struct LevelInfo *level)
     // bits 0 - 31 of "has_event[]"
     event_bits = getFile32BitBE(file);
     for (j = 0; j < MIN(NUM_CHANGE_EVENTS, 32); j++)
-      if (event_bits & (1 << j))
+      if (event_bits & (1u << j))
        ei->change->has_event[j] = TRUE;
 
     ei->change->target_element = getMappedElement(getFile16BitBE(file));
@@ -2984,7 +3017,7 @@ static int LoadLevel_CUS4(File *file, int chunk_size, struct LevelInfo *level)
     // bits 0 - 31 of "has_event[]" ...
     event_bits = getFile32BitBE(file);
     for (j = 0; j < MIN(NUM_CHANGE_EVENTS, 32); j++)
-      if (event_bits & (1 << j))
+      if (event_bits & (1u << j))
        change->has_event[j] = TRUE;
 
     change->target_element = getMappedElement(getFile16BitBE(file));
@@ -3025,7 +3058,7 @@ static int LoadLevel_CUS4(File *file, int chunk_size, struct LevelInfo *level)
     // ... bits 32 - 39 of "has_event[]" (not nice, but downward compatible)
     event_bits = getFile8Bit(file);
     for (j = 32; j < NUM_CHANGE_EVENTS; j++)
-      if (event_bits & (1 << (j - 32)))
+      if (event_bits & (1u << (j - 32)))
        change->has_event[j] = TRUE;
   }
 
@@ -3680,6 +3713,7 @@ static void CopyNativeLevel_RND_to_EM(struct LevelInfo *level)
   cav->lenses_time             = level->lenses_time;
   cav->magnify_time            = level->magnify_time;
 
+  cav->wind_time = 9999;
   cav->wind_direction =
     map_direction_RND_to_EM(level->wind_direction_initial);
 
@@ -4129,7 +4163,7 @@ static void CopyNativeTape_SP_to_RND(struct LevelInfo *level)
 static void CopyNativeLevel_RND_to_MM(struct LevelInfo *level)
 {
   struct LevelInfo_MM *level_mm = level->native_mm_level;
-  int x, y;
+  int i, x, y;
 
   level_mm->fieldx = MIN(level->fieldx, MM_MAX_PLAYFIELD_WIDTH);
   level_mm->fieldy = MIN(level->fieldy, MM_MAX_PLAYFIELD_HEIGHT);
@@ -4138,9 +4172,13 @@ static void CopyNativeLevel_RND_to_MM(struct LevelInfo *level)
   level_mm->kettles_needed = level->gems_needed;
   level_mm->auto_count_kettles = level->auto_count_gems;
 
-  level_mm->laser_red = level->mm_laser_red;
-  level_mm->laser_green = level->mm_laser_green;
-  level_mm->laser_blue = level->mm_laser_blue;
+  level_mm->mm_laser_red   = level->mm_laser_red;
+  level_mm->mm_laser_green = level->mm_laser_green;
+  level_mm->mm_laser_blue  = level->mm_laser_blue;
+
+  level_mm->df_laser_red   = level->df_laser_red;
+  level_mm->df_laser_green = level->df_laser_green;
+  level_mm->df_laser_blue  = level->df_laser_blue;
 
   strcpy(level_mm->name, level->name);
   strcpy(level_mm->author, level->author);
@@ -4157,6 +4195,15 @@ static void CopyNativeLevel_RND_to_MM(struct LevelInfo *level)
   level_mm->time_ball    = level->mm_time_ball;
   level_mm->time_block   = level->mm_time_block;
 
+  level_mm->num_ball_contents = level->num_mm_ball_contents;
+  level_mm->ball_choice_mode = level->mm_ball_choice_mode;
+  level_mm->rotate_ball_content = level->rotate_mm_ball_content;
+  level_mm->explode_ball = level->explode_mm_ball;
+
+  for (i = 0; i < level->num_mm_ball_contents; i++)
+    level_mm->ball_content[i] =
+      map_element_RND_to_MM(level->mm_ball_content[i]);
+
   for (x = 0; x < level->fieldx; x++)
     for (y = 0; y < level->fieldy; y++)
       Ur[x][y] =
@@ -4166,7 +4213,7 @@ static void CopyNativeLevel_RND_to_MM(struct LevelInfo *level)
 static void CopyNativeLevel_MM_to_RND(struct LevelInfo *level)
 {
   struct LevelInfo_MM *level_mm = level->native_mm_level;
-  int x, y;
+  int i, x, y;
 
   level->fieldx = MIN(level_mm->fieldx, MAX_LEV_FIELDX);
   level->fieldy = MIN(level_mm->fieldy, MAX_LEV_FIELDY);
@@ -4175,9 +4222,13 @@ static void CopyNativeLevel_MM_to_RND(struct LevelInfo *level)
   level->gems_needed = level_mm->kettles_needed;
   level->auto_count_gems = level_mm->auto_count_kettles;
 
-  level->mm_laser_red = level_mm->laser_red;
-  level->mm_laser_green = level_mm->laser_green;
-  level->mm_laser_blue = level_mm->laser_blue;
+  level->mm_laser_red   = level_mm->mm_laser_red;
+  level->mm_laser_green = level_mm->mm_laser_green;
+  level->mm_laser_blue  = level_mm->mm_laser_blue;
+
+  level->df_laser_red   = level_mm->df_laser_red;
+  level->df_laser_green = level_mm->df_laser_green;
+  level->df_laser_blue  = level_mm->df_laser_blue;
 
   strcpy(level->name, level_mm->name);
 
@@ -4197,6 +4248,15 @@ static void CopyNativeLevel_MM_to_RND(struct LevelInfo *level)
   level->mm_time_ball  = level_mm->time_ball;
   level->mm_time_block = level_mm->time_block;
 
+  level->num_mm_ball_contents = level_mm->num_ball_contents;
+  level->mm_ball_choice_mode = level_mm->ball_choice_mode;
+  level->rotate_mm_ball_content = level_mm->rotate_ball_content;
+  level->explode_mm_ball = level_mm->explode_ball;
+
+  for (i = 0; i < level->num_mm_ball_contents; i++)
+    level->mm_ball_content[i] =
+      map_element_MM_to_RND(level_mm->ball_content[i]);
+
   for (x = 0; x < level->fieldx; x++)
     for (y = 0; y < level->fieldy; y++)
       level->field[x][y] = map_element_MM_to_RND(level_mm->field[x][y]);
@@ -5678,8 +5738,7 @@ static int getMappedElement_DC(int element)
   return getMappedElement(element);
 }
 
-static void LoadLevelFromFileStream_DC(File *file, struct LevelInfo *level,
-                                      int nr)
+static void LoadLevelFromFileStream_DC(File *file, struct LevelInfo *level)
 {
   byte header[DC_LEVEL_HEADER_SIZE];
   int envelope_size;
@@ -5928,7 +5987,7 @@ static void LoadLevelFromFileInfo_DC(struct LevelInfo *level,
     }
   }
 
-  LoadLevelFromFileStream_DC(file, level, level_file_info->nr);
+  LoadLevelFromFileStream_DC(file, level);
 
   closeFile(file);
 }
@@ -7327,7 +7386,7 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element)
     event_bits = 0;
     for (j = 0; j < MIN(NUM_CHANGE_EVENTS, 32); j++)
       if (change->has_event[j])
-       event_bits |= (1 << j);
+       event_bits |= (1u << j);
     putFile32BitBE(file, event_bits);
 
     putFile16BitBE(file, change->target_element);
@@ -7367,7 +7426,7 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element)
     event_bits = 0;
     for (j = 32; j < NUM_CHANGE_EVENTS; j++)
       if (change->has_event[j])
-       event_bits |= (1 << (j - 32));
+       event_bits |= (1u << (j - 32));
     putFile8Bit(file, event_bits);
   }
 }
@@ -9459,6 +9518,10 @@ static struct TokenInfo global_setup_tokens[] =
     TYPE_SWITCH,
     &setup.autorecord,                         "automatic_tape_recording"
   },
+  {
+    TYPE_SWITCH,
+    &setup.autorecord_after_replay,            "autorecord_after_replay"
+  },
   {
     TYPE_SWITCH,
     &setup.auto_pause_on_start,                        "auto_pause_on_start"
@@ -10112,10 +10175,18 @@ static struct TokenInfo internal_setup_tokens[] =
     TYPE_BOOLEAN,
     &setup.internal.create_user_levelset,      "create_user_levelset"
   },
+  {
+    TYPE_BOOLEAN,
+    &setup.internal.info_screens_from_main,    "info_screens_from_main"
+  },
   {
     TYPE_BOOLEAN,
     &setup.internal.menu_game,                 "menu_game"
   },
+  {
+    TYPE_BOOLEAN,
+    &setup.internal.menu_engines,              "menu_engines"
+  },
   {
     TYPE_BOOLEAN,
     &setup.internal.menu_editor,               "menu_editor"
@@ -10152,6 +10223,26 @@ static struct TokenInfo internal_setup_tokens[] =
     TYPE_BOOLEAN,
     &setup.internal.menu_save_and_exit,                "menu_save_and_exit"
   },
+  {
+    TYPE_BOOLEAN,
+    &setup.internal.menu_shortcuts_various,    "menu_shortcuts_various"
+  },
+  {
+    TYPE_BOOLEAN,
+    &setup.internal.menu_shortcuts_focus,      "menu_shortcuts_focus"
+  },
+  {
+    TYPE_BOOLEAN,
+    &setup.internal.menu_shortcuts_tape,       "menu_shortcuts_tape"
+  },
+  {
+    TYPE_BOOLEAN,
+    &setup.internal.menu_shortcuts_sound,      "menu_shortcuts_sound"
+  },
+  {
+    TYPE_BOOLEAN,
+    &setup.internal.menu_shortcuts_snap,       "menu_shortcuts_snap"
+  },
   {
     TYPE_BOOLEAN,
     &setup.internal.info_title,                        "info_title"
@@ -10295,6 +10386,14 @@ static struct TokenInfo options_setup_tokens[] =
     TYPE_BOOLEAN,
     &setup.options.verbose,                    "options.verbose"
   },
+  {
+    TYPE_BOOLEAN,
+    &setup.options.debug,                      "options.debug"
+  },
+  {
+    TYPE_STRING,
+    &setup.options.debug_mode,                 "options.debug_mode"
+  },
 };
 
 static void setSetupInfoToDefaults(struct SetupInfo *si)
@@ -10317,6 +10416,7 @@ static void setSetupInfoToDefaults(struct SetupInfo *si)
   si->engine_snapshot_memory = SNAPSHOT_MEMORY_DEFAULT;
   si->fade_screens = TRUE;
   si->autorecord = TRUE;
+  si->autorecord_after_replay = TRUE;
   si->auto_pause_on_start = FALSE;
   si->show_titlescreen = TRUE;
   si->quick_doors = FALSE;
@@ -10529,6 +10629,7 @@ static void setSetupInfoToDefaults(struct SetupInfo *si)
   si->internal.choose_from_top_leveldir = FALSE;
   si->internal.show_scaling_in_title = TRUE;
   si->internal.create_user_levelset = TRUE;
+  si->internal.info_screens_from_main = FALSE;
 
   si->internal.default_window_width  = WIN_XSIZE_DEFAULT;
   si->internal.default_window_height = WIN_YSIZE_DEFAULT;
@@ -10564,6 +10665,8 @@ static void setSetupInfoToDefaults(struct SetupInfo *si)
   si->debug.xsn_percent = 0;
 
   si->options.verbose = FALSE;
+  si->options.debug = FALSE;
+  si->options.debug_mode = getStringCopy(ARG_UNDEFINED_STRING);
 
 #if defined(PLATFORM_ANDROID)
   si->fullscreen = TRUE;
@@ -12833,7 +12936,7 @@ static boolean sound_info_listed(struct MusicFileInfo *list, char *basename)
 
 void LoadMusicInfo(void)
 {
-  char *music_directory = getCustomMusicDirectory();
+  char *music_directory = getCustomMusicDirectory_NoConf();
   int num_music = getMusicListSize();
   int num_music_noconf = 0;
   int num_sounds = getSoundListSize();
@@ -12841,6 +12944,7 @@ void LoadMusicInfo(void)
   DirectoryEntry *dir_entry;
   struct FileInfo *music, *sound;
   struct MusicFileInfo *next, **new;
+  boolean read_music_from_directory = TRUE;
   int i;
 
   while (music_file_info != NULL)
@@ -12893,10 +12997,11 @@ void LoadMusicInfo(void)
   {
     Warn("cannot read music directory '%s'", music_directory);
 
-    return;
+    read_music_from_directory = FALSE;
   }
 
-  while ((dir_entry = readDirectory(dir)) != NULL)     // loop all entries
+  while (read_music_from_directory &&
+        (dir_entry = readDirectory(dir)) != NULL)      // loop all entries
   {
     char *basename = dir_entry->basename;
     boolean music_already_used = FALSE;
@@ -12934,7 +13039,8 @@ void LoadMusicInfo(void)
     num_music_noconf++;
   }
 
-  closeDirectory(dir);
+  if (dir != NULL)
+    closeDirectory(dir);
 
   for (i = 0; i < num_sounds; i++)
   {
@@ -13489,7 +13595,7 @@ void CreateCollectElementImages(void)
                  SDL_MapRGB(dst_bitmap->surface->format, 0x00, 0x00, 0x00));
 
   dst_bitmap->surface =
-    SDL_ConvertSurfaceFormat(dst_bitmap->surface, SDL_PIXELFORMAT_RGBA32, 0);
+    SDL_ConvertSurfaceFormat(dst_bitmap->surface, SDL_PIXELFORMAT_ARGB8888, 0);
 
   for (i = 0; i < MAX_NUM_ELEMENTS; i++)
   {
@@ -13516,7 +13622,7 @@ void CreateCollectElementImages(void)
                    SDL_MapRGB(tmp_bitmap->surface->format, 0x00, 0x00, 0x00));
 
     tmp_bitmap->surface =
-      SDL_ConvertSurfaceFormat(tmp_bitmap->surface, SDL_PIXELFORMAT_RGBA32, 0);
+      SDL_ConvertSurfaceFormat(tmp_bitmap->surface, SDL_PIXELFORMAT_ARGB8888, 0);
 
     tmp_bitmap->surface_masked = tmp_bitmap->surface;