added sound loop debug output (deactivated)
[rocksndiamonds.git] / src / init.c
index dbba5f1250154305c8c1412d8ab0255326a72907..6605186c42351afa7c5ae78eb7a467834390361b 100644 (file)
@@ -37,6 +37,7 @@
 #define CONFIG_TOKEN_GLOBAL_BUSY_INITIAL       "global.busy_initial"
 #define CONFIG_TOKEN_GLOBAL_BUSY               "global.busy"
 #define CONFIG_TOKEN_GLOBAL_BUSY_PLAYFIELD     "global.busy_playfield"
+#define CONFIG_TOKEN_BACKGROUND                        "background"
 #define CONFIG_TOKEN_BACKGROUND_LOADING_INITIAL        "background.LOADING_INITIAL"
 #define CONFIG_TOKEN_BACKGROUND_LOADING                "background.LOADING"
 
 
 #define NUM_INITIAL_IMAGES_BUSY                        3
 
-#define INITIAL_IMG_BACKGROUND_LOADING_INITIAL 3
-#define INITIAL_IMG_BACKGROUND_LOADING         4
+#define INITIAL_IMG_BACKGROUND                 3
+#define INITIAL_IMG_BACKGROUND_LOADING_INITIAL 4
+#define INITIAL_IMG_BACKGROUND_LOADING         5
 
-#define NUM_INITIAL_IMAGES                     5
+#define NUM_INITIAL_IMAGES                     6
 
 
 static struct FontBitmapInfo font_initial[NUM_INITIAL_FONTS];
@@ -108,6 +110,16 @@ static int copy_properties[][5] =
 static int get_graphic_parameter_value(char *, char *, int);
 
 
+static int getLoadingBackgroundImage(int graphic)
+{
+  return getImageFromGraphicOrDefault(graphic, INITIAL_IMG_BACKGROUND);
+}
+
+static void SetLoadingWindowBackgroundImage(int graphic)
+{
+  SetBackgroundImage(getLoadingBackgroundImage(graphic), REDRAW_ALL);
+}
+
 static void SetLoadingBackgroundImage(void)
 {
   struct GraphicInfo *graphic_info_last = graphic_info;
@@ -120,7 +132,7 @@ static void SetLoadingBackgroundImage(void)
   SetDrawDeactivationMask(REDRAW_NONE);
   SetDrawBackgroundMask(REDRAW_ALL);
 
-  SetWindowBackgroundImage(background_image);
+  SetLoadingWindowBackgroundImage(background_image);
 
   graphic_info = graphic_info_last;
 }
@@ -138,11 +150,12 @@ static void DrawInitAnim(boolean only_when_loading)
                              game_status == GAME_MODE_LOADING ?
                              &init_last.busy :
                              &init_last.busy_playfield);
-  static unsigned int action_delay = 0;
-  unsigned int action_delay_value = GameFrameDelay;
+  static DelayCounter action_delay = { 0 };
   int sync_frame = FrameCounter;
   int x, y;
 
+  action_delay.value = GameFrameDelay;
+
   // prevent OS (Windows) from complaining about program not responding
   CheckQuitEvent();
 
@@ -152,7 +165,7 @@ static void DrawInitAnim(boolean only_when_loading)
   if (image_initial[graphic].bitmap == NULL || window == NULL)
     return;
 
-  if (!DelayReached(&action_delay, action_delay_value))
+  if (!DelayReached(&action_delay))
     return;
 
   if (busy->x == -1)
@@ -368,7 +381,7 @@ void InitImageTextures(void)
     CreateImageTextures(texture_graphics[i]);
 }
 
-static int getFontBitmapID(int font_nr)
+static int getFontSpecialSuffix(void)
 {
   int special = -1;
 
@@ -381,6 +394,13 @@ static int getFontBitmapID(int font_nr)
   else if (game_status == GAME_MODE_PSEUDO_TYPENAMES)
     special = GFX_SPECIAL_ARG_NAMES;
 
+  return special;
+}
+
+static int getFontBitmapID(int font_nr)
+{
+  int special = getFontSpecialSuffix();
+
   if (special != -1)
     return font_info[font_nr].special_bitmap_id[special];
   else
@@ -398,6 +418,22 @@ static int getFontFromToken(char *token)
   return FONT_INITIAL_1;
 }
 
+static char *getTokenFromFont(int font_nr)
+{
+  static char *token = NULL;
+  int special = getFontSpecialSuffix();
+
+  checked_free(token);
+
+  if (special != -1)
+    token = getStringCat2(font_info[font_nr].token_name,
+                          special_suffix_info[special].suffix);
+  else
+    token = getStringCopy(font_info[font_nr].token_name);
+
+  return token;
+}
+
 static void InitFontGraphicInfo(void)
 {
   static struct FontBitmapInfo *font_bitmap_info = NULL;
@@ -409,7 +445,7 @@ static void InitFontGraphicInfo(void)
   if (graphic_info == NULL)            // still at startup phase
   {
     InitFontInfo(font_initial, NUM_INITIAL_FONTS,
-                getFontBitmapID, getFontFromToken);
+                getFontBitmapID, getFontFromToken, getTokenFromFont);
 
     return;
   }
@@ -634,7 +670,7 @@ static void InitFontGraphicInfo(void)
   }
 
   InitFontInfo(font_bitmap_info, num_font_bitmaps,
-              getFontBitmapID, getFontFromToken);
+              getFontBitmapID, getFontFromToken, getTokenFromFont);
 }
 
 static void InitGlobalAnimGraphicInfo(void)
@@ -1548,6 +1584,9 @@ static void set_graphic_parameters_ext(int graphic, int *parameter,
   // animation synchronized with global frame counter, not move position
   g->anim_global_sync = parameter[GFX_ARG_GLOBAL_SYNC];
 
+  // animation synchronized with global anim frame counter, not move position
+  g->anim_global_anim_sync = parameter[GFX_ARG_GLOBAL_ANIM_SYNC];
+
   // optional element for cloning crumble graphics
   if (parameter[GFX_ARG_CRUMBLED_LIKE] != ARG_UNDEFINED_VALUE)
     g->crumbled_like = parameter[GFX_ARG_CRUMBLED_LIKE];
@@ -1652,6 +1691,12 @@ static void set_graphic_parameters_ext(int graphic, int *parameter,
   g->active_yoffset = parameter[GFX_ARG_ACTIVE_YOFFSET];
   g->pressed_xoffset = parameter[GFX_ARG_PRESSED_XOFFSET];
   g->pressed_yoffset = parameter[GFX_ARG_PRESSED_YOFFSET];
+
+  // this is only used for drawing stacked global animations
+  g->stacked_xfactor = parameter[GFX_ARG_STACKED_XFACTOR];
+  g->stacked_yfactor = parameter[GFX_ARG_STACKED_YFACTOR];
+  g->stacked_xoffset = parameter[GFX_ARG_STACKED_XOFFSET];
+  g->stacked_yoffset = parameter[GFX_ARG_STACKED_YOFFSET];
 }
 
 static void set_graphic_parameters(int graphic)
@@ -1930,6 +1975,16 @@ static void InitGraphicCompatibilityInfo(void)
        // process all images which default to same image as "global.door"
        if (strEqual(fi->default_filename, fi_global_door->default_filename))
        {
+         // skip all images that are cloned from images that default to same
+         // image as "global.door", but that are redefined to something else
+         if (graphic_info[i].clone_from != -1)
+         {
+           int cloned_graphic = graphic_info[i].clone_from;
+
+           if (getImageListEntryFromImageID(cloned_graphic)->redefined)
+             continue;
+         }
+
 #if 0
          Debug("init:InitGraphicCompatibilityInfo",
                "special treatment needed for token '%s'", fi->token);
@@ -1942,6 +1997,70 @@ static void InitGraphicCompatibilityInfo(void)
     }
   }
 
+  // special compatibility handling for "Snake Bite" graphics set
+  if (strPrefix(leveldir_current->identifier, "snake_bite"))
+  {
+    Bitmap *bitmap = graphic_info[IMG_BACKGROUND_SCORES].bitmap;
+
+    BlitBitmap(bitmap, bitmap, 18,  66, 32, 480, 50,  66);
+    BlitBitmap(bitmap, bitmap, 466, 66, 32, 480, 434, 66);
+
+    ClearRectangle(bitmap, 2,   66, 32, 480);
+    ClearRectangle(bitmap, 514, 66, 32, 480);
+  }
+
+  // special compatibility handling for "Jue" graphics sets (2007 and 2019)
+  boolean supports_score_info = (menu.draw_xoffset[GAME_MODE_SCOREINFO] != 0);
+  if (strPrefix(artwork.gfx_current_identifier, "jue") && !supports_score_info)
+  {
+    int font_title[] =
+    {
+      FONT_TITLE_1,
+      FONT_TITLE_2,
+
+      -1
+    };
+    int font_text[] =
+    {
+      FONT_TEXT_1,
+      FONT_TEXT_2,
+      FONT_TEXT_3,
+      FONT_TEXT_4,
+
+      -1
+    };
+    int mode_old = GAME_MODE_SCORES;
+    int mode_new = GAME_MODE_SCOREINFO;
+    int i, j;
+
+    // adjust title screens on score info page
+    for (i = 0; font_title[i] != -1; i++)
+    {
+      struct FontInfo *fi = &font_info[font_title[i]];
+
+      fi->special_graphic[mode_new]   = fi->special_graphic[mode_old];
+      fi->special_bitmap_id[mode_new] = fi->special_bitmap_id[mode_old];
+    }
+
+    // adjust vertical text and button positions on scores page
+    for (i = 0; font_text[i] != -1; i++)
+    {
+      for (j = 0; j < 2; j++)
+      {
+       boolean jue0 = strEqual(artwork.gfx_current_identifier, "jue0");
+       int font_nr = (j == 0 ? font_text[i] : FONT_ACTIVE(font_text[i]));
+       int font_bitmap_id = font_info[font_nr].special_bitmap_id[mode_old];
+       int font_yoffset = (jue0 ? 10 : 5);
+
+       gfx.font_bitmap_info[font_bitmap_id].draw_yoffset = font_yoffset;
+      }
+    }
+
+    // adjust page offsets on score info page
+    menu.draw_xoffset[mode_new] = menu.draw_xoffset[mode_old];
+    menu.draw_yoffset[mode_new] = menu.draw_yoffset[mode_old];
+  }
+
   InitGraphicCompatibilityInfo_Doors();
 }
 
@@ -2160,6 +2279,11 @@ static void InitSoundInfo(void)
     }
 
     set_sound_parameters(i, sound->parameter);
+
+#if 0
+    Debug("init:InitSoundInfo", "loop mode: %d ['%s']",
+         sound_info[i].loop, sound->token);
+#endif
   }
 
   free(sound_effect_properties);
@@ -4150,6 +4274,7 @@ void InitElementPropertiesStatic(void)
     EL_BD_AMOEBA,
     EL_EMC_MAGIC_BALL,
     EL_EMC_ANDROID,
+    EL_MM_GRAY_BALL,
 
     -1
   };
@@ -5351,6 +5476,12 @@ static void InitSetup(void)
   if (setup.options.verbose)
     options.verbose = TRUE;
 
+  if (setup.options.debug)
+    options.debug = TRUE;
+
+  if (!strEqual(setup.options.debug_mode, ARG_UNDEFINED_STRING))
+    options.debug_mode = getStringCopy(setup.options.debug_mode);
+
   if (setup.debug.show_frames_per_second)
     global.show_frames_per_second = TRUE;
 }
@@ -5564,7 +5695,6 @@ void InitGfxBuffers(void)
   }
 
   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);
 
@@ -5596,6 +5726,7 @@ static void InitGfx(void)
     CONFIG_TOKEN_GLOBAL_BUSY_INITIAL,
     CONFIG_TOKEN_GLOBAL_BUSY,
     CONFIG_TOKEN_GLOBAL_BUSY_PLAYFIELD,
+    CONFIG_TOKEN_BACKGROUND,
     CONFIG_TOKEN_BACKGROUND_LOADING_INITIAL,
     CONFIG_TOKEN_BACKGROUND_LOADING
   };
@@ -5891,17 +6022,14 @@ static void InitImages(void)
   print_timestamp_done("InitImages");
 }
 
-static void InitSound(char *identifier)
+static void InitSound(void)
 {
   print_timestamp_init("InitSound");
 
-  if (identifier == NULL)
-    identifier = artwork.snd_current->identifier;
-
   // set artwork path to send it to the sound server process
   setLevelArtworkDir(artwork.snd_first);
 
-  InitReloadCustomSounds(identifier);
+  InitReloadCustomSounds();
   print_timestamp_time("InitReloadCustomSounds");
 
   ReinitializeSounds();
@@ -5910,17 +6038,14 @@ static void InitSound(char *identifier)
   print_timestamp_done("InitSound");
 }
 
-static void InitMusic(char *identifier)
+static void InitMusic(void)
 {
   print_timestamp_init("InitMusic");
 
-  if (identifier == NULL)
-    identifier = artwork.mus_current->identifier;
-
   // set artwork path to send it to the sound server process
   setLevelArtworkDir(artwork.mus_first);
 
-  InitReloadCustomMusic(identifier);
+  InitReloadCustomMusic();
   print_timestamp_time("InitReloadCustomMusic");
 
   ReinitializeMusic();
@@ -6109,7 +6234,7 @@ static void InitOverrideArtwork(void)
 #endif
 }
 
-static char *getNewArtworkIdentifier(int type)
+static char *setNewArtworkIdentifier(int type)
 {
   static char *last_leveldir_identifier[3] = { NULL, NULL, NULL };
   static char *last_artwork_identifier[3] = { NULL, NULL, NULL };
@@ -6174,6 +6299,7 @@ static char *getNewArtworkIdentifier(int type)
   // (we cannot compare string pointers here, so copy string content itself)
   setString(&last_artwork_identifier[type], artwork_current_identifier);
 
+  // ---------- set new artwork identifier ----------
   *(ARTWORK_CURRENT_IDENTIFIER_PTR(artwork, type)) = artwork_current_identifier;
 
   // ---------- do not reload directly after starting -------------------------
@@ -6185,6 +6311,13 @@ static char *getNewArtworkIdentifier(int type)
   return artwork_new_identifier;
 }
 
+static void InitArtworkIdentifier(void)
+{
+  setNewArtworkIdentifier(ARTWORK_TYPE_GRAPHICS);
+  setNewArtworkIdentifier(ARTWORK_TYPE_SOUNDS);
+  setNewArtworkIdentifier(ARTWORK_TYPE_MUSIC);
+}
+
 void ReloadCustomArtwork(int force_reload)
 {
   int last_game_status = game_status;  // save current game status
@@ -6201,9 +6334,9 @@ void ReloadCustomArtwork(int force_reload)
   AdjustGraphicsForEMC();
   AdjustSoundsForEMC();
 
-  gfx_new_identifier = getNewArtworkIdentifier(ARTWORK_TYPE_GRAPHICS);
-  snd_new_identifier = getNewArtworkIdentifier(ARTWORK_TYPE_SOUNDS);
-  mus_new_identifier = getNewArtworkIdentifier(ARTWORK_TYPE_MUSIC);
+  gfx_new_identifier = setNewArtworkIdentifier(ARTWORK_TYPE_GRAPHICS);
+  snd_new_identifier = setNewArtworkIdentifier(ARTWORK_TYPE_SOUNDS);
+  mus_new_identifier = setNewArtworkIdentifier(ARTWORK_TYPE_MUSIC);
 
   reload_needed = (gfx_new_identifier != NULL || force_reload_gfx ||
                   snd_new_identifier != NULL || force_reload_snd ||
@@ -6227,6 +6360,8 @@ void ReloadCustomArtwork(int force_reload)
 
   UPDATE_BUSY_STATE();
 
+  InitMissingFileHash();
+
   if (gfx_new_identifier != NULL || force_reload_gfx)
   {
 #if 0
@@ -6244,13 +6379,13 @@ void ReloadCustomArtwork(int force_reload)
 
   if (snd_new_identifier != NULL || force_reload_snd)
   {
-    InitSound(snd_new_identifier);
+    InitSound();
     print_timestamp_time("InitSound");
   }
 
   if (mus_new_identifier != NULL || force_reload_mus)
   {
-    InitMusic(mus_new_identifier);
+    InitMusic();
     print_timestamp_time("InitMusic");
   }
 
@@ -6325,7 +6460,7 @@ void DisplayExitMessage(char *format, va_list ap)
   sy += 3 * font_height;
 
   num_lines_printed =
-    DrawTextBuffer(sx, sy, program.log_filename[LOG_ERR_ID], font_2,
+    DrawTextBuffer(sx, sy, program.log_filename, font_2,
                   line_length, line_length, max_lines,
                   0, BLIT_ON_BACKGROUND, TRUE, TRUE, FALSE);
 
@@ -6363,6 +6498,8 @@ void OpenAll(void)
   InitSimpleRandom(NEW_RANDOMIZE);
   InitBetterRandom(NEW_RANDOMIZE);
 
+  InitMissingFileHash();
+
   print_timestamp_time("[init global stuff]");
 
   InitSetup();
@@ -6430,13 +6567,16 @@ void OpenAll(void)
   InitOverrideArtwork();       // needs to know current level directory
   print_timestamp_time("InitOverrideArtwork");
 
+  InitArtworkIdentifier();     // needs to know current level directory
+  print_timestamp_time("InitArtworkIdentifier");
+
   InitImages();                        // needs to know current level directory
   print_timestamp_time("InitImages");
 
-  InitSound(NULL);             // needs to know current level directory
+  InitSound();                 // needs to know current level directory
   print_timestamp_time("InitSound");
 
-  InitMusic(NULL);             // needs to know current level directory
+  InitMusic();                 // needs to know current level directory
   print_timestamp_time("InitMusic");
 
   InitArtworkDone();
@@ -6521,8 +6661,7 @@ void OpenAll(void)
 
 static boolean WaitForApiThreads(void)
 {
-  unsigned int thread_delay = 0;
-  unsigned int thread_delay_value = 10000;
+  DelayCounter thread_delay = { 10000 };
 
   if (program.api_thread_count == 0)
     return TRUE;
@@ -6538,7 +6677,7 @@ static boolean WaitForApiThreads(void)
   // wait for threads to finish (and fail on timeout)
   while (program.api_thread_count > 0)
   {
-    if (DelayReached(&thread_delay, thread_delay_value))
+    if (DelayReached(&thread_delay))
     {
       Error("failed waiting for threads - TIMEOUT");