rnd-20100220-1-src
[rocksndiamonds.git] / src / game_sp / DDScrollBuffer.c
1 // ----------------------------------------------------------------------------
2 // DDScrollBuffer.c
3 // ----------------------------------------------------------------------------
4
5 #include "DDScrollBuffer.h"
6
7 #include <math.h>
8
9
10 // --- VERSION 1.0 CLASS
11 // --- BEGIN
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
17 // --- END
18
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;
24
25 // --- Option Explicit
26
27 // needs reference to: DirectX7 for Visual Basic Type Library
28
29 DirectDrawSurface7 Buffer;
30 DirectDrawSurface7 mPrimary;
31 long mWidth, mHeight;
32 long mhWnd;
33 long mScrollX, mScrollY;
34 long mScrollX_last, mScrollY_last;
35 long mDestXOff, mDestYOff;
36
37 long ScreenBuffer[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
38 boolean redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
39
40 int TEST_flag = 0;
41
42 void RestorePlayfield()
43 {
44   int x1 = mScrollX / TILEX - 2;
45   int y1 = mScrollY / TILEY - 2;
46   int x2 = mScrollX / TILEX + (SCR_FIELDX - 1) + 2;
47   int y2 = mScrollY / TILEY + (SCR_FIELDY - 1) + 2;
48   int x, y;
49
50   DrawFrameIfNeeded();
51
52   for (y = DisplayMinY; y <= DisplayMaxY; y++)
53   {
54     for (x = DisplayMinX; x <= DisplayMaxX; x++)
55     {
56       if (x >= x1 && x <= x2 && y >= y1 && y <= y2)
57       {
58         DrawFieldNoAnimated(x, y);
59         DrawFieldAnimated(x, y);
60       }
61     }
62   }
63 }
64
65 static void ScrollPlayfield(int dx, int dy)
66 {
67   int x1 = mScrollX_last / TILEX - 2;
68   int y1 = mScrollY_last / TILEY - 2;
69   int x2 = mScrollX_last / TILEX + (SCR_FIELDX - 1) + 2;
70   int y2 = mScrollY_last / TILEY + (SCR_FIELDY - 1) + 2;
71   int x, y;
72
73   BlitBitmap(screenBitmap, screenBitmap,
74              TILEX * (dx == -1),
75              TILEY * (dy == -1),
76              (MAX_BUF_XSIZE * TILEX) - TILEX * (dx != 0),
77              (MAX_BUF_YSIZE * TILEY) - TILEY * (dy != 0),
78              TILEX * (dx == 1),
79              TILEY * (dy == 1));
80
81   /* when scrolling the whole playfield, do not redraw single tiles */
82   for (x = 0; x < MAX_BUF_XSIZE; x++)
83     for (y = 0; y < MAX_BUF_YSIZE; y++)
84       redraw[x][y] = FALSE;
85   redraw_tiles = 0;
86
87 #if 1
88   DrawFrameIfNeeded();
89 #endif
90
91   for (y = DisplayMinY; y <= DisplayMaxY; y++)
92   {
93     for (x = DisplayMinX; x <= DisplayMaxX; x++)
94     {
95       if (x >= x1 && x <= x2 && y >= y1 && y <= y2)
96       {
97         int sx = x - x1;
98         int sy = y - y1;
99         int tsi = GetSI(x, y);
100         long id = ((PlayField16[tsi]) |
101                    (PlayField8[tsi] << 16) |
102                    (DisPlayField[tsi] << 24));
103
104 #if 0
105 #if 1
106         printf("::: [%d] %d [%d, %d] [%d]\n", dx, sx, x, y, buf_xsize);
107 #else
108         if (sx == 0 || sx == MAX_BUF_XSIZE - 1)
109           printf("::: %d, %d\n", dx, sx);
110 #endif
111 #endif
112
113         if ((dx == -1 && x == x2) ||
114             (dx == +1 && x == x1) ||
115             (dy == -1 && y == y2) ||
116             (dy == +1 && y == y1))
117         {
118 #if 0
119           printf("::: %d, %d\n", sx, sy);
120 #endif
121
122           TEST_flag = 1;
123
124           DrawFieldNoAnimated(x, y);
125           DrawFieldAnimated(x, y);
126
127           TEST_flag = 0;
128         }
129
130         ScreenBuffer[sx][sy] = id;
131       }
132     }
133   }
134 }
135
136 static void ScrollPlayfieldIfNeededExt(boolean reset)
137 {
138   if (reset)
139   {
140     mScrollX_last = -1;
141     mScrollY_last = -1;
142
143     return;
144   }
145
146   if (mScrollX_last == -1 || mScrollY_last == -1)
147   {
148     mScrollX_last = mScrollX;
149     mScrollY_last = mScrollY;
150
151     return;
152   }
153
154 #if 1
155
156   /* check if scrolling the playfield requires redrawing the viewport bitmap */
157   if ((mScrollX != mScrollX_last ||
158        mScrollY != mScrollY_last) &&
159       (ABS(mScrollX - mScrollX_last) >= TILEX ||
160        ABS(mScrollY - mScrollY_last) >= TILEY))
161   {
162     int dx = (ABS(mScrollX - mScrollX_last) < TILEX ? 0 :
163               mScrollX < mScrollX_last ? 1 : mScrollX > mScrollX_last ? -1 : 0);
164     int dy = (ABS(mScrollY - mScrollY_last) < TILEY ? 0 :
165               mScrollY < mScrollY_last ? 1 : mScrollY > mScrollY_last ? -1 : 0);
166
167     mScrollX_last -= dx * TILEX;
168     mScrollY_last -= dy * TILEY;
169
170     ScrollPlayfield(dx, dy);
171
172 #if 0
173     printf("::: %ld, %ld\n", mScrollX, mScrollY);
174 #endif
175   }
176
177 #else
178
179   /* check if scrolling the playfield reached the destination tile position */
180   if ((mScrollX != mScrollX_last || mScrollY != mScrollY_last) &&
181       mScrollX % TILEX == 0 && mScrollY % TILEY == 0)
182   {
183     int dx = (mScrollX < mScrollX_last ? 1 : mScrollX > mScrollX_last ? -1 : 0);
184     int dy = (mScrollY < mScrollY_last ? 1 : mScrollY > mScrollY_last ? -1 : 0);
185
186     mScrollX_last = mScrollX;
187     mScrollY_last = mScrollY;
188
189     ScrollPlayfield(dx, dy);
190
191 #if 0
192     printf("::: %ld, %ld\n", mScrollX, mScrollY);
193 #endif
194   }
195
196 #endif
197 }
198
199 static void ScrollPlayfieldIfNeeded()
200 {
201   ScrollPlayfieldIfNeededExt(FALSE);
202 }
203
204 void InitScrollPlayfield()
205 {
206   ScrollPlayfieldIfNeededExt(TRUE);
207 }
208
209 void UpdatePlayfield(boolean force_redraw)
210 {
211   int x, y;
212 #if 1
213   int num_redrawn = 0;
214 #endif
215
216   for (y = DisplayMinY; y <= DisplayMaxY; y++)
217   {
218     for (x = DisplayMinX; x <= DisplayMaxX; x++)
219     {
220       int element = LowByte(PlayField16[GetSI(x, y)]);
221       int graphic = GfxGraphic[x][y];
222       int sync_frame = GfxFrame[x][y];
223       boolean redraw = force_redraw;
224
225 #if 0
226       redraw = TRUE;    // !!! TEST ONLY -- ALWAYS REDRAW !!!
227 #endif
228
229       if (graphic < 0)
230         continue;
231
232       if (element != GfxElementLast[x][y] &&
233           graphic == GfxGraphicLast[x][y])
234       {
235         /* element changed, but not graphic => disable updating graphic */
236
237         GfxElementLast[x][y] = element;
238         GfxGraphicLast[x][y] = GfxGraphic[x][y] = -1;
239
240         continue;
241       }
242
243       if (graphic != GfxGraphicLast[x][y])                      // new graphic
244       {
245         redraw = TRUE;
246
247         GfxElementLast[x][y] = element;
248         GfxGraphicLast[x][y] = GfxGraphic[x][y];
249         sync_frame = GfxFrame[x][y] = 0;
250       }
251       else if (isNextAnimationFrame_SP(graphic, sync_frame))    // new frame
252       {
253         redraw = TRUE;
254       }
255
256       if (redraw)
257       {
258         int sx = x * StretchWidth;
259         int sy = y * StretchWidth;
260
261 #if 0
262         printf("::: REDRAW (%d, %d): %d, %d\n", x, y, graphic, sync_frame);
263 #endif
264
265         StretchedSprites.BltImg(sx, sy, graphic, sync_frame);
266
267 #if 1
268         num_redrawn++;
269 #endif
270       }
271     }
272   }
273
274 #if 0
275   printf("::: FRAME %d: %d redrawn\n", FrameCounter, num_redrawn);
276 #endif
277 }
278
279 void UpdatePlayfield_TMP()
280 {
281   int x1 = mScrollX_last / TILEX - 2;
282   int y1 = mScrollY_last / TILEY - 2;
283   int x2 = mScrollX_last / TILEX + (SCR_FIELDX - 1) + 2;
284   int y2 = mScrollY_last / TILEY + (SCR_FIELDY - 1) + 2;
285   int x, y;
286
287   for (y = DisplayMinY; y <= DisplayMaxY; y++)
288   {
289     for (x = DisplayMinX; x <= DisplayMaxX; x++)
290     {
291       if (x >= x1 && x <= x2 && y >= y1 && y <= y2)
292       {
293         int sx = x - x1;
294         int sy = y - y1;
295         int tsi = GetSI(x, y);
296         long id = ((PlayField16[tsi]) |
297                    (PlayField8[tsi] << 16) |
298                    (DisPlayField[tsi] << 24));
299         boolean redraw_screen_tile = (ScreenBuffer[sx][sy] != id);
300
301 #if 0
302         if (LowByte(PlayField16[tsi]) == fiMurphy)
303           continue;
304 #endif
305
306         if (redraw_screen_tile)
307         {
308 #if 0
309           DrawFieldNoAnimated(x, y);
310           DrawFieldAnimated(x, y);
311 #endif
312
313           ScreenBuffer[sx][sy] = id;
314
315           redraw[sx][sy] = TRUE;
316           redraw_tiles++;
317         }
318       }
319     }
320   }
321 }
322
323 void OLD_UpdatePlayfield()
324 {
325   int x, y;
326   int left = mScrollX / TILEX;
327   int top  = mScrollY / TILEY;
328
329   for (y = top; y < top + MAX_BUF_YSIZE; y++)
330   {
331     for (x = left; x < left + MAX_BUF_XSIZE; x++)
332     {
333       int sx = x % MAX_BUF_XSIZE;
334       int sy = y % MAX_BUF_YSIZE;
335       int tsi = GetSI(x, y);
336       long id = ((PlayField16[tsi]) |
337                  (PlayField8[tsi] << 16) |
338                  (DisPlayField[tsi] << 24));
339       boolean redraw_screen_tile = (ScreenBuffer[sx][sy] != id);
340
341       if (redraw_screen_tile)
342       {
343         DrawFieldNoAnimated(x, y);
344         DrawFieldAnimated(x, y);
345
346         ScreenBuffer[sx][sy] = id;
347
348         redraw[sx][sy] = TRUE;
349         redraw_tiles++;
350       }
351     }
352   }
353 }
354
355 void DDScrollBuffer_Let_DestXOff(long NewVal)
356 {
357   mDestXOff = NewVal;
358 }
359
360 long DDScrollBuffer_Get_DestXOff()
361 {
362   long DestXOff;
363
364   DestXOff = mDestXOff;
365
366   return DestXOff;
367 }
368
369 void DDScrollBuffer_Let_DestYOff(long NewVal)
370 {
371   mDestYOff = NewVal;
372 }
373
374 long DDScrollBuffer_Get_DestYOff()
375 {
376   long DestYOff;
377
378   DestYOff = mDestYOff;
379
380   return DestYOff;
381 }
382
383 DirectDrawSurface7 DDScrollBuffer_Get_Surface()
384 {
385   DirectDrawSurface7 Surface;
386
387   Surface = Buffer;
388
389   return Surface;
390 }
391
392 long DDScrollBuffer_Get_Width()
393 {
394   long Width;
395
396   Width = mWidth;
397
398   return Width;
399 }
400
401 int DDScrollBuffer_Get_Height()
402 {
403   int Height;
404
405   Height = mHeight;
406
407   return Height;
408 }
409
410 #if 0
411
412 long DDScrollBuffer_CreateAtSize(long Width, long Height, long hWndViewPort)
413 {
414   long CreateAtSize;
415
416   DDSURFACEDESC2 SD;
417
418   CreateAtSize = 0;
419   mhWnd = hWndViewPort;
420   // Create ScrollBuffer:
421   {
422     SD.lFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
423     SD.ddsCaps.lCaps = DDSCAPS_VIDEOMEMORY;
424     // SD.ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN
425     SD.LWidth = Width;
426     SD.LHeight = Height;
427   }
428
429   // --- On Error Resume Next
430   Buffer = DDraw.CreateSurface(SD);
431   if (Err.Number != 0)
432     return CreateAtSize;
433
434   // --- On Error GoTo 0
435
436   mWidth = Width;
437   mHeight = Height;
438   mScrollX = 0;
439   mScrollY = 0;
440   CreateAtSize = -1;
441
442   return CreateAtSize;
443 }
444
445 void DDScrollBuffer_Cls(int BackColor)
446 {
447   RECT EmptyRect;
448
449   if (NoDisplayFlag)
450     return;
451
452   Buffer.BltColorFill(EmptyRect, BackColor);
453 }
454
455 #endif
456
457 /* copy the entire screen to the window at the scroll position */
458
459 void BlitScreenToBitmap_SP(Bitmap *target_bitmap)
460 {
461 #if 0
462   int px = 2 * TILEX + mScrollX % TILEX;
463   int py = 2 * TILEY + mScrollY % TILEY;
464 #else
465   int px = 2 * TILEX + (mScrollX - mScrollX_last) % TILEX;
466   int py = 2 * TILEY + (mScrollY - mScrollY_last) % TILEY;
467 #endif
468   int sx, sy, sxsize, sysize;
469
470 #if 0
471   if (mScrollX % TILEX != (mScrollX - mScrollX_last) % TILEX ||
472       mScrollY % TILEY != (mScrollY - mScrollY_last) % TILEY)
473     printf("::: %ld, %ld / %ld, %ld\n",
474            mScrollX, mScrollY, mScrollX_last, mScrollY_last);
475 #endif
476
477 #if 1
478   int xsize = SXSIZE;
479   int ysize = SYSIZE;
480   int full_xsize = (FieldWidth  - (menBorder.Checked ? 0 : 1)) * TILEX;
481   int full_ysize = (FieldHeight - (menBorder.Checked ? 0 : 1)) * TILEY;
482
483   sxsize = (full_xsize < xsize ? full_xsize : xsize);
484   sysize = (full_ysize < ysize ? full_ysize : ysize);
485   sx = SX + (full_xsize < xsize ? (xsize - full_xsize) / 2 : 0);
486   sy = SY + (full_ysize < ysize ? (ysize - full_ysize) / 2 : 0);
487 #endif
488
489 #if 0
490   {
491     static int mScrollX_tmp = -1;
492     static int mScrollY_tmp = -1;
493
494     if (mScrollX != mScrollX_tmp || mScrollY != mScrollY_tmp)
495     {
496       printf("::: %ld, %ld\n", mScrollX, mScrollY);
497
498       mScrollX_tmp = mScrollX;
499       mScrollY_tmp = mScrollY;
500     }
501   }
502 #endif
503
504 #if 0
505   {
506     static boolean x = 0;
507
508     if (x == 0)
509     {
510       printf("::: %d, %d (%d, %d) (%d, %d) [%ld, %ld] [%ld, %ld] \n",
511              sx, sy, xsize, ysize, full_xsize, full_ysize,
512              mScrollX, mScrollY, mScrollX_last, mScrollY_last);
513
514       x = 1;
515     }
516   }
517 #endif
518
519 #if 1
520   if (!menBorder.Checked)
521   {
522     px += TILEX / 2;
523     py += TILEY / 2;
524   }
525 #endif
526
527 #if 0
528   if (mScrollX >= 0 && mScrollX <= 16)
529   {
530     px -= mScrollX;
531   }
532 #if 0
533   else if (mScrollX >= 352 && mScrollX <= 368)
534   {
535     px -= mScrollX;
536   }
537 #endif
538   else if (mScrollX >= 16) // && mScrollX <= 352)
539   {
540     px -= TILEX / 2;
541   }
542 #endif
543
544 #if 0
545   /* !!! TEST ONLY !!! */
546   px = py = 0;
547   sx = sy = SX;
548 #endif
549
550   BlitBitmap(screenBitmap, target_bitmap, px, py, sxsize, sysize, sx, sy);
551 }
552
553 void OLD_BlitScreenToBitmap_SP(Bitmap *target_bitmap)
554 {
555   int x = mScrollX % (MAX_BUF_XSIZE * TILEX);
556   int y = mScrollY % (MAX_BUF_YSIZE * TILEY);
557
558   if (x < 2 * TILEX && y < 2 * TILEY)
559   {
560     BlitBitmap(screenBitmap, target_bitmap, x, y,
561                SCR_FIELDX * TILEX, SCR_FIELDY * TILEY, SX, SY);
562   }
563   else if (x < 2 * TILEX && y >= 2 * TILEY)
564   {
565     BlitBitmap(screenBitmap, target_bitmap, x, y,
566                SCR_FIELDX * TILEX, MAX_BUF_YSIZE * TILEY - y,
567                SX, SY);
568     BlitBitmap(screenBitmap, target_bitmap, x, 0,
569                SCR_FIELDX * TILEX, y - 2 * TILEY,
570                SX, SY + MAX_BUF_YSIZE * TILEY - y);
571   }
572   else if (x >= 2 * TILEX && y < 2 * TILEY)
573   {
574     BlitBitmap(screenBitmap, target_bitmap, x, y,
575                MAX_BUF_XSIZE * TILEX - x, SCR_FIELDY * TILEY,
576                SX, SY);
577     BlitBitmap(screenBitmap, target_bitmap, 0, y,
578                x - 2 * TILEX, SCR_FIELDY * TILEY,
579                SX + MAX_BUF_XSIZE * TILEX - x, SY);
580   }
581   else
582   {
583     BlitBitmap(screenBitmap, target_bitmap, x, y,
584                MAX_BUF_XSIZE * TILEX - x, MAX_BUF_YSIZE * TILEY - y,
585                SX, SY);
586     BlitBitmap(screenBitmap, target_bitmap, 0, y,
587                x - 2 * TILEX, MAX_BUF_YSIZE * TILEY - y,
588                SX + MAX_BUF_XSIZE * TILEX - x, SY);
589     BlitBitmap(screenBitmap, target_bitmap, x, 0,
590                MAX_BUF_XSIZE * TILEX - x, y - 2 * TILEY,
591                SX, SY + MAX_BUF_YSIZE * TILEY - y);
592     BlitBitmap(screenBitmap, target_bitmap, 0, 0,
593                x - 2 * TILEX, y - 2 * TILEY,
594                SX + MAX_BUF_XSIZE * TILEX - x, SY + MAX_BUF_YSIZE * TILEY - y);
595   }
596 }
597
598 void BackToFront_SP(void)
599 {
600   static boolean scrolling_last = FALSE;
601   int left = mScrollX / TILEX;
602   int top  = mScrollY / TILEY;
603   boolean scrolling = (mScrollX % TILEX != 0 || mScrollY % TILEY != 0);
604   int x, y;
605
606   SyncDisplay();
607
608   if (1 ||
609       redraw_tiles > REDRAWTILES_THRESHOLD || scrolling || scrolling_last)
610   {
611 #if 1
612     BlitScreenToBitmap_SP(window);
613 #else
614     /* blit all (up to four) parts of the scroll buffer to the backbuffer */
615     BlitScreenToBitmap_SP(backbuffer);
616
617     /* blit the completely updated backbuffer to the window (in one blit) */
618     BlitBitmap(backbuffer, window, SX, SY, SXSIZE, SYSIZE, SX, SY);
619 #endif
620   }
621   else
622   {
623     for (x = 0; x < SCR_FIELDX; x++)
624     {
625       for (y = 0; y < SCR_FIELDY; y++)
626       {
627         int xx = (left + x) % MAX_BUF_XSIZE;
628         int yy = (top  + y) % MAX_BUF_YSIZE;
629
630         if (redraw[xx][yy])
631           BlitBitmap(screenBitmap, window,
632                      xx * TILEX, yy * TILEY, TILEX, TILEY,
633                      SX + x * TILEX, SY + y * TILEY);
634       }
635     }
636   }
637
638   FlushDisplay();
639
640   for (x = 0; x < MAX_BUF_XSIZE; x++)
641     for (y = 0; y < MAX_BUF_YSIZE; y++)
642       redraw[x][y] = FALSE;
643   redraw_tiles = 0;
644
645   scrolling_last = scrolling;
646 }
647
648
649 void DDScrollBuffer_Blt_Ext(Bitmap *target_bitmap)
650 {
651   MyRECT DR, SR;
652 #if 1
653   long tX, tY;
654 #else
655   long tX, tY, L;
656 #endif
657   int sX, sY;
658   // RECT ERect;
659   // long Restore;
660
661   if (NoDisplayFlag)
662     return;
663
664 #if 1
665   DR.left = 0;
666   DR.top = 0;
667   DR.right = SCR_FIELDX * TILEX;
668   DR.bottom = SCR_FIELDY * TILEY;
669 #else
670   // --- On Error GoTo BltEH
671   DirectX.GetWindowRect(mhWnd, DR);
672   // --- On Error GoTo 0
673 #endif
674
675   {
676     tX = (DR.right - DR.left) / Stretch;
677     tY = (DR.bottom - DR.top) / Stretch;
678   }
679
680   {
681     SR.left = mScrollX + mDestXOff;
682     SR.top = mScrollY + mDestYOff;
683
684     SR.right = SR.left + tX;
685     SR.bottom = SR.top + tY;
686
687     //    If mWidth < SR.right Then
688     //      SR.right = mWidth
689     //      DR.right = DR.left + Stretch * (SR.right - SR.left)
690     //    End If
691     //    If mHeight < SR.bottom Then
692     //      SR.bottom = mHeight
693     //      DR.bottom = DR.top + Stretch * (SR.bottom - SR.top)
694     //    End If
695     //    If (mScrollX + mDestXOff) < 0 Then
696     //      SR.left = 0
697     //      DR.left = DR.left - Stretch * (mScrollX + mDestXOff)
698     //    End If
699     //    If (mScrollY + mDestYOff) < 0 Then
700     //      SR.top = 0
701     //      DR.top = DR.top - Stretch * (mScrollY + mDestYOff)
702     //    End If
703   }
704
705 #if 1
706   SR.left = (SR.left < 0 ? 0 : SR.left);
707   SR.top  = (SR.top  < 0 ? 0 : SR.top);
708 #endif
709
710 #if 1
711   {
712     int full_xsize = (FieldWidth  - (menBorder.Checked ? 0 : 1)) * TILEX;
713     int full_ysize = (FieldHeight - (menBorder.Checked ? 0 : 1)) * TILEY;
714     int sxsize = SCR_FIELDX * TILEX;
715     int sysize = SCR_FIELDY * TILEY;
716
717     tX = (full_xsize < sxsize ? full_xsize : tX);
718     tY = (full_ysize < sysize ? full_ysize : tY);
719     sX = SX + (full_xsize < sxsize ? (sxsize - full_xsize) / 2 : 0);
720     sY = SY + (full_ysize < sysize ? (sysize - full_ysize) / 2 : 0);
721   }
722 #endif
723
724 #if 1
725   if (!menBorder.Checked)
726   {
727     SR.left += TILEX / 2;
728     SR.top  += TILEY / 2;
729   }
730 #endif
731
732 #if 1
733
734 #if 1
735   printf("::: DDScrollBuffer.c: DDScrollBuffer_Blt(): blit from %d, %d [%ld, %ld] [%ld, %ld] [%ld, %ld]\n",
736          SR.left, SR.top, mScrollX, mScrollY, mDestXOff, mDestYOff, tX, tY);
737 #endif
738
739 #if 0
740   /* !!! quick and dirty -- FIX THIS !!! */
741   if (tape.playing && tape.fast_forward &&
742       target_bitmap == window &&
743       (FrameCounter % 2) != 0)
744     printf("::: FrameCounter == %d\n", FrameCounter);
745 #endif
746
747 #if 1
748   SyncDisplay();
749 #endif
750
751 #if 1
752   BlitBitmap(screenBitmap, target_bitmap,
753              SR.left, SR.top, tX, tY, sX, sY);
754 #else
755   BlitBitmap(screenBitmap, target_bitmap,
756              SR.left, SR.top,
757              SCR_FIELDX * TILEX, SCR_FIELDY * TILEY, SX, SY);
758 #endif
759
760 #if 1
761   FlushDisplay();
762 #endif
763
764   return;
765
766 #endif
767
768   // DDraw.WaitForVerticalBlank DDWAITVB_BLOCKBEGIN, 0
769   if (IS_NOTHING(&Buffer, sizeof(Buffer)))
770     return;
771
772 #if 0
773   if (IS_NOTHING(&PrimarySurface, sizeof(PrimarySurface)))
774     return;
775 #endif
776
777 #if 0
778
779   L = PrimarySurface.Blt(DR, &Buffer, SR, DDBLT_WAIT);
780   if (L != DD_OK)
781   {
782     switch (L)
783     {
784 #if 0
785       case DDERR_GENERIC:
786         Debug.Assert(False);
787         break;
788
789       case DDERR_INVALIDCLIPLIST:
790         Debug.Assert(False);
791         break;
792
793       case DDERR_INVALIDOBJECT:
794         Debug.Assert(False);
795         break;
796
797       case DDERR_INVALIDPARAMS:
798         Debug.Assert(False);
799         break;
800
801       case DDERR_INVALIDRECT:
802         Debug.Assert(False);
803         break;
804
805       case DDERR_NOALPHAHW:
806         Debug.Assert(False);
807         break;
808
809       case DDERR_NOBLTHW:
810         Debug.Assert(False);
811         break;
812
813       case DDERR_NOCLIPLIST:
814         Debug.Assert(False);
815         break;
816
817       case DDERR_NODDROPSHW:
818         Debug.Assert(False);
819         break;
820
821       case DDERR_NOMIRRORHW:
822         Debug.Assert(False);
823         break;
824
825       case DDERR_NORASTEROPHW:
826         Debug.Assert(False);
827         break;
828
829       case DDERR_NOROTATIONHW:
830         Debug.Assert(False);
831         break;
832
833       case DDERR_NOSTRETCHHW:
834         Debug.Assert(False);
835         break;
836
837       case DDERR_NOZBUFFERHW:
838         Debug.Assert(False);
839         break;
840
841       case DDERR_SURFACEBUSY:
842         Debug.Assert(False);
843         break;
844 #endif
845
846 #if 0
847       case DDERR_SURFACELOST:
848         DDraw.RestoreAllSurfaces();
849         if (! PrimarySurface.isLost())
850         {
851           subDisplayLevel();
852           // Blt();
853         }
854
855         // RestorePrimarySurface
856         // ClipToWindow 0
857         break;
858 #endif
859
860 #if 0
861       case DDERR_UNSUPPORTED:
862         Debug.Assert(False);
863         break;
864
865       case DDERR_WASSTILLDRAWING:
866         Debug.Assert(False);
867         break;
868
869       default:
870         Debug.Assert(False);
871         break;
872 #endif
873     }
874   }
875
876 #endif
877
878 #if 0
879   //  Buffer.UpdateOverlay SR, PrimarySurface, DR, DDOVER_SHOW
880   if (EditFlag)
881     FMark.RefreshMarker();
882 #endif
883
884   // BltEH:
885 }
886
887 void DDScrollBuffer_Blt()
888 {
889 #if 1
890
891 #if 1
892   BackToFront_SP();
893 #else
894   /* !!! TEST ONLY !!! */
895   BlitBitmap(screenBitmap, window,
896              0, 0, SCR_FIELDX * TILEX, SCR_FIELDY * TILEY, SX, SY);
897 #endif
898
899 #else
900   DDScrollBuffer_Blt_Ext(window);
901 #endif
902 }
903
904 void DDScrollBuffer_ScrollTo(int X, int Y)
905 {
906   if (NoDisplayFlag)
907     return;
908
909   X = X / Stretch;
910   Y = Y / Stretch;
911   mScrollX = X;
912   mScrollY = Y;
913   ScrollX = mScrollX;
914   ScrollY = mScrollY;
915
916 #if 0
917   printf("::: DDScrollBuffer.c: DDScrollBuffer_ScrollTo():  mScroll: %ld, %ld [%d, %d]\n",
918          mScrollX, mScrollY, X, Y);
919 #endif
920
921 #if 1
922   ScrollPlayfieldIfNeeded();
923 #endif
924 }
925
926 void DDScrollBuffer_ScrollTowards(int X, int Y, double Step)
927 {
928   double dx, dY, r;
929
930   if (NoDisplayFlag)
931     return;
932
933 #if 0
934   printf("::: DDScrollBuffer.c: DDScrollBuffer_ScrollTowards(): (1) mScroll: %ld, %ld [%d, %d, %f, %f]\n",
935          mScrollX, mScrollY, X, Y, Step, Stretch);
936 #endif
937
938   X = X / Stretch;
939   Y = Y / Stretch;
940   dx = X - mScrollX;
941   dY = Y - mScrollY;
942   r = Sqr(dx * dx + dY * dY);
943   if (r == 0) // we are there already
944     return;
945
946   if (Step < r)
947     r = Step / r;
948   else
949     r = 1;
950
951   mScrollX = mScrollX + dx * r;
952   mScrollY = mScrollY + dY * r;
953   ScrollX = mScrollX;
954   ScrollY = mScrollY;
955
956 #if 0
957   printf("::: DDScrollBuffer.c: DDScrollBuffer_ScrollTowards(): (2) mScroll: %ld, %ld [%d, %d, %f]\n",
958          mScrollX, mScrollY, X, Y, Step);
959 #endif
960
961 #if 1
962   ScrollPlayfieldIfNeeded();
963 #endif
964 }
965
966 void DDScrollBuffer_SoftScrollTo(int X, int Y, long TimeMS, int FPS)
967 {
968   double dx, dY;
969 #if 0
970   TickCountObject Tick;
971 #endif
972   long dT, StepCount;
973   double T, tStep;
974   long oldX, oldY, maxD;
975   static boolean AlreadyRunning = False;
976
977 #if 0
978   printf(":a: %d, %d [%d, %d] [%d, %d] [%d, %d]\n",
979          mScrollX, mScrollY,
980          mScrollX_last, mScrollY_last,
981          ScreenScrollXPos, ScreenScrollYPos,
982          ScrollX, ScrollY);
983 #endif
984
985   if (NoDisplayFlag)
986     return;
987
988   if (AlreadyRunning)
989   {
990     return;
991   }
992
993   AlreadyRunning = True;
994   X = X / Stretch;
995   Y = Y / Stretch;
996   dx = X - mScrollX;
997   dY = Y - mScrollY;
998   maxD = (Abs(dx) < Abs(dY) ? Abs(dY) : Abs(dx));
999   StepCount = FPS * (TimeMS / (double)1000);
1000   if (StepCount > maxD)
1001     StepCount = maxD;
1002
1003   if (StepCount == 0)
1004     StepCount = 1;
1005
1006   dT = 1000 / FPS;
1007   tStep = (double)1 / StepCount;
1008   oldX = mScrollX;
1009   oldY = mScrollY;
1010   // R = Sqr(dX * dX + dY * dY)
1011   // If R = 0 Then Exit Sub 'we are there already
1012   for (T = (double)tStep; T <= (double)1; T += tStep)
1013   {
1014     if (UserDragFlag)
1015       goto SoftScrollEH;
1016
1017     // If Claim Then Exit For
1018
1019 #if 0
1020     Tick.DelayMS(dT, False);
1021 #endif
1022
1023     mScrollX = oldX + T * dx;
1024     mScrollY = oldY + T * dY;
1025     ScrollX = mScrollX;
1026     ScrollY = mScrollY;
1027
1028 #if 0
1029     Blt();
1030 #endif
1031   }
1032
1033 #if 0
1034   printf(":x: %d, %d [%d, %d] [%d, %d] [%d, %d]\n",
1035          mScrollX, mScrollY,
1036          mScrollX_last, mScrollY_last,
1037          ScreenScrollXPos, ScreenScrollYPos,
1038          ScrollX, ScrollY);
1039 #endif
1040
1041   if (UserDragFlag)
1042     goto SoftScrollEH;
1043
1044 #if 0
1045   Tick.DelayMS(dT, False);
1046 #endif
1047
1048   mScrollX = X;
1049   mScrollY = Y;
1050   ScrollX = mScrollX;
1051   ScrollY = mScrollY;
1052
1053 #if 0
1054   Blt();
1055 #endif
1056
1057 SoftScrollEH:
1058   AlreadyRunning = False;
1059
1060 #if 0
1061   printf("::: DDScrollBuffer.c: DDScrollBuffer_SoftScrollTo(): mScroll: %ld, %ld\n",
1062          mScrollX, mScrollY);
1063 #endif
1064
1065 #if 0
1066   printf(":y: %d, %d [%d, %d] [%d, %d] [%d, %d]\n",
1067          mScrollX, mScrollY,
1068          mScrollX_last, mScrollY_last,
1069          ScreenScrollXPos, ScreenScrollYPos,
1070          ScrollX, ScrollY);
1071 #endif
1072
1073 #if 1
1074   ScrollPlayfieldIfNeeded();
1075 #endif
1076
1077 #if 0
1078   printf(":z: %d, %d [%d, %d] [%d, %d] [%d, %d]\n",
1079          mScrollX, mScrollY,
1080          mScrollX_last, mScrollY_last,
1081          ScreenScrollXPos, ScreenScrollYPos,
1082          ScrollX, ScrollY);
1083 #endif
1084 }