added functions for masked drawing of sized elements
[rocksndiamonds.git] / src / tools.c
index 151fd94b1f4baad0b403d3b5c72254d6fdb71f88..bfaad2acdd577f844c51428332857eed3b0a9b30 100644 (file)
@@ -360,10 +360,12 @@ static int getLevelFromScreenY_SP(int sy)
 
 static int getLevelFromScreenX_MM(int sx)
 {
+#if 0
   int level_xsize = level.native_mm_level->fieldx;
   int full_xsize = level_xsize * TILESIZE_VAR;
 
   sx -= (full_xsize < SXSIZE ? (SXSIZE - full_xsize) / 2 : 0);
+#endif
 
   int px = sx - SX;
   int lx = px / TILESIZE_VAR;
@@ -373,10 +375,12 @@ static int getLevelFromScreenX_MM(int sx)
 
 static int getLevelFromScreenY_MM(int sy)
 {
+#if 0
   int level_ysize = level.native_mm_level->fieldy;
   int full_ysize = level_ysize * TILESIZE_VAR;
 
   sy -= (full_ysize < SYSIZE ? (SYSIZE - full_ysize) / 2 : 0);
+#endif
 
   int py = sy - SY;
   int ly = py / TILESIZE_VAR;
@@ -412,6 +416,7 @@ void DumpTile(int x, int y)
 {
   int sx = SCREENX(x);
   int sy = SCREENY(y);
+  char *token_name;
 
   printf_line("-", 79);
   printf("Field Info: SCREEN(%d, %d), LEVEL(%d, %d)\n", sx, sy, x, y);
@@ -425,8 +430,9 @@ void DumpTile(int x, int y)
     return;
   }
 
-  printf("  Feld:        %d\t['%s']\n", Feld[x][y],
-        element_info[Feld[x][y]].token_name);
+  token_name = element_info[Feld[x][y]].token_name;
+
+  printf("  Feld:        %d\t['%s']\n", Feld[x][y], token_name);
   printf("  Back:        %s\n", print_if_not_empty(Back[x][y]));
   printf("  Store:       %s\n", print_if_not_empty(Store[x][y]));
   printf("  Store2:      %s\n", print_if_not_empty(Store2[x][y]));
@@ -1354,6 +1360,10 @@ void SetBorderElement()
 
   BorderElement = EL_EMPTY;
 
+  /* the MM game engine does not use a visible border element */
+  if (level.game_engine_type == GAME_ENGINE_TYPE_MM)
+    return;
+
   for (y = 0; y < lev_fieldy && BorderElement == EL_EMPTY; y++)
   {
     for (x = 0; x < lev_fieldx; x++)
@@ -1625,6 +1635,14 @@ void DrawSizedGraphic(int x, int y, int graphic, int frame, int tilesize)
   MarkTileDirty(x / tilesize, y / tilesize);
 }
 
+void DrawSizedGraphicThruMask(int x, int y, int graphic, int frame,
+                             int tilesize)
+{
+  DrawSizedGraphicThruMaskExt(drawto, SX + x * tilesize, SY + y * tilesize,
+                             graphic, frame, tilesize);
+  MarkTileDirty(x / tilesize, y / tilesize);
+}
+
 void DrawSizedGraphicExt(DrawBuffer *d, int x, int y, int graphic, int frame,
                         int tilesize)
 {
@@ -1635,6 +1653,16 @@ void DrawSizedGraphicExt(DrawBuffer *d, int x, int y, int graphic, int frame,
   BlitBitmap(src_bitmap, d, src_x, src_y, tilesize, tilesize, x, y);
 }
 
+void DrawSizedGraphicThruMaskExt(DrawBuffer *d, int x, int y, int graphic,
+                                int frame, int tilesize)
+{
+  Bitmap *src_bitmap;
+  int src_x, src_y;
+
+  getSizedGraphicSource(graphic, frame, tilesize, &src_bitmap, &src_x, &src_y);
+  BlitBitmapMasked(src_bitmap, d, src_x, src_y, tilesize, tilesize, x, y);
+}
+
 void DrawMiniGraphic(int x, int y, int graphic)
 {
   DrawMiniGraphicExt(drawto, SX + x * MINI_TILEX,SY + y * MINI_TILEY, graphic);
@@ -2446,12 +2474,77 @@ void DrawLevelField(int x, int y)
   }
 }
 
+static void DrawSizedWallExt_MM(int dst_x, int dst_y, int element, int tilesize,
+                               int (*el2img_function)(int), boolean masked)
+{
+  int element_base = map_mm_wall_element(element);
+  int element_bits = (IS_DF_WALL(element) ?
+                     element - EL_DF_WALL_START :
+                     element - EL_MM_WALL_START) & 0x000f;
+  int graphic = el2img_function(element_base);
+  int tilesize_draw = tilesize / 2;
+  Bitmap *src_bitmap;
+  int src_x, src_y;
+  int i;
+
+  getSizedGraphicSource(graphic, 0, tilesize_draw, &src_bitmap, &src_x, &src_y);
+
+  for (i = 0; i < 4; i++)
+  {
+    int dst_draw_x = dst_x + (i % 2) * tilesize_draw;
+    int dst_draw_y = dst_y + (i / 2) * tilesize_draw;
+
+    if (element_bits & (1 << i))
+    {
+      if (masked)
+       BlitBitmapMasked(src_bitmap, drawto, src_x, src_y,
+                        tilesize_draw, tilesize_draw, dst_draw_x, dst_draw_y);
+      else
+       BlitBitmap(src_bitmap, drawto, src_x, src_y,
+                  tilesize_draw, tilesize_draw, dst_draw_x, dst_draw_y);
+    }
+    else
+    {
+      if (!masked)
+       ClearRectangle(drawto, dst_draw_x, dst_draw_y,
+                      tilesize_draw, tilesize_draw);
+    }
+  }
+}
+
+void DrawSizedWall_MM(int dst_x, int dst_y, int element, int tilesize,
+                     int (*el2img_function)(int))
+{
+  DrawSizedWallExt_MM(dst_x, dst_y, element, tilesize, el2img_function, FALSE);
+}
+
+void DrawSizedElementExt(int x, int y, int element, int tilesize,
+                        boolean masked)
+{
+  if (IS_MM_WALL(element))
+  {
+    DrawSizedWallExt_MM(SX + x * tilesize, SY + y * tilesize,
+                       element, tilesize, el2edimg, masked);
+  }
+  else
+  {
+    int graphic = el2edimg(element);
+
+    if (masked)
+      DrawSizedGraphicThruMask(x, y, graphic, 0, tilesize);
+    else
+      DrawSizedGraphic(x, y, graphic, 0, tilesize);
+  }
+}
+
 void DrawSizedElement(int x, int y, int element, int tilesize)
 {
-  int graphic;
+  DrawSizedElementExt(x, y, element, tilesize, FALSE);
+}
 
-  graphic = el2edimg(element);
-  DrawSizedGraphic(x, y, graphic, 0, tilesize);
+void DrawSizedElementThruMask(int x, int y, int element, int tilesize)
+{
+  DrawSizedElementExt(x, y, element, tilesize, TRUE);
 }
 
 void DrawMiniElement(int x, int y, int element)
@@ -2961,12 +3054,20 @@ void ShowEnvelopeRequest(char *text, unsigned int req_state, int action)
 
 void DrawPreviewElement(int dst_x, int dst_y, int element, int tilesize)
 {
-  Bitmap *src_bitmap;
-  int src_x, src_y;
-  int graphic = el2preimg(element);
+  if (IS_MM_WALL(element))
+  {
+    DrawSizedWall_MM(dst_x, dst_y, element, tilesize, el2preimg);
+  }
+  else
+  {
+    Bitmap *src_bitmap;
+    int src_x, src_y;
+    int graphic = el2preimg(element);
 
-  getSizedGraphicSource(graphic, 0, tilesize, &src_bitmap, &src_x, &src_y);
-  BlitBitmap(src_bitmap, drawto, src_x, src_y, tilesize, tilesize, dst_x,dst_y);
+    getSizedGraphicSource(graphic, 0, tilesize, &src_bitmap, &src_x, &src_y);
+    BlitBitmap(src_bitmap, drawto, src_x, src_y, tilesize, tilesize,
+              dst_x, dst_y);
+  }
 }
 
 void DrawLevel(int draw_background_mask)
@@ -7230,58 +7331,102 @@ int map_action_SP_to_RND(int action_sp)
 
 int map_element_RND_to_MM(int element_rnd)
 {
-  return (element_rnd >= EL_CHAR_START &&
-         element_rnd <= EL_CHAR_END ?
-         EL_CHAR_START_NATIVE_MM + element_rnd - EL_CHAR_START :
+  return (element_rnd >= EL_MM_START_1 &&
+         element_rnd <= EL_MM_END_1 ?
+         EL_MM_START_1_NATIVE + element_rnd - EL_MM_START_1 :
 
-         element_rnd >= EL_DF_START &&
-         element_rnd <= EL_DF_END ?
-         EL_DF_START_NATIVE_MM + element_rnd - EL_DF_START :
+         element_rnd >= EL_MM_START_2 &&
+         element_rnd <= EL_MM_END_2 ?
+         EL_MM_START_2_NATIVE + element_rnd - EL_MM_START_2 :
 
-         element_rnd >= EL_MM_START &&
-         element_rnd <= EL_MM_END ?
-         EL_MM_START_NATIVE_MM + element_rnd - EL_MM_START :
+         element_rnd >= EL_CHAR_START &&
+         element_rnd <= EL_CHAR_END ?
+         EL_MM_CHAR_START_NATIVE + element_rnd - EL_CHAR_START :
 
          element_rnd >= EL_MM_RUNTIME_START &&
          element_rnd <= EL_MM_RUNTIME_END ?
-         EL_MM_RUNTIME_START_NATIVE_MM + element_rnd - EL_MM_RUNTIME_START :
+         EL_MM_RUNTIME_START_NATIVE + element_rnd - EL_MM_RUNTIME_START :
 
          element_rnd >= EL_MM_DUMMY_START &&
          element_rnd <= EL_MM_DUMMY_END ?
-         EL_MM_DUMMY_START_NATIVE_MM + element_rnd - EL_MM_DUMMY_START :
+         EL_MM_DUMMY_START_NATIVE + element_rnd - EL_MM_DUMMY_START :
 
-         EL_EMPTY_NATIVE_MM);
+         EL_MM_EMPTY_NATIVE);
 }
 
 int map_element_MM_to_RND(int element_mm)
 {
-  return (element_mm == EL_EMPTY_NATIVE_MM ||
-         element_mm == EL_DF_EMPTY_NATIVE_MM ?
+  return (element_mm == EL_MM_EMPTY_NATIVE ||
+         element_mm == EL_DF_EMPTY_NATIVE ?
          EL_EMPTY :
 
-         element_mm >= EL_CHAR_START_NATIVE_MM &&
-         element_mm <= EL_CHAR_END_NATIVE_MM ?
-         EL_CHAR_START + element_mm - EL_CHAR_START_NATIVE_MM :
+         element_mm >= EL_MM_START_1_NATIVE &&
+         element_mm <= EL_MM_END_1_NATIVE ?
+         EL_MM_START_1 + element_mm - EL_MM_START_1_NATIVE :
 
-         element_mm >= EL_DF_START_NATIVE_MM &&
-         element_mm <= EL_DF_END_NATIVE_MM ?
-         EL_DF_START + element_mm - EL_DF_START_NATIVE_MM :
+         element_mm >= EL_MM_START_2_NATIVE &&
+         element_mm <= EL_MM_END_2_NATIVE ?
+         EL_MM_START_2 + element_mm - EL_MM_START_2_NATIVE :
 
-         element_mm >= EL_MM_START_NATIVE_MM &&
-         element_mm <= EL_MM_END_NATIVE_MM ?
-         EL_MM_START + element_mm - EL_MM_START_NATIVE_MM :
+         element_mm >= EL_MM_CHAR_START_NATIVE &&
+         element_mm <= EL_MM_CHAR_END_NATIVE ?
+         EL_CHAR_START + element_mm - EL_MM_CHAR_START_NATIVE :
 
-         element_mm >= EL_MM_RUNTIME_START_NATIVE_MM &&
-         element_mm <= EL_MM_RUNTIME_END_NATIVE_MM ?
-         EL_MM_RUNTIME_START + element_mm - EL_MM_RUNTIME_START_NATIVE_MM :
+         element_mm >= EL_MM_RUNTIME_START_NATIVE &&
+         element_mm <= EL_MM_RUNTIME_END_NATIVE ?
+         EL_MM_RUNTIME_START + element_mm - EL_MM_RUNTIME_START_NATIVE :
 
-         element_mm >= EL_MM_DUMMY_START_NATIVE_MM &&
-         element_mm <= EL_MM_DUMMY_END_NATIVE_MM ?
-         EL_MM_DUMMY_START + element_mm - EL_MM_DUMMY_START_NATIVE_MM :
+         element_mm >= EL_MM_DUMMY_START_NATIVE &&
+         element_mm <= EL_MM_DUMMY_END_NATIVE ?
+         EL_MM_DUMMY_START + element_mm - EL_MM_DUMMY_START_NATIVE :
 
          EL_EMPTY);
 }
 
+int map_mm_wall_element(int element)
+{
+  return (element >= EL_MM_STEEL_WALL_START &&
+         element <= EL_MM_STEEL_WALL_END ?
+         EL_MM_STEEL_WALL :
+
+         element >= EL_MM_WOODEN_WALL_START &&
+         element <= EL_MM_WOODEN_WALL_END ?
+         EL_MM_WOODEN_WALL :
+
+         element >= EL_MM_ICE_WALL_START &&
+         element <= EL_MM_ICE_WALL_END ?
+         EL_MM_ICE_WALL :
+
+         element >= EL_MM_AMOEBA_WALL_START &&
+         element <= EL_MM_AMOEBA_WALL_END ?
+         EL_MM_AMOEBA_WALL :
+
+         element >= EL_DF_STEEL_WALL_START &&
+         element <= EL_DF_STEEL_WALL_END ?
+         EL_DF_STEEL_WALL :
+
+         element >= EL_DF_WOODEN_WALL_START &&
+         element <= EL_DF_WOODEN_WALL_END ?
+         EL_DF_WOODEN_WALL :
+
+         element);
+}
+
+int map_mm_wall_element_editor(int element)
+{
+  switch (element)
+  {
+    case EL_MM_STEEL_WALL:     return EL_MM_STEEL_WALL_START;
+    case EL_MM_WOODEN_WALL:    return EL_MM_WOODEN_WALL_START;
+    case EL_MM_ICE_WALL:       return EL_MM_ICE_WALL_START;
+    case EL_MM_AMOEBA_WALL:    return EL_MM_AMOEBA_WALL_START;
+    case EL_DF_STEEL_WALL:     return EL_DF_STEEL_WALL_START;
+    case EL_DF_WOODEN_WALL:    return EL_DF_WOODEN_WALL_START;
+
+    default:                   return element;
+  }
+}
+
 int get_next_element(int element)
 {
   switch (element)