rnd-20091101-3-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 mDestXOff, mDestYOff;
35
36 void DDScrollBuffer_Let_DestXOff(long NewVal)
37 {
38   mDestXOff = NewVal;
39 }
40
41 long DDScrollBuffer_Get_DestXOff()
42 {
43   long DestXOff;
44
45   DestXOff = mDestXOff;
46
47   return DestXOff;
48 }
49
50 void DDScrollBuffer_Let_DestYOff(long NewVal)
51 {
52   mDestYOff = NewVal;
53 }
54
55 long DDScrollBuffer_Get_DestYOff()
56 {
57   long DestYOff;
58
59   DestYOff = mDestYOff;
60
61   return DestYOff;
62 }
63
64 DirectDrawSurface7 DDScrollBuffer_Get_Surface()
65 {
66   DirectDrawSurface7 Surface;
67
68   Surface = Buffer;
69
70   return Surface;
71 }
72
73 long DDScrollBuffer_Get_Width()
74 {
75   long Width;
76
77   Width = mWidth;
78
79   return Width;
80 }
81
82 int DDScrollBuffer_Get_Height()
83 {
84   int Height;
85
86   Height = mHeight;
87
88   return Height;
89 }
90
91 long DDScrollBuffer_CreateAtSize(long Width, long Height, long hWndViewPort)
92 {
93   long CreateAtSize;
94
95   DDSURFACEDESC2 SD;
96
97   CreateAtSize = 0;
98   mhWnd = hWndViewPort;
99   // Create ScrollBuffer:
100   {
101     SD.lFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
102     SD.ddsCaps.lCaps = DDSCAPS_VIDEOMEMORY;
103     // SD.ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN
104     SD.LWidth = Width;
105     SD.LHeight = Height;
106   }
107
108   // --- On Error Resume Next
109   Buffer = DDraw.CreateSurface(SD);
110   if (Err.Number != 0)
111     return CreateAtSize;
112
113   // --- On Error GoTo 0
114
115   mWidth = Width;
116   mHeight = Height;
117   mScrollX = 0;
118   mScrollY = 0;
119   CreateAtSize = -1;
120
121   return CreateAtSize;
122 }
123
124 void DDScrollBuffer_Cls(int BackColor)
125 {
126   RECT EmptyRect;
127
128   if (NoDisplayFlag)
129     return;
130
131   Buffer.BltColorFill(EmptyRect, BackColor);
132 }
133
134 void DDScrollBuffer_Blt_Ext(Bitmap *target_bitmap)
135 {
136   RECT DR, SR;
137   long tX, tY, L;
138   int sX, sY;
139   // RECT ERect;
140   // long Restore;
141
142   if (NoDisplayFlag)
143     return;
144
145 #if 1
146   DR.left = 0;
147   DR.top = 0;
148   DR.right = SCR_FIELDX * TILEX;
149   DR.bottom = SCR_FIELDY * TILEY;
150 #else
151   // --- On Error GoTo BltEH
152   DirectX.GetWindowRect(mhWnd, DR);
153   // --- On Error GoTo 0
154 #endif
155
156   {
157     tX = (DR.right - DR.left) / Stretch;
158     tY = (DR.bottom - DR.top) / Stretch;
159   }
160   {
161     SR.left = mScrollX + mDestXOff;
162     SR.top = mScrollY + mDestYOff;
163     SR.right = SR.left + tX;
164     SR.bottom = SR.top + tY;
165     //    If mWidth < SR.right Then
166     //      SR.right = mWidth
167     //      DR.right = DR.left + Stretch * (SR.right - SR.left)
168     //    End If
169     //    If mHeight < SR.bottom Then
170     //      SR.bottom = mHeight
171     //      DR.bottom = DR.top + Stretch * (SR.bottom - SR.top)
172     //    End If
173     //    If (mScrollX + mDestXOff) < 0 Then
174     //      SR.left = 0
175     //      DR.left = DR.left - Stretch * (mScrollX + mDestXOff)
176     //    End If
177     //    If (mScrollY + mDestYOff) < 0 Then
178     //      SR.top = 0
179     //      DR.top = DR.top - Stretch * (mScrollY + mDestYOff)
180     //    End If
181   }
182
183 #if 1
184   SR.left = (SR.left < 0 ? 0 : SR.left);
185   SR.top  = (SR.top  < 0 ? 0 : SR.top);
186 #endif
187
188 #if 1
189   {
190     int full_xsize = (FieldWidth  - (menBorder.Checked ? 0 : 1)) * TILEX;
191     int full_ysize = (FieldHeight - (menBorder.Checked ? 0 : 1)) * TILEY;
192     int sxsize = SCR_FIELDX * TILEX;
193     int sysize = SCR_FIELDY * TILEY;
194
195     tX = (full_xsize < sxsize ? full_xsize : tX);
196     tY = (full_ysize < sysize ? full_ysize : tY);
197     sX = SX + (full_xsize < sxsize ? (sxsize - full_xsize) / 2 : 0);
198     sY = SY + (full_ysize < sysize ? (sysize - full_ysize) / 2 : 0);
199   }
200 #endif
201
202 #if 1
203   if (!menBorder.Checked)
204   {
205     SR.left += 16;
206     SR.top  += 16;
207   }
208 #endif
209
210 #if 1
211
212 #if 1
213   printf("::: DDScrollBuffer.c: DDScrollBuffer_Blt(): blit from %d, %d [%ld, %ld] [%ld, %ld] [%ld, %ld]\n",
214          SR.left, SR.top, mScrollX, mScrollY, mDestXOff, mDestYOff, tX, tY);
215 #endif
216
217 #if 0
218   /* !!! quick and dirty -- FIX THIS !!! */
219   if (tape.playing && tape.fast_forward &&
220       target_bitmap == window &&
221       (FrameCounter % 2) != 0)
222     printf("::: FrameCounter == %d\n", FrameCounter);
223 #endif
224
225 #if 1
226   SyncDisplay();
227 #endif
228
229 #if 1
230   BlitBitmap(screenBitmap, target_bitmap,
231              SR.left, SR.top, tX, tY, sX, sY);
232 #else
233   BlitBitmap(screenBitmap, target_bitmap,
234              SR.left, SR.top,
235              SCR_FIELDX * TILEX, SCR_FIELDY * TILEY, SX, SY);
236 #endif
237
238 #if 1
239   FlushDisplay();
240 #endif
241
242   return;
243
244 #endif
245
246   // DDraw.WaitForVerticalBlank DDWAITVB_BLOCKBEGIN, 0
247   if (IS_NOTHING(&Buffer, sizeof(Buffer)))
248     return;
249
250   if (IS_NOTHING(&PrimarySurface, sizeof(PrimarySurface)))
251     return;
252
253   L = PrimarySurface.Blt(DR, &Buffer, SR, DDBLT_WAIT);
254   if (L != DD_OK)
255   {
256     switch (L)
257     {
258 #if 0
259       case DDERR_GENERIC:
260         Debug.Assert(False);
261         break;
262
263       case DDERR_INVALIDCLIPLIST:
264         Debug.Assert(False);
265         break;
266
267       case DDERR_INVALIDOBJECT:
268         Debug.Assert(False);
269         break;
270
271       case DDERR_INVALIDPARAMS:
272         Debug.Assert(False);
273         break;
274
275       case DDERR_INVALIDRECT:
276         Debug.Assert(False);
277         break;
278
279       case DDERR_NOALPHAHW:
280         Debug.Assert(False);
281         break;
282
283       case DDERR_NOBLTHW:
284         Debug.Assert(False);
285         break;
286
287       case DDERR_NOCLIPLIST:
288         Debug.Assert(False);
289         break;
290
291       case DDERR_NODDROPSHW:
292         Debug.Assert(False);
293         break;
294
295       case DDERR_NOMIRRORHW:
296         Debug.Assert(False);
297         break;
298
299       case DDERR_NORASTEROPHW:
300         Debug.Assert(False);
301         break;
302
303       case DDERR_NOROTATIONHW:
304         Debug.Assert(False);
305         break;
306
307       case DDERR_NOSTRETCHHW:
308         Debug.Assert(False);
309         break;
310
311       case DDERR_NOZBUFFERHW:
312         Debug.Assert(False);
313         break;
314
315       case DDERR_SURFACEBUSY:
316         Debug.Assert(False);
317         break;
318 #endif
319
320       case DDERR_SURFACELOST:
321         DDraw.RestoreAllSurfaces();
322         if (! PrimarySurface.isLost())
323         {
324           subDisplayLevel();
325           // Blt();
326         }
327
328         // RestorePrimarySurface
329         // ClipToWindow 0
330         break;
331
332 #if 0
333       case DDERR_UNSUPPORTED:
334         Debug.Assert(False);
335         break;
336
337       case DDERR_WASSTILLDRAWING:
338         Debug.Assert(False);
339         break;
340
341       default:
342         Debug.Assert(False);
343         break;
344 #endif
345     }
346   }
347
348 #if 0
349   //  Buffer.UpdateOverlay SR, PrimarySurface, DR, DDOVER_SHOW
350   if (EditFlag)
351     FMark.RefreshMarker();
352 #endif
353
354   // BltEH:
355 }
356
357 void DDScrollBuffer_Blt()
358 {
359   DDScrollBuffer_Blt_Ext(window);
360 }
361
362 void DDScrollBuffer_ScrollTo(int X, int Y)
363 {
364   if (NoDisplayFlag)
365     return;
366
367   X = X / Stretch;
368   Y = Y / Stretch;
369   mScrollX = X;
370   mScrollY = Y;
371   ScrollX = mScrollX;
372   ScrollY = mScrollY;
373
374 #if 0
375   printf("::: DDScrollBuffer.c: DDScrollBuffer_ScrollTo():  mScroll: %ld, %ld [%d, %d]\n",
376          mScrollX, mScrollY, X, Y);
377 #endif
378 }
379
380 void DDScrollBuffer_ScrollTowards(int X, int Y, double Step)
381 {
382   double dx, dY, r;
383
384   if (NoDisplayFlag)
385     return;
386
387 #if 0
388   printf("::: DDScrollBuffer.c: DDScrollBuffer_ScrollTowards(): (1) mScroll: %ld, %ld [%d, %d, %f]\n",
389          mScrollX, mScrollY, X, Y, Step);
390 #endif
391
392   X = X / Stretch;
393   Y = Y / Stretch;
394   dx = X - mScrollX;
395   dY = Y - mScrollY;
396   r = Sqr(dx * dx + dY * dY);
397   if (r == 0) // we are there already
398     return;
399
400   if (Step < r)
401     r = Step / r;
402   else
403     r = 1;
404
405   mScrollX = mScrollX + dx * r;
406   mScrollY = mScrollY + dY * r;
407   ScrollX = mScrollX;
408   ScrollY = mScrollY;
409
410 #if 0
411   printf("::: DDScrollBuffer.c: DDScrollBuffer_ScrollTowards(): (2) mScroll: %ld, %ld [%d, %d, %f]\n",
412          mScrollX, mScrollY, X, Y, Step);
413 #endif
414 }
415
416 void DDScrollBuffer_SoftScrollTo(int X, int Y, long TimeMS, int FPS)
417 {
418   double dx, dY;
419 #if 0
420   TickCountObject Tick;
421 #endif
422   long dT, StepCount;
423   double T, tStep;
424   long oldX, oldY, maxD;
425   static boolean AlreadyRunning = False;
426
427   if (NoDisplayFlag)
428     return;
429
430   if (AlreadyRunning)
431   {
432     return;
433   }
434
435   AlreadyRunning = True;
436   X = X / Stretch;
437   Y = Y / Stretch;
438   dx = X - mScrollX;
439   dY = Y - mScrollY;
440   maxD = (Abs(dx) < Abs(dY) ? Abs(dY) : Abs(dx));
441   StepCount = FPS * (TimeMS / (double)1000);
442   if (StepCount > maxD)
443     StepCount = maxD;
444
445   if (StepCount == 0)
446     StepCount = 1;
447
448   dT = 1000 / FPS;
449   tStep = (double)1 / StepCount;
450   oldX = mScrollX;
451   oldY = mScrollY;
452   // R = Sqr(dX * dX + dY * dY)
453   // If R = 0 Then Exit Sub 'we are there already
454   for (T = (double)tStep; T <= (double)1; T += tStep)
455   {
456     if (UserDragFlag)
457       goto SoftScrollEH;
458
459     // If Claim Then Exit For
460
461 #if 0
462     Tick.DelayMS(dT, False);
463 #endif
464
465     mScrollX = oldX + T * dx;
466     mScrollY = oldY + T * dY;
467     ScrollX = mScrollX;
468     ScrollY = mScrollY;
469     // Blt();
470   }
471
472   if (UserDragFlag)
473     goto SoftScrollEH;
474
475 #if 0
476   Tick.DelayMS(dT, False);
477 #endif
478
479   mScrollX = X;
480   mScrollY = Y;
481   ScrollX = mScrollX;
482   ScrollY = mScrollY;
483   // Blt();
484
485 SoftScrollEH:
486   AlreadyRunning = False;
487
488 #if 0
489   printf("::: DDScrollBuffer.c: DDScrollBuffer_SoftScrollTo(): mScroll: %ld, %ld\n",
490          mScrollX, mScrollY);
491 #endif
492 }