rnd-20100624-3-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   int pseudo_sxsize = SXSIZE * TILESIZE / TILESIZE_VAR;
192   int pseudo_sysize = SYSIZE * TILESIZE / TILESIZE_VAR;
193 #endif
194   int border1_offset = (menBorder ? 1 : 2);
195   int border2_offset = (menBorder ? 0 : TILESIZE / 2);
196
197   /* scroll correction for border frame (1 tile) or border element (2 tiles) */
198   ScrollMinX = 0;
199   ScrollMinY = 0;
200 #if NEW_TILESIZE
201   ScrollMaxX = (DisplayMaxX + border1_offset) * TILEX - pseudo_sxsize;
202   ScrollMaxY = (DisplayMaxY + border1_offset) * TILEY - pseudo_sysize;
203 #else
204   ScrollMaxX = (DisplayMaxX + border1_offset) * TILEX - SXSIZE;
205   ScrollMaxY = (DisplayMaxY + border1_offset) * TILEY - SYSIZE;
206 #endif
207
208   /* scroll correction for border element (half tile on left and right side) */
209   ScrollMinX += border2_offset;
210   ScrollMinY += border2_offset;
211   ScrollMaxX -= border2_offset;
212   ScrollMaxY -= border2_offset;
213
214   /* scroll correction for even number of visible tiles (half tile shifted) */
215   ScrollMinX -= game_sp.scroll_xoffset;
216   ScrollMaxX -= game_sp.scroll_xoffset;
217   ScrollMinY -= game_sp.scroll_yoffset;
218   ScrollMaxY -= game_sp.scroll_yoffset;
219
220 #if 0
221   printf("::: (%ld, %ld), (%ld, %ld) -> (%d, %d), (%d, %d)\n",
222          DisplayMinX, DisplayMinY, DisplayMaxX, DisplayMaxY,
223          ScrollMinX, ScrollMinY, ScrollMaxX, ScrollMaxY);
224 #endif
225 }
226
227 void DrawField(int X, int Y)
228 {
229   int tsi = GetSI(X, Y);
230   int Tmp = LowByte(PlayField16[tsi]);
231
232   if (Tmp < fiFirst || Tmp > fiLast)
233     Tmp = fiSpace;
234
235   if (Tmp == fiRAM ||
236       Tmp == fiHardWare ||
237       Tmp == fiBug ||
238       Tmp == fiWallSpace)
239     Tmp = DisPlayField[tsi];
240
241   subCopyImageToScreen(tsi, fiGraphic[Tmp]);
242
243   if (Tmp != fiSpace &&
244       Tmp != fiSnikSnak &&
245       Tmp != fiElectron)
246     GfxGraphic[X][Y] = fiGraphic[Tmp];
247 }
248
249 void DrawFieldAnimated(int X, int Y)
250 {
251   int tsi = GetSI(X, Y);
252   int Tmp = LowByte(PlayField16[tsi]);
253
254   switch (Tmp)
255   {
256     case fiSnikSnak:
257       subDrawAnimatedSnikSnaks(tsi);
258       break;
259
260     case fiElectron:
261       subDrawAnimatedElectrons(tsi);
262       break;
263
264     default:
265       break;
266   }
267 }
268
269 void DrawFieldNoAnimated(int X, int Y)
270 {
271   int tsi = GetSI(X, Y);
272   int Tmp = LowByte(PlayField16[tsi]);
273
274   switch (Tmp)
275   {
276     case fiSnikSnak:
277       subCopyImageToScreen(tsi, aniSpace);
278       break;
279
280     case fiElectron:
281       subCopyImageToScreen(tsi, aniSpace);
282       break;
283
284     default:
285 #if 1
286       DrawField(X, Y);
287 #else
288       if (Tmp < fiFirst || Tmp > fiLast)
289         Tmp = fiSpace;
290
291       if (Tmp == fiRAM ||
292           Tmp == fiHardWare ||
293           Tmp == fiBug ||
294           Tmp == fiWallSpace)
295         Tmp = DisPlayField[tsi];
296
297       subCopyImageToScreen(tsi, fiGraphic[Tmp]);
298
299       if (Tmp != fiSpace &&
300           Tmp != fiSnikSnak &&
301           Tmp != fiElectron)
302         GfxGraphic[X][Y] = fiGraphic[Tmp];
303 #endif
304       break;
305   }
306 }
307
308 void DrawImage(int X, int Y, int graphic)
309 {
310   DDSpriteBuffer_BltImg(StretchWidth * X, StretchWidth * Y, graphic, 0);
311 }