rnd-20100417-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 #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 #endif
201
202 #else
203   ScrollMinX = (int)(DisplayMinX - 0.5) * BaseWidth;
204   ScrollMinY = (int)(DisplayMinY - 0.5) * BaseWidth;
205   ScrollMaxX = (int)(DisplayMaxX + 1.5) * BaseWidth - SXSIZE;
206   ScrollMaxY = (int)(DisplayMaxY + 1.5) * BaseWidth - SYSIZE;
207 #endif
208
209 #if 1
210   printf("::: (%ld, %ld), (%ld, %ld) -> (%d, %d), (%d, %d)\n",
211          DisplayMinX, DisplayMinY, DisplayMaxX, DisplayMaxY,
212          ScrollMinX, ScrollMinY, ScrollMaxX, ScrollMaxY);
213 #endif
214 }
215
216 void DrawField(int X, int Y)
217 {
218   int tsi = GetSI(X, Y);
219   int Tmp = LowByte(PlayField16[tsi]);
220
221   if (Tmp < fiFirst || Tmp > fiLast)
222     Tmp = fiSpace;
223
224   if (Tmp == fiRAM ||
225       Tmp == fiHardWare ||
226       Tmp == fiBug ||
227       Tmp == fiWallSpace)
228     Tmp = DisPlayField[tsi];
229
230   subCopyImageToScreen(tsi, fiGraphic[Tmp]);
231
232   if (Tmp != fiSpace &&
233       Tmp != fiSnikSnak &&
234       Tmp != fiElectron)
235     GfxGraphic[X][Y] = fiGraphic[Tmp];
236 }
237
238 void DrawFieldAnimated(int X, int Y)
239 {
240   int tsi = GetSI(X, Y);
241   int Tmp = LowByte(PlayField16[tsi]);
242
243   switch (Tmp)
244   {
245     case fiSnikSnak:
246       subDrawAnimatedSnikSnaks(tsi);
247       break;
248
249     case fiElectron:
250       subDrawAnimatedElectrons(tsi);
251       break;
252
253     default:
254       break;
255   }
256 }
257
258 void DrawFieldNoAnimated(int X, int Y)
259 {
260   int tsi = GetSI(X, Y);
261   int Tmp = LowByte(PlayField16[tsi]);
262
263   switch (Tmp)
264   {
265     case fiSnikSnak:
266       subCopyImageToScreen(tsi, aniSpace);
267       break;
268
269     case fiElectron:
270       subCopyImageToScreen(tsi, aniSpace);
271       break;
272
273     default:
274 #if 1
275       DrawField(X, Y);
276 #else
277       if (Tmp < fiFirst || Tmp > fiLast)
278         Tmp = fiSpace;
279
280       if (Tmp == fiRAM ||
281           Tmp == fiHardWare ||
282           Tmp == fiBug ||
283           Tmp == fiWallSpace)
284         Tmp = DisPlayField[tsi];
285
286       subCopyImageToScreen(tsi, fiGraphic[Tmp]);
287
288       if (Tmp != fiSpace &&
289           Tmp != fiSnikSnak &&
290           Tmp != fiElectron)
291         GfxGraphic[X][Y] = fiGraphic[Tmp];
292 #endif
293       break;
294   }
295 }
296
297 void DrawImage(int X, int Y, int graphic)
298 {
299   DDSpriteBuffer_BltImg(StretchWidth * X, StretchWidth * Y, graphic, 0);
300 }