cleanup of function for fading laser in MM engine
[rocksndiamonds.git] / src / game_mm / mm_game.c
index 1ef6339e826957c521ef5d79efc81935cbd8ebba..8f61572d9c26a69da2b14f0704949c1ad049ca15 100644 (file)
@@ -411,6 +411,20 @@ static void CheckExitMM(void)
     PlayLevelSound_MM(exit_x, exit_y, exit_element, MM_ACTION_OPENING);
 }
 
+static void SetLaserColor(int brightness)
+{
+  int color_min = 0x00;
+  int color_max = brightness;          // (0x00 <= brightness <= 0xFF)
+  int color_up   = color_max * laser.overload_value / MAX_LASER_OVERLOAD;
+  int color_down = color_max - color_up;
+
+  pen_ray =
+    GetPixelFromRGB(window,
+                   (native_mm_level.laser_red   ? color_max  : color_up),
+                   (native_mm_level.laser_green ? color_down : color_min),
+                   (native_mm_level.laser_blue  ? color_down : color_min));
+}
+
 static void InitMovDir_MM(int x, int y)
 {
   int element = Tile[x][y];
@@ -573,10 +587,7 @@ static void InitLaser(void)
 
   AddLaserEdge(LX, LY);                // set laser starting edge
 
-  pen_ray = GetPixelFromRGB(window,
-                           native_mm_level.laser_red   * 0xFF,
-                           native_mm_level.laser_green * 0xFF,
-                           native_mm_level.laser_blue  * 0xFF);
+  SetLaserColor(0xFF);
 }
 
 void InitGameEngine_MM(void)
@@ -714,6 +725,46 @@ void InitGameActions_MM(void)
   SetTileCursorActive(TRUE);
 }
 
+static void FadeOutLaser(void)
+{
+  int i;
+
+  for (i = 15; i >= 0; i--)
+  {
+    SetLaserColor(0x11 * i);
+
+    DrawLaser(0, DL_LASER_ENABLED);
+
+    BackToFront();
+    Delay_WithScreenUpdates(50);
+  }
+
+  DrawLaser(0, DL_LASER_DISABLED);
+
+  StopSound_MM(SND_MM_GAME_HEALTH_CHARGING);
+}
+
+static void GameOver_MM(int game_over_cause)
+{
+  // do not handle game over if request dialog is already active
+  if (game.request_active)
+    return;
+
+  game_mm.game_over = TRUE;
+  game_mm.game_over_cause = game_over_cause;
+
+  if (setup.ask_on_game_over)
+    game.restart_game_message = (game_over_cause == GAME_OVER_BOMB ?
+                                "Bomb killed Mc Duffin! Play it again?" :
+                                game_over_cause == GAME_OVER_NO_ENERGY ?
+                                "Out of magic energy! Play it again?" :
+                                game_over_cause == GAME_OVER_OVERLOADED ?
+                                "Magic spell hit Mc Duffin! Play it again?" :
+                                NULL);
+
+  SetTileCursorActive(FALSE);
+}
+
 void AddLaserEdge(int lx, int ly)
 {
   int clx = dSX + lx;
@@ -1463,14 +1514,14 @@ boolean HitElement(int element, int hit_mask)
     LX += step_size * XS;
     LY += step_size * YS;
 
-#if 0
     // draw sparkles on mirror
-    if ((IS_MIRROR(element) || IS_MIRROR_FIXED(element)) &&
+    if ((IS_MIRROR(element) ||
+        IS_MIRROR_FIXED(element) ||
+        element == EL_PRISM) &&
        current_angle != laser.current_angle)
     {
-      MoveSprite(vp, &Pfeil[2], 4 + 16 * ELX, 5 + 16 * ELY + 1);
+      MovDelay[ELX][ELY] = 11;         // start animation
     }
-#endif
 
     if ((!IS_POLAR(element) && !IS_POLAR_CROSS(element)) &&
        current_angle != laser.current_angle)
@@ -2404,11 +2455,31 @@ static void GrowAmoeba(int x, int y)
 
 static void DrawFieldAnimated_MM(int x, int y)
 {
+  int element = Tile[x][y];
+
   if (IS_BLOCKED(x, y))
     return;
 
   DrawField_MM(x, y);
 
+  if (IS_MIRROR(element) ||
+      IS_MIRROR_FIXED(element) ||
+      element == EL_PRISM)
+  {
+    if (MovDelay[x][y] != 0)   // wait some time before next frame
+    {
+      MovDelay[x][y]--;
+
+      if (MovDelay[x][y] != 0)
+      {
+       int graphic = IMG_TWINKLE_WHITE;
+       int frame = getGraphicAnimationFrame(graphic, 10 - MovDelay[x][y]);
+
+       DrawGraphicThruMask_MM(SCREENX(x), SCREENY(y), graphic, frame);
+      }
+    }
+  }
+
   laser.redraw = TRUE;
 }
 
@@ -2466,10 +2537,7 @@ static void Explode_MM(int x, int y, int phase, int mode)
       Bang_MM(laser.start_edge.x, laser.start_edge.y);
       Store[x][y] = EL_EMPTY;
 
-      game_mm.game_over = TRUE;
-      game_mm.game_over_cause = GAME_OVER_BOMB;
-
-      SetTileCursorActive(FALSE);
+      GameOver_MM(GAME_OVER_DELAYED);
 
       laser.overloaded = FALSE;
     }
@@ -2477,7 +2545,7 @@ static void Explode_MM(int x, int y, int phase, int mode)
     {
       Store[x][y] = EL_EMPTY;
 
-      game.restart_game_message = "Bomb killed Mc Duffin! Play it again?";
+      GameOver_MM(GAME_OVER_BOMB);
     }
 
     Tile[x][y] = Store[x][y];
@@ -2930,7 +2998,9 @@ void RotateMirror(int x, int y, int button)
              LX, LY, laser.beamer_edge, laser.beamer[1].num);
 #endif
 
+#if 0
        laser.num_edges--;
+#endif
       }
 
       ScanLaser();
@@ -3126,6 +3196,10 @@ static void GameActions_MM_Ext(void)
     }
   }
 
+  // skip all following game actions if game is over
+  if (game_mm.game_over)
+    return;
+
   if (FrameReached(&energy_delay))
   {
     if (game_mm.energy_left > 0)
@@ -3136,35 +3210,9 @@ static void GameActions_MM_Ext(void)
     }
     else if (game.time_limit && !game_mm.game_over)
     {
-      int i;
-
-      for (i = 15; i >= 0; i--)
-      {
-#if 0
-       SetRGB(pen_ray, 0x0000, 0x0000, i * color_scale);
-#endif
-       pen_ray = GetPixelFromRGB(window,
-                                 native_mm_level.laser_red   * 0x11 * i,
-                                 native_mm_level.laser_green * 0x11 * i,
-                                 native_mm_level.laser_blue  * 0x11 * i);
-
-       DrawLaser(0, DL_LASER_ENABLED);
-       BackToFront();
-       Delay_WithScreenUpdates(50);
-      }
-
-      StopSound_MM(SND_MM_GAME_HEALTH_CHARGING);
-#if 0
-      FadeMusic();
-#endif
+      FadeOutLaser();
 
-      DrawLaser(0, DL_LASER_DISABLED);
-      game_mm.game_over = TRUE;
-      game_mm.game_over_cause = GAME_OVER_NO_ENERGY;
-
-      SetTileCursorActive(FALSE);
-
-      game.restart_game_message = "Out of magic energy! Play it again?";
+      GameOver_MM(GAME_OVER_NO_ENERGY);
 
       return;
     }
@@ -3213,18 +3261,7 @@ static void GameActions_MM_Ext(void)
 
     if (laser.overload_value < MAX_LASER_OVERLOAD - 8)
     {
-      int color_up = 0xFF * laser.overload_value / MAX_LASER_OVERLOAD;
-      int color_down = 0xFF - color_up;
-
-#if 0
-      SetRGB(pen_ray, (laser.overload_value / 6) * color_scale, 0x0000,
-            (15 - (laser.overload_value / 6)) * color_scale);
-#endif
-      pen_ray =
-       GetPixelFromRGB(window,
-                       (native_mm_level.laser_red  ? 0xFF : color_up),
-                       (native_mm_level.laser_green ? color_down : 0x00),
-                       (native_mm_level.laser_blue  ? color_down : 0x00));
+      SetLaserColor(0xFF);
 
       DrawLaser(0, DL_LASER_ENABLED);
     }
@@ -3262,31 +3299,11 @@ static void GameActions_MM_Ext(void)
 
     if (laser.overload_value == MAX_LASER_OVERLOAD)
     {
-      int i;
-
       UpdateAndDisplayGameControlValues();
 
-      for (i = 15; i >= 0; i--)
-      {
-#if 0
-       SetRGB(pen_ray, i * color_scale, 0x0000, 0x0000);
-#endif
-
-       pen_ray = GetPixelFromRGB(window, 0x11 * i, 0x00, 0x00);
-
-       DrawLaser(0, DL_LASER_ENABLED);
-       BackToFront();
-       Delay_WithScreenUpdates(50);
-      }
-
-      DrawLaser(0, DL_LASER_DISABLED);
-
-      game_mm.game_over = TRUE;
-      game_mm.game_over_cause = GAME_OVER_OVERLOADED;
-
-      SetTileCursorActive(FALSE);
+      FadeOutLaser();
 
-      game.restart_game_message = "Magic spell hit Mc Duffin! Play it again?";
+      GameOver_MM(GAME_OVER_OVERLOADED);
 
       return;
     }