rnd-20090801-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 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()
135 {
136   RECT DR, SR;
137   long tX, tY, L;
138   // RECT ERect;
139   // long Restore;
140
141   if (NoDisplayFlag)
142     return;
143
144 #if 0
145   // --- On Error GoTo BltEH
146   DirectX.GetWindowRect(mhWnd, DR);
147   // --- On Error GoTo 0
148 #endif
149
150   {
151     tX = (DR.right - DR.left) / Stretch;
152     tY = (DR.bottom - DR.top) / Stretch;
153   }
154   {
155     SR.left = mScrollX + mDestXOff;
156     SR.top = mScrollY + mDestYOff;
157     SR.right = SR.left + tX;
158     SR.bottom = SR.top + tY;
159     //    If mWidth < SR.right Then
160     //      SR.right = mWidth
161     //      DR.right = DR.left + Stretch * (SR.right - SR.left)
162     //    End If
163     //    If mHeight < SR.bottom Then
164     //      SR.bottom = mHeight
165     //      DR.bottom = DR.top + Stretch * (SR.bottom - SR.top)
166     //    End If
167     //    If (mScrollX + mDestXOff) < 0 Then
168     //      SR.left = 0
169     //      DR.left = DR.left - Stretch * (mScrollX + mDestXOff)
170     //    End If
171     //    If (mScrollY + mDestYOff) < 0 Then
172     //      SR.top = 0
173     //      DR.top = DR.top - Stretch * (mScrollY + mDestYOff)
174     //    End If
175   }
176
177 #if 1
178
179 #if 0
180   printf("::: DDScrollBuffer.c: DDScrollBuffer_Blt(): blit from %d, %d [%ld, %ld] [%ld, %ld]\n",
181          SR.left, SR.top, mScrollX, mScrollY, mDestXOff, mDestYOff);
182 #endif
183
184 #if 0
185   BlitBitmap(screenBitmap, window,
186              1600, 320,
187              SCR_FIELDX * TILEX, SCR_FIELDY * TILEY, SX, SY);
188 #else
189   BlitBitmap(screenBitmap, window,
190              SR.left, SR.top,
191              SCR_FIELDX * TILEX, SCR_FIELDY * TILEY, SX, SY);
192 #endif
193
194   return;
195 #endif
196
197   // DDraw.WaitForVerticalBlank DDWAITVB_BLOCKBEGIN, 0
198   if (IS_NOTHING(&Buffer, sizeof(Buffer)))
199     return;
200
201   if (IS_NOTHING(&PrimarySurface, sizeof(PrimarySurface)))
202     return;
203
204   L = PrimarySurface.Blt(DR, &Buffer, SR, DDBLT_WAIT);
205   if (L != DD_OK)
206   {
207     switch (L)
208     {
209 #if 0
210       case DDERR_GENERIC:
211         Debug.Assert(False);
212         break;
213
214       case DDERR_INVALIDCLIPLIST:
215         Debug.Assert(False);
216         break;
217
218       case DDERR_INVALIDOBJECT:
219         Debug.Assert(False);
220         break;
221
222       case DDERR_INVALIDPARAMS:
223         Debug.Assert(False);
224         break;
225
226       case DDERR_INVALIDRECT:
227         Debug.Assert(False);
228         break;
229
230       case DDERR_NOALPHAHW:
231         Debug.Assert(False);
232         break;
233
234       case DDERR_NOBLTHW:
235         Debug.Assert(False);
236         break;
237
238       case DDERR_NOCLIPLIST:
239         Debug.Assert(False);
240         break;
241
242       case DDERR_NODDROPSHW:
243         Debug.Assert(False);
244         break;
245
246       case DDERR_NOMIRRORHW:
247         Debug.Assert(False);
248         break;
249
250       case DDERR_NORASTEROPHW:
251         Debug.Assert(False);
252         break;
253
254       case DDERR_NOROTATIONHW:
255         Debug.Assert(False);
256         break;
257
258       case DDERR_NOSTRETCHHW:
259         Debug.Assert(False);
260         break;
261
262       case DDERR_NOZBUFFERHW:
263         Debug.Assert(False);
264         break;
265
266       case DDERR_SURFACEBUSY:
267         Debug.Assert(False);
268         break;
269 #endif
270
271       case DDERR_SURFACELOST:
272         DDraw.RestoreAllSurfaces();
273         if (! PrimarySurface.isLost())
274         {
275           subDisplayLevel();
276           // Blt();
277         }
278
279         // RestorePrimarySurface
280         // ClipToWindow 0
281         break;
282
283 #if 0
284       case DDERR_UNSUPPORTED:
285         Debug.Assert(False);
286         break;
287
288       case DDERR_WASSTILLDRAWING:
289         Debug.Assert(False);
290         break;
291
292       default:
293         Debug.Assert(False);
294         break;
295 #endif
296     }
297   }
298
299 #if 0
300   //  Buffer.UpdateOverlay SR, PrimarySurface, DR, DDOVER_SHOW
301   if (EditFlag)
302     FMark.RefreshMarker();
303 #endif
304
305   // BltEH:
306 }
307
308 void DDScrollBuffer_ScrollTo(int X, int Y)
309 {
310   if (NoDisplayFlag)
311     return;
312
313   X = X / Stretch;
314   Y = Y / Stretch;
315   mScrollX = X;
316   mScrollY = Y;
317   ScrollX = mScrollX;
318   ScrollY = mScrollY;
319
320 #if 0
321   printf("::: DDScrollBuffer.c: DDScrollBuffer_ScrollTo():  mScroll: %ld, %ld [%d, %d]\n",
322          mScrollX, mScrollY, X, Y);
323 #endif
324 }
325
326 void DDScrollBuffer_ScrollTowards(int X, int Y, double Step)
327 {
328   double dx, dY, r;
329
330   if (NoDisplayFlag)
331     return;
332
333 #if 0
334   printf("::: DDScrollBuffer.c: DDScrollBuffer_ScrollTowards(): (1) mScroll: %ld, %ld [%d, %d, %f]\n",
335          mScrollX, mScrollY, X, Y, Step);
336 #endif
337
338   X = X / Stretch;
339   Y = Y / Stretch;
340   dx = X - mScrollX;
341   dY = Y - mScrollY;
342   r = Sqr(dx * dx + dY * dY);
343   if (r == 0) // we are there already
344     return;
345
346   if (Step < r)
347     r = Step / r;
348   else
349     r = 1;
350
351   mScrollX = mScrollX + dx * r;
352   mScrollY = mScrollY + dY * r;
353   ScrollX = mScrollX;
354   ScrollY = mScrollY;
355
356 #if 0
357   printf("::: DDScrollBuffer.c: DDScrollBuffer_ScrollTowards(): (2) mScroll: %ld, %ld [%d, %d, %f]\n",
358          mScrollX, mScrollY, X, Y, Step);
359 #endif
360 }
361
362 void DDScrollBuffer_SoftScrollTo(int X, int Y, long TimeMS, int FPS)
363 {
364   double dx, dY;
365 #if 0
366   TickCountObject Tick;
367 #endif
368   long dT, StepCount;
369   double T, tStep;
370   long oldX, oldY, maxD;
371   static boolean AlreadyRunning = False;
372
373   if (NoDisplayFlag)
374     return;
375
376   if (AlreadyRunning)
377   {
378     return;
379   }
380
381   AlreadyRunning = True;
382   X = X / Stretch;
383   Y = Y / Stretch;
384   dx = X - mScrollX;
385   dY = Y - mScrollY;
386   maxD = (Abs(dx) < Abs(dY) ? Abs(dY) : Abs(dx));
387   StepCount = FPS * (TimeMS / (double)1000);
388   if (StepCount > maxD)
389     StepCount = maxD;
390
391   if (StepCount == 0)
392     StepCount = 1;
393
394   dT = 1000 / FPS;
395   tStep = (double)1 / StepCount;
396   oldX = mScrollX;
397   oldY = mScrollY;
398   // R = Sqr(dX * dX + dY * dY)
399   // If R = 0 Then Exit Sub 'we are there already
400   for (T = (double)tStep; T <= (double)1; T += tStep)
401   {
402     if (UserDragFlag)
403       goto SoftScrollEH;
404
405     // If Claim Then Exit For
406
407 #if 0
408     Tick.DelayMS(dT, False);
409 #endif
410
411     mScrollX = oldX + T * dx;
412     mScrollY = oldY + T * dY;
413     ScrollX = mScrollX;
414     ScrollY = mScrollY;
415     // Blt();
416   }
417
418   if (UserDragFlag)
419     goto SoftScrollEH;
420
421 #if 0
422   Tick.DelayMS(dT, False);
423 #endif
424
425   mScrollX = X;
426   mScrollY = Y;
427   ScrollX = mScrollX;
428   ScrollY = mScrollY;
429   // Blt();
430
431 SoftScrollEH:
432   AlreadyRunning = False;
433
434 #if 0
435   printf("::: DDScrollBuffer.c: DDScrollBuffer_SoftScrollTo(): mScroll: %ld, %ld\n",
436          mScrollX, mScrollY);
437 #endif
438 }