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 sx_last = mScrollX_last / TILEX;
+ int sy_last = mScrollY_last / TILEY;
+ int sx = mScrollX / TILEX;
+ int sy = mScrollY / TILEY;
+ int dx = (sx < sx_last ? +1 : sx > sx_last ? -1 : 0);
+ int dy = (sy < sy_last ? +1 : sy > sy_last ? -1 : 0);
+ 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;
+#if 1
+ int buf_xsize = SCR_FIELDX + 2;
+ int buf_ysize = SCR_FIELDY + 2;
+#else
+ int buf_xsize = MAX_BUF_XSIZE;
+ int buf_ysize = MAX_BUF_YSIZE;
+#endif
+
+ 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;
+
+ 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 && sx == buf_xsize - 1) ||
+ (dx == +1 && sx == 0) ||
+ (dy == -1 && sy == buf_ysize - 1) ||
+ (dy == +1 && sy == 0))
+ {
+ printf("::: %d, %d\n", sx, sy);
+
+ TEST_flag = 1;
+
+ DrawFieldNoAnimated(x, y);
+ DrawFieldAnimated(x, y);
+
+ TEST_flag = 0;
+ }
+
+ ScreenBuffer[sx][sy] = id;
+ }
+ }
+ }
+}
+
+static void ScrollPlayfieldIfNeededExt(boolean reset)
+{
+ int sx_last = mScrollX_last / TILEX;
+ int sy_last = mScrollY_last / TILEY;
+ int sx = mScrollX / TILEX;
+ int sy = mScrollY / TILEY;
+ boolean initialized = (mScrollX_last != -1 && mScrollY_last != -1);
+
+ if (reset)
+ {
+ mScrollX_last = -1;
+ mScrollY_last = -1;
+
+ return;
+ }
+
+#if 0
+ if (mScrollX_last == -1 || mScrollY_last == -1)
+ {
+ mScrollX_last = mScrollX;
+ mScrollY_last = mScrollY;
+
+ return;
+ }
+#endif
+
+ if (initialized && (sx != sx_last || sy != sy_last))
+ ScrollPlayfield();
+
+ mScrollX_last = mScrollX;
+ mScrollY_last = mScrollY;
+}
+
+static void ScrollPlayfieldIfNeeded()
+{
+ ScrollPlayfieldIfNeededExt(FALSE);
+}
+
+void InitScrollPlayfield()
+{
+ ScrollPlayfieldIfNeededExt(TRUE);
+}
+
+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 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 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;
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 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 += 16;
+ SR.top += 16;
+ }
+#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
- printf("::: DDScrollBuffer.c: DDScrollBuffer_Blt(): blit from %d, %d [%ld, %ld] [%ld, %ld]\n",
- SR.left, SR.top, mScrollX, mScrollY, mDestXOff, mDestYOff);
+ /* !!! quick and dirty -- FIX THIS !!! */
+ if (tape.playing && tape.fast_forward &&
+ target_bitmap == window &&
+ (FrameCounter % 2) != 0)
+ printf("::: FrameCounter == %d\n", FrameCounter);
+#endif
+
+#if 1
+ SyncDisplay();
#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);
#endif
+#if 1
+ FlushDisplay();
+#endif
+
return;
+
#endif
// DDraw.WaitForVerticalBlank DDWAITVB_BLOCKBEGIN, 0
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
}