1 // ----------------------------------------------------------------------------
3 // ----------------------------------------------------------------------------
5 #include "DDScrollBuffer.h"
10 // --- VERSION 1.0 CLASS
12 // --- MultiUse = -1 'True // True
13 // --- Persistable = 0 'NotPersistable // NotPersistable
14 // --- DataBindingBehavior = 0 'vbNone // vbNone
15 // --- DataSourceBehavior = 0 'vbNone // vbNone
16 // --- MTSTransactionMode = 0 'NotAnMTSObject // NotAnMTSObject
19 // static char *VB_Name = "DDScrollBuffer";
20 // static boolean VB_GlobalNameSpace = False;
21 // static boolean VB_Creatable = True;
22 // static boolean VB_PredeclaredId = False;
23 // static boolean VB_Exposed = False;
25 // --- Option Explicit
27 // needs reference to: DirectX7 for Visual Basic Type Library
29 DirectDrawSurface7 Buffer;
30 DirectDrawSurface7 mPrimary;
33 long mScrollX, mScrollY;
34 long mDestXOff, mDestYOff;
36 long ScreenBuffer[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
37 boolean redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
40 void UpdatePlayfield()
43 int sx1 = mScrollX - TILEX;
44 int sy1 = mScrollY - TILEY;
45 int sx2 = mScrollX + SXSIZE + TILEX;
46 int sy2 = mScrollY + SYSIZE + TILEY;
52 for (y = DisplayMinY; y <= DisplayMaxY; y++)
54 for (x = DisplayMinX; x <= DisplayMaxX; x++)
56 if (x >= x1 && x < x2 && y >= y1 && y < y2)
60 int tsi = GetSI(x, y);
61 long id = ((PlayField16[tsi]) |
62 (PlayField8[tsi] << 16) |
63 (DisPlayField[tsi] << 24));
64 boolean redraw_screen_tile = (ScreenBuffer[sx][sy] != id);
66 if (redraw_screen_tile)
68 DrawFieldNoAnimated(x, y);
69 DrawFieldAnimated(x, y);
71 ScreenBuffer[sx][sy] = id;
73 redraw[sx][sy] = TRUE;
81 void OLD_UpdatePlayfield()
84 int left = mScrollX / TILEX;
85 int top = mScrollY / TILEY;
87 for (y = top; y < top + MAX_BUF_YSIZE; y++)
89 for (x = left; x < left + MAX_BUF_XSIZE; x++)
91 int sx = x % MAX_BUF_XSIZE;
92 int sy = y % MAX_BUF_YSIZE;
93 int tsi = GetSI(x, y);
94 long id = ((PlayField16[tsi]) |
95 (PlayField8[tsi] << 16) |
96 (DisPlayField[tsi] << 24));
97 boolean redraw_screen_tile = (ScreenBuffer[sx][sy] != id);
99 if (redraw_screen_tile)
101 DrawFieldNoAnimated(x, y);
102 DrawFieldAnimated(x, y);
104 ScreenBuffer[sx][sy] = id;
106 redraw[sx][sy] = TRUE;
113 void DDScrollBuffer_Let_DestXOff(long NewVal)
118 long DDScrollBuffer_Get_DestXOff()
122 DestXOff = mDestXOff;
127 void DDScrollBuffer_Let_DestYOff(long NewVal)
132 long DDScrollBuffer_Get_DestYOff()
136 DestYOff = mDestYOff;
141 DirectDrawSurface7 DDScrollBuffer_Get_Surface()
143 DirectDrawSurface7 Surface;
150 long DDScrollBuffer_Get_Width()
159 int DDScrollBuffer_Get_Height()
168 long DDScrollBuffer_CreateAtSize(long Width, long Height, long hWndViewPort)
175 mhWnd = hWndViewPort;
176 // Create ScrollBuffer:
178 SD.lFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
179 SD.ddsCaps.lCaps = DDSCAPS_VIDEOMEMORY;
180 // SD.ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN
185 // --- On Error Resume Next
186 Buffer = DDraw.CreateSurface(SD);
190 // --- On Error GoTo 0
201 void DDScrollBuffer_Cls(int BackColor)
208 Buffer.BltColorFill(EmptyRect, BackColor);
212 /* copy the entire screen to the window at the scroll position */
214 void BlitScreenToBitmap_SP(Bitmap *target_bitmap)
216 int sx = TILEX + mScrollX % TILEX;
217 int sy = TILEY + mScrollY % TILEY;
219 BlitBitmap(screenBitmap, target_bitmap, sx, sy,
220 SCR_FIELDX * TILEX, SCR_FIELDY * TILEY, SX, SY);
223 void OLD_BlitScreenToBitmap_SP(Bitmap *target_bitmap)
225 int x = mScrollX % (MAX_BUF_XSIZE * TILEX);
226 int y = mScrollY % (MAX_BUF_YSIZE * TILEY);
228 if (x < 2 * TILEX && y < 2 * TILEY)
230 BlitBitmap(screenBitmap, target_bitmap, x, y,
231 SCR_FIELDX * TILEX, SCR_FIELDY * TILEY, SX, SY);
233 else if (x < 2 * TILEX && y >= 2 * TILEY)
235 BlitBitmap(screenBitmap, target_bitmap, x, y,
236 SCR_FIELDX * TILEX, MAX_BUF_YSIZE * TILEY - y,
238 BlitBitmap(screenBitmap, target_bitmap, x, 0,
239 SCR_FIELDX * TILEX, y - 2 * TILEY,
240 SX, SY + MAX_BUF_YSIZE * TILEY - y);
242 else if (x >= 2 * TILEX && y < 2 * TILEY)
244 BlitBitmap(screenBitmap, target_bitmap, x, y,
245 MAX_BUF_XSIZE * TILEX - x, SCR_FIELDY * TILEY,
247 BlitBitmap(screenBitmap, target_bitmap, 0, y,
248 x - 2 * TILEX, SCR_FIELDY * TILEY,
249 SX + MAX_BUF_XSIZE * TILEX - x, SY);
253 BlitBitmap(screenBitmap, target_bitmap, x, y,
254 MAX_BUF_XSIZE * TILEX - x, MAX_BUF_YSIZE * TILEY - y,
256 BlitBitmap(screenBitmap, target_bitmap, 0, y,
257 x - 2 * TILEX, MAX_BUF_YSIZE * TILEY - y,
258 SX + MAX_BUF_XSIZE * TILEX - x, SY);
259 BlitBitmap(screenBitmap, target_bitmap, x, 0,
260 MAX_BUF_XSIZE * TILEX - x, y - 2 * TILEY,
261 SX, SY + MAX_BUF_YSIZE * TILEY - y);
262 BlitBitmap(screenBitmap, target_bitmap, 0, 0,
263 x - 2 * TILEX, y - 2 * TILEY,
264 SX + MAX_BUF_XSIZE * TILEX - x, SY + MAX_BUF_YSIZE * TILEY - y);
268 void BackToFront_SP(void)
270 static boolean scrolling_last = FALSE;
271 int left = mScrollX / TILEX;
272 int top = mScrollY / TILEY;
273 boolean scrolling = (mScrollX % TILEX != 0 || mScrollY % TILEY != 0);
279 redraw_tiles > REDRAWTILES_THRESHOLD || scrolling || scrolling_last)
281 /* blit all (up to four) parts of the scroll buffer to the backbuffer */
282 BlitScreenToBitmap_SP(backbuffer);
284 /* blit the completely updated backbuffer to the window (in one blit) */
285 BlitBitmap(backbuffer, window, SX, SY, SXSIZE, SYSIZE, SX, SY);
289 for (x = 0; x < SCR_FIELDX; x++)
291 for (y = 0; y < SCR_FIELDY; y++)
293 int xx = (left + x) % MAX_BUF_XSIZE;
294 int yy = (top + y) % MAX_BUF_YSIZE;
297 BlitBitmap(screenBitmap, window,
298 xx * TILEX, yy * TILEY, TILEX, TILEY,
299 SX + x * TILEX, SY + y * TILEY);
306 for (x = 0; x < MAX_BUF_XSIZE; x++)
307 for (y = 0; y < MAX_BUF_YSIZE; y++)
308 redraw[x][y] = FALSE;
311 scrolling_last = scrolling;
315 void DDScrollBuffer_Blt_Ext(Bitmap *target_bitmap)
329 DR.right = SCR_FIELDX * TILEX;
330 DR.bottom = SCR_FIELDY * TILEY;
332 // --- On Error GoTo BltEH
333 DirectX.GetWindowRect(mhWnd, DR);
334 // --- On Error GoTo 0
338 tX = (DR.right - DR.left) / Stretch;
339 tY = (DR.bottom - DR.top) / Stretch;
343 SR.left = mScrollX + mDestXOff;
344 SR.top = mScrollY + mDestYOff;
346 SR.right = SR.left + tX;
347 SR.bottom = SR.top + tY;
349 // If mWidth < SR.right Then
351 // DR.right = DR.left + Stretch * (SR.right - SR.left)
353 // If mHeight < SR.bottom Then
354 // SR.bottom = mHeight
355 // DR.bottom = DR.top + Stretch * (SR.bottom - SR.top)
357 // If (mScrollX + mDestXOff) < 0 Then
359 // DR.left = DR.left - Stretch * (mScrollX + mDestXOff)
361 // If (mScrollY + mDestYOff) < 0 Then
363 // DR.top = DR.top - Stretch * (mScrollY + mDestYOff)
368 SR.left = (SR.left < 0 ? 0 : SR.left);
369 SR.top = (SR.top < 0 ? 0 : SR.top);
374 int full_xsize = (FieldWidth - (menBorder.Checked ? 0 : 1)) * TILEX;
375 int full_ysize = (FieldHeight - (menBorder.Checked ? 0 : 1)) * TILEY;
376 int sxsize = SCR_FIELDX * TILEX;
377 int sysize = SCR_FIELDY * TILEY;
379 tX = (full_xsize < sxsize ? full_xsize : tX);
380 tY = (full_ysize < sysize ? full_ysize : tY);
381 sX = SX + (full_xsize < sxsize ? (sxsize - full_xsize) / 2 : 0);
382 sY = SY + (full_ysize < sysize ? (sysize - full_ysize) / 2 : 0);
387 if (!menBorder.Checked)
397 printf("::: DDScrollBuffer.c: DDScrollBuffer_Blt(): blit from %d, %d [%ld, %ld] [%ld, %ld] [%ld, %ld]\n",
398 SR.left, SR.top, mScrollX, mScrollY, mDestXOff, mDestYOff, tX, tY);
402 /* !!! quick and dirty -- FIX THIS !!! */
403 if (tape.playing && tape.fast_forward &&
404 target_bitmap == window &&
405 (FrameCounter % 2) != 0)
406 printf("::: FrameCounter == %d\n", FrameCounter);
414 BlitBitmap(screenBitmap, target_bitmap,
415 SR.left, SR.top, tX, tY, sX, sY);
417 BlitBitmap(screenBitmap, target_bitmap,
419 SCR_FIELDX * TILEX, SCR_FIELDY * TILEY, SX, SY);
430 // DDraw.WaitForVerticalBlank DDWAITVB_BLOCKBEGIN, 0
431 if (IS_NOTHING(&Buffer, sizeof(Buffer)))
434 if (IS_NOTHING(&PrimarySurface, sizeof(PrimarySurface)))
437 L = PrimarySurface.Blt(DR, &Buffer, SR, DDBLT_WAIT);
447 case DDERR_INVALIDCLIPLIST:
451 case DDERR_INVALIDOBJECT:
455 case DDERR_INVALIDPARAMS:
459 case DDERR_INVALIDRECT:
463 case DDERR_NOALPHAHW:
471 case DDERR_NOCLIPLIST:
475 case DDERR_NODDROPSHW:
479 case DDERR_NOMIRRORHW:
483 case DDERR_NORASTEROPHW:
487 case DDERR_NOROTATIONHW:
491 case DDERR_NOSTRETCHHW:
495 case DDERR_NOZBUFFERHW:
499 case DDERR_SURFACEBUSY:
504 case DDERR_SURFACELOST:
505 DDraw.RestoreAllSurfaces();
506 if (! PrimarySurface.isLost())
512 // RestorePrimarySurface
517 case DDERR_UNSUPPORTED:
521 case DDERR_WASSTILLDRAWING:
533 // Buffer.UpdateOverlay SR, PrimarySurface, DR, DDOVER_SHOW
535 FMark.RefreshMarker();
541 void DDScrollBuffer_Blt()
548 /* !!! TEST ONLY !!! */
549 BlitBitmap(screenBitmap, window,
550 0, 0, SCR_FIELDX * TILEX, SCR_FIELDY * TILEY, SX, SY);
554 DDScrollBuffer_Blt_Ext(window);
558 void DDScrollBuffer_ScrollTo(int X, int Y)
571 printf("::: DDScrollBuffer.c: DDScrollBuffer_ScrollTo(): mScroll: %ld, %ld [%d, %d]\n",
572 mScrollX, mScrollY, X, Y);
576 void DDScrollBuffer_ScrollTowards(int X, int Y, double Step)
584 printf("::: DDScrollBuffer.c: DDScrollBuffer_ScrollTowards(): (1) mScroll: %ld, %ld [%d, %d, %f]\n",
585 mScrollX, mScrollY, X, Y, Step);
592 r = Sqr(dx * dx + dY * dY);
593 if (r == 0) // we are there already
601 mScrollX = mScrollX + dx * r;
602 mScrollY = mScrollY + dY * r;
607 printf("::: DDScrollBuffer.c: DDScrollBuffer_ScrollTowards(): (2) mScroll: %ld, %ld [%d, %d, %f]\n",
608 mScrollX, mScrollY, X, Y, Step);
612 void DDScrollBuffer_SoftScrollTo(int X, int Y, long TimeMS, int FPS)
616 TickCountObject Tick;
620 long oldX, oldY, maxD;
621 static boolean AlreadyRunning = False;
631 AlreadyRunning = True;
636 maxD = (Abs(dx) < Abs(dY) ? Abs(dY) : Abs(dx));
637 StepCount = FPS * (TimeMS / (double)1000);
638 if (StepCount > maxD)
645 tStep = (double)1 / StepCount;
648 // R = Sqr(dX * dX + dY * dY)
649 // If R = 0 Then Exit Sub 'we are there already
650 for (T = (double)tStep; T <= (double)1; T += tStep)
655 // If Claim Then Exit For
658 Tick.DelayMS(dT, False);
661 mScrollX = oldX + T * dx;
662 mScrollY = oldY + T * dY;
672 Tick.DelayMS(dT, False);
682 AlreadyRunning = False;
685 printf("::: DDScrollBuffer.c: DDScrollBuffer_SoftScrollTo(): mScroll: %ld, %ld\n",