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