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