added optional button to restart game (door, panel and touch variants)
[rocksndiamonds.git] / src / game_mm / mm_tools.c
index 48c99912b2a14a63bd6d1837300f2c34df76fe8c..12ca83cee8e22041ee608e659ad1f106c5d1ac3a 100644 (file)
@@ -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)