rnd-19990219-2
[rocksndiamonds.git] / src / game.c
index 530345f5f5462971a895a01fdc4df939519f2b7f..fcaedf73e391e6c0882991de5811ecfc1e1968c7 100644 (file)
                                 (s)==SND_TYGER || (s)==SND_VOYAGER || \
                                 (s)==SND_TWILIGHT)
 
-/* score for elements */
-#define SC_EDELSTEIN           0
-#define SC_DIAMANT             1
-#define SC_KAEFER              2
-#define SC_FLIEGER             3
-#define SC_MAMPFER             4
-#define SC_ROBOT               5
-#define SC_PACMAN              6
-#define SC_KOKOSNUSS           7
-#define SC_DYNAMIT             8
-#define SC_SCHLUESSEL          9
-#define SC_ZEITBONUS           10
+/* 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))
 
 /* game button identifiers */
 #define GAME_CTRL_ID_STOP              0
@@ -200,10 +196,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;
@@ -357,7 +349,7 @@ void InitGame()
     player->programmed_action = 0;
 
     player->score = 0;
-    player->gems_still_needed = level.edelsteine;
+    player->gems_still_needed = level.gems_needed;
     player->sokobanfields_still_needed = 0;
     player->lights_still_needed = 0;
     player->friends_still_needed = 0;
@@ -387,10 +379,10 @@ void InitGame()
     player->move_delay = 0;
     player->last_move_dir = MV_NO_MOVING;
 
-    player->move_speed = (level.double_speed ? 4 : 8);
-    player->snapped = FALSE;
+    player->move_delay_value =
+      (level.double_speed ? MOVE_DELAY_HIGH_SPEED : MOVE_DELAY_NORMAL_SPEED);
 
-    player->gone = FALSE;
+    player->snapped = FALSE;
 
     player->last_jx = player->last_jy = 0;
     player->jx = player->jy = 0;
@@ -412,7 +404,7 @@ void InitGame()
 
   ZX = ZY = -1;
 
-  MampferNr = 0;
+  game.yam_content_nr = 0;
   FrameCounter = 0;
   TimeFrames = 0;
   TimePlayed = 0;
@@ -422,16 +414,11 @@ void InitGame()
   ScreenMovPos = 0;
   ScreenGfxPos = 0;
 
-  /*
-  MoveSpeed = (level.double_speed ? 4 : 8);
-  ScrollStepSize = TILEX / MoveSpeed;
-  */
-
-  ScrollStepSize = 0;
+  ScrollStepSize = 0;  /* will be correctly initialized by ScrollScreen() */
 
   AllPlayersGone = FALSE;
-  SiebAktiv = FALSE;
-  SiebCount = 0;
+  game.magic_wall_active = FALSE;
+  game.magic_wall_time_left = 0;
 
   for (i=0; i<MAX_NUM_AMOEBA; i++)
     AmoebaCnt[i] = AmoebaCnt2[i] = 0;
@@ -559,7 +546,7 @@ void InitGame()
     }
   }
 
-  game_emulation = (emulate_bd ? EMU_BOULDERDASH :
+  game.emulation = (emulate_bd ? EMU_BOULDERDASH :
                    emulate_sb ? EMU_SOKOBAN :
                    emulate_sp ? EMU_SUPAPLEX : EMU_NONE);
 
@@ -604,50 +591,31 @@ void InitGame()
   DrawAllPlayers();
   FadeToFront();
 
-  XCopyArea(display, pix[PIX_DOOR], pix[PIX_DB_DOOR], gc,
-           DOOR_GFX_PAGEX5, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
-           DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
-  DrawTextExt(pix[PIX_DB_DOOR], gc,
-             DOOR_GFX_PAGEX1 + XX_LEVEL, DOOR_GFX_PAGEY1 + YY_LEVEL,
-             int2str(level_nr, 2), FS_SMALL, FC_YELLOW);
-  DrawTextExt(pix[PIX_DB_DOOR], gc,
-             DOOR_GFX_PAGEX1 + XX_EMERALDS, DOOR_GFX_PAGEY1 + YY_EMERALDS,
-             int2str(local_player->gems_still_needed,3), FS_SMALL, FC_YELLOW);
-  DrawTextExt(pix[PIX_DB_DOOR], gc,
-             DOOR_GFX_PAGEX1 + XX_DYNAMITE, DOOR_GFX_PAGEY1 + YY_DYNAMITE,
-             int2str(local_player->dynamite, 3), FS_SMALL, FC_YELLOW);
-  DrawTextExt(pix[PIX_DB_DOOR], gc,
-             DOOR_GFX_PAGEX1 + XX_SCORE, DOOR_GFX_PAGEY1 + YY_SCORE,
-             int2str(local_player->score, 5), FS_SMALL, FC_YELLOW);
-  DrawTextExt(pix[PIX_DB_DOOR], gc,
-             DOOR_GFX_PAGEX1 + XX_TIME, DOOR_GFX_PAGEY1 + YY_TIME,
-             int2str(TimeLeft, 3), FS_SMALL, FC_YELLOW);
-
-
+  /* copy default game door content to main double buffer */
+  XCopyArea(display, pix[PIX_DOOR], drawto, gc,
+           DOOR_GFX_PAGEX5, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE, DX, DY);
+
+  DrawText(DX + XX_LEVEL, DY + YY_LEVEL,
+          int2str(level_nr, 2), FS_SMALL, FC_YELLOW);
+  DrawText(DX + XX_EMERALDS, DY + YY_EMERALDS,
+          int2str(local_player->gems_still_needed,3), FS_SMALL, FC_YELLOW);
+  DrawText(DX + XX_DYNAMITE, DY + YY_DYNAMITE,
+          int2str(local_player->dynamite, 3), FS_SMALL, FC_YELLOW);
+  DrawText(DX + XX_SCORE, DY + YY_SCORE,
+          int2str(local_player->score, 5), FS_SMALL, FC_YELLOW);
+  DrawText(DX + XX_TIME, DY + 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 door content 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);
-
-
+           DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
 
   OpenDoor(DOOR_OPEN_ALL);
 
@@ -659,8 +627,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 "));
   }
 }
 
@@ -1083,7 +1051,7 @@ void DrawDynamite(int x, int y)
       phase = 7 - phase;
   }
 
-  if (game_emulation == EMU_SUPAPLEX)
+  if (game.emulation == EMU_SUPAPLEX)
     DrawGraphic(sx, sy, GFX_SP_DISK_RED);
   else if (Store[x][y])
     DrawGraphicThruMask(sx, sy, graphic + phase);
@@ -1171,7 +1139,7 @@ void Explode(int ex, int ey, int phase, int mode)
            break;
        }
 
-       if (game_emulation == EMU_SUPAPLEX)
+       if (game.emulation == EMU_SUPAPLEX)
          Store[x][y] = EL_LEERRAUM;
       }
       else if (center_element == EL_MAULWURF)
@@ -1185,9 +1153,9 @@ void Explode(int ex, int ey, int phase, int mode)
       else if (center_element == EL_SP_ELECTRON)
        Store[x][y] = EL_SP_INFOTRON;
       else if (center_element == EL_MAMPFER)
-       Store[x][y] = level.mampfer_inhalt[MampferNr][x-ex+1][y-ey+1];
+       Store[x][y] = level.yam_content[game.yam_content_nr][x-ex+1][y-ey+1];
       else if (center_element == EL_AMOEBA2DIAM)
-       Store[x][y] = level.amoebe_inhalt;
+       Store[x][y] = level.amoeba_content;
       else if (element == EL_ERZ_EDEL)
        Store[x][y] = EL_EDELSTEIN;
       else if (element == EL_ERZ_DIAM)
@@ -1224,7 +1192,7 @@ void Explode(int ex, int ey, int phase, int mode)
     }
 
     if (center_element == EL_MAMPFER)
-      MampferNr = (MampferNr + 1) % MampferMax;
+      game.yam_content_nr = (game.yam_content_nr + 1) % level.num_yam_contents;
 
     return;
   }
@@ -1280,7 +1248,7 @@ void Explode(int ex, int ey, int phase, int mode)
   {
     int graphic = GFX_EXPLOSION;
 
-    if (game_emulation == EMU_SUPAPLEX)
+    if (game.emulation == EMU_SUPAPLEX)
       graphic = (Store[x][y] == EL_SP_INFOTRON ?
                 GFX_SP_EXPLODE_INFOTRON :
                 GFX_SP_EXPLODE_EMPTY);
@@ -1337,7 +1305,7 @@ void Bang(int x, int y)
 {
   int element = Feld[x][y];
 
-  if (game_emulation == EMU_SUPAPLEX)
+  if (game.emulation == EMU_SUPAPLEX)
     PlaySoundLevel(x, y, SND_SP_BOOOM);
   else
     PlaySoundLevel(x, y, SND_ROAAAR);
@@ -1480,8 +1448,8 @@ void Impact(int x, int y)
          if (Feld[x][y] == smashed)
            Feld[x][y] = activated_magic_wall;
 
-      SiebCount = level.dauer_sieb * FRAMES_PER_SECOND;
-      SiebAktiv = TRUE;
+      game.magic_wall_time_left = level.time_magic_wall * FRAMES_PER_SECOND;
+      game.magic_wall_active = TRUE;
     }
 
     if (IS_PLAYER(x, y+1))
@@ -1864,7 +1832,7 @@ void TurnRound(int x, int y)
        struct PlayerInfo *player = &stored_player[i];
        int jx = player->jx, jy = player->jy;
 
-       if (!player->active || player->gone)
+       if (!player->active)
          continue;
 
        if (attr_x == -1 || ABS(jx-x)+ABS(jy-y) < ABS(attr_x-x)+ABS(attr_y-y))
@@ -1979,8 +1947,7 @@ static boolean JustBeingPushed(int x, int y)
   {
     struct PlayerInfo *player = &stored_player[i];
 
-    if (player->active && !player->gone &&
-       player->Pushing && player->MovPos)
+    if (player->active && player->Pushing && player->MovPos)
     {
       int next_jx = player->jx + (player->jx - player->last_jx);
       int next_jy = player->jy + (player->jy - player->last_jy);
@@ -2123,7 +2090,7 @@ void StartMoving(int x, int y)
 
       if (left || right)
       {
-       if (left && right && game_emulation != EMU_BOULDERDASH)
+       if (left && right && game.emulation != EMU_BOULDERDASH)
          left = !(right = RND(2));
 
        InitMovingField(x, y, left ? MV_LEFT : MV_RIGHT);
@@ -2455,22 +2422,24 @@ void ContinueMoving(int x, int y)
     else if (Store[x][y] == EL_SIEB_VOLL)
     {
       Store[x][y] = 0;
-      element = Feld[newx][newy] = (SiebAktiv ? EL_SIEB_VOLL : EL_SIEB_TOT);
+      element = Feld[newx][newy] =
+       (game.magic_wall_active ? EL_SIEB_VOLL : EL_SIEB_TOT);
     }
     else if (Store[x][y] == EL_SIEB_LEER)
     {
       Store[x][y] = Store2[x][y] = 0;
-      Feld[x][y] = (SiebAktiv ? EL_SIEB_LEER : EL_SIEB_TOT);
+      Feld[x][y] = (game.magic_wall_active ? EL_SIEB_LEER : EL_SIEB_TOT);
     }
     else if (Store[x][y] == EL_SIEB2_VOLL)
     {
       Store[x][y] = 0;
-      element = Feld[newx][newy] = (SiebAktiv ? EL_SIEB2_VOLL : EL_SIEB2_TOT);
+      element = Feld[newx][newy] =
+       (game.magic_wall_active ? EL_SIEB2_VOLL : EL_SIEB2_TOT);
     }
     else if (Store[x][y] == EL_SIEB2_LEER)
     {
       Store[x][y] = Store2[x][y] = 0;
-      Feld[x][y] = (SiebAktiv ? EL_SIEB2_LEER : EL_SIEB2_TOT);
+      Feld[x][y] = (game.magic_wall_active ? EL_SIEB2_LEER : EL_SIEB2_TOT);
     }
     else if (Store[x][y] == EL_SALZSAEURE)
     {
@@ -2727,7 +2696,7 @@ void AmoebeAbleger(int ax, int ay)
     { 0, +1 }
   };
 
-  if (!level.tempo_amoebe)
+  if (!level.amoeba_speed)
   {
     Feld[ax][ay] = EL_AMOEBE_TOT;
     DrawLevelField(ax, ay);
@@ -2735,7 +2704,7 @@ void AmoebeAbleger(int ax, int ay)
   }
 
   if (!MovDelay[ax][ay])       /* start making new amoeba field */
-    MovDelay[ax][ay] = RND(FRAMES_PER_SECOND * 25 / (1 + level.tempo_amoebe));
+    MovDelay[ax][ay] = RND(FRAMES_PER_SECOND * 25 / (1 + level.amoeba_speed));
 
   if (MovDelay[ax][ay])                /* wait some time before making new amoeba */
   {
@@ -2790,7 +2759,7 @@ void AmoebeAbleger(int ax, int ay)
 
     if (newax == ax && neway == ay)            /* amoeba cannot grow */
     {
-      if (i == 4 && (!waiting_for_player || game_emulation == EMU_BOULDERDASH))
+      if (i == 4 && (!waiting_for_player || game.emulation == EMU_BOULDERDASH))
       {
        Feld[ax][ay] = EL_AMOEBE_TOT;
        DrawLevelField(ax, ay);
@@ -2801,7 +2770,7 @@ void AmoebeAbleger(int ax, int ay)
          if (element == EL_AMOEBE_VOLL)
            AmoebeUmwandeln(ax, ay);
          else if (element == EL_AMOEBE_BD)
-           AmoebeUmwandelnBD(ax, ay, level.amoebe_inhalt);
+           AmoebeUmwandelnBD(ax, ay, level.amoeba_content);
        }
       }
       return;
@@ -2925,7 +2894,7 @@ void Life(int ax, int ay)
 void Ablenk(int x, int y)
 {
   if (!MovDelay[x][y])         /* next animation frame */
-    MovDelay[x][y] = level.dauer_ablenk * FRAMES_PER_SECOND;
+    MovDelay[x][y] = level.time_wheel * FRAMES_PER_SECOND;
 
   if (MovDelay[x][y])          /* wait some time before next frame */
   {
@@ -3368,7 +3337,7 @@ static void PlayerActions(struct PlayerInfo *player, byte player_action)
   stored_player_action[player->index_nr] = 0;
   num_stored_actions++;
 
-  if (!player->active || player->gone || tape.pausing)
+  if (!player->active || tape.pausing)
     return;
 
   if (player_action)
@@ -3391,32 +3360,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);
     CheckGravityMovement(player);
 
-    /*
-    if (++player->frame_reset_delay > MoveSpeed)
-      player->Frame = 0;
-    */
-
-    if (++player->frame_reset_delay > player->move_speed)
+    if (++player->frame_reset_delay > player->move_delay_value)
       player->Frame = 0;
   }
 
@@ -3469,40 +3425,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)
   {
@@ -3531,14 +3456,6 @@ void GameActions()
     }
   }
 
-
-  /*
-  if (tape.pausing || (tape.playing && !TapePlayDelay()))
-    return;
-  else if (tape.recording)
-    TapeRecordDelay();
-  */
-
   if (tape.pausing)
     return;
 
@@ -3570,24 +3487,7 @@ void GameActions()
     int actual_player_action = stored_player[i].effective_action;
 
     if (stored_player[i].programmed_action)
-    {
-#if 0
-      /* this is very bad and need to be fixed!!! */
-      unsigned long move_delay = stored_player[i].move_delay;
-
-      /*
-      if (FrameReached(&move_delay, MoveSpeed))
-      */
-
-      if (FrameReached(&move_delay, stored_player[i].move_speed))
-      {
-       actual_player_action = stored_player[i].programmed_action;
-       stored_player[i].programmed_action = 0;
-      }
-#else
       actual_player_action = stored_player[i].programmed_action;
-#endif
-    }
 
     if (recorded_player_action)
       actual_player_action = recorded_player_action[i];
@@ -3601,41 +3501,25 @@ void GameActions()
   ScrollScreen(NULL, SCROLL_GO_ON);
 
 
-  /*
-  if (tape.pausing || (tape.playing && !TapePlayDelay()))
-    return;
-  else if (tape.recording)
-    TapeRecordDelay();
-  */
-
-
-
-
 
 #ifdef DEBUG
-  /*
-  if (TimeFrames == 0 && !local_player->gone)
+#if 0
+  if (TimeFrames == 0 && local_player->active)
   {
     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
 
 
 
@@ -3656,7 +3540,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");
@@ -3721,7 +3605,7 @@ void GameActions()
     else if (element == EL_SP_TERMINAL_ACTIVE)
       DrawGraphicAnimation(x, y, GFX2_SP_TERMINAL_ACTIVE, 7, 4, ANIM_NORMAL);
 
-    if (SiebAktiv)
+    if (game.magic_wall_active)
     {
       boolean sieb = FALSE;
       int jx = local_player->jx, jy = local_player->jy;
@@ -3748,15 +3632,15 @@ void GameActions()
     }
   }
 
-  if (SiebAktiv)
+  if (game.magic_wall_active)
   {
-    if (!(SiebCount % 4))
+    if (!(game.magic_wall_time_left % 4))
       PlaySoundLevel(sieb_x, sieb_y, SND_MIEP);
 
-    if (SiebCount > 0)
+    if (game.magic_wall_time_left > 0)
     {
-      SiebCount--;
-      if (!SiebCount)
+      game.magic_wall_time_left--;
+      if (!game.magic_wall_time_left)
       {
        for (y=0; y<lev_fieldy; y++) for (x=0; x<lev_fieldx; x++)
        {
@@ -3773,7 +3657,7 @@ void GameActions()
          }
        }
 
-       SiebAktiv = FALSE;
+       game.magic_wall_active = FALSE;
       }
     }
   }
@@ -3815,8 +3699,7 @@ static boolean AllPlayersInSight(struct PlayerInfo *player, int x, int y)
   {
     int jx = stored_player[i].jx, jy = stored_player[i].jy;
 
-    if (!stored_player[i].active || stored_player[i].gone ||
-       &stored_player[i] == player)
+    if (!stored_player[i].active || &stored_player[i] == player)
       continue;
 
     min_x = MIN(min_x, jx);
@@ -3836,7 +3719,7 @@ static boolean AllPlayersInVisibleScreen()
   {
     int jx = stored_player[i].jx, jy = stored_player[i].jy;
 
-    if (!stored_player[i].active || stored_player[i].gone)
+    if (!stored_player[i].active)
       continue;
 
     if (!IN_VIS_FIELD(SCREENX(jx), SCREENY(jy)))
@@ -3909,7 +3792,7 @@ boolean MoveFigureOneStep(struct PlayerInfo *player,
   int element;
   int can_move;
 
-  if (player->gone || (!dx && !dy))
+  if (!player->active || (!dx && !dy))
     return MF_NO_ACTION;
 
   player->MovDir = (dx < 0 ? MV_LEFT :
@@ -3957,12 +3840,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_speed);
+    (dx > 0 || dy > 0 ? -1 : 1) * (TILEX - TILEX / player->move_delay_value);
 
   ScrollFigure(player, SCROLL_INIT);
 
@@ -3975,15 +3854,11 @@ boolean MoveFigure(struct PlayerInfo *player, int dx, int dy)
   int old_jx = jx, old_jy = jy;
   int moved = MF_NO_ACTION;
 
-  if (player->gone || (!dx && !dy))
+  if (!player->active || (!dx && !dy))
     return FALSE;
 
-  /*
-  if (!FrameReached(&player->move_delay, MoveSpeed) && !tape.playing)
-    return FALSE;
-  */
-
-  if (!FrameReached(&player->move_delay, player->move_speed) && !tape.playing)
+  if (!FrameReached(&player->move_delay, player->move_delay_value) &&
+      !tape.playing)
     return FALSE;
 
   /* remove the last programmed player action */
@@ -3994,23 +3869,14 @@ boolean MoveFigure(struct PlayerInfo *player, int dx, int dy)
     /* should only happen if pre-1.2 tape recordings are played */
     /* this is only for backward compatibility */
 
-    /*
-    int old_move_speed = MoveSpeed;
-    */
-
-    int old_move_speed = player->move_speed;
+    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_speed = 8;
+    player->move_delay_value = MOVE_DELAY_NORMAL_SPEED;
 
     while (player->MovPos)
     {
@@ -4021,12 +3887,7 @@ boolean MoveFigure(struct PlayerInfo *player, int dx, int dy)
       BackToFront();
     }
 
-    /*
-    MoveSpeed = old_move_speed;
-    */
-
-    player->move_speed = old_move_speed;
-
+    player->move_delay_value = original_move_delay_value;
   }
 
   if (player->last_move_dir & (MV_LEFT | MV_RIGHT))
@@ -4137,7 +3998,7 @@ boolean MoveFigure(struct PlayerInfo *player, int dx, int dy)
 
   TestIfHeroHitsBadThing(jx, jy);
 
-  if (player->gone)
+  if (!player->active)
     RemoveHero(player);
 
   return moved;
@@ -4147,9 +4008,9 @@ 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_speed;
+  int move_stepsize = TILEX / player->move_delay_value;
 
-  if (!player->active || player->gone || !player->MovPos)
+  if (!player->active || !player->MovPos)
     return;
 
   if (mode == SCROLL_INIT)
@@ -4172,43 +4033,20 @@ void ScrollFigure(struct PlayerInfo *player, int mode)
   if (Feld[last_jx][last_jy] == EL_PLAYER_IS_LEAVING)
     Feld[last_jx][last_jy] = EL_LEERRAUM;
 
-
-#if 0
-  if (!player->MovPos && level.gravity)
-  {
-    if (player->action == MV_NO_MOVING)
-      player->programmed_action = MV_DOWN;
-    else if (player->action == MV_UP)
-    {
-    }
-    else if (player->action & (MV_LEFT | MV_RIGHT))
-    {
-    }
-  }
-#else
-  if (!player->MovPos)
+  /* before DrawPlayer() to draw correct player graphic for this case */
+  if (player->MovPos == 0)
     CheckGravityMovement(player);
-#endif
-
 
   DrawPlayer(player);
 
-  if (!player->MovPos)
+  if (player->MovPos == 0)
   {
     if (IS_QUICK_GATE(Feld[last_jx][last_jy]))
     {
-      /* continue with normal speed after moving through port */
-      /* FIX THIS: what about player already having eaten a speed pill? */
-
-      /*
-      MoveSpeed = 8;
-      ScrollStepSize = TILEX / MoveSpeed;
-      */
+      /* continue with normal speed after quickly moving through gate */
+      HALVE_PLAYER_SPEED(player);
 
-      player->move_speed = 8;
-
-      /* don't wait for the next move -- the whole move delay stuff
-        is worse at the moment; FIX THIS! ;-) */
+      /* be able to make the next move without delay */
       player->move_delay = 0;
     }
 
@@ -4232,7 +4070,7 @@ 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_speed;
+    ScrollStepSize = TILEX / player->move_delay_value;
 
     screen_frame_counter = FrameCounter;
     ScreenMovDir = player->MovDir;
@@ -4419,7 +4257,7 @@ void KillHero(struct PlayerInfo *player)
 {
   int jx = player->jx, jy = player->jy;
 
-  if (player->gone)
+  if (!player->active)
     return;
 
   if (IS_PFORTE(Feld[jx][jy]))
@@ -4433,7 +4271,7 @@ void BuryHero(struct PlayerInfo *player)
 {
   int jx = player->jx, jy = player->jy;
 
-  if (player->gone)
+  if (!player->active)
     return;
 
   PlaySoundLevel(jx, jy, SND_AUTSCH);
@@ -4448,11 +4286,13 @@ void RemoveHero(struct PlayerInfo *player)
   int jx = player->jx, jy = player->jy;
   int i, found = FALSE;
 
-  player->gone = TRUE;
+  player->present = FALSE;
+  player->active = FALSE;
+
   StorePlayer[jx][jy] = 0;
 
   for (i=0; i<MAX_PLAYERS; i++)
-    if (stored_player[i].active && !stored_player[i].gone)
+    if (stored_player[i].active)
       found = TRUE;
 
   if (!found)
@@ -4527,14 +4367,7 @@ int DigField(struct PlayerInfo *player,
 
     case EL_SPEED_PILL:
       RemoveField(x, y);
-
-      player->move_speed = 4;
-
-      /*
-      MoveSpeed = 4;
-      ScrollStepSize = TILEX / MoveSpeed;
-      */
-
+      player->move_delay_value = MOVE_DELAY_HIGH_SPEED;
       PlaySoundLevel(x, y, SND_PONG);
       break;
 
@@ -4713,13 +4546,12 @@ int DigField(struct PlayerInfo *player,
     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;
-      player->move_speed = 4;
+      DOUBLE_PLAYER_SPEED(player);
 
       break;
 
@@ -4729,13 +4561,12 @@ int DigField(struct PlayerInfo *player,
     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;
-      player->move_speed = 4;
+      DOUBLE_PLAYER_SPEED(player);
 
       break;
 
@@ -4776,12 +4607,7 @@ int DigField(struct PlayerInfo *player,
 
       /* automatically move to the next field with double speed */
       player->programmed_action = move_direction;
-      player->move_speed = 4;
-
-      /*
-      MoveSpeed = 4;
-      ScrollStepSize = TILEX / MoveSpeed;
-      */
+      DOUBLE_PLAYER_SPEED(player);
 
       break;
 
@@ -4797,14 +4623,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:
@@ -4893,7 +4711,7 @@ int DigField(struct PlayerInfo *player,
 
       if (IS_SB_ELEMENT(element) &&
          local_player->sokobanfields_still_needed == 0 &&
-         game_emulation == EMU_SOKOBAN)
+         game.emulation == EMU_SOKOBAN)
       {
        player->LevelSolved = player->GameOver = TRUE;
        PlaySoundLevel(x, y, SND_BUING);
@@ -4921,7 +4739,7 @@ boolean SnapField(struct PlayerInfo *player, int dx, int dy)
   int jx = player->jx, jy = player->jy;
   int x = jx + dx, y = jy + dy;
 
-  if (player->gone || !IN_LEV_FIELD(x, y))
+  if (!player->active || !IN_LEV_FIELD(x, y))
     return FALSE;
 
   if (dx && dy)
@@ -4956,7 +4774,7 @@ boolean PlaceBomb(struct PlayerInfo *player)
   int jx = player->jx, jy = player->jy;
   int element;
 
-  if (player->gone || player->MovPos)
+  if (!player->active || player->MovPos)
     return FALSE;
 
   element = Feld[jx][jy];
@@ -4978,7 +4796,7 @@ boolean PlaceBomb(struct PlayerInfo *player)
             FS_SMALL, FC_YELLOW);
     if (IN_SCR_FIELD(SCREENX(jx), SCREENY(jy)))
     {
-      if (game_emulation == EMU_SUPAPLEX)
+      if (game.emulation == EMU_SUPAPLEX)
        DrawGraphic(SCREENX(jx), SCREENY(jy), GFX_SP_DISK_RED);
       else
        DrawGraphicThruMask(SCREENX(jx), SCREENY(jy), GFX_DYNAMIT);
@@ -5015,19 +4833,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);