changed using 'external' app data directory on Android version, if possible
[rocksndiamonds.git] / src / init.c
index 149b4ef2709e0ef6d6d26cf17cf798c897f85b88..ea7c8f9a744742b46fdf179a7d40ac3f5b719506 100644 (file)
@@ -21,7 +21,7 @@
 #include "files.h"
 #include "network.h"
 #include "netserv.h"
-#include "cartoons.h"
+#include "anim.h"
 #include "config.h"
 
 #include "conf_e2g.c"  /* include auto-generated data structure definitions */
@@ -84,6 +84,10 @@ static int copy_properties[][5] =
 };
 
 
+/* forward declaration for internal use */
+static int get_graphic_parameter_value(char *, char *, int);
+
+
 void DrawInitAnim()
 {
   struct GraphicInfo *graphic_info_last = graphic_info;
@@ -170,6 +174,18 @@ void InitElementSmallImages()
 
   static int special_graphics[] =
   {
+    IMG_FLAMES_1_LEFT,
+    IMG_FLAMES_2_LEFT,
+    IMG_FLAMES_3_LEFT,
+    IMG_FLAMES_1_RIGHT,
+    IMG_FLAMES_2_RIGHT,
+    IMG_FLAMES_3_RIGHT,
+    IMG_FLAMES_1_UP,
+    IMG_FLAMES_2_UP,
+    IMG_FLAMES_3_UP,
+    IMG_FLAMES_1_DOWN,
+    IMG_FLAMES_2_DOWN,
+    IMG_FLAMES_3_DOWN,
     IMG_EDITOR_ELEMENT_BORDER,
     IMG_EDITOR_ELEMENT_BORDER_INPUT,
     IMG_EDITOR_CASCADE_LIST,
@@ -183,22 +199,23 @@ void InitElementSmallImages()
   print_timestamp_time("getImageListPropertyMapping/Size");
 
   print_timestamp_init("InitElementSmallImagesScaledUp (1)");
-  /* initialize normal images from static configuration */
+  /* initialize normal element images from static configuration */
   for (i = 0; element_to_graphic[i].element > -1; i++)
     InitElementSmallImagesScaledUp(element_to_graphic[i].graphic);
   print_timestamp_done("InitElementSmallImagesScaledUp (1)");
 
-  /* initialize special images from static configuration */
+  /* initialize special element images from static configuration */
   for (i = 0; element_to_special_graphic[i].element > -1; i++)
     InitElementSmallImagesScaledUp(element_to_special_graphic[i].graphic);
   print_timestamp_time("InitElementSmallImagesScaledUp (2)");
 
-  /* initialize images from dynamic configuration (may be elements or other) */
+  /* initialize element images from dynamic configuration */
   for (i = 0; i < num_property_mappings; i++)
-    InitElementSmallImagesScaledUp(property_mapping[i].artwork_index);
+    if (property_mapping[i].base_index < MAX_NUM_ELEMENTS)
+      InitElementSmallImagesScaledUp(property_mapping[i].artwork_index);
   print_timestamp_time("InitElementSmallImagesScaledUp (3)");
 
-  /* initialize special images from above list (non-element images) */
+  /* initialize special non-element images from above list */
   for (i = 0; special_graphics[i] > -1; i++)
     InitElementSmallImagesScaledUp(special_graphics[i]);
   print_timestamp_time("InitElementSmallImagesScaledUp (4)");
@@ -206,13 +223,26 @@ void InitElementSmallImages()
   print_timestamp_done("InitElementSmallImages");
 }
 
+inline static void InitScaledImagesScaledUp(int graphic)
+{
+  struct GraphicInfo *g = &graphic_info[graphic];
+
+  ScaleImage(graphic, g->scale_up_factor);
+}
+
 void InitScaledImages()
 {
+  struct PropertyMapping *property_mapping = getImageListPropertyMapping();
+  int num_property_mappings = getImageListPropertyMappingSize();
   int i;
 
   /* scale normal images from static configuration, if not already scaled */
   for (i = 0; i < NUM_IMAGE_FILES; i++)
-    ScaleImage(i, graphic_info[i].scale_up_factor);
+    InitScaledImagesScaledUp(i);
+
+  /* scale images from dynamic configuration, if not already scaled */
+  for (i = 0; i < num_property_mappings; i++)
+    InitScaledImagesScaledUp(property_mapping[i].artwork_index);
 }
 
 void InitBitmapPointers()
@@ -383,7 +413,7 @@ void InitFontGraphicInfo()
     int special = property_mapping[i].ext3_index;
     int graphic = property_mapping[i].artwork_index;
 
-    if (font_nr < 0)
+    if (font_nr < 0 || font_nr >= NUM_FONTS)
       continue;
 
     if (IS_SPECIAL_GFX_ARG(special))
@@ -555,7 +585,7 @@ void InitGlobalAnimGraphicInfo()
     int j = GLOBAL_ANIM_ID_PART_BASE;
     int k = GFX_SPECIAL_ARG_DEFAULT;
 
-    global_anim_info[i].graphic[j][k] = IMG_GLOBAL_ANIM_1_GFX + i;
+    global_anim_info[i].graphic[j][k] = IMG_GFX_GLOBAL_ANIM_1 + i;
   }
 
   /* initialize global animation definitions from dynamic configuration */
@@ -578,6 +608,19 @@ void InitGlobalAnimGraphicInfo()
       special = GFX_SPECIAL_ARG_DEFAULT;
 
     global_anim_info[anim_nr].graphic[part_nr][special] = graphic;
+
+    /* fix default value for ".draw_masked" (for backward compatibility) */
+    struct GraphicInfo *g = &graphic_info[graphic];
+    struct FileInfo *image = getImageListEntryFromImageID(graphic);
+    char **parameter_raw = image->parameter;
+    int p = GFX_ARG_DRAW_MASKED;
+    int draw_masked = get_graphic_parameter_value(parameter_raw[p],
+                                                 image_config_suffix[p].token,
+                                                 image_config_suffix[p].type);
+
+    /* if ".draw_masked" parameter is undefined, use default value "TRUE" */
+    if (draw_masked == ARG_UNDEFINED_VALUE)
+      g->draw_masked = TRUE;
   }
 
 #if 0
@@ -593,6 +636,104 @@ void InitGlobalAnimGraphicInfo()
 #endif
 }
 
+void InitGlobalAnimSoundInfo()
+{
+  struct PropertyMapping *property_mapping = getSoundListPropertyMapping();
+  int num_property_mappings = getSoundListPropertyMappingSize();
+  int i, j, k;
+
+  /* always start with reliable default values (no global animation sounds) */
+  for (i = 0; i < NUM_GLOBAL_ANIM_TOKENS; i++)
+    for (j = 0; j < NUM_GLOBAL_ANIM_PARTS_ALL; j++)
+      for (k = 0; k < NUM_SPECIAL_GFX_ARGS; k++)
+       global_anim_info[i].sound[j][k] = SND_UNDEFINED;
+
+  /* initialize global animation sound definitions from dynamic configuration */
+  for (i = 0; i < num_property_mappings; i++)
+  {
+    int anim_nr = property_mapping[i].base_index - 2 * MAX_NUM_ELEMENTS;
+    int part_nr = property_mapping[i].ext1_index - ACTION_PART_1;
+    int special = property_mapping[i].ext3_index;
+    int sound   = property_mapping[i].artwork_index;
+
+    // sound uses control definition; map it to position of graphic (artwork)
+    anim_nr -= GLOBAL_ANIM_ID_CONTROL_FIRST;
+
+    if (anim_nr < 0 || anim_nr >= NUM_GLOBAL_ANIM_TOKENS)
+      continue;
+
+    /* set animation part to base part, if not specified */
+    if (!IS_GLOBAL_ANIM_PART(part_nr))
+      part_nr = GLOBAL_ANIM_ID_PART_BASE;
+
+    /* set animation screen to default, if not specified */
+    if (!IS_SPECIAL_GFX_ARG(special))
+      special = GFX_SPECIAL_ARG_DEFAULT;
+
+    global_anim_info[anim_nr].sound[part_nr][special] = sound;
+  }
+
+#if 0
+  printf("::: InitGlobalAnimSoundInfo\n");
+
+  for (i = 0; i < NUM_GLOBAL_ANIMS; i++)
+    for (j = 0; j < NUM_GLOBAL_ANIM_PARTS_ALL; j++)
+      for (k = 0; k < NUM_SPECIAL_GFX_ARGS; k++)
+       if (global_anim_info[i].sound[j][k] != SND_UNDEFINED)
+         printf("::: - anim %d, part %d, mode %d => %d\n",
+                i, j, k, global_anim_info[i].sound[j][k]);
+#endif
+}
+
+void InitGlobalAnimMusicInfo()
+{
+  struct PropertyMapping *property_mapping = getMusicListPropertyMapping();
+  int num_property_mappings = getMusicListPropertyMappingSize();
+  int i, j, k;
+
+  /* always start with reliable default values (no global animation music) */
+  for (i = 0; i < NUM_GLOBAL_ANIM_TOKENS; i++)
+    for (j = 0; j < NUM_GLOBAL_ANIM_PARTS_ALL; j++)
+      for (k = 0; k < NUM_SPECIAL_GFX_ARGS; k++)
+       global_anim_info[i].music[j][k] = MUS_UNDEFINED;
+
+  /* initialize global animation music definitions from dynamic configuration */
+  for (i = 0; i < num_property_mappings; i++)
+  {
+    int anim_nr = property_mapping[i].base_index - NUM_MUSIC_PREFIXES;
+    int part_nr = property_mapping[i].ext1_index - ACTION_PART_1;
+    int special = property_mapping[i].ext2_index;
+    int music   = property_mapping[i].artwork_index;
+
+    // music uses control definition; map it to position of graphic (artwork)
+    anim_nr -= GLOBAL_ANIM_ID_CONTROL_FIRST;
+
+    if (anim_nr < 0 || anim_nr >= NUM_GLOBAL_ANIM_TOKENS)
+      continue;
+
+    /* set animation part to base part, if not specified */
+    if (!IS_GLOBAL_ANIM_PART(part_nr))
+      part_nr = GLOBAL_ANIM_ID_PART_BASE;
+
+    /* set animation screen to default, if not specified */
+    if (!IS_SPECIAL_GFX_ARG(special))
+      special = GFX_SPECIAL_ARG_DEFAULT;
+
+    global_anim_info[anim_nr].music[part_nr][special] = music;
+  }
+
+#if 0
+  printf("::: InitGlobalAnimMusicInfo\n");
+
+  for (i = 0; i < NUM_GLOBAL_ANIMS; i++)
+    for (j = 0; j < NUM_GLOBAL_ANIM_PARTS_ALL; j++)
+      for (k = 0; k < NUM_SPECIAL_GFX_ARGS; k++)
+       if (global_anim_info[i].music[j][k] != MUS_UNDEFINED)
+         printf("::: - anim %d, part %d, mode %d => %d\n",
+                i, j, k, global_anim_info[i].music[j][k]);
+#endif
+}
+
 void InitElementGraphicInfo()
 {
   struct PropertyMapping *property_mapping = getImageListPropertyMapping();
@@ -826,14 +967,12 @@ void InitElementGraphicInfo()
              (move_dir == MV_BIT_UP    && !front_is_left_or_upper) ||
              (move_dir == MV_BIT_RIGHT &&  front_is_left_or_upper) ||
              (move_dir == MV_BIT_DOWN  &&  front_is_left_or_upper)));
-         Bitmap *dummy;
 
          /* swap frontside and backside graphic tile coordinates, if needed */
          if (swap_movement_tiles_always || swap_movement_tiles_autodetected)
          {
            /* get current (wrong) backside tile coordinates */
-           getFixedGraphicSourceExt(graphic, 0, &dummy,
-                                    &src_x_back, &src_y_back, TRUE);
+           getGraphicSourceXY(graphic, 0, &src_x_back, &src_y_back, TRUE);
 
            /* set frontside tile coordinates to backside tile coordinates */
            g->src_x = src_x_back;
@@ -1136,6 +1275,10 @@ static void set_graphic_parameters_ext(int graphic, int *parameter,
   g->anim_delay_random = 0;
   g->post_delay_fixed = 0;
   g->post_delay_random = 0;
+  g->init_event = ANIM_EVENT_DEFAULT;
+  g->anim_event = ANIM_EVENT_DEFAULT;
+  g->draw_masked = FALSE;
+  g->draw_order = 0;
   g->fade_mode = FADE_MODE_DEFAULT;
   g->fade_delay = -1;
   g->post_delay = -1;
@@ -1234,13 +1377,13 @@ static void set_graphic_parameters_ext(int graphic, int *parameter,
 
     if (parameter[GFX_ARG_TILE_SIZE] != ARG_UNDEFINED_VALUE)
     {
-      anim_frames_per_row = src_image_width  / g->tile_size;
-      anim_frames_per_col = src_image_height / g->tile_size;
+      anim_frames_per_row = MAX(1, src_image_width  / g->tile_size);
+      anim_frames_per_col = MAX(1, src_image_height / g->tile_size);
     }
     else
     {
-      anim_frames_per_row = src_image_width  / g->width;
-      anim_frames_per_col = src_image_height / g->height;
+      anim_frames_per_row = MAX(1, src_image_width  / g->width);
+      anim_frames_per_col = MAX(1, src_image_height / g->height);
     }
 
     g->src_image_width  = src_image_width;
@@ -1351,6 +1494,12 @@ static void set_graphic_parameters_ext(int graphic, int *parameter,
   if (parameter[GFX_ARG_POST_DELAY_RANDOM] != ARG_UNDEFINED_VALUE)
     g->post_delay_random = parameter[GFX_ARG_POST_DELAY_RANDOM];
 
+  /* used for global animations */
+  if (parameter[GFX_ARG_INIT_EVENT] != ARG_UNDEFINED_VALUE)
+    g->init_event = parameter[GFX_ARG_INIT_EVENT];
+  if (parameter[GFX_ARG_ANIM_EVENT] != ARG_UNDEFINED_VALUE)
+    g->anim_event = parameter[GFX_ARG_ANIM_EVENT];
+
   /* used for toon animations and global animations */
   g->step_offset  = parameter[GFX_ARG_STEP_OFFSET];
   g->step_xoffset = parameter[GFX_ARG_STEP_XOFFSET];
@@ -1365,11 +1514,18 @@ static void set_graphic_parameters_ext(int graphic, int *parameter,
   g->draw_xoffset = parameter[GFX_ARG_DRAW_XOFFSET];
   g->draw_yoffset = parameter[GFX_ARG_DRAW_YOFFSET];
 
-  /* this is only used for drawing envelope graphics */
-  g->draw_masked = parameter[GFX_ARG_DRAW_MASKED];
+  /* use a different default value for global animations and toons */
+  if ((graphic >= IMG_GFX_GLOBAL_ANIM_1 && graphic <= IMG_GFX_GLOBAL_ANIM_8) ||
+      (graphic >= IMG_TOON_1            && graphic <= IMG_TOON_20))
+    g->draw_masked = TRUE;
+
+  /* this is used for drawing envelopes, global animations and toons */
+  if (parameter[GFX_ARG_DRAW_MASKED] != ARG_UNDEFINED_VALUE)
+    g->draw_masked = parameter[GFX_ARG_DRAW_MASKED];
 
   /* used for toon animations and global animations */
-  g->draw_order = parameter[GFX_ARG_DRAW_ORDER];
+  if (parameter[GFX_ARG_DRAW_ORDER] != ARG_UNDEFINED_VALUE)
+    g->draw_order = parameter[GFX_ARG_DRAW_ORDER];
 
   /* optional graphic for cloning all graphics settings */
   if (parameter[GFX_ARG_CLONE_FROM] != ARG_UNDEFINED_VALUE)
@@ -1586,6 +1742,9 @@ static void InitGraphicInfo()
     src_x = graphic_info[i].src_x;
     src_y = graphic_info[i].src_y;
 
+    if (program.headless)
+      continue;
+
     if (src_x < 0 || src_y < 0 ||
        src_x + width  > src_bitmap_width ||
        src_y + height > src_bitmap_height)
@@ -1595,6 +1754,7 @@ static void InitGraphicInfo()
       Error(ERR_INFO, "- config file: '%s'", getImageConfigFilename());
       Error(ERR_INFO, "- config token: '%s'", getTokenFromImageID(i));
       Error(ERR_INFO, "- image file: '%s'", src_bitmap->source_filename);
+      Error(ERR_INFO, "- frame size: %d, %d", width, height);
       Error(ERR_INFO,
            "error: first animation frame out of bounds (%d, %d) [%d, %d]",
            src_x, src_y, src_bitmap_width, src_bitmap_height);
@@ -1623,10 +1783,10 @@ static void InitGraphicInfo()
       Error(ERR_INFO, "- config file: '%s'", getImageConfigFilename());
       Error(ERR_INFO, "- config token: '%s'", getTokenFromImageID(i));
       Error(ERR_INFO, "- image file: '%s'", src_bitmap->source_filename);
+      Error(ERR_INFO, "- frame size: %d, %d", width, height);
       Error(ERR_INFO,
            "error: last animation frame (%d) out of bounds (%d, %d) [%d, %d]",
            last_frame, src_x, src_y, src_bitmap_width, src_bitmap_height);
-      Error(ERR_INFO, "::: %d, %d", width, height);
       Error(ERR_INFO, "custom graphic rejected for this element/action");
 
       if (i == fallback_graphic)
@@ -1672,7 +1832,8 @@ static void InitGraphicCompatibilityInfo()
        {
          // printf("::: special treatment needed for token '%s'\n", fi->token);
 
-         graphic_info[i].bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
+         graphic_info[i].bitmaps = graphic_info[IMG_GLOBAL_DOOR].bitmaps;
+         graphic_info[i].bitmap  = graphic_info[IMG_GLOBAL_DOOR].bitmap;
        }
       }
     }
@@ -1928,8 +2089,8 @@ static void InitGameModeMusicInfo()
   for (i = 0; i < num_property_mappings; i++)
   {
     int prefix   = property_mapping[i].base_index;
-    int gamemode = property_mapping[i].ext1_index;
-    int level    = property_mapping[i].ext2_index;
+    int gamemode = property_mapping[i].ext2_index;
+    int level    = property_mapping[i].ext3_index;
     int music    = property_mapping[i].artwork_index;
 
     if (prefix < 0 || prefix >= NUM_MUSIC_PREFIXES)
@@ -2058,9 +2219,6 @@ static void ReinitializeGraphics()
 
   InitGadgets();
   print_timestamp_time("InitGadgets");
-  InitToons();
-  InitGlobalAnimations();
-  print_timestamp_time("InitToons");
   InitDoors();
   print_timestamp_time("InitDoors");
 
@@ -2072,6 +2230,7 @@ static void ReinitializeSounds()
   InitSoundInfo();             /* sound properties mapping */
   InitElementSoundInfo();      /* element game sound mapping */
   InitGameModeSoundInfo();     /* game mode sound mapping */
+  InitGlobalAnimSoundInfo();   /* global animation sound settings */
 
   InitPlayLevelSound();                /* internal game sound settings */
 }
@@ -2080,6 +2239,7 @@ static void ReinitializeMusic()
 {
   InitMusicInfo();             /* music properties mapping */
   InitGameModeMusicInfo();     /* game mode music mapping */
+  InitGlobalAnimMusicInfo();   /* global animation music settings */
 }
 
 static int get_special_property_bit(int element, int property_bit_nr)
@@ -4562,6 +4722,16 @@ static void InitGlobal()
     element_info[i].editor_description= element_name_info[i].editor_description;
   }
 
+  for (i = 0; i < NUM_GLOBAL_ANIM_TOKENS + 1; i++)
+  {
+    /* check if global_anim_name_info defined for each entry in "main.h" */
+    if (i < NUM_GLOBAL_ANIM_TOKENS &&
+       global_anim_name_info[i].token_name == NULL)
+      Error(ERR_EXIT, "undefined 'global_anim_name_info' entry for anim %d", i);
+
+    global_anim_info[i].token_name = global_anim_name_info[i].token_name;
+  }
+
   /* create hash from image config list */
   image_config_hash = newSetupFileHash();
   for (i = 0; image_config[i].token != NULL; i++)
@@ -4793,13 +4963,17 @@ void Execute_Command(char *command)
   }
   else if (strPrefix(command, "autotest ") ||
           strPrefix(command, "autoplay ") ||
-          strPrefix(command, "autoffwd "))
+          strPrefix(command, "autoffwd ") ||
+          strPrefix(command, "autowarp "))
   {
     char *str_ptr = getStringCopy(&command[9]);        /* read command parameters */
 
-    global.autoplay_mode = (strPrefix(command, "autotest") ? AUTOPLAY_TEST :
-                           strPrefix(command, "autoplay") ? AUTOPLAY_PLAY :
-                           strPrefix(command, "autoffwd") ? AUTOPLAY_FFWD : 0);
+    global.autoplay_mode =
+      (strPrefix(command, "autotest") ? AUTOPLAY_MODE_TEST :
+       strPrefix(command, "autoplay") ? AUTOPLAY_MODE_PLAY :
+       strPrefix(command, "autoffwd") ? AUTOPLAY_MODE_FFWD :
+       strPrefix(command, "autowarp") ? AUTOPLAY_MODE_WARP :
+       AUTOPLAY_MODE_NONE);
 
     while (*str_ptr != '\0')                   /* continue parsing string */
     {
@@ -4832,6 +5006,9 @@ void Execute_Command(char *command)
       while (*str_ptr != ' ' && *str_ptr != '\t' && *str_ptr != '\0')
        str_ptr++;
     }
+
+    if (global.autoplay_mode == AUTOPLAY_MODE_TEST)
+      program.headless = TRUE;
   }
   else if (strPrefix(command, "convert "))
   {
@@ -4846,6 +5023,8 @@ void Execute_Command(char *command)
       *str_ptr++ = '\0';                       /* terminate leveldir string */
       global.convert_level_nr = atoi(str_ptr); /* get level_nr value */
     }
+
+    program.headless = TRUE;
   }
   else if (strPrefix(command, "create images "))
   {
@@ -4861,94 +5040,6 @@ void Execute_Command(char *command)
 
     exit(0);
   }
-
-#if DEBUG
-#if defined(TARGET_SDL2)
-  else if (strEqual(command, "SDL_ListModes"))
-  {
-    SDL_Init(SDL_INIT_VIDEO);
-
-    int num_displays = SDL_GetNumVideoDisplays();
-
-    // check if there are any displays available
-    if (num_displays < 0)
-    {
-      Print("No displays available: %s\n", SDL_GetError());
-
-      exit(-1);
-    }
-
-    for (i = 0; i < num_displays; i++)
-    {
-      int num_modes = SDL_GetNumDisplayModes(i);
-      int j;
-
-      Print("Available display modes for display %d:\n", i);
-
-      // check if there are any display modes available for this display
-      if (num_modes < 0)
-      {
-       Print("No display modes available for display %d: %s\n",
-             i, SDL_GetError());
-
-       exit(-1);
-      }
-
-      for (j = 0; j < num_modes; j++)
-      {
-       SDL_DisplayMode mode;
-
-       if (SDL_GetDisplayMode(i, j, &mode) < 0)
-       {
-         Print("Cannot get display mode %d for display %d: %s\n",
-               j, i, SDL_GetError());
-
-         exit(-1);
-       }
-
-       Print("- %d x %d\n", mode.w, mode.h);
-      }
-    }
-
-    exit(0);
-  }
-#elif defined(TARGET_SDL)
-  else if (strEqual(command, "SDL_ListModes"))
-  {
-    SDL_Rect **modes;
-    int i;
-
-    SDL_Init(SDL_INIT_VIDEO);
-
-    /* get available fullscreen/hardware modes */
-    modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_HWSURFACE);
-
-    /* check if there are any modes available */
-    if (modes == NULL)
-    {
-      Print("No modes available!\n");
-
-      exit(-1);
-    }
-
-    /* check if our resolution is restricted */
-    if (modes == (SDL_Rect **)-1)
-    {
-      Print("All resolutions available.\n");
-    }
-    else
-    {
-      Print("Available display modes:\n");
-
-      for (i = 0; modes[i]; i++)
-       Print("- %d x %d\n", modes[i]->w, modes[i]->h);
-    }
-
-    exit(0);
-  }
-#endif
-#endif
-
   else
   {
     Error(ERR_EXIT_HELP, "unrecognized command '%s'", command);
@@ -5014,8 +5105,10 @@ static void InitArtworkConfig()
   static char *image_id_prefix[MAX_NUM_ELEMENTS +
                               NUM_FONTS +
                               NUM_GLOBAL_ANIM_TOKENS + 1];
-  static char *sound_id_prefix[2 * MAX_NUM_ELEMENTS + 1];
-  static char *music_id_prefix[NUM_MUSIC_PREFIXES + 1];
+  static char *sound_id_prefix[2 * MAX_NUM_ELEMENTS +
+                              NUM_GLOBAL_ANIM_TOKENS + 1];
+  static char *music_id_prefix[NUM_MUSIC_PREFIXES +
+                              NUM_GLOBAL_ANIM_TOKENS + 1];
   static char *action_id_suffix[NUM_ACTIONS + 1];
   static char *direction_id_suffix[NUM_DIRECTIONS_FULL + 1];
   static char *special_id_suffix[NUM_SPECIAL_GFX_ARGS + 1];
@@ -5084,11 +5177,17 @@ static void InitArtworkConfig()
   for (i = 0; i < MAX_NUM_ELEMENTS; i++)
     sound_id_prefix[MAX_NUM_ELEMENTS + i] =
       get_string_in_brackets(element_info[i].class_name);
-  sound_id_prefix[2 * MAX_NUM_ELEMENTS] = NULL;
+  for (i = 0; i < NUM_GLOBAL_ANIM_TOKENS; i++)
+    sound_id_prefix[2 * MAX_NUM_ELEMENTS + i] =
+      global_anim_info[i].token_name;
+  sound_id_prefix[2 * MAX_NUM_ELEMENTS + NUM_GLOBAL_ANIM_TOKENS] = NULL;
 
   for (i = 0; i < NUM_MUSIC_PREFIXES; i++)
     music_id_prefix[i] = music_prefix_info[i].prefix;
-  music_id_prefix[NUM_MUSIC_PREFIXES] = NULL;
+  for (i = 0; i < NUM_GLOBAL_ANIM_TOKENS; i++)
+    music_id_prefix[NUM_MUSIC_PREFIXES + i] =
+      global_anim_info[i].token_name;
+  music_id_prefix[NUM_MUSIC_PREFIXES + NUM_GLOBAL_ANIM_TOKENS] = NULL;
 
   for (i = 0; i < NUM_ACTIONS; i++)
     action_id_suffix[i] = element_action_info[i].suffix;
@@ -5113,8 +5212,8 @@ static void InitArtworkConfig()
                sound_id_prefix, action_id_suffix, dummy,
                special_id_suffix, ignore_sound_tokens);
   InitMusicList(music_config, NUM_MUSIC_FILES, music_config_suffix,
-               music_id_prefix, special_id_suffix, level_id_suffix,
-               dummy, ignore_music_tokens);
+               music_id_prefix, action_id_suffix, special_id_suffix,
+               level_id_suffix, ignore_music_tokens);
 }
 
 static void InitMixer()
@@ -5133,19 +5232,18 @@ void InitGfxBuffers()
 
   if (WIN_XSIZE != win_xsize_last || WIN_YSIZE != win_ysize_last)
   {
-    /* may contain content for cross-fading -- only re-create if changed */
-    ReCreateBitmap(&bitmap_db_store, WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH);
-    ReCreateBitmap(&bitmap_db_cross, WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH);
+    /* used to temporarily store the backbuffer -- only re-create if changed */
+    ReCreateBitmap(&bitmap_db_store_1, WIN_XSIZE, WIN_YSIZE);
+    ReCreateBitmap(&bitmap_db_store_2, WIN_XSIZE, WIN_YSIZE);
 
     win_xsize_last = WIN_XSIZE;
     win_ysize_last = WIN_YSIZE;
   }
 
-  ReCreateBitmap(&bitmap_db_field, FXSIZE, FYSIZE, DEFAULT_DEPTH);
-  ReCreateBitmap(&bitmap_db_panel, DXSIZE, DYSIZE, DEFAULT_DEPTH);
-  ReCreateBitmap(&bitmap_db_door_1, 3 * DXSIZE, DYSIZE, DEFAULT_DEPTH);
-  ReCreateBitmap(&bitmap_db_door_2, 3 * VXSIZE, VYSIZE, DEFAULT_DEPTH);
-  ReCreateBitmap(&bitmap_db_toons, FULL_SXSIZE, FULL_SYSIZE, DEFAULT_DEPTH);
+  ReCreateBitmap(&bitmap_db_field, FXSIZE, FYSIZE);
+  ReCreateBitmap(&bitmap_db_panel, DXSIZE, DYSIZE);
+  ReCreateBitmap(&bitmap_db_door_1, 3 * DXSIZE, DYSIZE);
+  ReCreateBitmap(&bitmap_db_door_2, 3 * VXSIZE, VYSIZE);
 
   /* initialize screen properties */
   InitGfxFieldInfo(SX, SY, SXSIZE, SYSIZE,
@@ -5322,9 +5420,11 @@ void InitGfx()
   InitMenuDesignSettings_Static();
 
   InitGfxDrawBusyAnimFunction(DrawInitAnim);
-  InitGfxDrawGlobalAnimFunction(DrawGlobalAnim);
+  InitGfxDrawGlobalAnimFunction(DrawGlobalAnimations);
   InitGfxDrawGlobalBorderFunction(DrawMaskedBorderToTarget);
 
+  gfx.fade_border_source_status = global.border_status;
+  gfx.fade_border_target_status = global.border_status;
   gfx.masked_border_bitmap_ptr = backbuffer;
 
   /* use copy of busy animation to prevent change while reloading artwork */
@@ -5334,7 +5434,7 @@ void InitGfx()
 void InitGfxBackground()
 {
   fieldbuffer = bitmap_db_field;
-  SetDrawtoField(DRAW_BACKBUFFER);
+  SetDrawtoField(DRAW_TO_BACKBUFFER);
 
   ClearRectangle(backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE);
 
@@ -5348,7 +5448,7 @@ static void InitLevelInfo()
   LoadLevelSetup_SeriesInfo();                 /* last played level info */
 
   if (global.autoplay_leveldir &&
-      global.autoplay_mode != AUTOPLAY_TEST)
+      global.autoplay_mode != AUTOPLAY_MODE_TEST)
   {
     leveldir_current = getTreeInfoFromIdentifier(leveldir_first,
                                                  global.autoplay_leveldir);
@@ -5419,6 +5519,9 @@ static void InitImages()
   ReinitializeGraphics();
   print_timestamp_time("ReinitializeGraphics");
 
+  LoadMenuDesignSettings_AfterGraphics();
+  print_timestamp_time("LoadMenuDesignSettings_AfterGraphics");
+
   UPDATE_BUSY_STATE();
 
   print_timestamp_done("InitImages");
@@ -5462,6 +5565,14 @@ static void InitMusic(char *identifier)
   print_timestamp_done("InitMusic");
 }
 
+static void InitArtworkDone()
+{
+  if (program.headless)
+    return;
+
+  InitGlobalAnimations();
+}
+
 void InitNetworkServer()
 {
 #if defined(NETWORK_AVALIABLE)
@@ -5737,6 +5848,8 @@ void ReloadCustomArtwork(int force_reload)
     print_timestamp_time("InitMusic");
   }
 
+  InitArtworkDone();
+
   SetGameStatus(last_game_status);     /* restore current game status */
 
   init_last = init;                    /* switch to new busy animation */
@@ -5844,6 +5957,8 @@ void OpenAll()
 
   print_timestamp_time("[init setup/config stuff (1)]");
 
+  InitScoresInfo();
+
   if (options.execute_command)
     Execute_Command(options.execute_command);
 
@@ -5879,7 +5994,7 @@ void OpenAll()
   InitVideoDisplay();
   InitVideoBuffer(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH, setup.fullscreen);
 
-  InitEventFilter(FilterEvents);
+  InitOverlayInfo();
 
   print_timestamp_time("[init video stuff]");
 
@@ -5911,6 +6026,8 @@ void OpenAll()
   InitMusic(NULL);             /* needs to know current level directory */
   print_timestamp_time("InitMusic");
 
+  InitArtworkDone();
+
   InitGfxBackground();
 
   em_open_all();
@@ -5957,10 +6074,10 @@ void OpenAll()
   Error(ERR_DEBUG, "::: SDL_AndroidGetExternalStoragePath() == '%s'",
        SDL_AndroidGetExternalStoragePath());
   Error(ERR_DEBUG, "::: SDL_AndroidGetExternalStorageState() == '%s'",
-       (SDL_AndroidGetExternalStorageState() ==
-        SDL_ANDROID_EXTERNAL_STORAGE_READ ? "read" :
-        SDL_AndroidGetExternalStorageState() ==
-        SDL_ANDROID_EXTERNAL_STORAGE_WRITE ? "write" : "not available"));
+       (SDL_AndroidGetExternalStorageState() &
+        SDL_ANDROID_EXTERNAL_STORAGE_WRITE ? "writable" :
+        SDL_AndroidGetExternalStorageState() &
+        SDL_ANDROID_EXTERNAL_STORAGE_READ ? "readable" : "not available"));
 #endif
 #endif
 }