rnd-20050202-1-src
[rocksndiamonds.git] / src / tools.c
index 15841b17a993c0c85060d5d0ab64fd5203bb3801..794de36ea7f860ad80e9e5c06cd3f3767ec9f79b 100644 (file)
@@ -1509,7 +1509,7 @@ static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
 {
   int x, y;
 
-  DrawBackground(xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
+  DrawBackground(xpos, ypos, MICROLEVEL_XSIZE, MICROLEVEL_YSIZE);
 
   if (lev_fieldx < STD_LEV_FIELDX)
     xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
@@ -1540,10 +1540,12 @@ static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
 
 #define MICROLABEL_EMPTY               0
 #define MICROLABEL_LEVEL_NAME          1
-#define MICROLABEL_CREATED_BY          2
+#define MICROLABEL_LEVEL_AUTHOR_HEAD   2
 #define MICROLABEL_LEVEL_AUTHOR                3
-#define MICROLABEL_IMPORTED_FROM       4
-#define MICROLABEL_LEVEL_IMPORT_INFO   5
+#define MICROLABEL_IMPORTED_FROM_HEAD  4
+#define MICROLABEL_IMPORTED_FROM       5
+#define MICROLABEL_IMPORTED_BY_HEAD    6
+#define MICROLABEL_IMPORTED_BY         7
 
 static void DrawMicroLevelLabelExt(int mode)
 {
@@ -1551,26 +1553,30 @@ static void DrawMicroLevelLabelExt(int mode)
   int max_len_label_text;
   int font_nr = FONT_TEXT_2;
 
-  if (mode == MICROLABEL_CREATED_BY || mode == MICROLABEL_IMPORTED_FROM)
+  if (mode == MICROLABEL_LEVEL_AUTHOR_HEAD ||
+      mode == MICROLABEL_IMPORTED_FROM_HEAD ||
+      mode == MICROLABEL_IMPORTED_BY_HEAD)
     font_nr = FONT_TEXT_3;
 
   max_len_label_text = SXSIZE / getFontWidth(font_nr);
 
-  DrawBackground(SX, MICROLABEL_YPOS, SXSIZE, getFontHeight(font_nr));
+  DrawBackground(SX, MICROLABEL2_YPOS, SXSIZE, getFontHeight(font_nr));
 
-  strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name :
-                      mode == MICROLABEL_CREATED_BY ? "created by" :
-                      mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
-                      mode == MICROLABEL_IMPORTED_FROM ? "imported from" :
-                      mode == MICROLABEL_LEVEL_IMPORT_INFO ?
-                      leveldir_current->imported_from : ""),
+  strncpy(label_text,
+         (mode == MICROLABEL_LEVEL_NAME ? level.name :
+          mode == MICROLABEL_LEVEL_AUTHOR_HEAD ? "created by" :
+          mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
+          mode == MICROLABEL_IMPORTED_FROM_HEAD ? "imported from" :
+          mode == MICROLABEL_IMPORTED_FROM ? leveldir_current->imported_from :
+          mode == MICROLABEL_IMPORTED_BY_HEAD ? "imported by" :
+          mode == MICROLABEL_IMPORTED_BY ? leveldir_current->imported_by :""),
          max_len_label_text);
   label_text[max_len_label_text] = '\0';
 
   if (strlen(label_text) > 0)
   {
     int lxpos = SX + (SXSIZE - getTextWidth(label_text, font_nr)) / 2;
-    int lypos = MICROLABEL_YPOS;
+    int lypos = MICROLABEL2_YPOS;
 
     DrawText(lxpos, lypos, label_text, font_nr);
   }
@@ -1605,11 +1611,18 @@ void DrawMicroLevel(int xpos, int ypos, boolean restart)
 
     if (leveldir_current->name)
     {
-      int text_width = getTextWidth(leveldir_current->name, FONT_TEXT_1);
-      int lxpos = SX + (SXSIZE - text_width) / 2;
-      int lypos = SY + 352;
+      char label_text[MAX_OUTPUT_LINESIZE + 1];
+      int font_nr = FONT_TEXT_1;
+      int max_len_label_text = SXSIZE / getFontWidth(font_nr);
+      int lxpos, lypos;
 
-      DrawText(lxpos, lypos, leveldir_current->name, FONT_TEXT_1);
+      strncpy(label_text, leveldir_current->name, max_len_label_text);
+      label_text[max_len_label_text] = '\0';
+
+      lxpos = SX + (SXSIZE - getTextWidth(label_text, font_nr)) / 2;
+      lypos = SY + MICROLABEL1_YPOS;
+
+      DrawText(lxpos, lypos, label_text, font_nr);
     }
 
     game_status = last_game_status;    /* restore current game status */
@@ -1658,6 +1671,7 @@ void DrawMicroLevel(int xpos, int ypos, boolean restart)
     DrawMicroLevelExt(xpos, ypos, from_x, from_y);
   }
 
+  /* !!! THIS ALL SUCKS -- SHOULD BE CLEANLY REWRITTEN !!! */
   /* redraw micro level label, if needed */
   if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 &&
       strcmp(level.author, ANONYMOUS_NAME) != 0 &&
@@ -1668,18 +1682,31 @@ void DrawMicroLevel(int xpos, int ypos, boolean restart)
 
     if (leveldir_current->imported_from != NULL)
       max_label_counter += 14;
+    if (leveldir_current->imported_by != NULL)
+      max_label_counter += 14;
 
     label_counter = (label_counter + 1) % max_label_counter;
     label_state = (label_counter >= 0 && label_counter <= 7 ?
                   MICROLABEL_LEVEL_NAME :
                   label_counter >= 9 && label_counter <= 12 ?
-                  MICROLABEL_CREATED_BY :
+                  MICROLABEL_LEVEL_AUTHOR_HEAD :
                   label_counter >= 14 && label_counter <= 21 ?
                   MICROLABEL_LEVEL_AUTHOR :
                   label_counter >= 23 && label_counter <= 26 ?
-                  MICROLABEL_IMPORTED_FROM :
+                  MICROLABEL_IMPORTED_FROM_HEAD :
                   label_counter >= 28 && label_counter <= 35 ?
-                  MICROLABEL_LEVEL_IMPORT_INFO : MICROLABEL_EMPTY);
+                  MICROLABEL_IMPORTED_FROM :
+                  label_counter >= 37 && label_counter <= 40 ?
+                  MICROLABEL_IMPORTED_BY_HEAD :
+                  label_counter >= 42 && label_counter <= 49 ?
+                  MICROLABEL_IMPORTED_BY : MICROLABEL_EMPTY);
+
+    if (leveldir_current->imported_from == NULL &&
+       (label_state == MICROLABEL_IMPORTED_FROM_HEAD ||
+        label_state == MICROLABEL_IMPORTED_FROM))
+      label_state = (label_state == MICROLABEL_IMPORTED_FROM_HEAD ?
+                    MICROLABEL_IMPORTED_BY_HEAD : MICROLABEL_IMPORTED_BY);
+
     DrawMicroLevelLabelExt(label_state);
   }
 
@@ -3975,19 +4002,19 @@ em_object_mapping_list[] =
   },
   {
     Ykey_5_eat,                                FALSE,  FALSE,
-    EL_EM_KEY_5,                       ACTION_COLLECTING, -1
+    EL_EMC_KEY_5,                      ACTION_COLLECTING, -1
   },
   {
     Ykey_6_eat,                                FALSE,  FALSE,
-    EL_EM_KEY_6,                       ACTION_COLLECTING, -1
+    EL_EMC_KEY_6,                      ACTION_COLLECTING, -1
   },
   {
     Ykey_7_eat,                                FALSE,  FALSE,
-    EL_EM_KEY_7,                       ACTION_COLLECTING, -1
+    EL_EMC_KEY_7,                      ACTION_COLLECTING, -1
   },
   {
     Ykey_8_eat,                                FALSE,  FALSE,
-    EL_EM_KEY_8,                       ACTION_COLLECTING, -1
+    EL_EMC_KEY_8,                      ACTION_COLLECTING, -1
   },
   {
     Ylenses_eat,                       FALSE,  FALSE,
@@ -4079,19 +4106,19 @@ em_object_mapping_list[] =
   },
   {
     Xdoor_5,                           TRUE,   FALSE,
-    EL_EM_GATE_5,                      -1, -1
+    EL_EMC_GATE_5,                     -1, -1
   },
   {
     Xdoor_6,                           TRUE,   FALSE,
-    EL_EM_GATE_6,                      -1, -1
+    EL_EMC_GATE_6,                     -1, -1
   },
   {
     Xdoor_7,                           TRUE,   FALSE,
-    EL_EM_GATE_7,                      -1, -1
+    EL_EMC_GATE_7,                     -1, -1
   },
   {
     Xdoor_8,                           TRUE,   FALSE,
-    EL_EM_GATE_8,                      -1, -1
+    EL_EMC_GATE_8,                     -1, -1
   },
   {
     Xkey_1,                            TRUE,   FALSE,
@@ -4111,19 +4138,19 @@ em_object_mapping_list[] =
   },
   {
     Xkey_5,                            TRUE,   FALSE,
-    EL_EM_KEY_5,                       -1, -1
+    EL_EMC_KEY_5,                      -1, -1
   },
   {
     Xkey_6,                            TRUE,   FALSE,
-    EL_EM_KEY_6,                       -1, -1
+    EL_EMC_KEY_6,                      -1, -1
   },
   {
     Xkey_7,                            TRUE,   FALSE,
-    EL_EM_KEY_7,                       -1, -1
+    EL_EMC_KEY_7,                      -1, -1
   },
   {
     Xkey_8,                            TRUE,   FALSE,
-    EL_EM_KEY_8,                       -1, -1
+    EL_EMC_KEY_8,                      -1, -1
   },
   {
     Xwind_n,                           TRUE,   FALSE,
@@ -4335,19 +4362,51 @@ em_object_mapping_list[] =
   },
   {
     Xfake_door_5,                      TRUE,   FALSE,
-    EL_EM_GATE_5_GRAY,                 -1, -1
+    EL_EMC_GATE_5_GRAY,                        -1, -1
   },
   {
     Xfake_door_6,                      TRUE,   FALSE,
-    EL_EM_GATE_6_GRAY,                 -1, -1
+    EL_EMC_GATE_6_GRAY,                        -1, -1
   },
   {
     Xfake_door_7,                      TRUE,   FALSE,
-    EL_EM_GATE_7_GRAY,                 -1, -1
+    EL_EMC_GATE_7_GRAY,                        -1, -1
   },
   {
     Xfake_door_8,                      TRUE,   FALSE,
-    EL_EM_GATE_8_GRAY,                 -1, -1
+    EL_EMC_GATE_8_GRAY,                        -1, -1
+  },
+  {
+    Xfake_acid_1,                      TRUE,   FALSE,
+    EL_EMC_FAKE_ACID,                  -1, -1
+  },
+  {
+    Xfake_acid_2,                      FALSE,  FALSE,
+    EL_EMC_FAKE_ACID,                  -1, -1
+  },
+  {
+    Xfake_acid_3,                      FALSE,  FALSE,
+    EL_EMC_FAKE_ACID,                  -1, -1
+  },
+  {
+    Xfake_acid_4,                      FALSE,  FALSE,
+    EL_EMC_FAKE_ACID,                  -1, -1
+  },
+  {
+    Xfake_acid_5,                      FALSE,  FALSE,
+    EL_EMC_FAKE_ACID,                  -1, -1
+  },
+  {
+    Xfake_acid_6,                      FALSE,  FALSE,
+    EL_EMC_FAKE_ACID,                  -1, -1
+  },
+  {
+    Xfake_acid_7,                      FALSE,  FALSE,
+    EL_EMC_FAKE_ACID,                  -1, -1
+  },
+  {
+    Xfake_acid_8,                      FALSE,  FALSE,
+    EL_EMC_FAKE_ACID,                  -1, -1
   },
   {
     Xsteel_1,                          TRUE,   FALSE,
@@ -5798,6 +5857,14 @@ void InitGraphicInfo_EM(void)
                        i == Xacid_6 ? 50 :
                        i == Xacid_7 ? 60 :
                        i == Xacid_8 ? 70 :
+                       i == Xfake_acid_1 ? 0 :
+                       i == Xfake_acid_2 ? 10 :
+                       i == Xfake_acid_3 ? 20 :
+                       i == Xfake_acid_4 ? 30 :
+                       i == Xfake_acid_5 ? 40 :
+                       i == Xfake_acid_6 ? 50 :
+                       i == Xfake_acid_7 ? 60 :
+                       i == Xfake_acid_8 ? 70 :
                        i == Xball_2 ? 7 :
                        i == Xball_2B ? j + 8 :
                        i == Yball_eat ? j + 1 :
@@ -5907,11 +5974,13 @@ void InitGraphicInfo_EM(void)
       g_em->width  = TILEX;
       g_em->height = TILEY;
 
-      g_em->has_crumbled_graphics = FALSE;
       g_em->crumbled_bitmap = NULL;
       g_em->crumbled_src_x = 0;
       g_em->crumbled_src_y = 0;
       g_em->crumbled_border_size = 0;
+
+      g_em->has_crumbled_graphics = FALSE;
+      g_em->preserve_background = FALSE;
 #endif
 
 #if 0
@@ -5950,42 +6019,116 @@ void InitGraphicInfo_EM(void)
          (effective_action == ACTION_FALLING ? MV_DOWN : direction);
        int dx = (move_dir == MV_LEFT ? -1 : move_dir == MV_RIGHT ? 1 : 0);
        int dy = (move_dir == MV_UP   ? -1 : move_dir == MV_DOWN  ? 1 : 0);
-       int cx = ABS(dx) * TILEX / 8;
-       int cy = ABS(dy) * TILEY / 8;
+       int num_steps = (i == Ydrip_s1 ||
+                        i == Ydrip_s1B ||
+                        i == Ydrip_s2 ||
+                        i == Ydrip_s2B ? 16 : 8);
+       int cx = ABS(dx) * (TILEX / num_steps);
+       int cy = ABS(dy) * (TILEY / num_steps);
+       int step_frame = (i == Ydrip_s2 ||
+                         i == Ydrip_s2B ? j + 8 : j) + 1;
+       int step = (is_backside ? step_frame : num_steps - step_frame);
 
        if (is_backside)        /* tile where movement starts */
        {
          if (dx < 0 || dy < 0)
          {
-           g_em->src_offset_x = cx * (j + 1);
-           g_em->src_offset_y = cy * (j + 1);
+           g_em->src_offset_x = cx * step;
+           g_em->src_offset_y = cy * step;
          }
          else
          {
-           g_em->dst_offset_x = cx * (j + 1);
-           g_em->dst_offset_y = cy * (j + 1);
+           g_em->dst_offset_x = cx * step;
+           g_em->dst_offset_y = cy * step;
          }
-
-         g_em->width  = TILEX - cx * (j + 1);
-         g_em->height = TILEY - cy * (j + 1);
        }
        else                    /* tile where movement ends */
        {
          if (dx < 0 || dy < 0)
          {
-           g_em->dst_offset_x = cx * (7 - j);
-           g_em->dst_offset_y = cy * (7 - j);
+           g_em->dst_offset_x = cx * step;
+           g_em->dst_offset_y = cy * step;
          }
          else
          {
-           g_em->src_offset_x = cx * (7 - j);
-           g_em->src_offset_y = cy * (7 - j);
+           g_em->src_offset_x = cx * step;
+           g_em->src_offset_y = cy * step;
          }
+       }
+
+       g_em->width  = TILEX - cx * step;
+       g_em->height = TILEY - cy * step;
+      }
+
+#if 0
+      if (effective_action == ACTION_SMASHED_BY_ROCK &&
+         element_info[effective_element].graphic[effective_action] ==
+         element_info[effective_element].graphic[ACTION_DEFAULT])
+      {
+       int move_dir = MV_DOWN;
+       int dx = (move_dir == MV_LEFT ? -1 : move_dir == MV_RIGHT ? 1 : 0);
+       int dy = (move_dir == MV_UP   ? -1 : move_dir == MV_DOWN  ? 1 : 0);
+       int num_steps = 8;
+       int cx = ABS(dx) * (TILEX / num_steps);
+       int cy = ABS(dy) * (TILEY / num_steps);
+       int step_frame = j + 1;
+       int step = (is_backside ? step_frame : num_steps - step_frame);
+
+       graphic = (el_act_dir2img(EL_ROCK, ACTION_FALLING, MV_DOWN));
+       g = &graphic_info[graphic];
+       sync_frame = j;
+       frame = getAnimationFrame(g->anim_frames,
+                                 g->anim_delay,
+                                 g->anim_mode,
+                                 g->anim_start_frame,
+                                 sync_frame);
+       getGraphicSourceExt(graphic, frame, &src_bitmap, &src_x, &src_y,
+                           g->double_movement && is_backside);
+
+       g_em->bitmap = src_bitmap;
+       g_em->src_x = src_x;
+       g_em->src_y = src_y;
+       g_em->src_offset_x = 0;
+       g_em->src_offset_y = 0;
+       g_em->dst_offset_x = 0;
+       g_em->dst_offset_y = 0;
 
-         g_em->width  = TILEX - cx * (7 - j);
-         g_em->height = TILEY - cy * (7 - j);
+       if (is_backside)        /* tile where movement starts */
+       {
+         if (dx < 0 || dy < 0)
+         {
+           g_em->src_offset_x = cx * step;
+           g_em->src_offset_y = cy * step;
+         }
+         else
+         {
+           g_em->dst_offset_x = cx * step;
+           g_em->dst_offset_y = cy * step;
+         }
        }
+       else                    /* tile where movement ends */
+       {
+         if (dx < 0 || dy < 0)
+         {
+           g_em->dst_offset_x = cx * step;
+           g_em->dst_offset_y = cy * step;
+         }
+         else
+         {
+           g_em->src_offset_x = cx * step;
+           g_em->src_offset_y = cy * step;
+         }
+       }
+
+       g_em->width  = TILEX - cx * step;
+       g_em->height = TILEY - cy * step;
+
+#if 0
+       printf("::: -> '%s'\n", element_info[effective_element].token_name);
+#endif
       }
+#endif
+
 #endif
 
       /* create unique graphic identifier to decide if tile must be redrawn */
@@ -6059,6 +6202,38 @@ void InitGraphicInfo_EM(void)
     }
   }
 
+#if 1
+  for (i = 0; i < TILE_MAX; i++)
+  {
+    for (j = 0; j < 8; j++)
+    {
+      int element = object_mapping[i].element_rnd;
+      int action = object_mapping[i].action;
+
+      if (action == ACTION_SMASHED_BY_ROCK &&
+         element_info[element].graphic[action] ==
+         element_info[element].graphic[ACTION_DEFAULT])
+      {
+       /* no separate animation for "smashed by rock" -- use rock instead */
+       struct GraphicInfo_EM *g_em = &graphic_info_em_object[i][7 - j];
+       struct GraphicInfo_EM *g_xx = &graphic_info_em_object[Ystone_s][7 - j];
+
+       g_em->bitmap            = g_xx->bitmap;
+       g_em->src_x             = g_xx->src_x;
+       g_em->src_y             = g_xx->src_y;
+       g_em->src_offset_x      = g_xx->src_offset_x;
+       g_em->src_offset_y      = g_xx->src_offset_y;
+       g_em->dst_offset_x      = g_xx->dst_offset_x;
+       g_em->dst_offset_y      = g_xx->dst_offset_y;
+       g_em->width             = g_xx->width;
+       g_em->height            = g_xx->height;
+
+       g_em->preserve_background = TRUE;
+      }
+    }
+  }
+#endif
+
   for (p = 0; p < 2; p++)
   {
     for (i = 0; i < SPR_MAX; i++)