long mWidth, mHeight;
long mhWnd;
long mScrollX, mScrollY;
+long mScrollX_last, mScrollY_last;
long mDestXOff, mDestYOff;
+long ScreenBuffer[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
+boolean redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
+
+int TEST_flag = 0;
+
+
+static void ScrollPlayfield(int dx, int dy)
+{
+ int x1 = mScrollX_last / TILEX - 2;
+ int y1 = mScrollY_last / TILEY - 2;
+ int x2 = mScrollX_last / TILEX + (SCR_FIELDX - 1) + 2;
+ int y2 = mScrollY_last / TILEY + (SCR_FIELDY - 1) + 2;
+ int x, y;
+
+ BlitBitmap(screenBitmap, screenBitmap,
+ TILEX * (dx == -1),
+ TILEY * (dy == -1),
+ (MAX_BUF_XSIZE * TILEX) - TILEX * (dx != 0),
+ (MAX_BUF_YSIZE * TILEY) - TILEY * (dy != 0),
+ TILEX * (dx == 1),
+ TILEY * (dy == 1));
+
+ /* when scrolling the whole playfield, do not redraw single tiles */
+ for (x = 0; x < MAX_BUF_XSIZE; x++)
+ for (y = 0; y < MAX_BUF_YSIZE; y++)
+ redraw[x][y] = FALSE;
+ redraw_tiles = 0;
+
+#if 1
+ DrawFrameIfNeeded();
+#endif
+
+ 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));
+
+#if 0
+#if 1
+ printf("::: [%d] %d [%d, %d] [%d]\n", dx, sx, x, y, buf_xsize);
+#else
+ if (sx == 0 || sx == MAX_BUF_XSIZE - 1)
+ printf("::: %d, %d\n", dx, sx);
+#endif
+#endif
+
+ if ((dx == -1 && x == x2) ||
+ (dx == +1 && x == x1) ||
+ (dy == -1 && y == y2) ||
+ (dy == +1 && y == y1))
+ {
+#if 0
+ printf("::: %d, %d\n", sx, sy);
+#endif
+
+ TEST_flag = 1;
+
+ DrawFieldNoAnimated(x, y);
+ DrawFieldAnimated(x, y);
+
+ TEST_flag = 0;
+ }
+
+ ScreenBuffer[sx][sy] = id;
+ }
+ }
+ }
+}
+
+static void ScrollPlayfieldIfNeededExt(boolean reset)
+{
+ if (reset)
+ {
+ mScrollX_last = -1;
+ mScrollY_last = -1;
+
+ return;
+ }
+
+ if (mScrollX_last == -1 || mScrollY_last == -1)
+ {
+ mScrollX_last = mScrollX;
+ mScrollY_last = mScrollY;
+
+ return;
+ }
+
+ /* check if scrolling the playfield reached the destination tile position */
+ if ((mScrollX != mScrollX_last || mScrollY != mScrollY_last) &&
+ mScrollX % TILEX == 0 && mScrollY % TILEY == 0)
+ {
+ int dx = (mScrollX < mScrollX_last ? 1 : mScrollX > mScrollX_last ? -1 : 0);
+ int dy = (mScrollY < mScrollY_last ? 1 : mScrollY > mScrollY_last ? -1 : 0);
+
+ mScrollX_last = mScrollX;
+ mScrollY_last = mScrollY;
+
+ ScrollPlayfield(dx, dy);
+ }
+}
+
+static void ScrollPlayfieldIfNeeded()
+{
+ ScrollPlayfieldIfNeededExt(FALSE);
+}
+
+void InitScrollPlayfield()
+{
+ ScrollPlayfieldIfNeededExt(TRUE);
+}
+
+void UpdatePlayfield()
+{
+ int x1 = mScrollX_last / TILEX - 2;
+ int y1 = mScrollY_last / TILEY - 2;
+ int x2 = mScrollX_last / TILEX + (SCR_FIELDX - 1) + 2;
+ int y2 = mScrollY_last / TILEY + (SCR_FIELDY - 1) + 2;
+ int x, y;
+
+ 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 0
+ if (LowByte(PlayField16[tsi]) == fiMurphy)
+ continue;
+#endif
+
+ if (redraw_screen_tile)
+ {
+#if 0
+ DrawFieldNoAnimated(x, y);
+ DrawFieldAnimated(x, y);
+#endif
+
+ 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;
Buffer.BltColorFill(EmptyRect, BackColor);
}
+
+/* copy the entire screen to the window at the scroll position */
+
+void BlitScreenToBitmap_SP(Bitmap *target_bitmap)
+{
+ int px = 2 * TILEX + (mScrollX - mScrollX_last) % TILEX;
+ int py = 2 * TILEY + (mScrollY - mScrollY_last) % TILEY;
+ int sx, sy, sxsize, sysize;
+
+#if 1
+ int xsize = SXSIZE;
+ int ysize = SYSIZE;
+ int full_xsize = (FieldWidth - (menBorder.Checked ? 0 : 1)) * TILEX;
+ int full_ysize = (FieldHeight - (menBorder.Checked ? 0 : 1)) * TILEY;
+
+ sxsize = (full_xsize < xsize ? full_xsize : xsize);
+ sysize = (full_ysize < ysize ? full_ysize : ysize);
+ sx = SX + (full_xsize < xsize ? (xsize - full_xsize) / 2 : 0);
+ sy = SY + (full_ysize < ysize ? (ysize - full_ysize) / 2 : 0);
+#endif
+
+#if 1
+ if (!menBorder.Checked)
+ {
+ px += TILEX / 2;
+ py += TILEY / 2;
+ }
+#endif
+
+ BlitBitmap(screenBitmap, target_bitmap, px, py, sxsize, sysize, 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)
+ {
+#if 1
+ BlitScreenToBitmap_SP(window);
+#else
+ /* 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);
+#endif
+ }
+ 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;
long tX, tY, L;
+ int sX, sY;
// RECT ERect;
// long Restore;
if (NoDisplayFlag)
return;
-#if 0
+#if 1
+ DR.left = 0;
+ DR.top = 0;
+ DR.right = SCR_FIELDX * TILEX;
+ DR.bottom = SCR_FIELDY * TILEY;
+#else
// --- On Error GoTo BltEH
DirectX.GetWindowRect(mhWnd, DR);
// --- On Error GoTo 0
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)
}
#if 1
+ SR.left = (SR.left < 0 ? 0 : SR.left);
+ SR.top = (SR.top < 0 ? 0 : SR.top);
+#endif
-#if 0
- printf("::: DDScrollBuffer.c: DDScrollBuffer_Blt(): blit from %d, %d [%ld, %ld] [%ld, %ld]\n",
- SR.left, SR.top, mScrollX, mScrollY, mDestXOff, mDestYOff);
+#if 1
+ {
+ int full_xsize = (FieldWidth - (menBorder.Checked ? 0 : 1)) * TILEX;
+ int full_ysize = (FieldHeight - (menBorder.Checked ? 0 : 1)) * TILEY;
+ int sxsize = SCR_FIELDX * TILEX;
+ int sysize = SCR_FIELDY * TILEY;
+
+ tX = (full_xsize < sxsize ? full_xsize : tX);
+ tY = (full_ysize < sysize ? full_ysize : tY);
+ sX = SX + (full_xsize < sxsize ? (sxsize - full_xsize) / 2 : 0);
+ sY = SY + (full_ysize < sysize ? (sysize - full_ysize) / 2 : 0);
+ }
+#endif
+
+#if 1
+ if (!menBorder.Checked)
+ {
+ SR.left += TILEX / 2;
+ SR.top += TILEY / 2;
+ }
+#endif
+
+#if 1
+
+#if 1
+ printf("::: DDScrollBuffer.c: DDScrollBuffer_Blt(): blit from %d, %d [%ld, %ld] [%ld, %ld] [%ld, %ld]\n",
+ SR.left, SR.top, mScrollX, mScrollY, mDestXOff, mDestYOff, tX, tY);
#endif
#if 0
#endif
#if 1
+ BlitBitmap(screenBitmap, target_bitmap,
+ SR.left, SR.top, tX, tY, sX, sY);
+#else
BlitBitmap(screenBitmap, target_bitmap,
SR.left, SR.top,
SCR_FIELDX * TILEX, SCR_FIELDY * TILEY, SX, SY);
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)
printf("::: DDScrollBuffer.c: DDScrollBuffer_ScrollTo(): mScroll: %ld, %ld [%d, %d]\n",
mScrollX, mScrollY, X, Y);
#endif
+
+#if 1
+ ScrollPlayfieldIfNeeded();
+#endif
}
void DDScrollBuffer_ScrollTowards(int X, int Y, double Step)
printf("::: DDScrollBuffer.c: DDScrollBuffer_ScrollTowards(): (2) mScroll: %ld, %ld [%d, %d, %f]\n",
mScrollX, mScrollY, X, Y, Step);
#endif
+
+#if 1
+ ScrollPlayfieldIfNeeded();
+#endif
}
void DDScrollBuffer_SoftScrollTo(int X, int Y, long TimeMS, int FPS)
printf("::: DDScrollBuffer.c: DDScrollBuffer_SoftScrollTo(): mScroll: %ld, %ld\n",
mScrollX, mScrollY);
#endif
+
+#if 1
+ ScrollPlayfieldIfNeeded();
+#endif
}