rnd-20091112-1-src
authorHolger Schemel <info@artsoft.org>
Thu, 12 Nov 2009 22:55:15 +0000 (23:55 +0100)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:57:57 +0000 (10:57 +0200)
* fixed bug with single step mode (there were some cases where the game
  did not automatically return to pause mode, e.g. when trying to push
  things that don't move or when trying to run against a wall)

13 files changed:
ChangeLog
src/conftime.h
src/game.c
src/game_sp/DDScrollBuffer.c
src/game_sp/DDScrollBuffer.h
src/game_sp/DDSpriteBuffer.c
src/game_sp/Globals.c
src/game_sp/MainForm.c
src/game_sp/MainGameLoop.c
src/game_sp/export.h
src/game_sp/init.c
src/game_sp/main.c
src/game_sp/main_sp.h

index e42c6d05e448025df1ab032528ac965e4d42c972..c1bb34c0938d3636d7fa30e5a502be24881d3150 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2009-11-12
+       * fixed bug with single step mode (there were some cases where the game
+         did not automatically return to pause mode, e.g. when trying to push
+         things that don't move or when trying to run against a wall)
+
 2009-11-01
        * added support for loading Supaplex levels in MPX level file format
 
index 524cdb82dc356d742cf6197af7579070c8e2071b..70b165cdf492c587b68c766d08a1cf40e72868db 100644 (file)
@@ -1 +1 @@
-#define COMPILE_DATE_STRING "2009-11-01 21:31"
+#define COMPILE_DATE_STRING "2009-11-12 23:54"
index 80f157012eddb293b42049a8db6e7ee26976d99d..e2b67c24da8a67be955cc3b5b9414702c158d1a1 100644 (file)
@@ -11983,7 +11983,16 @@ static byte PlayerActions(struct PlayerInfo *player, byte player_action)
 
     if (tape.single_step && tape.recording && !tape.pausing)
     {
+#if 1
+      /* as it is called "single step mode", just return to pause mode when the
+        player stopped moving after one tile (or never starts moving at all) */
+      if (!player->is_moving)
+#else
+      /* this is buggy: there are quite some cases where the single step mode
+        does not return to pause mode (like pushing things that don't move
+        or simply by trying to run against a wall) */
       if (button1 || (dropped && !moved))
+#endif
       {
        TapeTogglePause(TAPE_TOGGLE_AUTOMATIC);
        SnapField(player, 0, 0);                /* stop snapping */
index 23ce4ce9af381573ff42c585aefa7f7cc3867ea5..e9b94f96a367679080f1c92f64661b2ae3073708 100644 (file)
@@ -33,6 +33,83 @@ long mhWnd;
 long mScrollX, mScrollY;
 long mDestXOff, mDestYOff;
 
+long ScreenBuffer[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
+boolean redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
+
+
+void UpdatePlayfield()
+{
+  int x, y;
+  int sx1 = mScrollX - TILEX;
+  int sy1 = mScrollY - TILEY;
+  int sx2 = mScrollX + SXSIZE + TILEX;
+  int sy2 = mScrollY + SYSIZE + TILEY;
+  int x1 = sx1 / TILEX;
+  int y1 = sy1 / TILEY;
+  int x2 = sx2 / TILEX;
+  int y2 = sy2 / TILEY;
+
+  for (y = DisplayMinY; y <= DisplayMaxY; y++)
+  {
+    for (x = DisplayMinX; x <= DisplayMaxX; x++)
+    {
+      if (x >= x1 && x < x2 && y >= y1 && y < y2)
+      {
+       int sx = x - x1;
+       int sy = y - y1;
+       int tsi = GetSI(x, y);
+       long id = ((PlayField16[tsi]) |
+                  (PlayField8[tsi] << 16) |
+                  (DisPlayField[tsi] << 24));
+       boolean redraw_screen_tile = (ScreenBuffer[sx][sy] != id);
+
+       if (redraw_screen_tile)
+       {
+         DrawFieldNoAnimated(x, y);
+         DrawFieldAnimated(x, y);
+
+         ScreenBuffer[sx][sy] = id;
+
+         redraw[sx][sy] = TRUE;
+         redraw_tiles++;
+       }
+      }
+    }
+  }
+}
+
+void OLD_UpdatePlayfield()
+{
+  int x, y;
+  int left = mScrollX / TILEX;
+  int top  = mScrollY / TILEY;
+
+  for (y = top; y < top + MAX_BUF_YSIZE; y++)
+  {
+    for (x = left; x < left + MAX_BUF_XSIZE; x++)
+    {
+      int sx = x % MAX_BUF_XSIZE;
+      int sy = y % MAX_BUF_YSIZE;
+      int tsi = GetSI(x, y);
+      long id = ((PlayField16[tsi]) |
+                (PlayField8[tsi] << 16) |
+                (DisPlayField[tsi] << 24));
+      boolean redraw_screen_tile = (ScreenBuffer[sx][sy] != id);
+
+      if (redraw_screen_tile)
+      {
+        DrawFieldNoAnimated(x, y);
+        DrawFieldAnimated(x, y);
+
+       ScreenBuffer[sx][sy] = id;
+
+       redraw[sx][sy] = TRUE;
+       redraw_tiles++;
+      }
+    }
+  }
+}
+
 void DDScrollBuffer_Let_DestXOff(long NewVal)
 {
   mDestXOff = NewVal;
@@ -131,6 +208,110 @@ void DDScrollBuffer_Cls(int BackColor)
   Buffer.BltColorFill(EmptyRect, BackColor);
 }
 
+
+/* copy the entire screen to the window at the scroll position */
+
+void BlitScreenToBitmap_SP(Bitmap *target_bitmap)
+{
+  int sx = TILEX + mScrollX % TILEX;
+  int sy = TILEY + mScrollY % TILEY;
+
+  BlitBitmap(screenBitmap, target_bitmap, sx, sy,
+            SCR_FIELDX * TILEX, SCR_FIELDY * TILEY, SX, SY);
+}
+
+void OLD_BlitScreenToBitmap_SP(Bitmap *target_bitmap)
+{
+  int x = mScrollX % (MAX_BUF_XSIZE * TILEX);
+  int y = mScrollY % (MAX_BUF_YSIZE * TILEY);
+
+  if (x < 2 * TILEX && y < 2 * TILEY)
+  {
+    BlitBitmap(screenBitmap, target_bitmap, x, y,
+              SCR_FIELDX * TILEX, SCR_FIELDY * TILEY, SX, SY);
+  }
+  else if (x < 2 * TILEX && y >= 2 * TILEY)
+  {
+    BlitBitmap(screenBitmap, target_bitmap, x, y,
+              SCR_FIELDX * TILEX, MAX_BUF_YSIZE * TILEY - y,
+              SX, SY);
+    BlitBitmap(screenBitmap, target_bitmap, x, 0,
+              SCR_FIELDX * TILEX, y - 2 * TILEY,
+              SX, SY + MAX_BUF_YSIZE * TILEY - y);
+  }
+  else if (x >= 2 * TILEX && y < 2 * TILEY)
+  {
+    BlitBitmap(screenBitmap, target_bitmap, x, y,
+              MAX_BUF_XSIZE * TILEX - x, SCR_FIELDY * TILEY,
+              SX, SY);
+    BlitBitmap(screenBitmap, target_bitmap, 0, y,
+              x - 2 * TILEX, SCR_FIELDY * TILEY,
+              SX + MAX_BUF_XSIZE * TILEX - x, SY);
+  }
+  else
+  {
+    BlitBitmap(screenBitmap, target_bitmap, x, y,
+              MAX_BUF_XSIZE * TILEX - x, MAX_BUF_YSIZE * TILEY - y,
+              SX, SY);
+    BlitBitmap(screenBitmap, target_bitmap, 0, y,
+              x - 2 * TILEX, MAX_BUF_YSIZE * TILEY - y,
+              SX + MAX_BUF_XSIZE * TILEX - x, SY);
+    BlitBitmap(screenBitmap, target_bitmap, x, 0,
+              MAX_BUF_XSIZE * TILEX - x, y - 2 * TILEY,
+              SX, SY + MAX_BUF_YSIZE * TILEY - y);
+    BlitBitmap(screenBitmap, target_bitmap, 0, 0,
+              x - 2 * TILEX, y - 2 * TILEY,
+              SX + MAX_BUF_XSIZE * TILEX - x, SY + MAX_BUF_YSIZE * TILEY - y);
+  }
+}
+
+void BackToFront_SP(void)
+{
+  static boolean scrolling_last = FALSE;
+  int left = mScrollX / TILEX;
+  int top  = mScrollY / TILEY;
+  boolean scrolling = (mScrollX % TILEX != 0 || mScrollY % TILEY != 0);
+  int x, y;
+
+  SyncDisplay();
+
+  if (1 ||
+      redraw_tiles > REDRAWTILES_THRESHOLD || scrolling || scrolling_last)
+  {
+    /* blit all (up to four) parts of the scroll buffer to the backbuffer */
+    BlitScreenToBitmap_SP(backbuffer);
+
+    /* blit the completely updated backbuffer to the window (in one blit) */
+    BlitBitmap(backbuffer, window, SX, SY, SXSIZE, SYSIZE, SX, SY);
+  }
+  else
+  {
+    for (x = 0; x < SCR_FIELDX; x++)
+    {
+      for (y = 0; y < SCR_FIELDY; y++)
+      {
+       int xx = (left + x) % MAX_BUF_XSIZE;
+       int yy = (top  + y) % MAX_BUF_YSIZE;
+
+       if (redraw[xx][yy])
+         BlitBitmap(screenBitmap, window,
+                    xx * TILEX, yy * TILEY, TILEX, TILEY,
+                    SX + x * TILEX, SY + y * TILEY);
+      }
+    }
+  }
+
+  FlushDisplay();
+
+  for (x = 0; x < MAX_BUF_XSIZE; x++)
+    for (y = 0; y < MAX_BUF_YSIZE; y++)
+      redraw[x][y] = FALSE;
+  redraw_tiles = 0;
+
+  scrolling_last = scrolling;
+}
+
+
 void DDScrollBuffer_Blt_Ext(Bitmap *target_bitmap)
 {
   RECT DR, SR;
@@ -157,11 +338,14 @@ void DDScrollBuffer_Blt_Ext(Bitmap *target_bitmap)
     tX = (DR.right - DR.left) / Stretch;
     tY = (DR.bottom - DR.top) / Stretch;
   }
+
   {
     SR.left = mScrollX + mDestXOff;
     SR.top = mScrollY + mDestYOff;
+
     SR.right = SR.left + tX;
     SR.bottom = SR.top + tY;
+
     //    If mWidth < SR.right Then
     //      SR.right = mWidth
     //      DR.right = DR.left + Stretch * (SR.right - SR.left)
@@ -356,7 +540,19 @@ void DDScrollBuffer_Blt_Ext(Bitmap *target_bitmap)
 
 void DDScrollBuffer_Blt()
 {
+#if 1
+
+#if 1
+  BackToFront_SP();
+#else
+  /* !!! TEST ONLY !!! */
+  BlitBitmap(screenBitmap, window,
+            0, 0, SCR_FIELDX * TILEX, SCR_FIELDY * TILEY, SX, SY);
+#endif
+
+#else
   DDScrollBuffer_Blt_Ext(window);
+#endif
 }
 
 void DDScrollBuffer_ScrollTo(int X, int Y)
index 9f30e307a7d87dcf9c1898980a71d14f31b8aac4..dbcb1db5f7f6a722ed41c23ec0e340d65cca31f8 100644 (file)
 
 #include "global.h"
 
+extern long mScrollX, mScrollY;
+
+extern boolean redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
+
+extern void UpdatePlayfield();
+
 extern void DDScrollBuffer_Blt_Ext(Bitmap *);
 extern void DDScrollBuffer_Blt();
 extern void DDScrollBuffer_Cls(int BackColor);
index e7412265cfde796c41926c6280793321eef035cd..7572c919d2e415d6d8e0aecd4c89ba21af02da79 100644 (file)
@@ -177,13 +177,109 @@ static void Blt(int pX, int pY, int SpriteX, int SpriteY)
   long Tmp;
 #endif
 
+  int sx1 = mScrollX - TILEX;
+  int sy1 = mScrollY - TILEY;
+  int sx2 = mScrollX + SXSIZE + TILEX;
+  int sy2 = mScrollY + SYSIZE + TILEY;
+  int x1 = sx1 / TILEX;
+  int y1 = sy1 / TILEY;
+  int x2 = sx2 / TILEX;
+  int y2 = sy2 / TILEY;
+
+  int sx = pX - x1 * TILEX;
+  int sy = pY - y1 * TILEY;
+
+#if 0
+  printf(":1: DDSpriteBuffer.c: Blt(): %d, %d [%ld, %ld]\n",
+        pX, pY, mScrollX, mScrollY);
+#endif
+
+  if (NoDisplayFlag)
+    return;
+
+  /* do not draw fields that are outside the visible screen area */
+  if (pX < sx1 || pX >= sx2 || pY < sy1 || pY >= sy2)
+    return;
+
+#if 0
+  printf(":2: DDSpriteBuffer.c: Blt(): %d, %d [%ld, %ld]\n",
+        pX, pY, mScrollX, mScrollY);
+#endif
+
+  {
+    DR.left = pX + mDestXOff;
+    DR.top = pY + mDestYOff;
+    DR.right = pX + mSpriteWidth + mDestXOff;
+    DR.bottom = pY + mSpriteHeight + mDestYOff;
+  }
+  {
+    SR.left = mSpriteWidth * (SpriteX - 1);
+    SR.top = mSpriteHeight * (SpriteY - 1);
+    SR.right = SR.left + mSpriteWidth;
+    SR.bottom = SR.top + mSpriteHeight;
+  }
+
+#if 0
+  printf("::: DDSpriteBuffer.c: Blt(): %d, %d\n", DR.left, DR.top);
+#endif
+
+#if 0
+  if (pX == 0 * StretchWidth && pY == 0 * StretchWidth)
+    printf("::: TEST: drawing topleft corner ...\n");
+  if (pX == 59 * StretchWidth && pY == 23 * StretchWidth)
+    printf("::: TEST: drawing bottomright corner ...\n");
+#endif
+
+#if 1
+
+#if 1
+  BlitBitmap(sp_objects, screenBitmap,
+            SR.left, SR.top,
+            mSpriteWidth, mSpriteHeight,
+            sx, sy);
+#else
+  BlitBitmap(sp_objects, screenBitmap,
+            SR.left, SR.top,
+            mSpriteWidth, mSpriteHeight,
+            DR.left, DR.top);
+#endif
+
+#else
+  Tmp = mDest.Blt(DR, &Buffer, SR, DDBLT_WAIT);
+#endif
+}
+
+static void OLD_Blt(int pX, int pY, int SpriteX, int SpriteY)
+{
+  RECT DR, SR;
+#if 0
+  long Tmp;
+#endif
+
+#if 1
+  int left = mScrollX;
+  int top  = mScrollY;
+#else
+  int left = mScrollX / TILEX;
+  int top  = mScrollY / TILEY;
+#endif
+
+  int sx = pX % (MAX_BUF_XSIZE * TILEX);
+  int sy = pY % (MAX_BUF_YSIZE * TILEY);
+
 #if 0
-  printf("::: DDSpriteBuffer.c: Blt(): %d, %d\n", pX, pY);
+  printf("::: DDSpriteBuffer.c: Blt(): %d, %d [%ld, %ld] [%d, %d]\n",
+        pX, pY, mScrollX, mScrollY, left, top);
 #endif
 
   if (NoDisplayFlag)
     return;
 
+  /* do not draw fields that are outside the visible screen area */
+  if (pX < left || pX >= left + MAX_BUF_XSIZE * TILEX ||
+      pY < top  || pY >= top  + MAX_BUF_YSIZE * TILEY)
+    return;
+
   {
     DR.left = pX + mDestXOff;
     DR.top = pY + mDestYOff;
@@ -208,11 +304,20 @@ static void Blt(int pX, int pY, int SpriteX, int SpriteY)
     printf("::: TEST: drawing bottomright corner ...\n");
 #endif
 
+#if 1
+
 #if 1
+  BlitBitmap(sp_objects, screenBitmap,
+            SR.left, SR.top,
+            mSpriteWidth, mSpriteHeight,
+            sx, sy);
+#else
   BlitBitmap(sp_objects, screenBitmap,
             SR.left, SR.top,
             mSpriteWidth, mSpriteHeight,
             DR.left, DR.top);
+#endif
+
 #else
   Tmp = mDest.Blt(DR, &Buffer, SR, DDBLT_WAIT);
 #endif
@@ -227,6 +332,7 @@ void DDSpriteBuffer_BltEx(int pX, int pY, int SpritePos)
 
   XPos = (SpritePos % mXSpriteCount) + 1;
   YPos = (SpritePos / mXSpriteCount) + 1;
+
   Blt(pX, pY, XPos, YPos);
 }
 
index a54380ef768bd59d73188c3a718d5853b111b265..4c4f7afebfac4b97f8a4f7fa93bf254a57024503 100644 (file)
@@ -64,8 +64,6 @@ int *PlayField16;
 byte *PlayField8;
 byte *DisPlayField;
 
-long ScreenBuffer[SP_SCREEN_BUFFER_XSIZE][SP_SCREEN_BUFFER_YSIZE];
-
 // Public DisplayMin%, DisplayMax%, DisplayWidth%, DisplayHeight%
 
 int TimerVar;
index 7936fee2f28d9e6d4a1f2b3d7969fd3bef8c494e..2f845154c45d05043d924fd7609ffd06163657d1 100644 (file)
@@ -1370,8 +1370,9 @@ void Form_Load()
   PauseMode = 0;
   //  BaseWidth = 16
 
-#if 0
-  menBorder_Click();
+#if 1
+  if (0)
+    menBorder_Click();
 #endif
 
   Loaded = True;
index bae1d6d95d4aa886acbca1a8586bacae1bd36874..42bafa50fe9e253fbf04201159caa617171c7a12 100644 (file)
@@ -117,8 +117,15 @@ locRepeatMainGameLoop:                           // start repeating game loop
   LastFrame = Clock.TickNow(); // store the frame time
 #endif
   //   never any additional code between here!
+
+
+
+#if 0
   if (! NoDisplayFlag) // copy the BackBuffer(=Stage) to visible screen
     Stage.Blt();
+#endif
+
+
 
   // FS   end of synchronization
   // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
index aecfcc856a83c9741678ddafbe802bed168ed911..f54bb28aee2c012a4b1405d5e4a0a630147393ba 100644 (file)
                                         SP_PLAYFIELD_HEIGHT)
 #define SP_LEVEL_SIZE                  (SP_HEADER_SIZE + SP_PLAYFIELD_SIZE)
 
+#if 0
 #define SP_SCREEN_BUFFER_XSIZE         (SCR_FIELDX + 2)
 #define SP_SCREEN_BUFFER_YSIZE         (SCR_FIELDY + 2)
+#endif
 
 #define SP_FRAMES_PER_SECOND           35
 #define SP_MAX_TAPE_LEN                        64010   /* (see "spfix63.doc") */
index 0e217a9dcbbc90216629237b495b71e44242c799..ee7034247ef27228fa77cc6e585a50d00b10412b 100644 (file)
@@ -36,7 +36,7 @@ void sp_open_all()
 
   SetBitmaps_SP(&sp_objects);
 
-#if 1
+#if 0
   /* too small for oversized levels, but too big for graphics performance */
   /* (the whole playfield is drawn/updated, not only visible/scrolled area) */
   /* !!! FIX THIS !!! */
index be2cb29fcde4758aac875a5578c0c317076f663d..467c82d2a2d267abea2c5275284abe3c3ec73eef 100644 (file)
@@ -18,19 +18,27 @@ void InitGameEngine_SP()
 #endif
 }
 
+#if 0
 void BlitScreenToBitmap_SP(Bitmap *target_bitmap)
 {
   DDScrollBuffer_Blt_Ext(target_bitmap);
 }
+#endif
+
+void RedrawPlayfield_SP(boolean force_redraw)
+{
+  // subDisplayLevel();
+
+  UpdatePlayfield();
+
+  BackToFront_SP();
+}
 
 void GameActions_SP(byte action[MAX_PLAYERS], boolean warp_mode)
 {
   byte single_player_action = action[0];
 
   subMainGameLoop_Main(single_player_action, warp_mode);
-}
 
-void RedrawPlayfield_SP(boolean force_redraw)
-{
-  subDisplayLevel();
+  RedrawPlayfield_SP(FALSE);
 }
index d9294194132c2bf45cafe567410fcba0ef5b0de1..7e0480e2c9f6fea89103b15e52fbfa4329e8571f 100644 (file)
@@ -40,8 +40,8 @@
 #define SCR_MENUY              12
 #define SCR_FIELDX             17
 #define SCR_FIELDY             17
-#define MAX_BUF_XSIZE          (SCR_FIELDX + 2)
-#define MAX_BUF_YSIZE          (SCR_FIELDY + 2)
+#define MAX_BUF_XSIZE          (2 + SCR_FIELDX + 2)
+#define MAX_BUF_YSIZE          (2 + SCR_FIELDY + 2)
 
 /* often used screen positions */
 #define SX                     8