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