rnd-20060816-2-src
[rocksndiamonds.git] / src / init.c
index 279618d4993fad01db3271e257c843f86bba9b46..e8bf10b6882b507396039e60f8e966998f9b457c 100644 (file)
@@ -143,6 +143,15 @@ void InitElementSmallImages()
     InitElementSmallImagesScaledUp(special_graphics[i]);
 }
 
+void InitScaledImages()
+{
+  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);
+}
+
 #if 1
 /* !!! FIX THIS (CHANGE TO USING NORMAL ELEMENT GRAPHIC DEFINITIONS) !!! */
 void SetBitmaps_EM(Bitmap **em_bitmap)
@@ -286,7 +295,7 @@ void InitFontGraphicInfo()
       if (graphic_info[graphic].anim_frames < MIN_NUM_CHARS_PER_FONT)
       {
        graphic_info[graphic].anim_frames = DEFAULT_NUM_CHARS_PER_FONT;
-       graphic_info[graphic].anim_frames_per_line= DEFAULT_NUM_CHARS_PER_LINE;
+       graphic_info[graphic].anim_frames_per_line = DEFAULT_NUM_CHARS_PER_LINE;
       }
 
       /* copy font relevant information from graphics information */
@@ -295,8 +304,11 @@ void InitFontGraphicInfo()
       font_bitmap_info[font_bitmap_id].src_y  = graphic_info[graphic].src_y;
       font_bitmap_info[font_bitmap_id].width  = graphic_info[graphic].width;
       font_bitmap_info[font_bitmap_id].height = graphic_info[graphic].height;
-      font_bitmap_info[font_bitmap_id].draw_x = graphic_info[graphic].draw_x;
-      font_bitmap_info[font_bitmap_id].draw_y = graphic_info[graphic].draw_y;
+
+      font_bitmap_info[font_bitmap_id].draw_xoffset =
+       graphic_info[graphic].draw_xoffset;
+      font_bitmap_info[font_bitmap_id].draw_yoffset =
+       graphic_info[graphic].draw_yoffset;
 
       font_bitmap_info[font_bitmap_id].num_chars =
        graphic_info[graphic].anim_frames;
@@ -824,12 +836,12 @@ static int get_graphic_parameter_value(char *value_raw, char *suffix, int type)
   if (type != TYPE_TOKEN)
     return get_parameter_value(value_raw, suffix, type);
 
-  if (strcmp(value_raw, ARG_UNDEFINED) == 0)
+  if (strEqual(value_raw, ARG_UNDEFINED))
     return ARG_UNDEFINED_VALUE;
 
   /* !!! OPTIMIZE THIS BY USING HASH !!! */
   for (i = 0; i < MAX_NUM_ELEMENTS; i++)
-    if (strcmp(element_info[i].token_name, value_raw) == 0)
+    if (strEqual(element_info[i].token_name, value_raw))
       return i;
 
   /* !!! OPTIMIZE THIS BY USING HASH !!! */
@@ -837,12 +849,12 @@ static int get_graphic_parameter_value(char *value_raw, char *suffix, int type)
   {
     int len_config_value = strlen(image_config[i].value);
 
-    if (strcmp(&image_config[i].value[len_config_value - 4], ".pcx") != 0 &&
-       strcmp(&image_config[i].value[len_config_value - 4], ".wav") != 0 &&
-       strcmp(image_config[i].value, UNDEFINED_FILENAME) != 0)
+    if (!strEqual(&image_config[i].value[len_config_value - 4], ".pcx") &&
+       !strEqual(&image_config[i].value[len_config_value - 4], ".wav") &&
+       !strEqual(image_config[i].value, UNDEFINED_FILENAME))
       continue;
 
-    if (strcmp(image_config[i].token, value_raw) == 0)
+    if (strEqual(image_config[i].token, value_raw))
       return x;
 
     x++;
@@ -1006,6 +1018,9 @@ static void set_graphic_parameters(int graphic)
   else
     graphic_info[graphic].anim_frames = 1;
 
+  if (graphic_info[graphic].anim_frames == 0)  /* frames must be at least 1 */
+    graphic_info[graphic].anim_frames = 1;
+
   graphic_info[graphic].anim_frames_per_line =
     (parameter[GFX_ARG_FRAMES_PER_LINE] != ARG_UNDEFINED_VALUE ?
      parameter[GFX_ARG_FRAMES_PER_LINE] : anim_frames_per_line);
@@ -1063,8 +1078,8 @@ static void set_graphic_parameters(int graphic)
   graphic_info[graphic].step_delay  = parameter[GFX_ARG_STEP_DELAY];
 
   /* this is only used for drawing font characters */
-  graphic_info[graphic].draw_x = parameter[GFX_ARG_DRAW_XOFFSET];
-  graphic_info[graphic].draw_y = parameter[GFX_ARG_DRAW_YOFFSET];
+  graphic_info[graphic].draw_xoffset = parameter[GFX_ARG_DRAW_XOFFSET];
+  graphic_info[graphic].draw_yoffset = parameter[GFX_ARG_DRAW_YOFFSET];
 
   /* this is only used for drawing envelope graphics */
   graphic_info[graphic].draw_masked = parameter[GFX_ARG_DRAW_MASKED];
@@ -1290,8 +1305,8 @@ static void InitElementSoundInfo()
       element_info[element].sound[action] = sound;
     else
       for (j = 0; j < MAX_NUM_ELEMENTS; j++)
-       if (strcmp(element_info[j].class_name,
-                  element_info[element].class_name) == 0)
+       if (strEqual(element_info[j].class_name,
+                    element_info[element].class_name))
          element_info[j].sound[action] = sound;
   }
 
@@ -1309,8 +1324,8 @@ static void InitElementSoundInfo()
       action = ACTION_DEFAULT;
 
     for (j = 0; j < MAX_NUM_ELEMENTS; j++)
-      if (strcmp(element_info[j].class_name,
-                element_info[element_class].class_name) == 0)
+      if (strEqual(element_info[j].class_name,
+                  element_info[element_class].class_name))
        element_info[j].sound[action] = sound;
   }
 
@@ -1465,8 +1480,8 @@ static void InitSoundInfo()
       int len_action_text = strlen(element_action_info[j].suffix);
 
       if (len_action_text < len_effect_text &&
-         strcmp(&sound->token[len_effect_text - len_action_text],
-                element_action_info[j].suffix) == 0)
+         strEqual(&sound->token[len_effect_text - len_action_text],
+                  element_action_info[j].suffix))
       {
        sound_effect_properties[i] = element_action_info[j].value;
        sound_info[i].loop = element_action_info[j].is_loop_sound;
@@ -1644,7 +1659,8 @@ static void ReinitializeGraphics()
   InitElementGraphicInfo();            /* element game graphic mapping */
   InitElementSpecialGraphicInfo();     /* element special graphic mapping */
 
-  InitElementSmallImages();            /* scale images to all needed sizes */
+  InitElementSmallImages();            /* scale elements to all needed sizes */
+  InitScaledImages();                  /* scale all other images, if needed */
   InitFontGraphicInfo();               /* initialize text drawing functions */
 
   InitGraphicInfo_EM();                        /* graphic mapping for EM engine */
@@ -2891,6 +2907,7 @@ void InitElementPropertiesStatic()
     EL_EXPANDABLE_WALL_VERTICAL,
     EL_EXPANDABLE_WALL_ANY,
     EL_EXPANDABLE_WALL_GROWING,
+    EL_BD_EXPANDABLE_WALL,
     EL_BD_WALL,
     EL_SP_CHIP_SINGLE,
     EL_SP_CHIP_LEFT,
@@ -2940,6 +2957,7 @@ void InitElementPropertiesStatic()
     EL_EXPANDABLE_WALL_HORIZONTAL,
     EL_EXPANDABLE_WALL_VERTICAL,
     EL_EXPANDABLE_WALL_ANY,
+    EL_BD_EXPANDABLE_WALL,
     EL_BD_WALL,
     EL_WALL_SLIPPERY,
     EL_EXIT_CLOSED,
@@ -3519,8 +3537,8 @@ void InitElementPropertiesStatic()
     EL_INTERNAL_CASCADE_CHARS_ACTIVE,
     EL_INTERNAL_CASCADE_CE_ACTIVE,
     EL_INTERNAL_CASCADE_GE_ACTIVE,
+    EL_INTERNAL_CASCADE_REF_ACTIVE,
     EL_INTERNAL_CASCADE_USER_ACTIVE,
-    EL_INTERNAL_CASCADE_GENERIC_ACTIVE,
     EL_INTERNAL_CASCADE_DYNAMIC_ACTIVE,
 
     -1
@@ -3539,13 +3557,26 @@ void InitElementPropertiesStatic()
     EL_INTERNAL_CASCADE_CHARS,
     EL_INTERNAL_CASCADE_CE,
     EL_INTERNAL_CASCADE_GE,
+    EL_INTERNAL_CASCADE_REF,
     EL_INTERNAL_CASCADE_USER,
-    EL_INTERNAL_CASCADE_GENERIC,
     EL_INTERNAL_CASCADE_DYNAMIC,
 
     -1
   };
 
+  static int ep_obsolete[] =
+  {
+    EL_PLAYER_OBSOLETE,
+    EL_KEY_OBSOLETE,
+    EL_EM_KEY_1_FILE_OBSOLETE,
+    EL_EM_KEY_2_FILE_OBSOLETE,
+    EL_EM_KEY_3_FILE_OBSOLETE,
+    EL_EM_KEY_4_FILE_OBSOLETE,
+    EL_ENVELOPE_OBSOLETE,
+
+    -1
+  };
+
   static struct
   {
     int *elements;
@@ -3616,6 +3647,8 @@ void InitElementPropertiesStatic()
     { ep_editor_cascade_active,                EP_EDITOR_CASCADE_ACTIVE        },
     { ep_editor_cascade_inactive,      EP_EDITOR_CASCADE_INACTIVE      },
 
+    { ep_obsolete,                     EP_OBSOLETE                     },
+
     { NULL,                            -1                              }
   };
 
@@ -3891,6 +3924,7 @@ void InitElementPropertiesEngine(int engine_version)
                  engine_version > VERSION_IDENT(2,0,1,0)));
   }
 
+#if 0
   /* set default push delay values (corrected since version 3.0.7-1) */
   if (engine_version < VERSION_IDENT(3,0,7,1))
   {
@@ -3902,7 +3936,9 @@ void InitElementPropertiesEngine(int engine_version)
     game.default_push_delay_fixed = 8;
     game.default_push_delay_random = 8;
   }
+#endif
 
+#if 0
   /* set uninitialized push delay values of custom elements in older levels */
   for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
   {
@@ -3913,7 +3949,9 @@ void InitElementPropertiesEngine(int engine_version)
     if (element_info[element].push_delay_random == -1)
       element_info[element].push_delay_random = game.default_push_delay_random;
   }
+#endif
 
+#if 0
   /* set some other uninitialized values of custom elements in older levels */
   if (engine_version < VERSION_IDENT(3,1,0,0))
   {
@@ -3927,6 +3965,7 @@ void InitElementPropertiesEngine(int engine_version)
       element_info[element].ignition_delay = 8;
     }
   }
+#endif
 
 #if 0
   /* set element properties that were handled incorrectly in older levels */
@@ -3942,6 +3981,54 @@ void InitElementPropertiesEngine(int engine_version)
     InitElementGraphicInfo();
 }
 
+void InitElementPropertiesAfterLoading(int engine_version)
+{
+  int i;
+
+#if 0
+  /* set default push delay values (corrected since version 3.0.7-1) */
+  if (engine_version < VERSION_IDENT(3,0,7,1))
+  {
+    game.default_push_delay_fixed = 2;
+    game.default_push_delay_random = 8;
+  }
+  else
+  {
+    game.default_push_delay_fixed = 8;
+    game.default_push_delay_random = 8;
+  }
+#endif
+
+#if 0
+  /* set uninitialized push delay values of custom elements in older levels */
+  for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
+  {
+    int element = EL_CUSTOM_START + i;
+
+    if (element_info[element].push_delay_fixed == -1)
+      element_info[element].push_delay_fixed = game.default_push_delay_fixed;
+    if (element_info[element].push_delay_random == -1)
+      element_info[element].push_delay_random = game.default_push_delay_random;
+  }
+#endif
+
+#if 1
+  /* set some other uninitialized values of custom elements in older levels */
+  if (engine_version < VERSION_IDENT(3,1,0,0))
+  {
+    for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
+    {
+      int element = EL_CUSTOM_START + i;
+
+      element_info[element].access_direction = MV_ALL_DIRECTIONS;
+
+      element_info[element].explosion_delay = 17;
+      element_info[element].ignition_delay = 8;
+    }
+  }
+#endif
+}
+
 static void InitGlobal()
 {
   int i;
@@ -3969,7 +4056,7 @@ void Execute_Command(char *command)
 {
   int i;
 
-  if (strcmp(command, "print graphicsinfo.conf") == 0)
+  if (strEqual(command, "print graphicsinfo.conf"))
   {
     printf("# You can configure additional/alternative image files here.\n");
     printf("# (The entries below are default and therefore commented out.)\n");
@@ -3985,7 +4072,7 @@ void Execute_Command(char *command)
 
     exit(0);
   }
-  else if (strcmp(command, "print soundsinfo.conf") == 0)
+  else if (strEqual(command, "print soundsinfo.conf"))
   {
     printf("# You can configure additional/alternative sound files here.\n");
     printf("# (The entries below are default and therefore commented out.)\n");
@@ -4001,7 +4088,7 @@ void Execute_Command(char *command)
 
     exit(0);
   }
-  else if (strcmp(command, "print musicinfo.conf") == 0)
+  else if (strEqual(command, "print musicinfo.conf"))
   {
     printf("# You can configure additional/alternative music files here.\n");
     printf("# (The entries below are default and therefore commented out.)\n");
@@ -4017,7 +4104,7 @@ void Execute_Command(char *command)
 
     exit(0);
   }
-  else if (strcmp(command, "print editorsetup.conf") == 0)
+  else if (strEqual(command, "print editorsetup.conf"))
   {
     printf("# You can configure your personal editor element list here.\n");
     printf("# (The entries below are default and therefore commented out.)\n");
@@ -4031,7 +4118,7 @@ void Execute_Command(char *command)
 
     exit(0);
   }
-  else if (strcmp(command, "print helpanim.conf") == 0)
+  else if (strEqual(command, "print helpanim.conf"))
   {
     printf("# You can configure different element help animations here.\n");
     printf("# (The entries below are default and therefore commented out.)\n");
@@ -4042,13 +4129,13 @@ void Execute_Command(char *command)
       printf("# %s\n", getFormattedSetupEntry(helpanim_config[i].token,
                                              helpanim_config[i].value));
 
-      if (strcmp(helpanim_config[i].token, "end") == 0)
+      if (strEqual(helpanim_config[i].token, "end"))
        printf("#\n");
     }
 
     exit(0);
   }
-  else if (strcmp(command, "print helptext.conf") == 0)
+  else if (strEqual(command, "print helptext.conf"))
   {
     printf("# You can configure different element help text here.\n");
     printf("# (The entries below are default and therefore commented out.)\n");
@@ -4134,6 +4221,45 @@ void Execute_Command(char *command)
       global.convert_level_nr = atoi(str_ptr); /* get level_nr value */
     }
   }
+
+#if DEBUG
+#if 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)
+    {
+      printf("No modes available!\n");
+
+      exit(-1);
+    }
+
+    /* check if our resolution is restricted */
+    if (modes == (SDL_Rect **)-1)
+    {
+      printf("All resolutions available.\n");
+    }
+    else
+    {
+      printf("Available Modes:\n");
+
+      for(i = 0; modes[i]; i++)
+       printf("  %d x %d\n", modes[i]->w, modes[i]->h);
+    }
+
+    exit(0);
+  }
+#endif
+#endif
+
   else
   {
     Error(ERR_EXIT_HELP, "unrecognized command '%s'", command);
@@ -4329,6 +4455,7 @@ void InitGfx()
 {
   char *filename_font_initial = NULL;
   Bitmap *bitmap_font_initial = NULL;
+  int font_height;
   int i, j;
 
   /* determine settings for initial font (for displaying startup messages) */
@@ -4342,18 +4469,18 @@ void InitGfx()
       sprintf(font_token, "%s_%d", CONFIG_TOKEN_FONT_INITIAL, j + 1);
       len_font_token = strlen(font_token);
 
-      if (strcmp(image_config[i].token, font_token) == 0)
+      if (strEqual(image_config[i].token, font_token))
        filename_font_initial = image_config[i].value;
       else if (strlen(image_config[i].token) > len_font_token &&
               strncmp(image_config[i].token, font_token, len_font_token) == 0)
       {
-       if (strcmp(&image_config[i].token[len_font_token], ".x") == 0)
+       if (strEqual(&image_config[i].token[len_font_token], ".x"))
          font_initial[j].src_x = atoi(image_config[i].value);
-       else if (strcmp(&image_config[i].token[len_font_token], ".y") == 0)
+       else if (strEqual(&image_config[i].token[len_font_token], ".y"))
          font_initial[j].src_y = atoi(image_config[i].value);
-       else if (strcmp(&image_config[i].token[len_font_token], ".width") == 0)
+       else if (strEqual(&image_config[i].token[len_font_token], ".width"))
          font_initial[j].width = atoi(image_config[i].value);
-       else if (strcmp(&image_config[i].token[len_font_token],".height") == 0)
+       else if (strEqual(&image_config[i].token[len_font_token],".height"))
          font_initial[j].height = atoi(image_config[i].value);
       }
     }
@@ -4368,8 +4495,10 @@ void InitGfx()
   if (filename_font_initial == NULL)   /* should not happen */
     Error(ERR_EXIT, "cannot get filename for '%s'", CONFIG_TOKEN_FONT_INITIAL);
 
-  /* create additional image buffers for double-buffering */
+  /* create additional image buffers for double-buffering and cross-fading */
+  bitmap_db_cross = CreateBitmap(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH);
   bitmap_db_field = CreateBitmap(FXSIZE, FYSIZE, DEFAULT_DEPTH);
+  bitmap_db_panel = CreateBitmap(DXSIZE, DYSIZE, DEFAULT_DEPTH);
   bitmap_db_door  = CreateBitmap(3 * DXSIZE, DYSIZE + VYSIZE, DEFAULT_DEPTH);
 
   /* initialize screen properties */
@@ -4387,12 +4516,23 @@ void InitGfx()
 
   InitFontGraphicInfo();
 
+  font_height = getFontHeight(FC_RED);
+
   DrawInitText(getProgramInitString(), 20, FC_YELLOW);
   DrawInitText(PROGRAM_COPYRIGHT_STRING, 50, FC_RED);
+  DrawInitText(PROGRAM_WEBSITE_STRING, WIN_YSIZE - 20 - font_height, FC_RED);
 
   DrawInitText("Loading graphics:", 120, FC_GREEN);
 }
 
+void RedrawBackground()
+{
+  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;
@@ -4401,8 +4541,8 @@ void InitGfxBackground()
   fieldbuffer = bitmap_db_field;
   SetDrawtoField(DRAW_BACKBUFFER);
 
-  BlitBitmap(graphic_info[IMG_GLOBAL_BORDER].bitmap, backbuffer,
-            0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+  RedrawBackground();
+
   ClearRectangle(backbuffer, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
   ClearRectangle(bitmap_db_door, 0, 0, 3 * DXSIZE, DYSIZE + VYSIZE);
 
@@ -4573,8 +4713,8 @@ static char *getNewArtworkIdentifier(int type)
 #endif
 
   /* ---------- reload if current artwork identifier has changed ----------- */
-  if (strcmp(ARTWORK_CURRENT_IDENTIFIER(artwork, type),
-            artwork_current_identifier) != 0)
+  if (!strEqual(ARTWORK_CURRENT_IDENTIFIER(artwork, type),
+               artwork_current_identifier))
     artwork_new_identifier = artwork_current_identifier;
 
   *(ARTWORK_CURRENT_IDENTIFIER_PTR(artwork, type))= artwork_current_identifier;
@@ -4608,14 +4748,20 @@ static char *getNewArtworkIdentifier(int type)
 
 void ReloadCustomArtwork(int force_reload)
 {
-  char *gfx_new_identifier = getNewArtworkIdentifier(ARTWORK_TYPE_GRAPHICS);
-  char *snd_new_identifier = getNewArtworkIdentifier(ARTWORK_TYPE_SOUNDS);
-  char *mus_new_identifier = getNewArtworkIdentifier(ARTWORK_TYPE_MUSIC);
+  char *gfx_new_identifier;
+  char *snd_new_identifier;
+  char *mus_new_identifier;
   boolean force_reload_gfx = (force_reload & (1 << ARTWORK_TYPE_GRAPHICS));
   boolean force_reload_snd = (force_reload & (1 << ARTWORK_TYPE_SOUNDS));
   boolean force_reload_mus = (force_reload & (1 << ARTWORK_TYPE_MUSIC));
   boolean redraw_screen = FALSE;
 
+  force_reload_gfx |= AdjustGraphicsForEMC();
+
+  gfx_new_identifier = getNewArtworkIdentifier(ARTWORK_TYPE_GRAPHICS);
+  snd_new_identifier = getNewArtworkIdentifier(ARTWORK_TYPE_SOUNDS);
+  mus_new_identifier = getNewArtworkIdentifier(ARTWORK_TYPE_MUSIC);
+
   if (gfx_new_identifier != NULL || force_reload_gfx)
   {
 #if 0
@@ -4653,7 +4799,11 @@ void ReloadCustomArtwork(int force_reload)
 
   if (redraw_screen)
   {
+#if 1
+    RedrawBackground();
+#else
     InitGfxBackground();
+#endif
 
     /* force redraw of (open or closed) door graphics */
     SetDoorState(DOOR_OPEN_ALL);
@@ -4742,7 +4892,11 @@ void OpenAll()
   em_open_all();
 #endif
 
+#if 0
+  DrawMainMenuExt(REDRAW_ALL);
+#else
   DrawMainMenu();
+#endif
 
   InitNetworkServer();
 }
@@ -4768,5 +4922,8 @@ void CloseAllAndExit(int exit_value)
   CloseVideoDisplay();
   ClosePlatformDependentStuff();
 
+  if (exit_value != 0)
+    NotifyUserAboutErrorFile();
+
   exit(exit_value);
 }