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