rnd-20041124-1-src
[rocksndiamonds.git] / src / init.c
index 18eab0224ee040bd2f25189700dfea9eea29b5c2..b02d08838168225d8a80c012f2a72a0eb2f1d59b 100644 (file)
@@ -258,12 +258,19 @@ void InitElementSmallImages()
   for (i = 0; element_to_special_graphic[i].element > -1; i++)
     InitElementSmallImagesScaledUp(element_to_special_graphic[i].graphic);
 
-  /* initialize images from dynamic configuration */
+  /* initialize images from dynamic configuration (may be elements or other) */
+#if 1
+  for (i = 0; i < num_property_mappings; i++)
+    InitElementSmallImagesScaledUp(property_mapping[i].artwork_index);
+#else
+  /* !!! THIS DOES NOT WORK -- "artwork_index" is graphic, not element !!! */
+  /* !!! ALSO, non-element graphics might need scaling-up !!! */
   for (i = 0; i < num_property_mappings; i++)
     if (property_mapping[i].artwork_index < MAX_NUM_ELEMENTS)
       InitElementSmallImagesScaledUp(property_mapping[i].artwork_index);
+#endif
 
-#if 1
+#if 0
   /* !!! FIX THIS (CHANGE TO USING NORMAL ELEMENT GRAPHIC DEFINITIONS) !!! */
   for (i = IMG_EMC_OBJECT; i <= IMG_EMC_SPRITE; i++)
     InitElementSmallImagesScaledUp(i);
@@ -468,8 +475,10 @@ void InitElementGraphicInfo()
     if ((action > -1 || direction > -1 || crumbled == TRUE) &&
        base_graphic != -1)
     {
-      boolean base_redefined = getImageListEntry(base_graphic)->redefined;
-      boolean act_dir_redefined = getImageListEntry(graphic)->redefined;
+      boolean base_redefined =
+       getImageListEntryFromImageID(base_graphic)->redefined;
+      boolean act_dir_redefined =
+       getImageListEntryFromImageID(graphic)->redefined;
 
       /* if the base graphic ("emerald", for example) has been redefined,
         but not the action graphic ("emerald.falling", for example), do not
@@ -615,6 +624,69 @@ void InitElementGraphicInfo()
   }
 #endif
 
+#if 1
+  /* adjust graphics with 2nd tile for movement according to direction
+     (do this before correcting '-1' values to minimize calculations) */
+  for (i = 0; i < MAX_NUM_ELEMENTS; i++)
+  {
+    for (act = 0; act < NUM_ACTIONS; act++)
+    {
+      for (dir = 0; dir < NUM_DIRECTIONS; dir++)
+      {
+       int graphic = element_info[i].direction_graphic[act][dir];
+       int move_dir = (act == ACTION_FALLING ? MV_BIT_DOWN : dir);
+
+       if (act == ACTION_FALLING)      /* special case */
+         graphic = element_info[i].graphic[act];
+
+       if (graphic != -1 && graphic_info[graphic].double_movement)
+       {
+         struct GraphicInfo *g = &graphic_info[graphic];
+         int src_x_front = g->src_x;
+         int src_y_front = g->src_y;
+         int src_x_back = g->src_x + g->offset2_x;
+         int src_y_back = g->src_y + g->offset2_y;
+         boolean frames_are_ordered_diagonally = (g->offset_x != 0 &&
+                                                  g->offset_y != 0);
+         boolean front_is_left_or_upper = (src_x_front < src_x_back ||
+                                           src_y_front < src_y_back);
+         Bitmap *dummy;
+
+#if 0
+         printf("::: CHECKING ELEMENT %d ('%s'), ACTION '%s', DIRECTION %d\n",
+                i, element_info[i].token_name,
+                element_action_info[act].suffix, move_dir);
+#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)))
+         {
+           /* get current (wrong) backside tile coordinates */
+           getGraphicSourceExt(graphic, 0, &dummy, &src_x_back, &src_y_back,
+                               TRUE);
+
+           /* set frontside tile coordinates to backside tile coordinates */
+           g->src_x = src_x_back;
+           g->src_y = src_y_back;
+
+           /* invert tile offset to point to new backside tile coordinates */
+           g->offset2_x *= -1;
+           g->offset2_y *= -1;
+
+#if 0
+           printf("    CORRECTED\n");
+#endif
+         }
+       }
+      }
+    }
+  }
+#endif
+
   /* now set all '-1' values to element specific default values */
   for (i = 0; i < MAX_NUM_ELEMENTS; i++)
   {
@@ -691,6 +763,7 @@ void InitElementGraphicInfo()
        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 :
@@ -787,8 +860,10 @@ void InitElementSpecialGraphicInfo()
     int special = element_to_special_graphic[i].special;
     int graphic = element_to_special_graphic[i].graphic;
     int base_graphic = el2baseimg(element);
-    boolean base_redefined = getImageListEntry(base_graphic)->redefined;
-    boolean special_redefined = getImageListEntry(graphic)->redefined;
+    boolean base_redefined =
+      getImageListEntryFromImageID(base_graphic)->redefined;
+    boolean special_redefined =
+      getImageListEntryFromImageID(graphic)->redefined;
 
     /* if the base graphic ("emerald", for example) has been redefined,
        but not the special graphic ("emerald.EDITOR", for example), do not
@@ -835,9 +910,27 @@ static int get_element_from_token(char *token)
   return -1;
 }
 
-static void set_graphic_parameters(int graphic, char **parameter_raw)
+static int get_scaled_graphic_width(int graphic)
+{
+  int original_width = getOriginalImageWidthFromImageID(graphic);
+  int scale_up_factor = graphic_info[graphic].scale_up_factor;
+
+  return original_width * scale_up_factor;
+}
+
+static int get_scaled_graphic_height(int graphic)
 {
-  Bitmap *src_bitmap = getBitmapFromImageID(graphic);
+  int original_height = getOriginalImageHeightFromImageID(graphic);
+  int scale_up_factor = graphic_info[graphic].scale_up_factor;
+
+  return original_height * scale_up_factor;
+}
+
+static void set_graphic_parameters(int graphic, int graphic_copy_from)
+{
+  struct FileInfo *image = getImageListEntryFromImageID(graphic_copy_from);
+  char **parameter_raw = image->parameter;
+  Bitmap *src_bitmap = getBitmapFromImageID(graphic_copy_from);
   int parameter[NUM_GFX_ARGS];
   int anim_frames_per_row = 1, anim_frames_per_col = 1;
   int anim_frames_per_line = 1;
@@ -863,6 +956,8 @@ static void set_graphic_parameters(int graphic, char **parameter_raw)
   graphic_info[graphic].height = TILEY;
   graphic_info[graphic].offset_x = 0;  /* one or both of these values ... */
   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].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 */
@@ -898,10 +993,9 @@ static void set_graphic_parameters(int graphic, char **parameter_raw)
 
   if (src_bitmap)
   {
-    /* bitmap is not scaled at this stage, so calculate final size */
-    int scale_up_factor = graphic_info[graphic].scale_up_factor;
-    int src_bitmap_width  = src_bitmap->width  * scale_up_factor;
-    int src_bitmap_height = src_bitmap->height * scale_up_factor;
+    /* get final bitmap size (with scaling, but without small images) */
+    int src_bitmap_width  = get_scaled_graphic_width(graphic);
+    int src_bitmap_height = get_scaled_graphic_height(graphic);
 
     anim_frames_per_row = src_bitmap_width  / graphic_info[graphic].width;
     anim_frames_per_col = src_bitmap_height / graphic_info[graphic].height;
@@ -929,6 +1023,28 @@ static void set_graphic_parameters(int graphic, char **parameter_raw)
   if (parameter[GFX_ARG_YOFFSET] != ARG_UNDEFINED_VALUE)
     graphic_info[graphic].offset_y = parameter[GFX_ARG_YOFFSET];
 
+  /* optionally, moving animations may have separate start and end graphics */
+  graphic_info[graphic].double_movement = parameter[GFX_ARG_2ND_MOVEMENT_TILE];
+
+  if (parameter[GFX_ARG_2ND_VERTICAL] == ARG_UNDEFINED_VALUE)
+    parameter[GFX_ARG_2ND_VERTICAL] = !parameter[GFX_ARG_VERTICAL];
+
+  /* correct x or y offset2 dependent of vertical or horizontal frame order */
+  if (parameter[GFX_ARG_2ND_VERTICAL]) /* frames are ordered vertically */
+    graphic_info[graphic].offset2_y =
+      (parameter[GFX_ARG_2ND_OFFSET] != ARG_UNDEFINED_VALUE ?
+       parameter[GFX_ARG_2ND_OFFSET] : graphic_info[graphic].height);
+  else                                 /* frames are ordered horizontally */
+    graphic_info[graphic].offset2_x =
+      (parameter[GFX_ARG_2ND_OFFSET] != ARG_UNDEFINED_VALUE ?
+       parameter[GFX_ARG_2ND_OFFSET] : graphic_info[graphic].width);
+
+  /* optionally, the x and y offset of 2nd graphic can be specified directly */
+  if (parameter[GFX_ARG_2ND_XOFFSET] != ARG_UNDEFINED_VALUE)
+    graphic_info[graphic].offset2_x = parameter[GFX_ARG_2ND_XOFFSET];
+  if (parameter[GFX_ARG_2ND_YOFFSET] != ARG_UNDEFINED_VALUE)
+    graphic_info[graphic].offset2_y = parameter[GFX_ARG_2ND_YOFFSET];
+
   /* 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];
@@ -1006,8 +1122,6 @@ static void set_graphic_parameters(int graphic, char **parameter_raw)
 static void InitGraphicInfo()
 {
   int fallback_graphic = IMG_CHAR_EXCLAM;
-  struct FileInfo *fallback_image = getImageListEntry(fallback_graphic);
-  Bitmap *fallback_bitmap = getBitmapFromImageID(fallback_graphic);
   int num_images = getImageListSize();
   int i;
 
@@ -1045,11 +1159,10 @@ static void InitGraphicInfo()
 
   for (i = 0; i < num_images; i++)
   {
-    struct FileInfo *image = getImageListEntry(i);
     Bitmap *src_bitmap;
     int src_x, src_y;
     int first_frame, last_frame;
-    int scale_up_factor, src_bitmap_width, src_bitmap_height;
+    int src_bitmap_width, src_bitmap_height;
 
 #if 0
     printf("::: image: '%s' [%d]\n", image->token, i);
@@ -1061,17 +1174,16 @@ static void InitGraphicInfo()
           getTokenFromImageID(i));
 #endif
 
-    set_graphic_parameters(i, image->parameter);
+    set_graphic_parameters(i, i);
 
     /* now check if no animation frames are outside of the loaded image */
 
     if (graphic_info[i].bitmap == NULL)
       continue;                /* skip check for optional images that are undefined */
 
-    /* bitmap is not scaled at this stage, so calculate final size */
-    scale_up_factor = graphic_info[i].scale_up_factor;
-    src_bitmap_width  = graphic_info[i].bitmap->width  * scale_up_factor;
-    src_bitmap_height = graphic_info[i].bitmap->height * scale_up_factor;
+    /* get final bitmap size (with scaling, but without small images) */
+    src_bitmap_width  = get_scaled_graphic_width(i);
+    src_bitmap_height = get_scaled_graphic_height(i);
 
     first_frame = 0;
     getGraphicSource(i, first_frame, &src_bitmap, &src_x, &src_y);
@@ -1102,8 +1214,7 @@ static void InitGraphicInfo()
       Error(ERR_RETURN, "fallback done to 'char_exclam' for this graphic");
       Error(ERR_RETURN_LINE, "-");
 
-      set_graphic_parameters(i, fallback_image->default_parameter);
-      graphic_info[i].bitmap = fallback_bitmap;
+      set_graphic_parameters(i, fallback_graphic);
     }
 
     last_frame = graphic_info[i].anim_frames - 1;
@@ -1131,8 +1242,7 @@ static void InitGraphicInfo()
       Error(ERR_RETURN, "fallback done to 'char_exclam' for this graphic");
       Error(ERR_RETURN_LINE, "-");
 
-      set_graphic_parameters(i, fallback_image->default_parameter);
-      graphic_info[i].bitmap = fallback_bitmap;
+      set_graphic_parameters(i, fallback_graphic);
     }
 
 #if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
@@ -1610,6 +1720,8 @@ static void ReinitializeGraphics()
   InitElementSmallImages();            /* scale images to all needed sizes */
   InitFontGraphicInfo();               /* initialize text drawing functions */
 
+  InitGraphicInfo_EM();                        /* graphic mapping for EM engine */
+
   SetMainBackgroundImage(IMG_BACKGROUND);
   SetDoorBackgroundImage(IMG_BACKGROUND_DOOR);