rnd-20131203-1-src
[rocksndiamonds.git] / src / game_sp / MainForm.c
1 // ----------------------------------------------------------------------------
2 // MainForm.c
3 // ----------------------------------------------------------------------------
4
5 #include "MainForm.h"
6
7
8 static void DrawFrame(int Delta);
9 static void ReStretch();
10
11 void DrawField(int X, int Y);
12 void DrawFieldAnimated(int X, int Y);
13 void DrawFieldNoAnimated(int X, int Y);
14
15 void DrawFrameIfNeeded()
16 {
17   DrawFrame(0);
18
19   /* !!! CHECK THIS !!! */
20 #if 1
21   if (! menBorder)
22     DrawFrame(1);
23 #endif
24 }
25
26 void DisplayLevel()
27 {
28   int X, Y;
29
30   if (! LevelLoaded)
31     return;
32
33   ClearRectangle(backbuffer, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
34 #if 1
35   ClearRectangle(bitmap_db_field_sp, 0, 0, FXSIZE, FYSIZE);
36 #else
37   ClearRectangle(bitmap_db_field_sp, 0, 0,
38                  MAX_BUF_XSIZE * TILEX, MAX_BUF_YSIZE * TILEY);
39 #endif
40
41 #if 1
42   SetDisplayRegion();
43 #endif
44
45   DrawFrameIfNeeded();
46
47   if (bPlaying)
48   {
49     for (Y = DisplayMinY; Y <= DisplayMaxY; Y++)
50       for (X = DisplayMinX; X <= DisplayMaxX; X++)
51         DrawFieldNoAnimated(X, Y);
52
53     for (Y = DisplayMinY; Y <= DisplayMaxY; Y++)
54       for (X = DisplayMinX; X <= DisplayMaxX; X++)
55         DrawFieldAnimated(X, Y);
56   }
57   else
58   {
59     for (Y = DisplayMinY; Y <= DisplayMaxY; Y++)
60       for (X = DisplayMinX; X <= DisplayMaxX; X++)
61         DrawField(X, Y);
62   }
63 }
64
65 void Form_Load()
66 {
67   InitGlobals();
68
69   ReStretch();
70 }
71
72 static void DrawFrame(int Delta)
73 {
74   int i, LX, tY, RX, BY;
75
76   LX = -1 + Delta;
77   tY = -1 + Delta;
78   RX = FieldWidth - Delta;
79   BY = FieldHeight - Delta;
80
81   DrawImage(LX, tY, (Delta > 0 ? imgFrameCorner : aniSpace));
82   DrawImage(LX, BY, (Delta > 0 ? imgFrameCorner : aniSpace));
83   DrawImage(RX, tY, (Delta > 0 ? imgFrameCorner : aniSpace));
84   DrawImage(RX, BY, (Delta > 0 ? imgFrameCorner : aniSpace));
85
86   for (i = LX + 1; i <= RX - 1; i++)
87   {
88     DrawImage(i, tY, (Delta > 0 ? imgFrameHorizontal : aniSpace));
89     DrawImage(i, BY, (Delta > 0 ? imgFrameHorizontal : aniSpace));
90   }
91
92   for (i = tY + 1; i <= BY - 1; i++)
93   {
94     DrawImage(LX, i, (Delta > 0 ? imgFrameVertical : aniSpace));
95     DrawImage(RX, i, (Delta > 0 ? imgFrameVertical : aniSpace));
96   }
97
98   if (Delta > 0)
99   {
100     // ...
101     // ClearRectangle(bitmap_db_field_sp, 
102   }
103 }
104
105 static void RestoreFrame()
106 {
107   int i, LX, tY, RX, BY;
108
109   LX = 0;
110   tY = 0;
111   RX = FieldWidth - 1;
112   BY = FieldHeight - 1;
113
114   for (i = LX; i <= RX; i++)
115   {
116     DrawField(i, tY);
117     DrawField(i, BY);
118   }
119
120   for (i = tY + 1; i <= BY - 1; i++)
121   {
122     DrawField(LX, i);
123     DrawField(RX, i);
124   }
125 }
126
127 void SetDisplayRegion()
128 {
129   if (! menBorder)
130   {
131     DisplayMinX = 1;
132     DisplayMinY = 1;
133     DisplayMaxX = FieldWidth - 2;
134     DisplayMaxY = FieldHeight - 2;
135
136     if (LevelLoaded)
137       DrawFrame(1);
138   }
139   else
140   {
141     DisplayMinX = 0;
142     DisplayMinY = 0;
143     DisplayMaxX = FieldWidth - 1;
144     DisplayMaxY = FieldHeight - 1;
145
146     if (LevelLoaded)
147       RestoreFrame();
148   }
149 }
150
151 void menPlay_Click()
152 {
153   bPlaying = True;
154
155   subFetchAndInitLevelB();
156
157   ReStretch();
158
159   subMainGameLoop_Init();
160
161 #if 1
162   return;
163 #endif
164
165   bPlaying = False;
166
167   subFetchAndInitLevel();
168 }
169
170 static void ReStretch()
171 {
172   if (LevelLoaded)
173   {
174     SetDisplayRegion();
175
176     SetScrollEdges();
177
178     ScrollTo(ScrollX, ScrollY);
179
180     DisplayLevel();
181   }
182
183   subCalculateScreenScrollPos();
184
185   ScrollTo(ScreenScrollXPos, ScreenScrollYPos);
186 }
187
188 void SetScrollEdges()
189 {
190 #if NEW_TILESIZE
191 #if 0
192   int pseudo_sxsize = SXSIZE * TILESIZE / TILESIZE_VAR;
193   int pseudo_sysize = SYSIZE * TILESIZE / TILESIZE_VAR;
194 #endif
195 #endif
196   int border1_offset = (menBorder ? 1 : 2);
197   int border2_offset = (menBorder ? 0 : TILESIZE / 2);
198
199   /* scroll correction for border frame (1 tile) or border element (2 tiles) */
200   ScrollMinX = 0;
201   ScrollMinY = 0;
202 #if NEW_TILESIZE
203 #if 1
204   ScrollMaxX = (DisplayMaxX + border1_offset - SCR_FIELDX) * TILEX;
205   ScrollMaxY = (DisplayMaxY + border1_offset - SCR_FIELDY) * TILEY;
206 #else
207   ScrollMaxX = (DisplayMaxX + border1_offset) * TILEX - pseudo_sxsize;
208   ScrollMaxY = (DisplayMaxY + border1_offset) * TILEY - pseudo_sysize;
209 #endif
210 #else
211   ScrollMaxX = (DisplayMaxX + border1_offset) * TILEX - SXSIZE;
212   ScrollMaxY = (DisplayMaxY + border1_offset) * TILEY - SYSIZE;
213 #endif
214
215   /* scroll correction for border element (half tile on left and right side) */
216   ScrollMinX += border2_offset;
217   ScrollMinY += border2_offset;
218   ScrollMaxX -= border2_offset;
219   ScrollMaxY -= border2_offset;
220
221   /* scroll correction for even number of visible tiles (half tile shifted) */
222   ScrollMinX -= game_sp.scroll_xoffset;
223   ScrollMaxX -= game_sp.scroll_xoffset;
224   ScrollMinY -= game_sp.scroll_yoffset;
225   ScrollMaxY -= game_sp.scroll_yoffset;
226
227 #if 0
228   printf("::: (%ld, %ld), (%ld, %ld) -> (%d, %d), (%d, %d)\n",
229          DisplayMinX, DisplayMinY, DisplayMaxX, DisplayMaxY,
230          ScrollMinX, ScrollMinY, ScrollMaxX, ScrollMaxY);
231 #endif
232 }
233
234 void DrawField(int X, int Y)
235 {
236   int tsi = GetSI(X, Y);
237   int Tmp = LowByte(PlayField16[tsi]);
238
239   if (Tmp < fiFirst || Tmp > fiLast)
240     Tmp = fiSpace;
241
242   if (Tmp == fiRAM ||
243       Tmp == fiHardWare ||
244       Tmp == fiBug ||
245       Tmp == fiWallSpace)
246     Tmp = DisPlayField[tsi];
247
248   subCopyImageToScreen(tsi, fiGraphic[Tmp]);
249
250   if (Tmp != fiSpace &&
251       Tmp != fiSnikSnak &&
252       Tmp != fiElectron)
253     GfxGraphic[X][Y] = fiGraphic[Tmp];
254 }
255
256 void DrawFieldAnimated(int X, int Y)
257 {
258   int tsi = GetSI(X, Y);
259   int Tmp = LowByte(PlayField16[tsi]);
260
261   switch (Tmp)
262   {
263     case fiSnikSnak:
264       subDrawAnimatedSnikSnaks(tsi);
265       break;
266
267     case fiElectron:
268       subDrawAnimatedElectrons(tsi);
269       break;
270
271     default:
272       break;
273   }
274 }
275
276 void DrawFieldNoAnimated(int X, int Y)
277 {
278   int tsi = GetSI(X, Y);
279   int Tmp = LowByte(PlayField16[tsi]);
280
281   switch (Tmp)
282   {
283     case fiSnikSnak:
284       subCopyImageToScreen(tsi, aniSpace);
285       break;
286
287     case fiElectron:
288       subCopyImageToScreen(tsi, aniSpace);
289       break;
290
291     default:
292 #if 1
293       DrawField(X, Y);
294 #else
295       if (Tmp < fiFirst || Tmp > fiLast)
296         Tmp = fiSpace;
297
298       if (Tmp == fiRAM ||
299           Tmp == fiHardWare ||
300           Tmp == fiBug ||
301           Tmp == fiWallSpace)
302         Tmp = DisPlayField[tsi];
303
304       subCopyImageToScreen(tsi, fiGraphic[Tmp]);
305
306       if (Tmp != fiSpace &&
307           Tmp != fiSnikSnak &&
308           Tmp != fiElectron)
309         GfxGraphic[X][Y] = fiGraphic[Tmp];
310 #endif
311       break;
312   }
313 }
314
315 void DrawImage(int X, int Y, int graphic)
316 {
317   DDSpriteBuffer_BltImg(StretchWidth * X, StretchWidth * Y, graphic, 0);
318 }