parallelized initial charging of laser and cycling of mirrors (MM engine)
[rocksndiamonds.git] / src / game_mm / mm_game.c
index 97dc986b20ea1fba1c617dbffb010cb660319b5c..9d8a8763f5d77de1f3e407485c844008ca8b3c59 100644 (file)
 /* values for 'click_delay_value' in ClickElement() */
 #define CLICK_DELAY_SHORT      125
 #define CLICK_DELAY_LONG       250
+
 #define AUTO_ROTATE_DELAY      CLICK_DELAY_SHORT
+#define INIT_GAME_ACTIONS_DELAY        ONE_SECOND_DELAY
+#define NUM_INIT_CYCLE_STEPS   16
 
 /* forward declaration for internal use */
 static int MovingOrBlocked2Element_MM(int, int);
@@ -215,41 +218,28 @@ static void InitField(int x, int y, boolean init_game)
   }
 }
 
-static void InitCycleElements()
+static void InitCycleElements_RotateSingleStep()
 {
-  int i, j;
+  int i;
 
   if (game_mm.num_cycle == 0)  /* no elements to cycle */
     return;
 
-  for (i = 0; i < 16; i++)
+  for (i = 0; i < game_mm.num_cycle; i++)
   {
-    for (j = 0; j < game_mm.num_cycle; j++)
-    {
-      int x = game_mm.cycle[j].x;
-      int y = game_mm.cycle[j].y;
-      int step = SIGN(game_mm.cycle[j].steps);
-      int last_element = Feld[x][y];
-      int next_element = get_rotated_element(last_element, step);
-
-      if (!game_mm.cycle[j].steps)
-       continue;
-
-      Feld[x][y] = next_element;
-
-      DrawField_MM(x, y);
-      game_mm.cycle[j].steps -= step;
-    }
-
-    BackToFront();
-    ColorCycling();
+    int x = game_mm.cycle[i].x;
+    int y = game_mm.cycle[i].y;
+    int step = SIGN(game_mm.cycle[i].steps);
+    int last_element = Feld[x][y];
+    int next_element = get_rotated_element(last_element, step);
 
-#ifdef DEBUG
-    if (setup.quick_doors)
+    if (!game_mm.cycle[i].steps)
       continue;
-#endif
 
-    Delay(AUTO_ROTATE_DELAY);
+    Feld[x][y] = next_element;
+
+    DrawField_MM(x, y);
+    game_mm.cycle[i].steps -= step;
   }
 }
 
@@ -297,7 +287,7 @@ void InitGameEngine_MM()
   game_mm.num_pacman = 0;
 
   game_mm.score = 0;
-  game_mm.energy_left = native_mm_level.time;
+  game_mm.energy_left = 0;     // later set to "native_mm_level.time"
   game_mm.kettles_still_needed =
     (native_mm_level.auto_count_kettles ? 0 : native_mm_level.kettles_needed);
   game_mm.lights_still_needed = 0;
@@ -307,6 +297,8 @@ void InitGameEngine_MM()
   game_mm.game_over = FALSE;
   game_mm.game_over_cause = 0;
 
+  game_mm.laser_overload_value = 0;
+
   /* set global laser control values (must be set before "InitLaser()") */
   laser.start_edge.x = 0;
   laser.start_edge.y = 0;
@@ -348,9 +340,12 @@ void InitGameEngine_MM()
   DrawLevel_MM();
 }
 
-void InitGameEngine_MM_AfterFadingIn()
+void InitGameActions_MM()
 {
-  InitCycleElements();
+  int num_init_game_frames = INIT_GAME_ACTIONS_DELAY / GAME_FRAME_DELAY;
+  int cycle_steps_done = 0;
+  int i;
+
   InitLaser();
 
 #if 0
@@ -386,21 +381,22 @@ void InitGameEngine_MM_AfterFadingIn()
   if (setup.sound_loops)
     PlaySoundExt(SND_FUEL, SOUND_MAX_VOLUME, SOUND_MAX_RIGHT, SND_CTRL_PLAY_LOOP);
 
-#if 0 // !!! TEMPORARILY DISABLED !!!
-  for (i = 0; i <= game_mm.energy_left; i += 2)
+  for (i = 0; i <= num_init_game_frames; i++)
   {
     if (!setup.sound_loops)
       PlaySoundStereo(SND_FUEL, SOUND_MAX_RIGHT);
 
-#if 0
-    BlitBitmap(pix[PIX_DOOR], drawto,
-              DOOR_GFX_PAGEX4 + XX_ENERGY,
-              DOOR_GFX_PAGEY1 + YY_ENERGY + ENERGY_YSIZE - i,
-              ENERGY_XSIZE, i,
-              DX_ENERGY, DY_ENERGY + ENERGY_YSIZE - i);
-#endif
+    game_mm.energy_left = native_mm_level.time * i / num_init_game_frames;
+
+    UpdateAndDisplayGameControlValues();
+
+    while (cycle_steps_done < NUM_INIT_CYCLE_STEPS * i / num_init_game_frames)
+    {
+      InitCycleElements_RotateSingleStep();
+
+      cycle_steps_done++;
+    }
 
-    redraw_mask |= REDRAW_DOOR_1;
     BackToFront();
 
     ColorCycling();
@@ -409,13 +405,10 @@ void InitGameEngine_MM_AfterFadingIn()
     if (setup.quick_doors)
       continue;
 #endif
-
-    Delay(20);
   }
 
   if (setup.sound_loops)
     StopSound(SND_FUEL);
-#endif
 
 #if 0
   if (setup.sound_music && num_bg_loops)
@@ -2922,6 +2915,8 @@ static void GameActions_MM_Ext(byte action[MAX_PLAYERS], boolean warp_mode)
       laser.overload_value = 0;
     }
 
+    game_mm.laser_overload_value = laser.overload_value;
+
     if (laser.overload_value < MAX_LASER_OVERLOAD - 8)
     {
       int color_up = 0xFF * laser.overload_value / MAX_LASER_OVERLOAD;