removed unused image file for native Boulder Dash graphics
[rocksndiamonds.git] / src / game_mm / mm_tools.c
index 15b540aa290ece08381c2773cd51def6e74fcb8c..3deac03390bad2d1a6e2fa3c6fa99648817320b1 100644 (file)
@@ -29,8 +29,8 @@ void SetDrawtoField_MM(int mode)
   // for convenience, absolute screen position to centered level playfield
   cSX = SX + dSX;
   cSY = SY + dSY;
-  cSX2 = SX + dSX + 2; // including playfield border
-  cSY2 = SY + dSY + 2; // including playfield border
+  cSX2 = SX + dSX + 2;         // including half laser line size
+  cSY2 = SY + dSY + 2;         // including half laser line size
 
   if (mode == DRAW_TO_BACKBUFFER)
   {
@@ -165,35 +165,35 @@ void DrawGraphicShifted_MM(int x, int y, int dx, int dy, int graphic,
     return;
   }
 
-  if (dx || dy)                        // Verschiebung der Grafik?
+  if (dx || dy)                                // Verschiebung der Grafik?
   {
-    if (x < BX1)               // Element kommt von links ins Bild
+    if (x < BX1)                       // Element kommt von links ins Bild
     {
       x = BX1;
       width = dx;
       cx = TILEX - dx;
       dx = 0;
     }
-    else if (x > BX2)          // Element kommt von rechts ins Bild
+    else if (x > BX2)                  // Element kommt von rechts ins Bild
     {
       x = BX2;
       width = -dx;
       dx = TILEX + dx;
     }
-    else if (x==BX1 && dx < 0) // Element verläßt links das Bild
+    else if (x == BX1 && dx < 0)       // Element verläßt links das Bild
     {
       width += dx;
       cx = -dx;
       dx = 0;
     }
-    else if (x==BX2 && dx > 0) // Element verläßt rechts das Bild
+    else if (x == BX2 && dx > 0)       // Element verläßt rechts das Bild
       width -= dx;
-    else if (dx)               // allg. Bewegung in x-Richtung
+    else if (dx)                       // allg. Bewegung in x-Richtung
       MarkTileDirty(x + SIGN(dx), y);
 
-    if (y < BY1)               // Element kommt von oben ins Bild
+    if (y < BY1)                       // Element kommt von oben ins Bild
     {
-      if (cut_mode==CUT_BELOW) // Element oberhalb des Bildes
+      if (cut_mode == CUT_BELOW)       // Element oberhalb des Bildes
        return;
 
       y = BY1;
@@ -201,13 +201,13 @@ void DrawGraphicShifted_MM(int x, int y, int dx, int dy, int graphic,
       cy = TILEY - dy;
       dy = 0;
     }
-    else if (y > BY2)          // Element kommt von unten ins Bild
+    else if (y > BY2)                  // Element kommt von unten ins Bild
     {
       y = BY2;
       height = -dy;
       dy = TILEY + dy;
     }
-    else if (y==BY1 && dy < 0) // Element verläßt oben das Bild
+    else if (y == BY1 && dy < 0)       // Element verläßt oben das Bild
     {
       height += dy;
       cy = -dy;
@@ -215,19 +215,19 @@ void DrawGraphicShifted_MM(int x, int y, int dx, int dy, int graphic,
     }
     else if (dy > 0 && cut_mode == CUT_ABOVE)
     {
-      if (y == BY2)            // Element unterhalb des Bildes
+      if (y == BY2)                    // Element unterhalb des Bildes
        return;
 
       height = dy;
       cy = TILEY - dy;
       dy = TILEY;
       MarkTileDirty(x, y + 1);
-    }                          // Element verläßt unten das Bild
+    }                                  // Element verläßt unten das Bild
     else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
     {
       height -= dy;
     }
-    else if (dy)               // allg. Bewegung in y-Richtung
+    else if (dy)                       // allg. Bewegung in y-Richtung
     {
       MarkTileDirty(x, y + SIGN(dy));
     }
@@ -1057,7 +1057,8 @@ static void DrawTileCursor_Xsn(int draw_target)
   }
 }
 
-void DrawTileCursor_MM(int draw_target, boolean tile_cursor_active)
+void DrawTileCursor_MM(int draw_target, int drawing_stage,
+                      boolean tile_cursor_active)
 {
   if (program.headless)
     return;
@@ -1072,7 +1073,12 @@ void DrawTileCursor_MM(int draw_target, boolean tile_cursor_active)
   int width = tilesize;
   int height = tilesize;
 
-  DrawTileCursor_Xsn(draw_target);
+  if (!drawing_stage)
+  {
+    DrawTileCursor_Xsn(draw_target);
+
+    return;
+  }
 
   if (!tile_cursor.enabled ||
       !tile_cursor.active ||
@@ -1147,6 +1153,10 @@ int get_base_element(int element)
     return EL_DF_MIRROR_START;
   else if (IS_DF_MIRROR_AUTO(element))
     return EL_DF_MIRROR_AUTO_START;
+  else if (IS_DF_MIRROR_FIXED(element))
+    return EL_DF_MIRROR_FIXED_START;
+  else if (IS_DF_SLOPE(element))
+    return EL_DF_SLOPE_START;
   else if (IS_PACMAN(element))
     return EL_PACMAN_START;
   else if (IS_GRID_STEEL(element))
@@ -1190,7 +1200,8 @@ int get_num_elements(int element)
       IS_POLAR(element) ||
       IS_BEAMER(element) ||
       IS_DF_MIRROR(element) ||
-      IS_DF_MIRROR_AUTO(element))
+      IS_DF_MIRROR_AUTO(element) ||
+      IS_DF_MIRROR_FIXED(element))
     return 16;
   else if (IS_GRID_STEEL_FIXED(element) ||
           IS_GRID_WOOD_FIXED(element) ||
@@ -1204,7 +1215,8 @@ int get_num_elements(int element)
           IS_RECEIVER(element) ||
           IS_PACMAN(element) ||
           IS_GRID_STEEL(element) ||
-          IS_GRID_WOOD(element))
+          IS_GRID_WOOD(element) ||
+          IS_DF_SLOPE(element))
     return 4;
   else
     return 1;
@@ -1219,6 +1231,110 @@ int get_rotated_element(int element, int step)
   return base_element + (element_phase + step + num_elements) % num_elements;
 }
 
+static boolean has_full_rotation(int element)
+{
+  return (IS_BEAMER(element) ||
+         IS_MCDUFFIN(element) ||
+         IS_LASER(element) ||
+         IS_RECEIVER(element) ||
+         IS_PACMAN(element));
+}
+
+#define MM_FLIP_X                      0
+#define MM_FLIP_Y                      1
+#define MM_FLIP_XY                     2
+
+static int getFlippedTileExt_MM(int element, int mode)
+{
+  if (IS_WALL(element))
+  {
+    int base = WALL_BASE(element);
+    int bits = WALL_BITS(element);
+
+    if (mode == MM_FLIP_X)
+    {
+      bits = ((bits & 1) << 1 |
+             (bits & 2) >> 1 |
+             (bits & 4) << 1 |
+             (bits & 8) >> 1);
+    }
+    else if (mode == MM_FLIP_Y)
+    {
+      bits = ((bits & 1) << 2 |
+             (bits & 2) << 2 |
+             (bits & 4) >> 2 |
+             (bits & 8) >> 2);
+    }
+    else if (mode == MM_FLIP_XY)
+    {
+      bits = ((bits & 1) << 0 |
+             (bits & 2) << 1 |
+             (bits & 4) >> 1 |
+             (bits & 8) >> 0);
+    }
+
+    element = base | bits;
+  }
+  else
+  {
+    int base_element = get_base_element(element);
+    int num_elements = get_num_elements(element);
+    int element_phase = element - base_element;
+
+    if (IS_GRID_STEEL(element) || IS_GRID_WOOD(element))
+    {
+      if ((mode == MM_FLIP_XY && element_phase < 2) ||
+         (mode != MM_FLIP_XY && element_phase > 1))
+       element_phase ^= 1;
+    }
+    else if (IS_DF_SLOPE(element))
+    {
+      element_phase = (mode == MM_FLIP_X  ? 5 - element_phase :
+                      mode == MM_FLIP_Y  ? 3 - element_phase :
+                      mode == MM_FLIP_XY ? 4 - element_phase :
+                      element_phase);
+    }
+    else
+    {
+      int num_elements_flip = num_elements;
+
+      if (has_full_rotation(element))
+      {
+       if (mode == MM_FLIP_X)
+         num_elements_flip = num_elements / 2;
+       else if (mode == MM_FLIP_XY)
+         num_elements_flip = num_elements * 3 / 4;
+      }
+      else
+      {
+       if (mode == MM_FLIP_XY)
+         num_elements_flip = num_elements / 2;
+      }
+
+      element_phase = num_elements_flip - element_phase;
+    }
+
+    element = base_element + (element_phase + num_elements) % num_elements;
+  }
+
+  return element;
+}
+
+int getFlippedTileX_MM(int element)
+{
+  return getFlippedTileExt_MM(element, MM_FLIP_X);
+}
+
+int getFlippedTileY_MM(int element)
+{
+  return getFlippedTileExt_MM(element, MM_FLIP_Y);
+}
+
+int getFlippedTileXY_MM(int element)
+{
+  return getFlippedTileExt_MM(element, MM_FLIP_XY);
+}
+
 int map_wall_from_base_element(int element)
 {
   switch (element)