rnd-20090623-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 // --- Option Explicit
25
26 // needs reference to: DirectX7 for Visual Basic Type Library
27
28 DirectDrawSurface7 Buffer;
29 DirectDrawSurface7 mPrimary;
30 long mWidth, mHeight;
31 long mhWnd;
32 long mScrollX, mScrollY;
33 long mDestXOff, mDestYOff;
34
35 void DDScrollBuffer_Let_DestXOff(long NewVal)
36 {
37   mDestXOff = NewVal;
38 }
39
40 long DDScrollBuffer_Get_DestXOff()
41 {
42   long DestXOff;
43
44   DestXOff = mDestXOff;
45
46   return DestXOff;
47 }
48
49 void DDScrollBuffer_Let_DestYOff(long NewVal)
50 {
51   mDestYOff = NewVal;
52 }
53
54 long DDScrollBuffer_Get_DestYOff()
55 {
56   long DestYOff;
57
58   DestYOff = mDestYOff;
59
60   return DestYOff;
61 }
62
63 DirectDrawSurface7 DDScrollBuffer_Get_Surface()
64 {
65   DirectDrawSurface7 Surface;
66
67   Surface = Buffer;
68
69   return Surface;
70 }
71
72 long DDScrollBuffer_Get_Width()
73 {
74   long Width;
75
76   Width = mWidth;
77
78   return Width;
79 }
80
81 int DDScrollBuffer_Get_Height()
82 {
83   int Height;
84
85   Height = mHeight;
86
87   return Height;
88 }
89
90 long DDScrollBuffer_CreateAtSize(long Width, long Height, long hWndViewPort)
91 {
92   long CreateAtSize;
93
94   DDSURFACEDESC2 SD;
95
96   CreateAtSize = 0;
97   mhWnd = hWndViewPort;
98   // Create ScrollBuffer:
99   {
100     SD.lFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
101     SD.ddsCaps.lCaps = DDSCAPS_VIDEOMEMORY;
102     // SD.ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN
103     SD.LWidth = Width;
104     SD.LHeight = Height;
105   }
106
107   // --- On Error Resume Next
108   Buffer = DDraw.CreateSurface(SD);
109   if (Err.Number != 0)
110     return CreateAtSize;
111
112   // --- On Error GoTo 0
113
114   mWidth = Width;
115   mHeight = Height;
116   mScrollX = 0;
117   mScrollY = 0;
118   CreateAtSize = -1;
119
120   return CreateAtSize;
121 }
122
123 void DDScrollBuffer_Cls(int BackColor)
124 {
125   RECT EmptyRect;
126
127   if (NoDisplayFlag)
128     return;
129
130   Buffer.BltColorFill(EmptyRect, BackColor);
131 }
132
133 void DDScrollBuffer_Blt()
134 {
135   RECT DR, SR;
136   long tX, tY, L;
137   // RECT ERect;
138   // long Restore;
139
140   if (NoDisplayFlag)
141     return;
142
143
144   // --- On Error GoTo BltEH
145   DirectX.GetWindowRect(mhWnd, DR);
146   // --- On Error GoTo 0
147
148   {
149     tX = (DR.right - DR.left) / Stretch;
150     tY = (DR.bottom - DR.top) / Stretch;
151   }
152   {
153     SR.left = mScrollX + mDestXOff;
154     SR.top = mScrollY + mDestYOff;
155     SR.right = SR.left + tX;
156     SR.bottom = SR.top + tY;
157     //    If mWidth < SR.right Then
158     //      SR.right = mWidth
159     //      DR.right = DR.left + Stretch * (SR.right - SR.left)
160     //    End If
161     //    If mHeight < SR.bottom Then
162     //      SR.bottom = mHeight
163     //      DR.bottom = DR.top + Stretch * (SR.bottom - SR.top)
164     //    End If
165     //    If (mScrollX + mDestXOff) < 0 Then
166     //      SR.left = 0
167     //      DR.left = DR.left - Stretch * (mScrollX + mDestXOff)
168     //    End If
169     //    If (mScrollY + mDestYOff) < 0 Then
170     //      SR.top = 0
171     //      DR.top = DR.top - Stretch * (mScrollY + mDestYOff)
172     //    End If
173   }
174   // DDraw.WaitForVerticalBlank DDWAITVB_BLOCKBEGIN, 0
175   if (IS_NOTHING(&Buffer, sizeof(Buffer)))
176     return;
177
178   if (IS_NOTHING(&PrimarySurface, sizeof(PrimarySurface)))
179     return;
180
181   L = PrimarySurface_Blt(DR, Buffer, SR, DDBLT_WAIT);
182   if (L != DD_OK)
183   {
184     switch (L)
185     {
186       case DDERR_GENERIC:
187         Debug.Assert(False);
188         break;
189
190       case DDERR_INVALIDCLIPLIST:
191         Debug.Assert(False);
192         break;
193
194       case DDERR_INVALIDOBJECT:
195         Debug.Assert(False);
196         break;
197
198       case DDERR_INVALIDPARAMS:
199         Debug.Assert(False);
200         break;
201
202       case DDERR_INVALIDRECT:
203         Debug.Assert(False);
204         break;
205
206       case DDERR_NOALPHAHW:
207         Debug.Assert(False);
208         break;
209
210       case DDERR_NOBLTHW:
211         Debug.Assert(False);
212         break;
213
214       case DDERR_NOCLIPLIST:
215         Debug.Assert(False);
216         break;
217
218       case DDERR_NODDROPSHW:
219         Debug.Assert(False);
220         break;
221
222       case DDERR_NOMIRRORHW:
223         Debug.Assert(False);
224         break;
225
226       case DDERR_NORASTEROPHW:
227         Debug.Assert(False);
228         break;
229
230       case DDERR_NOROTATIONHW:
231         Debug.Assert(False);
232         break;
233
234       case DDERR_NOSTRETCHHW:
235         Debug.Assert(False);
236         break;
237
238       case DDERR_NOZBUFFERHW:
239         Debug.Assert(False);
240         break;
241
242       case DDERR_SURFACEBUSY:
243         Debug.Assert(False);
244         break;
245
246       case DDERR_SURFACELOST:
247         DDraw.RestoreAllSurfaces();
248         if (! PrimarySurface.isLost())
249         {
250           subDisplayLevel();
251           // Blt();
252         }
253
254         // RestorePrimarySurface
255         // ClipToWindow 0
256         break;
257
258       case DDERR_UNSUPPORTED:
259         Debug.Assert(False);
260         break;
261
262       case DDERR_WASSTILLDRAWING:
263         Debug.Assert(False);
264         break;
265
266       default:
267         Debug.Assert(False);
268         break;
269     }
270   }
271
272 #if 0
273   //  Buffer.UpdateOverlay SR, PrimarySurface, DR, DDOVER_SHOW
274   if (EditFlag)
275     FMark.RefreshMarker();
276 #endif
277
278   // BltEH:
279 }
280
281 void DDScrollBuffer_ScrollTo(int X, int Y)
282 {
283   if (NoDisplayFlag)
284     return;
285
286   X = X / Stretch;
287   Y = Y / Stretch;
288   mScrollX = X;
289   mScrollY = Y;
290   ScrollX = mScrollX;
291   ScrollY = mScrollY;
292 }
293
294 void DDScrollBuffer_ScrollTowards(int X, int Y, double Step)
295 {
296   double dx, dY, r;
297
298   if (NoDisplayFlag)
299     return;
300
301   X = X / Stretch;
302   Y = Y / Stretch;
303   dx = X - mScrollX;
304   dY = Y - mScrollY;
305   r = Sqr(dx * dx + dY * dY);
306   if (r == 0) // we are there already
307     return;
308
309   if (Step < r)
310     r = Step / r;
311   else
312     r = 1;
313
314   mScrollX = mScrollX + dx * r;
315   mScrollY = mScrollY + dY * r;
316   ScrollX = mScrollX;
317   ScrollY = mScrollY;
318 }
319
320 void DDScrollBuffer_SoftScrollTo(int X, int Y, long TimeMS, int FPS)
321 {
322   double dx, dY;
323   TickCountObject Tick;
324   long dT, StepCount;
325   double T, tStep;
326   long oldX, oldY, maxD;
327   boolean AlreadyRunning;
328
329   if (NoDisplayFlag)
330     return;
331
332   if (AlreadyRunning)
333   {
334     return;
335   }
336
337   AlreadyRunning = True;
338   X = X / Stretch;
339   Y = Y / Stretch;
340   dx = X - mScrollX;
341   dY = Y - mScrollY;
342   maxD = (Abs(dx) < Abs(dY) ?  Abs(dY) :  Abs(dY));
343   StepCount = FPS * (TimeMS / (double)1000);
344   if (StepCount > maxD)
345     StepCount = maxD;
346
347   if (StepCount == 0)
348     StepCount = 1;
349
350   dT = 1000 / FPS;
351   tStep = (double)1 / StepCount;
352   oldX = mScrollX;
353   oldY = mScrollY;
354   // R = Sqr(dX * dX + dY * dY)
355   // If R = 0 Then Exit Sub 'we are there already
356   for (T = (double)tStep; T <= (double)1; T += tStep)
357   {
358     if (UserDragFlag)
359       goto SoftScrollEH;
360
361     // If Claim Then Exit For
362     Tick.DelayMS(dT, False);
363     mScrollX = oldX + T * dx;
364     mScrollY = oldY + T * dY;
365     ScrollX = mScrollX;
366     ScrollY = mScrollY;
367     // Blt();
368   }
369
370   if (UserDragFlag)
371     goto SoftScrollEH;
372
373   Tick.DelayMS(dT, False);
374   mScrollX = X;
375   mScrollY = Y;
376   ScrollX = mScrollX;
377   ScrollY = mScrollY;
378   // Blt();
379
380 SoftScrollEH:
381   AlreadyRunning = False;
382 }