rnd-20100417-2-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, imgFrameCorner);
82   DrawImage(LX, BY, imgFrameCorner);
83   DrawImage(RX, tY, imgFrameCorner);
84   DrawImage(RX, BY, imgFrameCorner);
85
86   for (i = LX + 1; i <= RX - 1; i++)
87   {
88     DrawImage(i, tY, imgFrameHorizontal);
89     DrawImage(i, BY, imgFrameHorizontal);
90   }
91
92   for (i = tY + 1; i <= BY - 1; i++)
93   {
94     DrawImage(LX, i, imgFrameVertical);
95     DrawImage(RX, i, imgFrameVertical);
96   }
97 }
98
99 static void RestoreFrame()
100 {
101   int i, LX, tY, RX, BY;
102
103   LX = 0;
104   tY = 0;
105   RX = FieldWidth - 1;
106   BY = FieldHeight - 1;
107
108   for (i = LX; i <= RX; i++)
109   {
110     DrawField(i, tY);
111     DrawField(i, BY);
112   }
113
114   for (i = tY + 1; i <= BY - 1; i++)
115   {
116     DrawField(LX, i);
117     DrawField(RX, i);
118   }
119 }
120
121 void SetDisplayRegion()
122 {
123   if (! menBorder)
124   {
125     DisplayMinX = 1;
126     DisplayMinY = 1;
127     DisplayMaxX = FieldWidth - 2;
128     DisplayMaxY = FieldHeight - 2;
129
130     if (LevelLoaded)
131       DrawFrame(1);
132   }
133   else
134   {
135     DisplayMinX = 0;
136     DisplayMinY = 0;
137     DisplayMaxX = FieldWidth - 1;
138     DisplayMaxY = FieldHeight - 1;
139
140     if (LevelLoaded)
141       RestoreFrame();
142   }
143 }
144
145 void menPlay_Click()
146 {
147   bPlaying = True;
148
149   subFetchAndInitLevelB();
150
151   ReStretch();
152
153   subMainGameLoop_Init();
154
155 #if 1
156   return;
157 #endif
158
159   bPlaying = False;
160
161   subFetchAndInitLevel();
162 }
163
164 static void ReStretch()
165 {
166   if (LevelLoaded)
167   {
168     SetDisplayRegion();
169
170     SetScrollEdges();
171
172     ScrollTo(ScrollX, ScrollY);
173
174     DisplayLevel();
175   }
176
177   subCalculateScreenScrollPos();
178
179   ScrollTo(ScreenScrollXPos, ScreenScrollYPos);
180 }
181
182 void SetScrollEdges()
183 {
184 #if 1
185   int border_offset = (menBorder ? 1 : 2);
186
187   ScrollMinX = 0;
188   ScrollMinY = 0;
189   ScrollMaxX = (DisplayMaxX + border_offset) * BaseWidth - SXSIZE;
190   ScrollMaxY = (DisplayMaxY + border_offset) * BaseWidth - SYSIZE;
191
192 #if 1
193   if (!menBorder)
194   {
195     ScrollMinX += TILEX / 2;
196     ScrollMinY += TILEY / 2;
197     ScrollMaxX -= TILEX / 2;
198     ScrollMaxY -= TILEY / 2;
199   }
200 #if 1
201   {
202     ScrollMinX -= game_sp.scroll_xoffset;
203     ScrollMaxX -= game_sp.scroll_xoffset;
204     ScrollMinY -= game_sp.scroll_yoffset;
205     ScrollMaxY -= game_sp.scroll_yoffset;
206   }
207 #else
208   if (1)
209   {
210     ScrollMinX -= TILEX / 2;
211     ScrollMaxX -= TILEX / 2;
212     ScrollMinY -= TILEY / 2;
213     ScrollMaxY -= TILEY / 2;
214   }
215 #endif
216 #else
217   if (!menBorder)
218   {
219     ScrollMinX += TILEX / 2;
220     ScrollMinY += TILEY / 2;
221     ScrollMaxX -= TILEX / 2;
222     ScrollMaxY -= TILEY / 2;
223   }
224 #endif
225
226 #else
227   ScrollMinX = (int)(DisplayMinX - 0.5) * BaseWidth;
228   ScrollMinY = (int)(DisplayMinY - 0.5) * BaseWidth;
229   ScrollMaxX = (int)(DisplayMaxX + 1.5) * BaseWidth - SXSIZE;
230   ScrollMaxY = (int)(DisplayMaxY + 1.5) * BaseWidth - SYSIZE;
231 #endif
232
233 #if 1
234   printf("::: (%ld, %ld), (%ld, %ld) -> (%d, %d), (%d, %d)\n",
235          DisplayMinX, DisplayMinY, DisplayMaxX, DisplayMaxY,
236          ScrollMinX, ScrollMinY, ScrollMaxX, ScrollMaxY);
237 #endif
238 }
239
240 void DrawField(int X, int Y)
241 {
242   int tsi = GetSI(X, Y);
243   int Tmp = LowByte(PlayField16[tsi]);
244
245   if (Tmp < fiFirst || Tmp > fiLast)
246     Tmp = fiSpace;
247
248   if (Tmp == fiRAM ||
249       Tmp == fiHardWare ||
250       Tmp == fiBug ||
251       Tmp == fiWallSpace)
252     Tmp = DisPlayField[tsi];
253
254   subCopyImageToScreen(tsi, fiGraphic[Tmp]);
255
256   if (Tmp != fiSpace &&
257       Tmp != fiSnikSnak &&
258       Tmp != fiElectron)
259     GfxGraphic[X][Y] = fiGraphic[Tmp];
260 }
261
262 void DrawFieldAnimated(int X, int Y)
263 {
264   int tsi = GetSI(X, Y);
265   int Tmp = LowByte(PlayField16[tsi]);
266
267   switch (Tmp)
268   {
269     case fiSnikSnak:
270       subDrawAnimatedSnikSnaks(tsi);
271       break;
272
273     case fiElectron:
274       subDrawAnimatedElectrons(tsi);
275       break;
276
277     default:
278       break;
279   }
280 }
281
282 void DrawFieldNoAnimated(int X, int Y)
283 {
284   int tsi = GetSI(X, Y);
285   int Tmp = LowByte(PlayField16[tsi]);
286
287   switch (Tmp)
288   {
289     case fiSnikSnak:
290       subCopyImageToScreen(tsi, aniSpace);
291       break;
292
293     case fiElectron:
294       subCopyImageToScreen(tsi, aniSpace);
295       break;
296
297     default:
298 #if 1
299       DrawField(X, Y);
300 #else
301       if (Tmp < fiFirst || Tmp > fiLast)
302         Tmp = fiSpace;
303
304       if (Tmp == fiRAM ||
305           Tmp == fiHardWare ||
306           Tmp == fiBug ||
307           Tmp == fiWallSpace)
308         Tmp = DisPlayField[tsi];
309
310       subCopyImageToScreen(tsi, fiGraphic[Tmp]);
311
312       if (Tmp != fiSpace &&
313           Tmp != fiSnikSnak &&
314           Tmp != fiElectron)
315         GfxGraphic[X][Y] = fiGraphic[Tmp];
316 #endif
317       break;
318   }
319 }
320
321 void DrawImage(int X, int Y, int graphic)
322 {
323   DDSpriteBuffer_BltImg(StretchWidth * X, StretchWidth * Y, graphic, 0);
324 }