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