rnd-19990215-1
[rocksndiamonds.git] / src / game.c
index f51b2dc48ab3d13ed1bddd881935af1974ba8e7b..b510a0e56c72e434be4d71e74c6784d5e25acd3e 100644 (file)
                                 (s)==SND_TYGER || (s)==SND_VOYAGER || \
                                 (s)==SND_TWILIGHT)
 
+/* values for player movement speed (which is in fact a delay value) */
+#define MOVE_DELAY_NORMAL_SPEED        8
+#define MOVE_DELAY_HIGH_SPEED  4
+
+#define DOUBLE_MOVE_DELAY(x)   (x = (x <= MOVE_DELAY_HIGH_SPEED ? x * 2 : x))
+#define HALVE_MOVE_DELAY(x)    (x = (x >= MOVE_DELAY_HIGH_SPEED ? x / 2 : x))
+#define DOUBLE_PLAYER_SPEED(p) (HALVE_MOVE_DELAY((p)->move_delay_value))
+#define HALVE_PLAYER_SPEED(p)  (DOUBLE_MOVE_DELAY((p)->move_delay_value))
+
 /* score for elements */
 #define SC_EDELSTEIN           0
 #define SC_DIAMANT             1
 #define NUM_GAME_BUTTONS               6
 
 /* forward declaration for internal use */
+static void CheckGravityMovement(struct PlayerInfo *);
+
 static void MapGameButtons();
 static void HandleGameButtons(struct GadgetInfo *);
 
@@ -198,10 +209,6 @@ static void InitField(int x, int y, boolean init_game)
 
        player->present = TRUE;
 
-       /*
-       if (!network_playing || player->connected)
-       */
-
        if (!options.network || player->connected)
        {
          player->active = TRUE;
@@ -312,6 +319,19 @@ static void InitField(int x, int y, boolean init_game)
       Feld[x][y] = EL_LEERRAUM;
       break;
 
+    case EL_EM_KEY_1_FILE:
+      Feld[x][y] = EL_EM_KEY_1;
+      break;
+    case EL_EM_KEY_2_FILE:
+      Feld[x][y] = EL_EM_KEY_2;
+      break;
+    case EL_EM_KEY_3_FILE:
+      Feld[x][y] = EL_EM_KEY_3;
+      break;
+    case EL_EM_KEY_4_FILE:
+      Feld[x][y] = EL_EM_KEY_4;
+      break;
+
     default:
       break;
   }
@@ -339,6 +359,7 @@ void InitGame()
 
     player->action = 0;
     player->effective_action = 0;
+    player->programmed_action = 0;
 
     player->score = 0;
     player->gems_still_needed = level.edelsteine;
@@ -371,6 +392,9 @@ void InitGame()
     player->move_delay = 0;
     player->last_move_dir = MV_NO_MOVING;
 
+    player->move_delay_value =
+      (level.double_speed ? MOVE_DELAY_HIGH_SPEED : MOVE_DELAY_NORMAL_SPEED);
+
     player->snapped = FALSE;
 
     player->gone = FALSE;
@@ -405,8 +429,7 @@ void InitGame()
   ScreenMovPos = 0;
   ScreenGfxPos = 0;
 
-  MoveSpeed = (level.double_speed ? 4 : 8);
-  ScrollStepSize = TILEX / MoveSpeed;
+  ScrollStepSize = 0;  /* will be correctly initialized by ScrollScreen() */
 
   AllPlayersGone = FALSE;
   SiebAktiv = FALSE;
@@ -560,10 +583,10 @@ void InitGame()
     SBY_Lower = lev_fieldy - SCR_FIELDY + 1;
   }
 
-  if (lev_fieldx < SCR_FIELDX)
+  if (lev_fieldx + (SBX_Left == -1 ? 2 : 0) <= SCR_FIELDX)
     SBX_Left = SBX_Right = -1 * (SCR_FIELDX - lev_fieldx) / 2;
 
-  if (lev_fieldy < SCR_FIELDY)
+  if (lev_fieldy + (SBY_Upper == -1 ? 2 : 0) <= SCR_FIELDY)
     SBY_Upper = SBY_Lower = -1 * (SCR_FIELDY - lev_fieldy) / 2;
 
   scroll_x = SBX_Left;
@@ -602,32 +625,20 @@ void InitGame()
              DOOR_GFX_PAGEX1 + XX_TIME, DOOR_GFX_PAGEY1 + YY_TIME,
              int2str(TimeLeft, 3), FS_SMALL, FC_YELLOW);
 
-
-
-#if 0
-  DrawGameButton(BUTTON_GAME_STOP);
-  DrawGameButton(BUTTON_GAME_PAUSE);
-  DrawGameButton(BUTTON_GAME_PLAY);
-  DrawSoundDisplay(BUTTON_SOUND_MUSIC  | (setup.sound_music  ? BUTTON_ON : 0));
-  DrawSoundDisplay(BUTTON_SOUND_LOOPS  | (setup.sound_loops  ? BUTTON_ON : 0));
-  DrawSoundDisplay(BUTTON_SOUND_SIMPLE | (setup.sound_simple ? BUTTON_ON : 0));
-#else
   UnmapGameButtons();
   game_gadget[SOUND_CTRL_ID_MUSIC]->checked = setup.sound_music;
   game_gadget[SOUND_CTRL_ID_LOOPS]->checked = setup.sound_loops;
   game_gadget[SOUND_CTRL_ID_SIMPLE]->checked = setup.sound_simple;
   MapGameButtons();
   MapTapeButtons();
-#endif
 
+  /* copy actual game buttons to door double buffer for OpenDoor() */
   XCopyArea(display, drawto, pix[PIX_DB_DOOR], gc,
            DX + GAME_CONTROL_XPOS, DY + GAME_CONTROL_YPOS,
            GAME_CONTROL_XSIZE, 2 * GAME_CONTROL_YSIZE,
            DOOR_GFX_PAGEX1 + GAME_CONTROL_XPOS,
            DOOR_GFX_PAGEY1 + GAME_CONTROL_YPOS);
 
-
-
   OpenDoor(DOOR_OPEN_ALL);
 
   if (setup.sound_music)
@@ -638,8 +649,8 @@ void InitGame()
   if (options.verbose)
   {
     for (i=0; i<4; i++)
-      printf("Spieler %d %saktiv.\n",
-            i+1, (stored_player[i].active ? "" : "nicht "));
+      printf("Player %d %sactive.\n",
+            i + 1, (stored_player[i].active ? "" : "not "));
   }
 }
 
@@ -968,6 +979,29 @@ int MovingOrBlocked2Element(int x, int y)
     return element;
 }
 
+static int MovingOrBlocked2ElementIfNotLeaving(int x, int y)
+{
+  /* like MovingOrBlocked2Element(), but if element is moving
+     and (x,y) is the field the moving element is just leaving,
+     return EL_BLOCKED instead of the element value */
+  int element = Feld[x][y];
+
+  if (IS_MOVING(x, y))
+  {
+    if (element == EL_BLOCKED)
+    {
+      int oldx, oldy;
+
+      Blocked2Moving(x, y, &oldx, &oldy);
+      return Feld[oldx][oldy];
+    }
+    else
+      return EL_BLOCKED;
+  }
+  else
+    return element;
+}
+
 static void RemoveField(int x, int y)
 {
   Feld[x][y] = EL_LEERRAUM;
@@ -1529,6 +1563,10 @@ void Impact(int x, int y)
       case EL_SCHLUESSEL2:
       case EL_SCHLUESSEL3:
       case EL_SCHLUESSEL4:
+      case EL_EM_KEY_1:
+      case EL_EM_KEY_2:
+      case EL_EM_KEY_3:
+      case EL_EM_KEY_4:
        sound = SND_KINK;
        break;
       case EL_ZEIT_VOLL:
@@ -3343,25 +3381,19 @@ static void PlayerActions(struct PlayerInfo *player, byte player_action)
        player_action &= JOY_BUTTON;
 
       stored_player_action[player->index_nr] = player_action;
-
-#if 0
-      /* this allows cycled sequences of PlayerActions() */
-      if (num_stored_actions >= MAX_PLAYERS)
-      {
-       TapeRecordAction(stored_player_action);
-       num_stored_actions = 0;
-      }
-#endif
-
     }
     else if (tape.playing && snapped)
       SnapField(player, 0, 0);                 /* stop snapping */
   }
   else
   {
+    /* no actions for this player (no input at player's configured device) */
+
     DigField(player, 0, 0, 0, 0, DF_NO_PUSH);
     SnapField(player, 0, 0);
-    if (++player->frame_reset_delay > MoveSpeed)
+    CheckGravityMovement(player);
+
+    if (++player->frame_reset_delay > player->move_delay_value)
       player->Frame = 0;
   }
 
@@ -3414,40 +3446,9 @@ void GameActions()
   action_delay_value =
     (tape.playing && tape.fast_forward ? FfwdFrameDelay : GameFrameDelay);
 
-  /*
-  if (tape.playing && tape.fast_forward)
-  {
-    char buf[100];
-
-    sprintf(buf, "FFWD: %ld ms", action_delay_value);
-    print_debug(buf);
-  }
-  */
-
+  /* ---------- main game synchronization point ---------- */
 
-  /* main game synchronization point */
-
-
-
-
-#if 1
   WaitUntilDelayReached(&action_delay, action_delay_value);
-#else
-
-  while (!DelayReached(&action_delay, action_delay_value))
-  {
-    char buf[100];
-
-    sprintf(buf, "%ld %ld %ld",
-           Counter(), action_delay, action_delay_value);
-    print_debug(buf);
-  }
-  print_debug("done");
-
-#endif
-
-
-
 
   if (network_playing && !network_player_action_received)
   {
@@ -3476,14 +3477,6 @@ void GameActions()
     }
   }
 
-
-  /*
-  if (tape.pausing || (tape.playing && !TapePlayDelay()))
-    return;
-  else if (tape.recording)
-    TapeRecordDelay();
-  */
-
   if (tape.pausing)
     return;
 
@@ -3514,6 +3507,9 @@ void GameActions()
   {
     int actual_player_action = stored_player[i].effective_action;
 
+    if (stored_player[i].programmed_action)
+      actual_player_action = stored_player[i].programmed_action;
+
     if (recorded_player_action)
       actual_player_action = recorded_player_action[i];
 
@@ -3526,41 +3522,25 @@ void GameActions()
   ScrollScreen(NULL, SCROLL_GO_ON);
 
 
-  /*
-  if (tape.pausing || (tape.playing && !TapePlayDelay()))
-    return;
-  else if (tape.recording)
-    TapeRecordDelay();
-  */
-
-
-
-
 
 #ifdef DEBUG
-  /*
+#if 0
   if (TimeFrames == 0 && !local_player->gone)
   {
     extern unsigned int last_RND();
 
     printf("DEBUG: %03d last RND was %d \t [state checksum is %d]\n",
-          TimePlayed,
-          last_RND(),
-          getStateCheckSum(TimePlayed));
+          TimePlayed, last_RND(), getStateCheckSum(TimePlayed));
   }
-  */
 #endif
-
-
+#endif
 
 #ifdef DEBUG
-  /*
+#if 0
   if (GameFrameDelay >= 500)
     printf("FrameCounter == %d\n", FrameCounter);
-  */
 #endif
-
-
+#endif
 
 
 
@@ -3581,7 +3561,7 @@ void GameActions()
       Blocked2Moving(x, y, &oldx, &oldy);
       if (!IS_MOVING(oldx, oldy))
       {
-       printf("GameActions(): (BLOCKED=>MOVING) context corrupted!\n");
+       printf("GameActions(): (BLOCKED => MOVING) context corrupted!\n");
        printf("GameActions(): BLOCKED: x = %d, y = %d\n", x, y);
        printf("GameActions(): !MOVING: oldx = %d, oldy = %d\n", oldx, oldy);
        printf("GameActions(): This should never happen!\n");
@@ -3800,6 +3780,32 @@ void ScrollLevel(int dx, int dy)
   redraw_mask |= REDRAW_FIELD;
 }
 
+static void CheckGravityMovement(struct PlayerInfo *player)
+{
+  if (level.gravity && !player->programmed_action)
+  {
+    int move_dir_vertical = player->action & (MV_UP | MV_DOWN);
+    int move_dir_horizontal = player->action & (MV_LEFT | MV_RIGHT);
+    int move_dir =
+      (player->last_move_dir & (MV_LEFT | MV_RIGHT) ?
+       (move_dir_vertical ? move_dir_vertical : move_dir_horizontal) :
+       (move_dir_horizontal ? move_dir_horizontal : move_dir_vertical));
+    int jx = player->jx, jy = player->jy;
+    int dx = (move_dir & MV_LEFT ? -1 : move_dir & MV_RIGHT ? +1 : 0);
+    int dy = (move_dir & MV_UP ? -1 : move_dir & MV_DOWN ? +1 : 0);
+    int new_jx = jx + dx, new_jy = jy + dy;
+    boolean field_under_player_is_free =
+      (IN_LEV_FIELD(jx, jy + 1) && IS_FREE(jx, jy + 1));
+    boolean player_is_moving_to_valid_field =
+      (IN_LEV_FIELD(new_jx, new_jy) &&
+       (Feld[new_jx][new_jy] == EL_SP_BASE ||
+       Feld[new_jx][new_jy] == EL_ERDREICH));
+
+    if (field_under_player_is_free && !player_is_moving_to_valid_field)
+      player->programmed_action = MV_DOWN;
+  }
+}
+
 boolean MoveFigureOneStep(struct PlayerInfo *player,
                          int dx, int dy, int real_dx, int real_dy)
 {
@@ -3822,7 +3828,11 @@ boolean MoveFigureOneStep(struct PlayerInfo *player,
   if (!options.network && !AllPlayersInSight(player, new_jx, new_jy))
     return MF_NO_ACTION;
 
+#if 0
   element = MovingOrBlocked2Element(new_jx, new_jy);
+#else
+  element = MovingOrBlocked2ElementIfNotLeaving(new_jx, new_jy);
+#endif
 
   if (DONT_GO_TO(element))
   {
@@ -3852,7 +3862,8 @@ boolean MoveFigureOneStep(struct PlayerInfo *player,
   jy = player->jy = new_jy;
   StorePlayer[jx][jy] = player->element_nr;
 
-  player->MovPos = (dx > 0 || dy > 0 ? -1 : 1) * (TILEX - TILEX / MoveSpeed);
+  player->MovPos =
+    (dx > 0 || dy > 0 ? -1 : 1) * (TILEX - TILEX / player->move_delay_value);
 
   ScrollFigure(player, SCROLL_INIT);
 
@@ -3868,22 +3879,26 @@ boolean MoveFigure(struct PlayerInfo *player, int dx, int dy)
   if (player->gone || (!dx && !dy))
     return FALSE;
 
-  if (!FrameReached(&player->move_delay, MoveSpeed) && !tape.playing)
+  if (!FrameReached(&player->move_delay, player->move_delay_value) &&
+      !tape.playing)
     return FALSE;
 
+  /* remove the last programmed player action */
+  player->programmed_action = 0;
+
   if (player->MovPos)
   {
     /* should only happen if pre-1.2 tape recordings are played */
     /* this is only for backward compatibility */
 
-    int old_move_speed = MoveSpeed;
+    int original_move_delay_value = player->move_delay_value;
 
 #if DEBUG
     printf("THIS SHOULD ONLY HAPPEN WITH PRE-1.2 LEVEL TAPES.\n");
 #endif
 
     /* scroll remaining steps with finest movement resolution */
-    MoveSpeed = 8;
+    player->move_delay_value = MOVE_DELAY_NORMAL_SPEED;
 
     while (player->MovPos)
     {
@@ -3894,7 +3909,7 @@ boolean MoveFigure(struct PlayerInfo *player, int dx, int dy)
       BackToFront();
     }
 
-    MoveSpeed = old_move_speed;
+    player->move_delay_value = original_move_delay_value;
   }
 
   if (player->last_move_dir & (MV_LEFT | MV_RIGHT))
@@ -3997,7 +4012,11 @@ boolean MoveFigure(struct PlayerInfo *player, int dx, int dy)
     player->last_move_dir = player->MovDir;
   }
   else
+  {
+    CheckGravityMovement(player);
+
     player->last_move_dir = MV_NO_MOVING;
+  }
 
   TestIfHeroHitsBadThing(jx, jy);
 
@@ -4011,6 +4030,7 @@ void ScrollFigure(struct PlayerInfo *player, int mode)
 {
   int jx = player->jx, jy = player->jy;
   int last_jx = player->last_jx, last_jy = player->last_jy;
+  int move_stepsize = TILEX / player->move_delay_value;
 
   if (!player->active || player->gone || !player->MovPos)
     return;
@@ -4018,7 +4038,7 @@ void ScrollFigure(struct PlayerInfo *player, int mode)
   if (mode == SCROLL_INIT)
   {
     player->actual_frame_counter = FrameCounter;
-    player->GfxPos = ScrollStepSize * (player->MovPos / ScrollStepSize);
+    player->GfxPos = move_stepsize * (player->MovPos / move_stepsize);
 
     if (Feld[last_jx][last_jy] == EL_LEERRAUM)
       Feld[last_jx][last_jy] = EL_PLAYER_IS_LEAVING;
@@ -4029,16 +4049,29 @@ void ScrollFigure(struct PlayerInfo *player, int mode)
   else if (!FrameReached(&player->actual_frame_counter, 1))
     return;
 
-  player->MovPos += (player->MovPos > 0 ? -1 : 1) * TILEX / MoveSpeed;
-  player->GfxPos = ScrollStepSize * (player->MovPos / ScrollStepSize);
+  player->MovPos += (player->MovPos > 0 ? -1 : 1) * move_stepsize;
+  player->GfxPos = move_stepsize * (player->MovPos / move_stepsize);
 
   if (Feld[last_jx][last_jy] == EL_PLAYER_IS_LEAVING)
     Feld[last_jx][last_jy] = EL_LEERRAUM;
 
+  /* before DrawPlayer() to draw correct player graphic for this case */
+  if (player->MovPos == 0)
+    CheckGravityMovement(player);
+
   DrawPlayer(player);
 
-  if (!player->MovPos)
+  if (player->MovPos == 0)
   {
+    if (IS_QUICK_GATE(Feld[last_jx][last_jy]))
+    {
+      /* continue with normal speed after quickly moving through gate */
+      HALVE_PLAYER_SPEED(player);
+
+      /* be able to make the next move without delay */
+      player->move_delay = 0;
+    }
+
     player->last_jx = jx;
     player->last_jy = jy;
 
@@ -4058,6 +4091,9 @@ void ScrollScreen(struct PlayerInfo *player, int mode)
 
   if (mode == SCROLL_INIT)
   {
+    /* set scrolling step size according to actual player's moving speed */
+    ScrollStepSize = TILEX / player->move_delay_value;
+
     screen_frame_counter = FrameCounter;
     ScreenMovDir = player->MovDir;
     ScreenMovPos = player->MovPos;
@@ -4069,7 +4105,7 @@ void ScrollScreen(struct PlayerInfo *player, int mode)
 
   if (ScreenMovPos)
   {
-    ScreenMovPos += (ScreenMovPos > 0 ? -1 : 1) * TILEX / MoveSpeed;
+    ScreenMovPos += (ScreenMovPos > 0 ? -1 : 1) * ScrollStepSize;
     ScreenGfxPos = ScrollStepSize * (ScreenMovPos / ScrollStepSize);
     redraw_mask |= REDRAW_FIELD;
   }
@@ -4104,7 +4140,11 @@ void TestIfGoodThingHitsBadThing(int goodx, int goody)
     if (!IN_LEV_FIELD(x, y))
       continue;
 
+#if 0
     element = Feld[x][y];
+#else
+    element = MovingOrBlocked2ElementIfNotLeaving(x, y);
+#endif
 
     if (DONT_TOUCH(element))
     {
@@ -4287,6 +4327,10 @@ int DigField(struct PlayerInfo *player,
 {
   int jx = player->jx, jy = player->jy;
   int dx = x - jx, dy = y - jy;
+  int move_direction = (dx == -1 ? MV_LEFT :
+                       dx == +1 ? MV_RIGHT :
+                       dy == -1 ? MV_UP :
+                       dy == +1 ? MV_DOWN : MV_NO_MOVING);
   int element;
 
   if (!player->MovPos)
@@ -4343,8 +4387,7 @@ int DigField(struct PlayerInfo *player,
 
     case EL_SPEED_PILL:
       RemoveField(x, y);
-      MoveSpeed = 4;
-      ScrollStepSize = TILEX/4;
+      player->move_delay_value = MOVE_DELAY_HIGH_SPEED;
       PlaySoundLevel(x, y, SND_PONG);
       break;
 
@@ -4389,7 +4432,27 @@ int DigField(struct PlayerInfo *player,
     case EL_SCHLUESSEL3:
     case EL_SCHLUESSEL4:
     {
-      int key_nr = element-EL_SCHLUESSEL1;
+      int key_nr = element - EL_SCHLUESSEL1;
+
+      RemoveField(x, y);
+      player->key[key_nr] = TRUE;
+      RaiseScoreElement(EL_SCHLUESSEL);
+      DrawMiniGraphicExt(drawto, gc,
+                        DX_KEYS+key_nr*MINI_TILEX, DY_KEYS,
+                        GFX_SCHLUESSEL1+key_nr);
+      DrawMiniGraphicExt(window, gc,
+                        DX_KEYS+key_nr*MINI_TILEX, DY_KEYS,
+                        GFX_SCHLUESSEL1+key_nr);
+      PlaySoundLevel(x, y, SND_PONG);
+      break;
+    }
+
+    case EL_EM_KEY_1:
+    case EL_EM_KEY_2:
+    case EL_EM_KEY_3:
+    case EL_EM_KEY_4:
+    {
+      int key_nr = element - EL_EM_KEY_1;
 
       RemoveField(x, y);
       player->key[key_nr] = TRUE;
@@ -4485,7 +4548,7 @@ int DigField(struct PlayerInfo *player,
     case EL_PFORTE2:
     case EL_PFORTE3:
     case EL_PFORTE4:
-      if (!player->key[element-EL_PFORTE1])
+      if (!player->key[element - EL_PFORTE1])
        return MF_NO_ACTION;
       break;
 
@@ -4493,8 +4556,38 @@ int DigField(struct PlayerInfo *player,
     case EL_PFORTE2X:
     case EL_PFORTE3X:
     case EL_PFORTE4X:
-      if (!player->key[element-EL_PFORTE1X])
+      if (!player->key[element - EL_PFORTE1X])
+       return MF_NO_ACTION;
+      break;
+
+    case EL_EM_GATE_1:
+    case EL_EM_GATE_2:
+    case EL_EM_GATE_3:
+    case EL_EM_GATE_4:
+      if (!player->key[element - EL_EM_GATE_1])
        return MF_NO_ACTION;
+      if (!IN_LEV_FIELD(x + dx, y + dy) || !IS_FREE(x + dx, y + dy))
+       return MF_NO_ACTION;
+
+      /* automatically move to the next field with double speed */
+      player->programmed_action = move_direction;
+      DOUBLE_PLAYER_SPEED(player);
+
+      break;
+
+    case EL_EM_GATE_1X:
+    case EL_EM_GATE_2X:
+    case EL_EM_GATE_3X:
+    case EL_EM_GATE_4X:
+      if (!player->key[element - EL_EM_GATE_1X])
+       return MF_NO_ACTION;
+      if (!IN_LEV_FIELD(x + dx, y + dy) || !IS_FREE(x + dx, y + dy))
+       return MF_NO_ACTION;
+
+      /* automatically move to the next field with double speed */
+      player->programmed_action = move_direction;
+      DOUBLE_PLAYER_SPEED(player);
+
       break;
 
     case EL_SP_PORT1_LEFT:
@@ -4531,6 +4624,11 @@ int DigField(struct PlayerInfo *player,
          !IN_LEV_FIELD(x + dx, y + dy) ||
          !IS_FREE(x + dx, y + dy))
        return MF_NO_ACTION;
+
+      /* automatically move to the next field with double speed */
+      player->programmed_action = move_direction;
+      DOUBLE_PLAYER_SPEED(player);
+
       break;
 
     case EL_AUSGANG_ZU:
@@ -4545,14 +4643,6 @@ int DigField(struct PlayerInfo *player,
 
       PlaySoundLevel(x, y, SND_BUING);
 
-      /*
-      player->gone = TRUE;
-      PlaySoundLevel(x, y, SND_BUING);
-
-      if (!local_player->friends_still_needed)
-       player->LevelSolved = player->GameOver = TRUE;
-      */
-
       break;
 
     case EL_BIRNE_AUS:
@@ -4763,19 +4853,21 @@ void PlaySoundLevel(int x, int y, int sound_nr)
   volume = PSND_MAX_VOLUME;
 
 #ifndef MSDOS
-  stereo = (sx-SCR_FIELDX/2)*12;
+  stereo = (sx - SCR_FIELDX/2) * 12;
 #else
-  stereo = PSND_MIDDLE+(2*sx-(SCR_FIELDX-1))*5;
-  if(stereo > PSND_MAX_RIGHT) stereo = PSND_MAX_RIGHT;
-  if(stereo < PSND_MAX_LEFT) stereo = PSND_MAX_LEFT;
+  stereo = PSND_MIDDLE + (2 * sx - (SCR_FIELDX - 1)) * 5;
+  if (stereo > PSND_MAX_RIGHT)
+    stereo = PSND_MAX_RIGHT;
+  if (stereo < PSND_MAX_LEFT)
+    stereo = PSND_MAX_LEFT;
 #endif
 
   if (!IN_SCR_FIELD(sx, sy))
   {
-    int dx = ABS(sx-SCR_FIELDX/2)-SCR_FIELDX/2;
-    int dy = ABS(sy-SCR_FIELDY/2)-SCR_FIELDY/2;
+    int dx = ABS(sx - SCR_FIELDX/2) - SCR_FIELDX/2;
+    int dy = ABS(sy - SCR_FIELDY/2) - SCR_FIELDY/2;
 
-    volume -= volume*(dx > dy ? dx : dy)/silence_distance;
+    volume -= volume * (dx > dy ? dx : dy) / silence_distance;
   }
 
   PlaySoundExt(sound_nr, volume, stereo, PSND_NO_LOOP);
@@ -4990,7 +5082,8 @@ static void HandleGameButtons(struct GadgetInfo *gi)
        break;
       }
 
-      if (Request("Do you really want to quit the game ?",
+      if (level_editor_test_game ||
+         Request("Do you really want to quit the game ?",
                  REQ_ASK | REQ_STAY_CLOSED))
       { 
 #ifndef MSDOS