rnd-20000917-1-src
[rocksndiamonds.git] / src / game.c
index c75171ba1306cd893467e33428f739e204f7a2ce..0b731c327dc35ad1276082b0193367580f70fac3 100644 (file)
@@ -176,6 +176,9 @@ void GetPlayerConfig()
     setup.sound_music = FALSE;
   }
 
+  if (!fullscreen_available)
+    setup.fullscreen = FALSE;
+
   setup.sound_simple = setup.sound;
 
   InitJoysticks();
@@ -229,8 +232,17 @@ static void InitField(int x, int y, boolean init_game)
 {
   switch (Feld[x][y])
   {
-    case EL_SPIELFIGUR:
     case EL_SP_MURPHY:
+      if (init_game)
+      {
+       if (stored_player[0].present)
+       {
+         Feld[x][y] = EL_SP_MURPHY_CLONE;
+         break;
+       }
+      }
+      /* no break! */
+    case EL_SPIELFIGUR:
       if (init_game)
        Feld[x][y] = EL_SPIELER1;
       /* no break! */
@@ -493,7 +505,7 @@ void InitGame()
 
   network_player_action_received = FALSE;
 
-#ifndef MSDOS
+#if !defined(MSDOS) && !defined(WIN32)
   /* initial null action */
   if (network_playing)
     SendToServer_MovePlayer(MV_NO_MOVING);
@@ -700,20 +712,18 @@ void InitGame()
   DrawAllPlayers();
   FadeToFront();
 
-  /* after drawing the level, corect some elements */
-
+  /* after drawing the level, correct some elements */
   if (game.timegate_time_left == 0)
     CloseAllOpenTimegates();
 
   if (setup.soft_scrolling)
-    XCopyArea(display, fieldbuffer, backbuffer, gc,
-             FX, FY, SXSIZE, SYSIZE, SX, SY);
+    BlitBitmap(fieldbuffer, backbuffer, FX, FY, SXSIZE, SYSIZE, SX, SY);
 
   redraw_mask |= REDRAW_FROM_BACKBUFFER;
 
   /* 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);
+  BlitBitmap(pix[PIX_DOOR], drawto,
+            DOOR_GFX_PAGEX5, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE, DX, DY);
 
   if (level_nr < 100)
     DrawText(DX + XX_LEVEL, DY + YY_LEVEL,
@@ -722,10 +732,10 @@ void InitGame()
   {
     DrawTextExt(drawto, gc, DX + XX_EMERALDS, DY + YY_EMERALDS,
                int2str(level_nr, 3), FS_SMALL, FC_SPECIAL3);
-    XCopyArea(display, drawto, drawto, gc,
-             DX + XX_EMERALDS, DY + YY_EMERALDS + 1,
-             FONT5_XSIZE * 3, FONT5_YSIZE - 1,
-             DX + XX_LEVEL - 1, DY + YY_LEVEL + 1);
+    BlitBitmap(drawto, drawto,
+              DX + XX_EMERALDS, DY + YY_EMERALDS + 1,
+              FONT5_XSIZE * 3, FONT5_YSIZE - 1,
+              DX + XX_LEVEL - 1, DY + YY_LEVEL + 1);
   }
 
   DrawText(DX + XX_EMERALDS, DY + YY_EMERALDS,
@@ -745,15 +755,15 @@ void InitGame()
   MapTapeButtons();
 
   /* copy actual game door content to door double buffer for OpenDoor() */
-  XCopyArea(display, drawto, pix[PIX_DB_DOOR], gc,
-           DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
+  BlitBitmap(drawto, pix[PIX_DB_DOOR],
+            DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
 
   OpenDoor(DOOR_OPEN_ALL);
 
   if (setup.sound_music)
     PlaySoundLoop(background_loop[level_nr % num_bg_loops]);
 
-  XAutoRepeatOff(display);
+  KeyboardAutoRepeatOff();
 
   if (options.verbose)
   {
@@ -1160,8 +1170,8 @@ void RemoveMovingField(int x, int y)
 
   if (Feld[x][y] == EL_BLOCKED &&
       (Store[oldx][oldy] == EL_MORAST_LEER ||
-       Store[oldx][oldy] == EL_SIEB_LEER ||
-       Store[oldx][oldy] == EL_SIEB2_LEER ||
+       Store[oldx][oldy] == EL_MAGIC_WALL_EMPTY ||
+       Store[oldx][oldy] == EL_MAGIC_WALL_BD_EMPTY ||
        Store[oldx][oldy] == EL_AMOEBE_NASS))
   {
     Feld[oldx][oldy] = Store[oldx][oldy];
@@ -1804,11 +1814,12 @@ void Impact(int x, int y)
   if (!lastline && object_hit)         /* check which object was hit */
   {
     if (CAN_CHANGE(element) && 
-       (smashed == EL_SIEB_INAKTIV || smashed == EL_SIEB2_INAKTIV))
+       (smashed == EL_MAGIC_WALL_OFF || smashed == EL_MAGIC_WALL_BD_OFF))
     {
       int x, y;
       int activated_magic_wall =
-       (smashed == EL_SIEB_INAKTIV ? EL_SIEB_LEER : EL_SIEB2_LEER);
+       (smashed == EL_MAGIC_WALL_OFF ? EL_MAGIC_WALL_EMPTY :
+        EL_MAGIC_WALL_BD_EMPTY);
 
       /* activate magic wall / mill */
 
@@ -1898,7 +1909,8 @@ void Impact(int x, int y)
 
   /* play sound of magic wall / mill */
   if (!lastline &&
-      (Feld[x][y+1] == EL_SIEB_LEER || Feld[x][y+1] == EL_SIEB2_LEER))
+      (Feld[x][y+1] == EL_MAGIC_WALL_EMPTY ||
+       Feld[x][y+1] == EL_MAGIC_WALL_BD_EMPTY))
   {
     PlaySoundLevel(x, y, SND_QUIRK);
     return;
@@ -2440,15 +2452,15 @@ void StartMoving(int x, int y)
       InitMovingField(x, y, MV_DOWN);
       Store[x][y] = EL_MORAST_VOLL;
     }
-    else if (element == EL_SIEB_VOLL)
+    else if (element == EL_MAGIC_WALL_FULL)
     {
       if (IS_FREE(x, y+1))
       {
        InitMovingField(x, y, MV_DOWN);
        Feld[x][y] = EL_CHANGED(Store2[x][y]);
-       Store[x][y] = EL_SIEB_LEER;
+       Store[x][y] = EL_MAGIC_WALL_EMPTY;
       }
-      else if (Feld[x][y+1] == EL_SIEB_LEER)
+      else if (Feld[x][y+1] == EL_MAGIC_WALL_EMPTY)
       {
        if (!MovDelay[x][y])
          MovDelay[x][y] = TILEY/4 + 1;
@@ -2460,21 +2472,21 @@ void StartMoving(int x, int y)
            return;
        }
 
-       Feld[x][y] = EL_SIEB_LEER;
-       Feld[x][y+1] = EL_SIEB_VOLL;
+       Feld[x][y] = EL_MAGIC_WALL_EMPTY;
+       Feld[x][y+1] = EL_MAGIC_WALL_FULL;
        Store2[x][y+1] = EL_CHANGED(Store2[x][y]);
        Store2[x][y] = 0;
       }
     }
-    else if (element == EL_SIEB2_VOLL)
+    else if (element == EL_MAGIC_WALL_BD_FULL)
     {
       if (IS_FREE(x, y+1))
       {
        InitMovingField(x, y, MV_DOWN);
        Feld[x][y] = EL_CHANGED2(Store2[x][y]);
-       Store[x][y] = EL_SIEB2_LEER;
+       Store[x][y] = EL_MAGIC_WALL_BD_EMPTY;
       }
-      else if (Feld[x][y+1] == EL_SIEB2_LEER)
+      else if (Feld[x][y+1] == EL_MAGIC_WALL_BD_EMPTY)
       {
        if (!MovDelay[x][y])
          MovDelay[x][y] = TILEY/4 + 1;
@@ -2486,18 +2498,20 @@ void StartMoving(int x, int y)
            return;
        }
 
-       Feld[x][y] = EL_SIEB2_LEER;
-       Feld[x][y+1] = EL_SIEB2_VOLL;
+       Feld[x][y] = EL_MAGIC_WALL_BD_EMPTY;
+       Feld[x][y+1] = EL_MAGIC_WALL_BD_FULL;
        Store2[x][y+1] = EL_CHANGED2(Store2[x][y]);
        Store2[x][y] = 0;
       }
     }
     else if (CAN_CHANGE(element) &&
-            (Feld[x][y+1] == EL_SIEB_LEER || Feld[x][y+1] == EL_SIEB2_LEER))
+            (Feld[x][y+1] == EL_MAGIC_WALL_EMPTY ||
+             Feld[x][y+1] == EL_MAGIC_WALL_BD_EMPTY))
     {
       InitMovingField(x, y, MV_DOWN);
       Store[x][y] =
-       (Feld[x][y+1] == EL_SIEB_LEER ? EL_SIEB_VOLL : EL_SIEB2_VOLL);
+       (Feld[x][y+1] == EL_MAGIC_WALL_EMPTY ? EL_MAGIC_WALL_FULL :
+        EL_MAGIC_WALL_BD_FULL);
       Store2[x][y+1] = element;
     }
     else if (CAN_SMASH(element) && Feld[x][y+1] == EL_SALZSAEURE)
@@ -2941,27 +2955,30 @@ void ContinueMoving(int x, int y)
       Store[x][y] = 0;
       Feld[x][y] = EL_MORAST_LEER;
     }
-    else if (Store[x][y] == EL_SIEB_VOLL)
+    else if (Store[x][y] == EL_MAGIC_WALL_FULL)
     {
       Store[x][y] = 0;
       element = Feld[newx][newy] =
-       (game.magic_wall_active ? EL_SIEB_VOLL : EL_SIEB_TOT);
+       (game.magic_wall_active ? EL_MAGIC_WALL_FULL : EL_MAGIC_WALL_DEAD);
     }
-    else if (Store[x][y] == EL_SIEB_LEER)
+    else if (Store[x][y] == EL_MAGIC_WALL_EMPTY)
     {
       Store[x][y] = Store2[x][y] = 0;
-      Feld[x][y] = (game.magic_wall_active ? EL_SIEB_LEER : EL_SIEB_TOT);
+      Feld[x][y] = (game.magic_wall_active ? EL_MAGIC_WALL_EMPTY :
+                   EL_MAGIC_WALL_DEAD);
     }
-    else if (Store[x][y] == EL_SIEB2_VOLL)
+    else if (Store[x][y] == EL_MAGIC_WALL_BD_FULL)
     {
       Store[x][y] = 0;
       element = Feld[newx][newy] =
-       (game.magic_wall_active ? EL_SIEB2_VOLL : EL_SIEB2_TOT);
+       (game.magic_wall_active ? EL_MAGIC_WALL_BD_FULL :
+        EL_MAGIC_WALL_BD_DEAD);
     }
-    else if (Store[x][y] == EL_SIEB2_LEER)
+    else if (Store[x][y] == EL_MAGIC_WALL_BD_EMPTY)
     {
       Store[x][y] = Store2[x][y] = 0;
-      Feld[x][y] = (game.magic_wall_active ? EL_SIEB2_LEER : EL_SIEB2_TOT);
+      Feld[x][y] = (game.magic_wall_active ? EL_MAGIC_WALL_BD_EMPTY :
+                   EL_MAGIC_WALL_BD_DEAD);
     }
     else if (Store[x][y] == EL_SALZSAEURE)
     {
@@ -3575,7 +3592,7 @@ void BreakingPearl(int x, int y)
 
 void SiebAktivieren(int x, int y, int typ)
 {
-  int graphic = (typ == 1 ? GFX_SIEB_VOLL : GFX_SIEB2_VOLL) + 3;
+  int graphic = (typ == 1 ? GFX_MAGIC_WALL_FULL : GFX_MAGIC_WALL_BD_FULL) + 3;
 
   DrawGraphicAnimation(x, y, graphic, 4, 4, ANIM_REVERSE);
 }
@@ -3777,8 +3794,8 @@ void EdelsteinFunkeln(int x, int y)
          dest_x = FX + SCREENX(x)*TILEX;
          dest_y = FY + SCREENY(y)*TILEY;
 
-         XCopyArea(display, drawto_field, window, gc,
-                   dest_x, dest_y, TILEX, TILEY, dest_x, dest_y);
+         BlitBitmap(drawto_field, window,
+                    dest_x, dest_y, TILEX, TILEY, dest_x, dest_y);
          SetDrawtoField(DRAW_DIRECT);
        }
       }
@@ -4225,7 +4242,7 @@ void GameActions()
 #endif
     */
 
-#ifndef MSDOS
+#if !defined(MSDOS) && !defined(WIN32)
     /* last chance to get network player actions without main loop delay */
     HandleNetworking();
 #endif
@@ -4262,7 +4279,7 @@ void GameActions()
       stored_player[i].effective_action = stored_player[i].action;
   }
 
-#ifndef MSDOS
+#if !defined(MSDOS) && !defined(WIN32)
   if (network_playing)
     SendToServer_MovePlayer(summarized_player_action);
 #endif
@@ -4422,14 +4439,15 @@ void GameActions()
       boolean sieb = FALSE;
       int jx = local_player->jx, jy = local_player->jy;
 
-      if (element == EL_SIEB_LEER || element == EL_SIEB_VOLL ||
-         Store[x][y] == EL_SIEB_LEER)
+      if (element == EL_MAGIC_WALL_EMPTY || element == EL_MAGIC_WALL_FULL ||
+         Store[x][y] == EL_MAGIC_WALL_EMPTY)
       {
        SiebAktivieren(x, y, 1);
        sieb = TRUE;
       }
-      else if (element == EL_SIEB2_LEER || element == EL_SIEB2_VOLL ||
-              Store[x][y] == EL_SIEB2_LEER)
+      else if (element == EL_MAGIC_WALL_BD_EMPTY ||
+              element == EL_MAGIC_WALL_BD_FULL ||
+              Store[x][y] == EL_MAGIC_WALL_BD_EMPTY)
       {
        SiebAktivieren(x, y, 2);
        sieb = TRUE;
@@ -4458,14 +4476,15 @@ void GameActions()
        {
          element = Feld[x][y];
 
-         if (element == EL_SIEB_LEER || element == EL_SIEB_VOLL)
+         if (element == EL_MAGIC_WALL_EMPTY || element == EL_MAGIC_WALL_FULL)
          {
-           Feld[x][y] = EL_SIEB_TOT;
+           Feld[x][y] = EL_MAGIC_WALL_DEAD;
            DrawLevelField(x, y);
          }
-         else if (element == EL_SIEB2_LEER || element == EL_SIEB2_VOLL)
+         else if (element == EL_MAGIC_WALL_BD_EMPTY ||
+                  element == EL_MAGIC_WALL_BD_FULL)
          {
-           Feld[x][y] = EL_SIEB2_TOT;
+           Feld[x][y] = EL_MAGIC_WALL_BD_DEAD;
            DrawLevelField(x, y);
          }
        }
@@ -4543,6 +4562,25 @@ void GameActions()
   }
 
   DrawAllPlayers();
+
+  if (options.debug)                   /* calculate frames per second */
+  {
+    static unsigned long fps_counter = 0;
+    static int fps_frames = 0;
+    unsigned long fps_delay_ms = Counter() - fps_counter;
+
+    fps_frames++;
+
+    if (fps_delay_ms >= 500)   /* calculate fps every 0.5 seconds */
+    {
+      global.frames_per_second = 1000 * (float)fps_frames / fps_delay_ms;
+
+      fps_frames = 0;
+      fps_counter = Counter();
+    }
+
+    redraw_mask |= REDRAW_FPS;
+  }
 }
 
 static boolean AllPlayersInSight(struct PlayerInfo *player, int x, int y)
@@ -4589,13 +4627,13 @@ void ScrollLevel(int dx, int dy)
   int softscroll_offset = (setup.soft_scrolling ? TILEX : 0);
   int x, y;
 
-  XCopyArea(display, drawto_field, drawto_field, gc,
-           FX + TILEX*(dx == -1) - softscroll_offset,
-           FY + TILEY*(dy == -1) - softscroll_offset,
-           SXSIZE - TILEX*(dx!=0) + 2*softscroll_offset,
-           SYSIZE - TILEY*(dy!=0) + 2*softscroll_offset,
-           FX + TILEX*(dx == 1) - softscroll_offset,
-           FY + TILEY*(dy == 1) - softscroll_offset);
+  BlitBitmap(drawto_field, drawto_field,
+            FX + TILEX*(dx == -1) - softscroll_offset,
+            FY + TILEY*(dy == -1) - softscroll_offset,
+            SXSIZE - TILEX*(dx!=0) + 2*softscroll_offset,
+            SYSIZE - TILEY*(dy!=0) + 2*softscroll_offset,
+            FX + TILEX*(dx == 1) - softscroll_offset,
+            FY + TILEY*(dy == 1) - softscroll_offset);
 
   if (dx)
   {
@@ -6047,7 +6085,7 @@ void CreateGameButtons()
 
   for (i=0; i<NUM_GAME_BUTTONS; i++)
   {
-    Pixmap gd_pixmap = pix[PIX_DOOR];
+    Bitmap gd_bitmap = pix[PIX_DOOR];
     struct GadgetInfo *gi;
     int button_type;
     boolean checked;
@@ -6092,10 +6130,10 @@ void CreateGameButtons()
                      GDI_TYPE, button_type,
                      GDI_STATE, GD_BUTTON_UNPRESSED,
                      GDI_CHECKED, checked,
-                     GDI_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y1,
-                     GDI_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y1,
-                     GDI_ALT_DESIGN_UNPRESSED, gd_pixmap, gd_x1, gd_y2,
-                     GDI_ALT_DESIGN_PRESSED, gd_pixmap, gd_x2, gd_y2,
+                     GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y1,
+                     GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y1,
+                     GDI_ALT_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y2,
+                     GDI_ALT_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y2,
                      GDI_EVENT_MASK, event_mask,
                      GDI_CALLBACK_ACTION, HandleGameButtons,
                      GDI_END);
@@ -6145,7 +6183,7 @@ static void HandleGameButtons(struct GadgetInfo *gi)
          Request("Do you really want to quit the game ?",
                  REQ_ASK | REQ_STAY_CLOSED))
       { 
-#ifndef MSDOS
+#if !defined(MSDOS) && !defined(WIN32)
        if (options.network)
          SendToServer_StopPlaying();
        else
@@ -6162,7 +6200,7 @@ static void HandleGameButtons(struct GadgetInfo *gi)
     case GAME_CTRL_ID_PAUSE:
       if (options.network)
       {
-#ifndef MSDOS
+#if !defined(MSDOS) && !defined(WIN32)
        if (tape.pausing)
          SendToServer_ContinuePlaying();
        else
@@ -6176,7 +6214,7 @@ static void HandleGameButtons(struct GadgetInfo *gi)
     case GAME_CTRL_ID_PLAY:
       if (tape.pausing)
       {
-#ifndef MSDOS
+#if !defined(MSDOS) && !defined(WIN32)
        if (options.network)
          SendToServer_ContinuePlaying();
        else