changed delays in MM engine from clock delay to deterministic frame delay
[rocksndiamonds.git] / src / game_mm / mm_game.c
index d282dfe110eccbb1db631072a13035ee07ce64c0..3a0c60d1254c37a61be0950e9c33b40c83ea7069 100644 (file)
 #define DL_LASER_ENABLED       1
 
 /* values for 'click_delay_value' in ClickElement() */
-#define CLICK_DELAY_SHORT      125
-#define CLICK_DELAY_LONG       250
+#define CLICK_DELAY_FIRST      12      /* delay (frames) after first click */
+#define CLICK_DELAY            6       /* delay (frames) for pressed butten */
 
-#define AUTO_ROTATE_DELAY      CLICK_DELAY_SHORT
-#define INIT_GAME_ACTIONS_DELAY        ONE_SECOND_DELAY
+#define AUTO_ROTATE_DELAY      CLICK_DELAY
+#define INIT_GAME_ACTIONS_DELAY        (ONE_SECOND_DELAY / GAME_FRAME_DELAY)
 #define NUM_INIT_CYCLE_STEPS   16
+#define PACMAN_MOVE_DELAY      12
+#define ENERGY_DELAY           (4 * ONE_SECOND_DELAY / GAME_FRAME_DELAY)
+#define HEALTH_DEC_DELAY       3
+#define HEALTH_INC_DELAY       9
+#define HEALTH_DELAY(x)                ((x) ? HEALTH_DEC_DELAY : HEALTH_INC_DELAY)
 
 /* forward declaration for internal use */
 static int MovingOrBlocked2Element_MM(int, int);
@@ -342,7 +347,7 @@ void InitGameEngine_MM()
 
 void InitGameActions_MM()
 {
-  int num_init_game_frames = INIT_GAME_ACTIONS_DELAY / GAME_FRAME_DELAY;
+  int num_init_game_frames = INIT_GAME_ACTIONS_DELAY;
   int cycle_steps_done = 0;
   int i;
 
@@ -733,7 +738,7 @@ void ScanLaser()
   if (rf)
     DrawLaser(rf - 1, DL_LASER_ENABLED);
 
-  Ct = CT = Counter();
+  Ct = CT = FrameCounter;
 
 #if 0
     if (!IN_LEV_FIELD(ELX, ELY))
@@ -2182,11 +2187,14 @@ 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;
+
+      laser.overloaded = FALSE;
     }
     else if (IS_MCDUFFIN(Store[x][y]))
     {
-      game_mm.game_over = TRUE;
-      game_mm.game_over_cause = GAME_OVER_BOMB;
       Store[x][y] = EL_EMPTY;
     }
 
@@ -2434,7 +2442,7 @@ static void ContinueMoving_MM(int x, int y)
 void ClickElement(int x, int y, int button)
 {
   static unsigned int click_delay = 0;
-  static int click_delay_value = CLICK_DELAY_SHORT;
+  static int click_delay_value = CLICK_DELAY;
   static boolean new_button = TRUE;
   int element;
 
@@ -2445,7 +2453,7 @@ void ClickElement(int x, int y, int button)
   if (button == MB_RELEASED)
   {
     new_button = TRUE;
-    click_delay_value = CLICK_DELAY_SHORT;
+    click_delay_value = CLICK_DELAY;
 
     /* release eventually hold auto-rotating mirror */
     RotateMirror(x, y, MB_RELEASED);
@@ -2453,7 +2461,7 @@ void ClickElement(int x, int y, int button)
     return;
   }
 
-  if (!DelayReached(&click_delay, click_delay_value) && !new_button)
+  if (!FrameReached(&click_delay, click_delay_value) && !new_button)
     return;
 
   if (button == MB_MIDDLEBUTTON)       /* middle button has no function */
@@ -2530,7 +2538,7 @@ void ClickElement(int x, int y, int button)
     DrawLaser(0, DL_LASER_ENABLED);
   }
 
-  click_delay_value = (new_button ? CLICK_DELAY_LONG : CLICK_DELAY_SHORT);
+  click_delay_value = (new_button ? CLICK_DELAY_FIRST : CLICK_DELAY);
   new_button = FALSE;
 }
 
@@ -2636,7 +2644,7 @@ void AutoRotateMirrors()
   static unsigned int rotate_delay = 0;
   int x, y;
 
-  if (!DelayReached(&rotate_delay, AUTO_ROTATE_DELAY))
+  if (!FrameReached(&rotate_delay, AUTO_ROTATE_DELAY))
     return;
 
   for (x = 0; x < lev_fieldx; x++)
@@ -2728,9 +2736,9 @@ void ColorCycling(void)
   if (color_status == STATIC_COLORS)
     return;
 
-  CC = Counter();
+  CC = FrameCounter;
 
-  if (CC < Cc || CC > Cc + 50)
+  if (CC < Cc || CC > Cc + 2)
   {
     Cc = CC;
 
@@ -2764,7 +2772,6 @@ void ColorCycling(void)
 
 static void GameActions_MM_Ext(struct MouseActionInfo action, boolean warp_mode)
 {
-  static unsigned int action_delay = 0;
   static unsigned int pacman_delay = 0;
   static unsigned int energy_delay = 0;
   static unsigned int overload_delay = 0;
@@ -2773,8 +2780,6 @@ static void GameActions_MM_Ext(struct MouseActionInfo action, boolean warp_mode)
 
   int r, d;
 
-  WaitUntilDelayReached(&action_delay, GameFrameDelay);
-
   for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++)
     Stop[x][y] = FALSE;
 
@@ -2809,9 +2814,9 @@ static void GameActions_MM_Ext(struct MouseActionInfo action, boolean warp_mode)
   laser.redraw = FALSE;
 #endif
 
-  CT = Counter();
+  CT = FrameCounter;
 
-  if (game_mm.num_pacman && DelayReached(&pacman_delay, 250))
+  if (game_mm.num_pacman && FrameReached(&pacman_delay, PACMAN_MOVE_DELAY))
   {
     MovePacMen();
 
@@ -2822,7 +2827,7 @@ static void GameActions_MM_Ext(struct MouseActionInfo action, boolean warp_mode)
     }
   }
 
-  if (DelayReached(&energy_delay, 4000))
+  if (FrameReached(&energy_delay, ENERGY_DELAY))
   {
     game_mm.energy_left--;
     if (game_mm.energy_left >= 0)
@@ -2902,7 +2907,7 @@ static void GameActions_MM_Ext(struct MouseActionInfo action, boolean warp_mode)
 
   if (((laser.overloaded && laser.overload_value < MAX_LASER_OVERLOAD) ||
        (!laser.overloaded && laser.overload_value > 0)) &&
-      DelayReached(&overload_delay, 60 + !laser.overloaded * 120))
+      FrameReached(&overload_delay, HEALTH_DELAY(laser.overloaded)))
   {
     if (laser.overloaded)
       laser.overload_value++;
@@ -2933,7 +2938,9 @@ static void GameActions_MM_Ext(struct MouseActionInfo action, boolean warp_mode)
                        (native_mm_level.laser_blue  ? color_down : 0x00));
 
       DrawLaser(0, DL_LASER_ENABLED);
+#if 0
       BackToFront();
+#endif
     }
 
     if (!laser.overloaded)
@@ -3011,7 +3018,7 @@ static void GameActions_MM_Ext(struct MouseActionInfo action, boolean warp_mode)
 
   CT -= Ct;
 
-  if (element == EL_BOMB && CT > 1500)
+  if (element == EL_BOMB && CT > 75)
   {
     if (game_mm.cheat_no_explosion)
       return;
@@ -3049,7 +3056,7 @@ static void GameActions_MM_Ext(struct MouseActionInfo action, boolean warp_mode)
     return;
   }
 
-  if (element == EL_FUSE_ON && CT > 500)
+  if (element == EL_FUSE_ON && CT > 25)
   {
     laser.fuse_off = TRUE;
     laser.fuse_x = ELX;
@@ -3059,7 +3066,7 @@ static void GameActions_MM_Ext(struct MouseActionInfo action, boolean warp_mode)
     DrawGraphic_MM(ELX, ELY, IMG_MM_FUSE);
   }
 
-  if (element == EL_BALL_GRAY && CT > 1500)
+  if (element == EL_BALL_GRAY && CT > 75)
   {
     static int new_elements[] =
     {
@@ -3178,7 +3185,7 @@ static void GameActions_MM_Ext(struct MouseActionInfo action, boolean warp_mode)
     return;
   }
 
-  if (IS_WALL_ICE(element) && CT > 1000)
+  if (IS_WALL_ICE(element) && CT > 50)
   {
     PlayLevelSound_MM(ELX, ELY, element, MM_ACTION_SHRINKING);
 
@@ -3230,7 +3237,7 @@ static void GameActions_MM_Ext(struct MouseActionInfo action, boolean warp_mode)
     return;
   }
 
-  if (IS_WALL_AMOEBA(element) && CT > 1200)
+  if (IS_WALL_AMOEBA(element) && CT > 60)
   {
     int k1, k2, k3, dx, dy, de, dm;
     int element2 = Feld[ELX][ELY];
@@ -3348,7 +3355,7 @@ static void GameActions_MM_Ext(struct MouseActionInfo action, boolean warp_mode)
   }
 
   if ((element == EL_BLOCK_WOOD || element == EL_BLOCK_STONE) &&
-      laser.stops_inside_element && CT > 1500)
+      laser.stops_inside_element && CT > 75)
   {
     int x, y;
     int k;
@@ -3405,7 +3412,7 @@ static void GameActions_MM_Ext(struct MouseActionInfo action, boolean warp_mode)
     return;
   }
 
-  if (element == EL_FUEL_FULL && CT > 200)
+  if (element == EL_FUEL_FULL && CT > 10)
   {
     for (i = game_mm.energy_left; i <= MAX_LASER_ENERGY; i+=2)
     {
@@ -3507,7 +3514,7 @@ void MovePacMen()
 
       getGraphicSource(graphic, 0, &bitmap, &src_x, &src_y);
 
-      CT = Counter();
+      CT = FrameCounter;
       ox = SX + ox * TILEX;
       oy = SY + oy * TILEY;
 
@@ -3515,7 +3522,7 @@ void MovePacMen()
        BlitBitmap(bitmap, window,
                   src_x, src_y, TILEX, TILEY,
                   ox + i * mx, oy + i * my);
-      Ct = Ct + Counter() - CT;
+      Ct = Ct + FrameCounter - CT;
     }
 
     DrawField_MM(nx, ny);