rnd-20100615-2-src
[rocksndiamonds.git] / src / init.c
index 5d862c6f3689a860c6e6f51ecd23335a123eba30..4f7ca41ab30ee78edf0f5ebf7f043af760b05bf3 100644 (file)
@@ -186,20 +186,8 @@ void DrawInitAnim()
   }
 #endif
 
-#if 0
-  anim_initial.anim_mode = ANIM_LOOP;
-  anim_initial.anim_start_frame = 0;
-  anim_initial.offset_x = anim_initial.width;
-  anim_initial.offset_y = 0;
-#endif
-
-#if 1
-  x = ALIGNED_TEXT_XPOS(&init.busy);
-  y = ALIGNED_TEXT_YPOS(&init.busy);
-#else
-  x = WIN_XSIZE / 2 - TILESIZE / 2;
-  y = WIN_YSIZE / 2 - TILESIZE / 2;
-#endif
+  x = ALIGNED_TEXT_XPOS(&init_last.busy);
+  y = ALIGNED_TEXT_YPOS(&init_last.busy);
 
   graphic_info = &anim_initial;                /* graphic == 0 => anim_initial */
 
@@ -329,6 +317,14 @@ void SetBitmaps_EM(Bitmap **em_bitmap)
 }
 #endif
 
+#if 0
+/* !!! FIX THIS (CHANGE TO USING NORMAL ELEMENT GRAPHIC DEFINITIONS) !!! */
+void SetBitmaps_SP(Bitmap **sp_bitmap)
+{
+  *sp_bitmap = graphic_info[IMG_SP_OBJECTS].bitmap;
+}
+#endif
+
 static int getFontBitmapID(int font_nr)
 {
   int special = -1;
@@ -344,6 +340,15 @@ static int getFontBitmapID(int font_nr)
     special = GFX_SPECIAL_ARG_DOOR;
 #endif
 
+#if 0
+  if (special != -1)
+  {
+    printf("%s%s\n",
+          font_info[font_nr].token_name,
+          special_suffix_info[special].suffix);
+  }
+#endif
+
   if (special != -1)
     return font_info[font_nr].special_bitmap_id[special];
   else
@@ -1289,6 +1294,8 @@ static void set_graphic_parameters_ext(int graphic, int *parameter,
   g->align = ALIGN_CENTER;             /* default for title screens */
   g->valign = VALIGN_MIDDLE;           /* default for title screens */
   g->sort_priority = 0;                        /* default for title screens */
+  g->class = 0;
+  g->style = STYLE_DEFAULT;
 
   g->bitmap = src_bitmap;
 
@@ -1489,6 +1496,17 @@ static void set_graphic_parameters_ext(int graphic, int *parameter,
     g->valign = parameter[GFX_ARG_VALIGN];
   if (parameter[GFX_ARG_SORT_PRIORITY] != ARG_UNDEFINED_VALUE)
     g->sort_priority = parameter[GFX_ARG_SORT_PRIORITY];
+
+  if (parameter[GFX_ARG_CLASS] != ARG_UNDEFINED_VALUE)
+    g->class = parameter[GFX_ARG_CLASS];
+  if (parameter[GFX_ARG_STYLE] != ARG_UNDEFINED_VALUE)
+    g->style = parameter[GFX_ARG_STYLE];
+
+  /* this is only used for drawing menu buttons and text */
+  g->active_xoffset = parameter[GFX_ARG_ACTIVE_XOFFSET];
+  g->active_yoffset = parameter[GFX_ARG_ACTIVE_YOFFSET];
+  g->pressed_xoffset = parameter[GFX_ARG_PRESSED_XOFFSET];
+  g->pressed_yoffset = parameter[GFX_ARG_PRESSED_YOFFSET];
 }
 
 static void set_graphic_parameters(int graphic)
@@ -2019,6 +2037,60 @@ static void InitGraphicInfo()
 #endif
 }
 
+static void InitGraphicCompatibilityInfo()
+{
+  struct FileInfo *fi_global_door =
+    getImageListEntryFromImageID(IMG_GLOBAL_DOOR);
+  int num_images = getImageListSize();
+  int i;
+
+  /* the following compatibility handling is needed for the following case:
+     versions up to 3.3.0.0 used one large bitmap "global.door" for various
+     graphics mainly used for door and panel graphics, like editor, tape and
+     in-game buttons with hard-coded bitmap positions and button sizes; as
+     these graphics now have individual definitions, redefining "global.door"
+     to change all these graphics at once like before does not work anymore
+     (because all those individual definitions still have their default values);
+     to solve this, remap all those individual definitions that are not
+     redefined to the new bitmap of "global.door" if it was redefined */
+
+  /* special compatibility handling if image "global.door" was redefined */
+  if (fi_global_door->redefined)
+  {
+    for (i = 0; i < num_images; i++)
+    {
+      struct FileInfo *fi = getImageListEntryFromImageID(i);
+
+      /* process only those images that still use the default settings */
+      if (!fi->redefined)
+      {
+       /* process all images which default to same image as "global.door" */
+       if (strEqual(fi->default_filename, fi_global_door->default_filename))
+       {
+         // printf("::: special treatment needed for token '%s'\n", fi->token);
+
+         graphic_info[i].bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
+       }
+      }
+    }
+  }
+
+#if 0
+  for (i = 0; i < num_images; i++)
+  {
+    struct FileInfo *fi = getImageListEntryFromImageID(i);
+
+    if (i == IMG_GLOBAL_DOOR)
+    {
+      printf("::: %s, %s, %d\n",
+            fi->default_filename,
+            fi->filename,
+            fi->redefined);
+    }
+  }
+#endif
+}
+
 static void InitElementSoundInfo()
 {
   struct PropertyMapping *property_mapping = getSoundListPropertyMapping();
@@ -2414,6 +2486,9 @@ static void ReinitializeGraphics()
   InitGraphicInfo_EM();                        /* graphic mapping for EM engine */
   print_timestamp_time("InitGraphicInfo_EM");
 
+  InitGraphicCompatibilityInfo();
+  print_timestamp_time("InitGraphicCompatibilityInfo");
+
   SetMainBackgroundImage(IMG_BACKGROUND);
   print_timestamp_time("SetMainBackgroundImage");
   SetDoorBackgroundImage(IMG_BACKGROUND_DOOR);
@@ -2820,8 +2895,12 @@ void InitElementPropertiesStatic()
     EL_SIGN_FRANKIE,
     EL_STEEL_EXIT_CLOSED,
     EL_STEEL_EXIT_OPEN,
+    EL_STEEL_EXIT_OPENING,
+    EL_STEEL_EXIT_CLOSING,
     EL_EM_STEEL_EXIT_CLOSED,
     EL_EM_STEEL_EXIT_OPEN,
+    EL_EM_STEEL_EXIT_OPENING,
+    EL_EM_STEEL_EXIT_CLOSING,
     EL_DC_STEELWALL_1_LEFT,
     EL_DC_STEELWALL_1_RIGHT,
     EL_DC_STEELWALL_1_TOP,
@@ -3144,10 +3223,16 @@ void InitElementPropertiesStatic()
     EL_SOKOBAN_FIELD_EMPTY,
     EL_EXIT_OPEN,
     EL_EM_EXIT_OPEN,
+#if 1
+    EL_EM_EXIT_OPENING,
+#endif
     EL_SP_EXIT_OPEN,
     EL_SP_EXIT_OPENING,
     EL_STEEL_EXIT_OPEN,
     EL_EM_STEEL_EXIT_OPEN,
+#if 1
+    EL_EM_STEEL_EXIT_OPENING,
+#endif
     EL_GATE_1,
     EL_GATE_2,
     EL_GATE_3,
@@ -4159,6 +4244,7 @@ void InitElementPropertiesStatic()
     EL_PLAYER_2,
     EL_PLAYER_3,
     EL_PLAYER_4,
+    EL_SOKOBAN_FIELD_PLAYER,
     EL_SP_MURPHY,
     EL_YAMYAM,
     EL_YAMYAM_LEFT,
@@ -4849,6 +4935,14 @@ void InitElementPropertiesEngine(int engine_version)
       -1
     };
 
+    static int ep_em_explodes_by_fire[] =
+    {
+      EL_EM_DYNAMITE,
+      EL_EM_DYNAMITE_ACTIVE,
+      EL_MOLE,
+      -1
+    };
+
     /* special EM style gems behaviour */
     for (i = 0; ep_em_slippery_wall[i] != -1; i++)
       SET_PROPERTY(ep_em_slippery_wall[i], EP_EM_SLIPPERY_WALL,
@@ -4858,6 +4952,11 @@ void InitElementPropertiesEngine(int engine_version)
     SET_PROPERTY(EL_EXPANDABLE_WALL_GROWING, EP_EM_SLIPPERY_WALL,
                 (level.em_slippery_gems &&
                  engine_version > VERSION_IDENT(2,0,1,0)));
+
+    /* special EM style explosion behaviour regarding chain reactions */
+    for (i = 0; ep_em_explodes_by_fire[i] != -1; i++)
+      SET_PROPERTY(ep_em_explodes_by_fire[i], EP_EXPLODES_BY_FIRE,
+                  level.em_explodes_by_fire);
   }
 
   /* this is needed because some graphics depend on element properties */
@@ -4884,6 +4983,18 @@ void InitElementPropertiesAfterLoading(int engine_version)
   }
 }
 
+void InitElementPropertiesGfxElement()
+{
+  int i;
+
+  for (i = 0; i < MAX_NUM_ELEMENTS; i++)
+  {
+    struct ElementInfo *ei = &element_info[i];
+
+    ei->gfx_element = (ei->use_gfx_element ? ei->gfx_element_initial : i);
+  }
+}
+
 static void InitGlobal()
 {
   int graphic;
@@ -4976,6 +5087,7 @@ static void InitGlobal()
 
   global.autoplay_leveldir = NULL;
   global.convert_leveldir = NULL;
+  global.create_images_dir = NULL;
 
   global.frames_per_second = 0;
   global.fps_slowdown = FALSE;
@@ -5083,7 +5195,7 @@ void Execute_Command(char *command)
 
     exit(0);
   }
-  else if (strncmp(command, "dump level ", 11) == 0)
+  else if (strPrefix(command, "dump level "))
   {
     char *filename = &command[11];
 
@@ -5095,7 +5207,7 @@ void Execute_Command(char *command)
 
     exit(0);
   }
-  else if (strncmp(command, "dump tape ", 10) == 0)
+  else if (strPrefix(command, "dump tape "))
   {
     char *filename = &command[10];
 
@@ -5107,7 +5219,7 @@ void Execute_Command(char *command)
 
     exit(0);
   }
-  else if (strncmp(command, "autoplay ", 9) == 0)
+  else if (strPrefix(command, "autoplay "))
   {
     char *str_ptr = getStringCopy(&command[9]);        /* read command parameters */
 
@@ -5143,9 +5255,9 @@ void Execute_Command(char *command)
        str_ptr++;
     }
   }
-  else if (strncmp(command, "convert ", 8) == 0)
+  else if (strPrefix(command, "convert "))
   {
-    char *str_copy = getStringCopy(&command[8]);
+    char *str_copy = getStringCopy(strchr(command, ' ') + 1);
     char *str_ptr = strchr(str_copy, ' ');
 
     global.convert_leveldir = str_copy;
@@ -5157,6 +5269,18 @@ void Execute_Command(char *command)
       global.convert_level_nr = atoi(str_ptr); /* get level_nr value */
     }
   }
+  else if (strPrefix(command, "create images "))
+  {
+#if defined(TARGET_SDL)
+    global.create_images_dir = getStringCopy(&command[14]);
+
+    if (access(global.create_images_dir, W_OK) != 0)
+      Error(ERR_EXIT, "image target directory '%s' not found or not writable",
+           global.create_images_dir);
+#else
+    Error(ERR_EXIT, "command only available for SDL target");
+#endif
+  }
 
 #if DEBUG
 #if defined(TARGET_SDL)
@@ -5388,6 +5512,28 @@ static void InitMixer()
   StartMixer();
 }
 
+void InitGfxBuffers()
+{
+  ReCreateBitmap(&bitmap_db_store, WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH);
+  ReCreateBitmap(&bitmap_db_cross, WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH);
+  ReCreateBitmap(&bitmap_db_field, FXSIZE, FYSIZE, DEFAULT_DEPTH);
+  ReCreateBitmap(&bitmap_db_panel, DXSIZE, DYSIZE, DEFAULT_DEPTH);
+  ReCreateBitmap(&bitmap_db_door, 3 * DXSIZE, DYSIZE + VYSIZE, DEFAULT_DEPTH);
+  ReCreateBitmap(&bitmap_db_toons, FULL_SXSIZE, FULL_SYSIZE, DEFAULT_DEPTH);
+
+  /* initialize screen properties */
+  InitGfxFieldInfo(SX, SY, SXSIZE, SYSIZE,
+                  REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE,
+                  bitmap_db_field);
+  InitGfxDoor1Info(DX, DY, DXSIZE, DYSIZE);
+  InitGfxDoor2Info(VX, VY, VXSIZE, VYSIZE);
+  InitGfxWindowInfo(WIN_XSIZE, WIN_YSIZE);
+  InitGfxScrollbufferInfo(FXSIZE, FYSIZE);
+  InitGfxClipRegion(FALSE, -1, -1, -1, -1);
+
+  InitGfxBuffers_SP();
+}
+
 void InitGfx()
 {
   struct GraphicInfo *graphic_info_last = graphic_info;
@@ -5434,7 +5580,11 @@ void InitGfx()
   if (filename_font_initial == NULL)   /* should not happen */
     Error(ERR_EXIT, "cannot get filename for '%s'", CONFIG_TOKEN_FONT_INITIAL);
 
+#if 1
+  InitGfxBuffers();
+#else
   /* create additional image buffers for double-buffering and cross-fading */
+  bitmap_db_store = CreateBitmap(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH);
   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);
@@ -5447,7 +5597,10 @@ void InitGfx()
                   bitmap_db_field);
   InitGfxDoor1Info(DX, DY, DXSIZE, DYSIZE);
   InitGfxDoor2Info(VX, VY, VXSIZE, VYSIZE);
+  InitGfxWindowInfo(WIN_XSIZE, WIN_YSIZE);
   InitGfxScrollbufferInfo(FXSIZE, FYSIZE);
+#endif
+
   InitGfxCustomArtworkInfo();
 
   bitmap_font_initial = LoadCustomImage(filename_font_initial);
@@ -5561,6 +5714,9 @@ void InitGfx()
 
   InitMenuDesignSettings_Static();
   InitGfxDrawBusyAnimFunction(DrawInitAnim);
+
+  /* use copy of busy animation to prevent change while reloading artwork */
+  init_last = init;
 #endif
 }
 
@@ -5758,71 +5914,94 @@ static boolean CheckArtworkConfigForCustomElements(char *filename)
   return redefined_ce_found;
 }
 
-static void InitOverrideArtwork()
+static boolean CheckArtworkTypeForRedefinedCustomElements(int type)
 {
-  boolean init_override_from_setup = TRUE;
-
-  gfx.override_level_graphics = FALSE;
-  gfx.override_level_sounds   = FALSE;
-  gfx.override_level_music    = FALSE;
-
-  if (setup.auto_override_artwork)
-  {
-    char *filename_base, *filename_local;
-    boolean redefined_ce_found = FALSE;
+  char *filename_base, *filename_local;
+  boolean redefined_ce_found = FALSE;
 
-    setLevelArtworkDir(artwork.gfx_first);
+  setLevelArtworkDir(ARTWORK_FIRST_NODE(artwork, type));
 
 #if 0
-    printf("::: leveldir_current->identifier == '%s'\n",
-          leveldir_current == NULL ? "[NULL]" : leveldir_current->identifier);
-    printf("::: leveldir_current->graphics_path == '%s'\n",
-          leveldir_current == NULL ? "[NULL]" : leveldir_current->graphics_path);
-    printf("::: leveldir_current->graphics_set == '%s'\n",
-          leveldir_current == NULL ? "[NULL]" : leveldir_current->graphics_set);
-    printf("::: getLevelArtworkSet(ARTWORK_TYPE_GRAPHICS) == '%s'\n",
-          leveldir_current == NULL ? "[NULL]" : LEVELDIR_ARTWORK_SET(leveldir_current, ARTWORK_TYPE_GRAPHICS));
+  printf("::: leveldir_current->identifier == '%s'\n",
+        leveldir_current == NULL ? "[NULL]" : leveldir_current->identifier);
+  printf("::: leveldir_current->graphics_path == '%s'\n",
+        leveldir_current == NULL ? "[NULL]" : leveldir_current->graphics_path);
+  printf("::: leveldir_current->graphics_set == '%s'\n",
+        leveldir_current == NULL ? "[NULL]" : leveldir_current->graphics_set);
+  printf("::: getLevelArtworkSet(ARTWORK_TYPE_GRAPHICS) == '%s'\n",
+        leveldir_current == NULL ? "[NULL]" :
+        LEVELDIR_ARTWORK_SET(leveldir_current, type));
 #endif
 
-    /* first look for special artwork configured in level series config */
-    filename_base = getCustomArtworkLevelConfigFilename(ARTWORK_TYPE_GRAPHICS);
+  /* first look for special artwork configured in level series config */
+  filename_base = getCustomArtworkLevelConfigFilename(type);
 
 #if 0
-    printf("::: filename_base == '%s'\n", filename_base);
+  printf("::: filename_base == '%s'\n", filename_base);
 #endif
 
-    if (fileExists(filename_base))
-      redefined_ce_found |= CheckArtworkConfigForCustomElements(filename_base);
+  if (fileExists(filename_base))
+    redefined_ce_found |= CheckArtworkConfigForCustomElements(filename_base);
 
-    filename_local = getCustomArtworkConfigFilename(ARTWORK_TYPE_GRAPHICS);
+  filename_local = getCustomArtworkConfigFilename(type);
 
 #if 0
-    printf("::: filename_local == '%s'\n", filename_local);
+  printf("::: filename_local == '%s'\n", filename_local);
 #endif
 
-    if (filename_local != NULL && !strEqual(filename_base, filename_local))
-      redefined_ce_found |= CheckArtworkConfigForCustomElements(filename_local);
+  if (filename_local != NULL && !strEqual(filename_base, filename_local))
+    redefined_ce_found |= CheckArtworkConfigForCustomElements(filename_local);
 
 #if 0
-    printf("::: redefined_ce_found == %d\n", redefined_ce_found);
+  printf("::: redefined_ce_found == %d\n", redefined_ce_found);
 #endif
 
-    if (!redefined_ce_found)
-    {
-      gfx.override_level_graphics = TRUE;
-      gfx.override_level_sounds   = TRUE;
-      gfx.override_level_music    = TRUE;
+  return redefined_ce_found;
+}
 
-      init_override_from_setup = FALSE;
-    }
-  }
+static void InitOverrideArtwork()
+{
+  boolean redefined_ce_found = FALSE;
+
+  /* to check if this level set redefines any CEs, do not use overriding */
+  gfx.override_level_graphics = FALSE;
+  gfx.override_level_sounds   = FALSE;
+  gfx.override_level_music    = FALSE;
+
+  /* now check if this level set has definitions for custom elements */
+  if (setup.override_level_graphics == AUTO ||
+      setup.override_level_sounds   == AUTO ||
+      setup.override_level_music    == AUTO)
+    redefined_ce_found =
+      (CheckArtworkTypeForRedefinedCustomElements(ARTWORK_TYPE_GRAPHICS) |
+       CheckArtworkTypeForRedefinedCustomElements(ARTWORK_TYPE_SOUNDS) |
+       CheckArtworkTypeForRedefinedCustomElements(ARTWORK_TYPE_MUSIC));
 
-  if (init_override_from_setup)
+#if 0
+  printf("::: redefined_ce_found == %d\n", redefined_ce_found);
+#endif
+
+  if (redefined_ce_found)
   {
-    gfx.override_level_graphics = setup.override_level_graphics;
-    gfx.override_level_sounds   = setup.override_level_sounds;
-    gfx.override_level_music    = setup.override_level_music;
+    /* this level set has CE definitions: change "AUTO" to "FALSE" */
+    gfx.override_level_graphics = (setup.override_level_graphics == TRUE);
+    gfx.override_level_sounds   = (setup.override_level_sounds   == TRUE);
+    gfx.override_level_music    = (setup.override_level_music    == TRUE);
   }
+  else
+  {
+    /* this level set has no CE definitions: change "AUTO" to "TRUE" */
+    gfx.override_level_graphics = (setup.override_level_graphics != FALSE);
+    gfx.override_level_sounds   = (setup.override_level_sounds   != FALSE);
+    gfx.override_level_music    = (setup.override_level_music    != FALSE);
+  }
+
+#if 0
+  printf("::: => %d, %d, %d\n",
+        gfx.override_level_graphics,
+        gfx.override_level_sounds,
+        gfx.override_level_music);
+#endif
 }
 
 static char *getNewArtworkIdentifier(int type)
@@ -6017,6 +6196,8 @@ void ReloadCustomArtwork(int force_reload)
 
   game_status = last_game_status;      /* restore current game status */
 
+  init_last = init;                    /* switch to new busy animation */
+
 #if 0
   printf("::: ----------------DELAY 1 ...\n");
   Delay(3000);
@@ -6074,8 +6255,14 @@ void OpenAll()
 
   game_status = GAME_MODE_LOADING;
 
+#if 1
+  InitCounter();
+#endif
+
   InitGlobal();                        /* initialize some global variables */
 
+  print_timestamp_time("[init global stuff]");
+
   if (options.execute_command)
     Execute_Command(options.execute_command);
 
@@ -6098,24 +6285,29 @@ void OpenAll()
   InitArtworkConfig();         /* needed before forking sound child process */
   InitMixer();
 
+#if 0
   InitCounter();
+#endif
 
   InitRND(NEW_RANDOMIZE);
   InitSimpleRandom(NEW_RANDOMIZE);
 
   InitJoysticks();
 
-  print_timestamp_time("[pre-video]");
+  print_timestamp_time("[init setup/config stuff]");
 
   InitVideoDisplay();
   InitVideoBuffer(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH, setup.fullscreen);
 
   InitEventFilter(FilterMouseMotionEvents);
 
+  print_timestamp_time("[init video stuff]");
+
   InitElementPropertiesStatic();
   InitElementPropertiesEngine(GAME_VERSION_ACTUAL);
+  InitElementPropertiesGfxElement();
 
-  print_timestamp_time("[post-video]");
+  print_timestamp_time("[init element properties stuff]");
 
   InitGfx();
 
@@ -6145,6 +6337,10 @@ void OpenAll()
   em_open_all();
 #endif
 
+#if 1
+  sp_open_all();
+#endif
+
   if (global.autoplay_leveldir)
   {
     AutoPlayTape();
@@ -6155,6 +6351,11 @@ void OpenAll()
     ConvertLevels();
     return;
   }
+  else if (global.create_images_dir)
+  {
+    CreateLevelSketchImages();
+    return;
+  }
 
   game_status = GAME_MODE_MAIN;
 
@@ -6187,6 +6388,10 @@ void CloseAllAndExit(int exit_value)
   em_close_all();
 #endif
 
+#if 1
+  sp_close_all();
+#endif
+
   FreeAllImages();
 
 #if defined(TARGET_SDL)