rnd-20050103-1-src
[rocksndiamonds.git] / src / init.c
index b02d08838168225d8a80c012f2a72a0eb2f1d59b..e07ea102e26ee56ab13af0f8f23aa7edd36a7c28 100644 (file)
@@ -639,7 +639,9 @@ void InitElementGraphicInfo()
        if (act == ACTION_FALLING)      /* special case */
          graphic = element_info[i].graphic[act];
 
-       if (graphic != -1 && graphic_info[graphic].double_movement)
+       if (graphic != -1 &&
+           graphic_info[graphic].double_movement &&
+           graphic_info[graphic].swap_double_tiles != 0)
        {
          struct GraphicInfo *g = &graphic_info[graphic];
          int src_x_front = g->src_x;
@@ -650,20 +652,40 @@ void InitElementGraphicInfo()
                                                   g->offset_y != 0);
          boolean front_is_left_or_upper = (src_x_front < src_x_back ||
                                            src_y_front < src_y_back);
+#if 0
+         boolean second_tile_is_back =
+           ((move_dir == MV_BIT_LEFT  && front_is_left_or_upper) ||
+            (move_dir == MV_BIT_UP    && front_is_left_or_upper));
+         boolean second_tile_is_front =
+           ((move_dir == MV_BIT_RIGHT && front_is_left_or_upper) ||
+            (move_dir == MV_BIT_DOWN  && front_is_left_or_upper));
+         boolean second_tile_should_be_front =
+           (g->second_tile_is_start == 0);
+         boolean second_tile_should_be_back =
+           (g->second_tile_is_start == 1);
+#endif
+         boolean swap_movement_tiles_always = (g->swap_double_tiles == 1);
+         boolean swap_movement_tiles_autodetected =
+           (!frames_are_ordered_diagonally &&
+            ((move_dir == MV_BIT_LEFT  && !front_is_left_or_upper) ||
+             (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;
 
 #if 0
-         printf("::: CHECKING ELEMENT %d ('%s'), ACTION '%s', DIRECTION %d\n",
+         printf("::: CHECKING element %d ('%s'), '%s', dir %d [(%d -> %d, %d), %d => %d]\n",
                 i, element_info[i].token_name,
-                element_action_info[act].suffix, move_dir);
+                element_action_info[act].suffix, move_dir,
+                g->swap_double_tiles,
+                swap_movement_tiles_never,
+                swap_movement_tiles_always,
+                swap_movement_tiles_autodetected,
+                swap_movement_tiles);
 #endif
 
          /* swap frontside and backside graphic tile coordinates, if needed */
-         if (!frames_are_ordered_diagonally &&
-             ((move_dir == MV_BIT_LEFT  && !front_is_left_or_upper) ||
-              (move_dir == MV_BIT_RIGHT && front_is_left_or_upper) ||
-              (move_dir == MV_BIT_UP    && !front_is_left_or_upper) ||
-              (move_dir == MV_BIT_DOWN  && front_is_left_or_upper)))
+         if (swap_movement_tiles_always || swap_movement_tiles_autodetected)
          {
            /* get current (wrong) backside tile coordinates */
            getGraphicSourceExt(graphic, 0, &dummy, &src_x_back, &src_y_back,
@@ -677,6 +699,9 @@ void InitElementGraphicInfo()
            g->offset2_x *= -1;
            g->offset2_y *= -1;
 
+           /* do not swap front and backside tiles again after correction */
+           g->swap_double_tiles = 0;
+
 #if 0
            printf("    CORRECTED\n");
 #endif
@@ -697,8 +722,14 @@ void InitElementGraphicInfo()
 
     if (default_graphic == -1)
       default_graphic = IMG_UNKNOWN;
+#if 1
+    if (default_crumbled == -1)
+      default_crumbled = default_graphic;
+#else
+    /* !!! THIS LOOKS CRAPPY FOR SAND ETC. WITHOUT CRUMBLED GRAPHICS !!! */
     if (default_crumbled == -1)
       default_crumbled = IMG_EMPTY;
+#endif
 
     for (dir = 0; dir < NUM_DIRECTIONS; dir++)
     {
@@ -709,8 +740,14 @@ void InitElementGraphicInfo()
 
       if (default_direction_graphic[dir] == -1)
        default_direction_graphic[dir] = default_graphic;
+#if 1
+      if (default_direction_crumbled[dir] == -1)
+       default_direction_crumbled[dir] = default_direction_graphic[dir];
+#else
+      /* !!! THIS LOOKS CRAPPY FOR SAND ETC. WITHOUT CRUMBLED GRAPHICS !!! */
       if (default_direction_crumbled[dir] == -1)
        default_direction_crumbled[dir] = default_crumbled;
+#endif
     }
 
     for (act = 0; act < NUM_ACTIONS; act++)
@@ -726,6 +763,10 @@ void InitElementGraphicInfo()
       /* generic default action graphic (defined by "[default]" directive) */
       int default_action_graphic = element_info[EL_DEFAULT].graphic[act];
       int default_action_crumbled = element_info[EL_DEFAULT].crumbled[act];
+      int default_remove_graphic = IMG_EMPTY;
+
+      if (act_remove && default_action_graphic != -1)
+       default_remove_graphic = default_action_graphic;
 
       /* look for special default action graphic (classic game specific) */
       if (IS_BD_ELEMENT(i) && element_info[EL_BD_DEFAULT].graphic[act] != -1)
@@ -754,48 +795,81 @@ void InitElementGraphicInfo()
 
       if (default_action_graphic == -1)
        default_action_graphic = default_graphic;
+#if 1
+      if (default_action_crumbled == -1)
+       default_action_crumbled = default_action_graphic;
+#else
+      /* !!! THIS LOOKS CRAPPY FOR SAND ETC. WITHOUT CRUMBLED GRAPHICS !!! */
       if (default_action_crumbled == -1)
        default_action_crumbled = default_crumbled;
+#endif
 
       for (dir = 0; dir < NUM_DIRECTIONS; dir++)
       {
+       /* use action graphic as the default direction graphic, if undefined */
        int default_action_direction_graphic = element_info[i].graphic[act];
        int default_action_direction_crumbled = element_info[i].crumbled[act];
 
        /* no graphic for current action -- use default direction graphic */
-       /* !!! maybe it's better to use default _action_ graphic here !!! */
        if (default_action_direction_graphic == -1)
          default_action_direction_graphic =
-           (act_remove ? IMG_EMPTY :
+           (act_remove ? default_remove_graphic :
             act_turning ?
             element_info[i].direction_graphic[ACTION_TURNING][dir] :
+            default_action_graphic != default_graphic ?
+            default_action_graphic :
             default_direction_graphic[dir]);
+
+       if (element_info[i].direction_graphic[act][dir] == -1)
+         element_info[i].direction_graphic[act][dir] =
+           default_action_direction_graphic;
+
+#if 1
        if (default_action_direction_crumbled == -1)
          default_action_direction_crumbled =
-           (act_remove ? IMG_EMPTY :
+           element_info[i].direction_graphic[act][dir];
+#else
+       if (default_action_direction_crumbled == -1)
+         default_action_direction_crumbled =
+           (act_remove ? default_remove_graphic :
             act_turning ?
             element_info[i].direction_crumbled[ACTION_TURNING][dir] :
+            default_action_crumbled != default_crumbled ?
+            default_action_crumbled :
             default_direction_crumbled[dir]);
+#endif
 
-       if (element_info[i].direction_graphic[act][dir] == -1)
-         element_info[i].direction_graphic[act][dir] =
-           default_action_direction_graphic;
        if (element_info[i].direction_crumbled[act][dir] == -1)
          element_info[i].direction_crumbled[act][dir] =
            default_action_direction_crumbled;
+
+#if 0
+       if (i == EL_EMC_GRASS &&
+           act == ACTION_DIGGING &&
+           dir == MV_BIT_DOWN)
+         printf("::: direction_crumbled == %d, %d, %d\n",
+                element_info[i].direction_crumbled[act][dir],
+                default_action_direction_crumbled,
+                element_info[i].crumbled[act]);
+#endif
       }
 
       /* no graphic for this specific action -- use default action graphic */
       if (element_info[i].graphic[act] == -1)
        element_info[i].graphic[act] =
-         (act_remove ? IMG_EMPTY :
+         (act_remove ? default_remove_graphic :
           act_turning ? element_info[i].graphic[ACTION_TURNING] :
           default_action_graphic);
+#if 1
+      if (element_info[i].crumbled[act] == -1)
+       element_info[i].crumbled[act] = element_info[i].graphic[act];
+#else
       if (element_info[i].crumbled[act] == -1)
        element_info[i].crumbled[act] =
-         (act_remove ? IMG_EMPTY :
+         (act_remove ? default_remove_graphic :
           act_turning ? element_info[i].crumbled[ACTION_TURNING] :
           default_action_crumbled);
+#endif
     }
   }
 
@@ -958,6 +1032,7 @@ static void set_graphic_parameters(int graphic, int graphic_copy_from)
   graphic_info[graphic].offset_y = 0;  /* ... will be corrected later */
   graphic_info[graphic].offset2_x = 0; /* one or both of these values ... */
   graphic_info[graphic].offset2_y = 0; /* ... will be corrected later */
+  graphic_info[graphic].swap_double_tiles = -1;        /* auto-detect tile swapping */
   graphic_info[graphic].crumbled_like = -1;    /* do not use clone element */
   graphic_info[graphic].diggable_like = -1;    /* do not use clone element */
   graphic_info[graphic].border_size = TILEX / 8;  /* "CRUMBLED" border size */
@@ -1045,6 +1120,10 @@ static void set_graphic_parameters(int graphic, int graphic_copy_from)
   if (parameter[GFX_ARG_2ND_YOFFSET] != ARG_UNDEFINED_VALUE)
     graphic_info[graphic].offset2_y = parameter[GFX_ARG_2ND_YOFFSET];
 
+  /* optionally, the second movement tile can be specified as start tile */
+  if (parameter[GFX_ARG_2ND_SWAP_TILES] != ARG_UNDEFINED_VALUE)
+    graphic_info[graphic].swap_double_tiles= parameter[GFX_ARG_2ND_SWAP_TILES];
+
   /* automatically determine correct number of frames, if not defined */
   if (parameter[GFX_ARG_FRAMES] != ARG_UNDEFINED_VALUE)
     graphic_info[graphic].anim_frames = parameter[GFX_ARG_FRAMES];
@@ -1246,7 +1325,7 @@ static void InitGraphicInfo()
     }
 
 #if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
-    /* currently we need only a tile clip mask from the first frame */
+    /* currently we only need a tile clip mask from the first frame */
     getGraphicSource(i, first_frame, &src_bitmap, &src_x, &src_y);
 
     if (copy_clipmask_gc == None)
@@ -3790,8 +3869,15 @@ void InitElementPropertiesEngine(int engine_version)
        SET_PROPERTY(i, EP_CAN_CHANGE, TRUE);
 
     /* ---------- GFX_CRUMBLED --------------------------------------------- */
+#if 1
+    SET_PROPERTY(i, EP_GFX_CRUMBLED,
+                element_info[i].crumbled[ACTION_DEFAULT] !=
+                element_info[i].graphic[ACTION_DEFAULT]);
+#else
+    /* !!! THIS LOOKS CRAPPY FOR SAND ETC. WITHOUT CRUMBLED GRAPHICS !!! */
     SET_PROPERTY(i, EP_GFX_CRUMBLED,
                 element_info[i].crumbled[ACTION_DEFAULT] != IMG_EMPTY);
+#endif
   }
 
 #if 0