changed global animations (esp. toons) to be controlled by game mode
[rocksndiamonds.git] / src / init.c
index 4808f114f691548193de8e85fb10d747bf0b30ad..e7cbd04a43af6d10c3515e66e5300a32469dd393 100644 (file)
@@ -102,6 +102,11 @@ void DrawInitAnim()
   if (!DelayReached(&action_delay, action_delay_value))
     return;
 
+  if (init_last.busy.x == -1)
+    init_last.busy.x = WIN_XSIZE / 2;
+  if (init_last.busy.y == -1)
+    init_last.busy.y = WIN_YSIZE / 2;
+
   x = ALIGNED_TEXT_XPOS(&init_last.busy);
   y = ALIGNED_TEXT_YPOS(&init_last.busy);
 
@@ -151,7 +156,7 @@ void InitGadgets()
   gadgets_initialized = TRUE;
 }
 
-inline void InitElementSmallImagesScaledUp(int graphic)
+inline static void InitElementSmallImagesScaledUp(int graphic)
 {
   struct GraphicInfo *g = &graphic_info[graphic];
 
@@ -221,6 +226,35 @@ void InitBitmapPointers()
       graphic_info[i].bitmap = graphic_info[i].bitmaps[IMG_BITMAP_STANDARD];
 }
 
+void InitImageTextures()
+{
+  int i, j, k;
+
+  FreeAllImageTextures();
+
+  for (i = IMG_GLOBAL_BORDER_FIRST; i <= IMG_GLOBAL_BORDER_LAST; i++)
+    CreateImageTextures(i);
+
+  for (i = 0; i < MAX_NUM_TOONS; i++)
+    CreateImageTextures(IMG_TOON_1 + i);
+
+  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++)
+      {
+       int graphic = global_anim_info[i].graphic[j][k];
+
+       if (graphic == IMG_UNDEFINED)
+         continue;
+
+       CreateImageTextures(graphic);
+      }
+    }
+  }
+}
+
 #if 1
 /* !!! FIX THIS (CHANGE TO USING NORMAL ELEMENT GRAPHIC DEFINITIONS) !!! */
 void SetBitmaps_EM(Bitmap **em_bitmap)
@@ -500,6 +534,65 @@ void InitFontGraphicInfo()
               getFontBitmapID, getFontFromToken);
 }
 
+void InitGlobalAnimGraphicInfo()
+{
+  struct PropertyMapping *property_mapping = getImageListPropertyMapping();
+  int num_property_mappings = getImageListPropertyMappingSize();
+  int i, j, k;
+
+  if (graphic_info == NULL)            /* still at startup phase */
+    return;
+
+  /* always start with reliable default values (no global animations) */
+  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].graphic[j][k] = IMG_UNDEFINED;
+
+  /* initialize global animation definitions from static configuration */
+  for (i = 0; i < NUM_GLOBAL_ANIM_TOKENS; i++)
+  {
+    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;
+  }
+
+  /* initialize global animation definitions from dynamic configuration */
+  for (i = 0; i < num_property_mappings; i++)
+  {
+    int anim_nr = property_mapping[i].base_index - MAX_NUM_ELEMENTS - NUM_FONTS;
+    int part_nr = property_mapping[i].ext1_index - ACTION_PART_1;
+    int special = property_mapping[i].ext3_index;
+    int graphic = property_mapping[i].artwork_index;
+
+    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].graphic[part_nr][special] = graphic;
+  }
+
+#if 0
+  printf("::: InitGlobalAnimGraphicInfo\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].graphic[j][k] != IMG_UNDEFINED &&
+           graphic_info[global_anim_info[i].graphic[j][k]].bitmap != NULL)
+         printf("::: - anim %d, part %d, mode %d => %d\n",
+                i, j, k, global_anim_info[i].graphic[j][k]);
+#endif
+}
+
 void InitElementGraphicInfo()
 {
   struct PropertyMapping *property_mapping = getImageListPropertyMapping();
@@ -1037,6 +1130,8 @@ static void set_graphic_parameters_ext(int graphic, int *parameter,
   g->scale_up_factor = 1;              /* default: no scaling up */
   g->tile_size = TILESIZE;             /* default: standard tile size */
   g->clone_from = -1;                  /* do not use clone graphic */
+  g->init_delay_fixed = 0;
+  g->init_delay_random = 0;
   g->anim_delay_fixed = 0;
   g->anim_delay_random = 0;
   g->post_delay_fixed = 0;
@@ -1071,11 +1166,9 @@ static void set_graphic_parameters_ext(int graphic, int *parameter,
       g->tile_size = TILESIZE;         /* standard tile size */
 #endif
 
-#if 0
-    // CHECK: when setting tile size, should this set width and height?
+    // when setting tile size, also set width and height accordingly
     g->width  = g->tile_size;
     g->height = g->tile_size;
-#endif
   }
 
   if (g->use_image_size)
@@ -1244,7 +1337,11 @@ static void set_graphic_parameters_ext(int graphic, int *parameter,
   if (parameter[GFX_ARG_BORDER_SIZE] != ARG_UNDEFINED_VALUE)
     g->border_size = parameter[GFX_ARG_BORDER_SIZE];
 
-  /* this is only used for player "boring" and "sleeping" actions */
+  /* used for global animations and player "boring" and "sleeping" actions */
+  if (parameter[GFX_ARG_INIT_DELAY_FIXED] != ARG_UNDEFINED_VALUE)
+    g->init_delay_fixed = parameter[GFX_ARG_INIT_DELAY_FIXED];
+  if (parameter[GFX_ARG_INIT_DELAY_RANDOM] != ARG_UNDEFINED_VALUE)
+    g->init_delay_random = parameter[GFX_ARG_INIT_DELAY_RANDOM];
   if (parameter[GFX_ARG_ANIM_DELAY_FIXED] != ARG_UNDEFINED_VALUE)
     g->anim_delay_fixed = parameter[GFX_ARG_ANIM_DELAY_FIXED];
   if (parameter[GFX_ARG_ANIM_DELAY_RANDOM] != ARG_UNDEFINED_VALUE)
@@ -1254,9 +1351,15 @@ 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];
 
-  /* this is only used for toon animations */
-  g->step_offset = parameter[GFX_ARG_STEP_OFFSET];
-  g->step_delay  = parameter[GFX_ARG_STEP_DELAY];
+  /* used for toon animations and global animations */
+  g->step_offset  = parameter[GFX_ARG_STEP_OFFSET];
+  g->step_xoffset = parameter[GFX_ARG_STEP_XOFFSET];
+  g->step_yoffset = parameter[GFX_ARG_STEP_YOFFSET];
+  g->step_delay   = parameter[GFX_ARG_STEP_DELAY];
+  g->direction    = parameter[GFX_ARG_DIRECTION];
+  g->position     = parameter[GFX_ARG_POSITION];
+  g->x            = parameter[GFX_ARG_X];      // (may be uninitialized,
+  g->y            = parameter[GFX_ARG_Y];      // unlike src_x and src_y)
 
   /* this is only used for drawing font characters */
   g->draw_xoffset = parameter[GFX_ARG_DRAW_XOFFSET];
@@ -1265,6 +1368,9 @@ static void set_graphic_parameters_ext(int graphic, int *parameter,
   /* this is only used for drawing envelope graphics */
   g->draw_masked = parameter[GFX_ARG_DRAW_MASKED];
 
+  /* used for toon animations and global animations */
+  g->draw_order = parameter[GFX_ARG_DRAW_ORDER];
+
   /* optional graphic for cloning all graphics settings */
   if (parameter[GFX_ARG_CLONE_FROM] != ARG_UNDEFINED_VALUE)
     g->clone_from = parameter[GFX_ARG_CLONE_FROM];
@@ -1369,6 +1475,10 @@ static void InitGraphicInfo()
   static int full_size_graphics[] =
   {
     IMG_GLOBAL_BORDER,
+    IMG_GLOBAL_BORDER_MAIN,
+    IMG_GLOBAL_BORDER_SCORES,
+    IMG_GLOBAL_BORDER_EDITOR,
+    IMG_GLOBAL_BORDER_PLAYING,
     IMG_GLOBAL_DOOR,
 
     IMG_BACKGROUND_ENVELOPE_1,
@@ -1929,6 +2039,11 @@ static void ReinitializeGraphics()
   print_timestamp_time("InitBitmapPointers");
   InitFontGraphicInfo();               /* initialize text drawing functions */
   print_timestamp_time("InitFontGraphicInfo");
+  InitGlobalAnimGraphicInfo();         /* initialize global animation config */
+  print_timestamp_time("InitGlobalAnimGraphicInfo");
+
+  InitImageTextures();                 /* create textures for certain images */
+  print_timestamp_time("InitImageTextures");
 
   InitGraphicInfo_EM();                        /* graphic mapping for EM engine */
   print_timestamp_time("InitGraphicInfo_EM");
@@ -1944,6 +2059,7 @@ static void ReinitializeGraphics()
   InitGadgets();
   print_timestamp_time("InitGadgets");
   InitToons();
+  InitGlobalAnimations();
   print_timestamp_time("InitToons");
   InitDoors();
   print_timestamp_time("InitDoors");
@@ -4549,8 +4665,6 @@ static void InitGlobal()
   global.create_images_dir = NULL;
 
   global.frames_per_second = 0;
-  global.fps_slowdown = FALSE;
-  global.fps_slowdown_factor = 1;
 
   global.border_status = GAME_MODE_MAIN;
 
@@ -4676,10 +4790,16 @@ void Execute_Command(char *command)
 
     exit(0);
   }
-  else if (strPrefix(command, "autoplay "))
+  else if (strPrefix(command, "autotest ") ||
+          strPrefix(command, "autoplay ") ||
+          strPrefix(command, "autoffwd "))
   {
     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);
+
     while (*str_ptr != '\0')                   /* continue parsing string */
     {
       /* cut leading whitespace from string, replace it by string terminator */
@@ -4890,7 +5010,9 @@ static char *get_level_id_suffix(int id_nr)
 
 static void InitArtworkConfig()
 {
-  static char *image_id_prefix[MAX_NUM_ELEMENTS + NUM_FONTS + 1];
+  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 *action_id_suffix[NUM_ACTIONS + 1];
@@ -4951,7 +5073,10 @@ static void InitArtworkConfig()
     image_id_prefix[i] = element_info[i].token_name;
   for (i = 0; i < NUM_FONTS; i++)
     image_id_prefix[MAX_NUM_ELEMENTS + i] = font_info[i].token_name;
-  image_id_prefix[MAX_NUM_ELEMENTS + NUM_FONTS] = NULL;
+  for (i = 0; i < NUM_GLOBAL_ANIM_TOKENS; i++)
+    image_id_prefix[MAX_NUM_ELEMENTS + NUM_FONTS + i] =
+      global_anim_info[i].token_name;
+  image_id_prefix[MAX_NUM_ELEMENTS + NUM_FONTS + NUM_GLOBAL_ANIM_TOKENS] = NULL;
 
   for (i = 0; i < MAX_NUM_ELEMENTS; i++)
     sound_id_prefix[i] = element_info[i].token_name;
@@ -5000,9 +5125,21 @@ static void InitMixer()
 
 void InitGfxBuffers()
 {
+  static int win_xsize_last = -1;
+  static int win_ysize_last = -1;
+
   /* create additional image buffers for double-buffering and cross-fading */
-  ReCreateBitmap(&bitmap_db_store, WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH);
-  ReCreateBitmap(&bitmap_db_cross, WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH);
+
+  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);
+
+    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);
@@ -5182,33 +5319,22 @@ void InitGfx()
   init.busy.height = anim_initial.height;
 
   InitMenuDesignSettings_Static();
+
   InitGfxDrawBusyAnimFunction(DrawInitAnim);
+  InitGfxDrawGlobalAnimFunction(DrawGlobalAnim);
+  InitGfxDrawGlobalBorderFunction(DrawMaskedBorderToScreen);
 
   /* use copy of busy animation to prevent change while reloading artwork */
   init_last = init;
 }
 
-void RedrawGlobalBorder()
-{
-  BlitBitmap(graphic_info[IMG_GLOBAL_BORDER].bitmap, backbuffer,
-            0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
-
-  redraw_mask = REDRAW_ALL;
-}
-
 void InitGfxBackground()
 {
-  int x, y;
-
   fieldbuffer = bitmap_db_field;
   SetDrawtoField(DRAW_BACKBUFFER);
 
   ClearRectangle(backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE);
 
-  for (x = 0; x < MAX_BUF_XSIZE; x++)
-    for (y = 0; y < MAX_BUF_YSIZE; y++)
-      redraw[x][y] = 0;
-  redraw_tiles = 0;
   redraw_mask = REDRAW_ALL;
 }
 
@@ -5217,6 +5343,15 @@ static void InitLevelInfo()
   LoadLevelInfo();                             /* global level info */
   LoadLevelSetup_LastSeries();                 /* last played series info */
   LoadLevelSetup_SeriesInfo();                 /* last played level info */
+
+  if (global.autoplay_leveldir &&
+      global.autoplay_mode != AUTOPLAY_TEST)
+  {
+    leveldir_current = getTreeInfoFromIdentifier(leveldir_first,
+                                                 global.autoplay_leveldir);
+    if (leveldir_current == NULL)
+      leveldir_current = getFirstValidTreeInfoEntry(leveldir_first);
+  }
 }
 
 static void InitLevelArtworkInfo()