added wrapper function for graphic animation frame at level position
[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(void);
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(void)
16 {
17   DrawFrame(0);
18
19   // !!! CHECK THIS !!!
20   if (! menBorder)
21     DrawFrame(1);
22 }
23
24 void DisplayLevel(void)
25 {
26   int X, Y;
27
28   if (! LevelLoaded)
29     return;
30
31   ClearRectangle(backbuffer, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
32   ClearRectangle(bitmap_db_field_sp, 0, 0, FXSIZE, FYSIZE);
33
34   SetDisplayRegion();
35
36   DrawFrameIfNeeded();
37
38   if (bPlaying)
39   {
40     for (Y = DisplayMinY; Y <= DisplayMaxY; Y++)
41       for (X = DisplayMinX; X <= DisplayMaxX; X++)
42         DrawFieldNoAnimated(X, Y);
43
44     for (Y = DisplayMinY; Y <= DisplayMaxY; Y++)
45       for (X = DisplayMinX; X <= DisplayMaxX; X++)
46         DrawFieldAnimated(X, Y);
47   }
48   else
49   {
50     for (Y = DisplayMinY; Y <= DisplayMaxY; Y++)
51       for (X = DisplayMinX; X <= DisplayMaxX; X++)
52         DrawField(X, Y);
53   }
54 }
55
56 void Form_Load(void)
57 {
58   InitGlobals();
59
60   ReStretch();
61 }
62
63 static void DrawFrame(int Delta)
64 {
65   int i, LX, tY, RX, BY;
66
67   LX = -1 + Delta;
68   tY = -1 + Delta;
69   RX = FieldWidth - Delta;
70   BY = FieldHeight - Delta;
71
72   DrawImage(LX, tY, (Delta > 0 ? imgFrameCorner : aniSpace));
73   DrawImage(LX, BY, (Delta > 0 ? imgFrameCorner : aniSpace));
74   DrawImage(RX, tY, (Delta > 0 ? imgFrameCorner : aniSpace));
75   DrawImage(RX, BY, (Delta > 0 ? imgFrameCorner : aniSpace));
76
77   for (i = LX + 1; i <= RX - 1; i++)
78   {
79     DrawImage(i, tY, (Delta > 0 ? imgFrameHorizontal : aniSpace));
80     DrawImage(i, BY, (Delta > 0 ? imgFrameHorizontal : aniSpace));
81   }
82
83   for (i = tY + 1; i <= BY - 1; i++)
84   {
85     DrawImage(LX, i, (Delta > 0 ? imgFrameVertical : aniSpace));
86     DrawImage(RX, i, (Delta > 0 ? imgFrameVertical : aniSpace));
87   }
88
89   if (Delta > 0)
90   {
91     // ...
92     // ClearRectangle(bitmap_db_field_sp, 
93   }
94 }
95
96 static void RestoreFrame(void)
97 {
98   int i, LX, tY, RX, BY;
99
100   LX = 0;
101   tY = 0;
102   RX = FieldWidth - 1;
103   BY = FieldHeight - 1;
104
105   for (i = LX; i <= RX; i++)
106   {
107     DrawField(i, tY);
108     DrawField(i, BY);
109   }
110
111   for (i = tY + 1; i <= BY - 1; i++)
112   {
113     DrawField(LX, i);
114     DrawField(RX, i);
115   }
116 }
117
118 void SetDisplayRegion(void)
119 {
120   if (! menBorder)
121   {
122     DisplayMinX = 1;
123     DisplayMinY = 1;
124     DisplayMaxX = FieldWidth - 2;
125     DisplayMaxY = FieldHeight - 2;
126
127     if (LevelLoaded)
128       DrawFrame(1);
129   }
130   else
131   {
132     DisplayMinX = 0;
133     DisplayMinY = 0;
134     DisplayMaxX = FieldWidth - 1;
135     DisplayMaxY = FieldHeight - 1;
136
137     if (LevelLoaded)
138       RestoreFrame();
139   }
140 }
141
142 void menPlay_Click(void)
143 {
144   bPlaying = True;
145
146   subFetchAndInitLevelB();
147
148   ReStretch();
149
150   subMainGameLoop_Init();
151 }
152
153 static void ReStretch(void)
154 {
155   if (LevelLoaded)
156   {
157     SetDisplayRegion();
158
159     SetScrollEdges();
160
161     ScrollTo(ScrollX, ScrollY);
162
163     DisplayLevel();
164   }
165
166   subCalculateScreenScrollPos();
167
168   ScrollTo(ScreenScrollXPos, ScreenScrollYPos);
169 }
170
171 void SetScrollEdges(void)
172 {
173   int border1_offset = (menBorder ? 1 : 2);
174   int border2_offset = (menBorder ? 0 : TILESIZE / 2);
175
176   // scroll correction for border frame (1 tile) or border element (2 tiles)
177   ScrollMinX = 0;
178   ScrollMinY = 0;
179   ScrollMaxX = (DisplayMaxX + border1_offset - SCR_FIELDX) * TILEX;
180   ScrollMaxY = (DisplayMaxY + border1_offset - SCR_FIELDY) * TILEY;
181
182   // scroll correction for border element (half tile on left and right side)
183   ScrollMinX += border2_offset;
184   ScrollMinY += border2_offset;
185   ScrollMaxX -= border2_offset;
186   ScrollMaxY -= border2_offset;
187
188   // scroll correction for even number of visible tiles (half tile shifted)
189   ScrollMinX -= game_sp.scroll_xoffset;
190   ScrollMaxX -= game_sp.scroll_xoffset;
191   ScrollMinY -= game_sp.scroll_yoffset;
192   ScrollMaxY -= game_sp.scroll_yoffset;
193 }
194
195 void DrawField(int X, int Y)
196 {
197   int tsi = GetSI(X, Y);
198   int Tmp = LowByte(PlayField16[tsi]);
199
200   if (Tmp < fiFirst || Tmp > fiLast)
201     Tmp = fiSpace;
202
203   if (Tmp == fiRAM ||
204       Tmp == fiHardWare ||
205       Tmp == fiBug ||
206       Tmp == fiWallSpace)
207     Tmp = DisPlayField[tsi];
208
209   subCopyImageToScreen(tsi, fiGraphic[Tmp]);
210
211   if (Tmp != fiSpace &&
212       Tmp != fiSnikSnak &&
213       Tmp != fiElectron)
214     GfxGraphic[X][Y] = fiGraphic[Tmp];
215 }
216
217 void DrawFieldAnimated(int X, int Y)
218 {
219   int tsi = GetSI(X, Y);
220   int Tmp = LowByte(PlayField16[tsi]);
221
222   switch (Tmp)
223   {
224     case fiSnikSnak:
225       subDrawAnimatedSnikSnaks(tsi);
226       break;
227
228     case fiElectron:
229       subDrawAnimatedElectrons(tsi);
230       break;
231
232     default:
233       break;
234   }
235 }
236
237 void DrawFieldNoAnimated(int X, int Y)
238 {
239   int tsi = GetSI(X, Y);
240   int Tmp = LowByte(PlayField16[tsi]);
241
242   switch (Tmp)
243   {
244     case fiSnikSnak:
245       subCopyImageToScreen(tsi, aniSpace);
246       break;
247
248     case fiElectron:
249       subCopyImageToScreen(tsi, aniSpace);
250       break;
251
252     default:
253       DrawField(X, Y);
254       break;
255   }
256 }
257
258 void DrawImage(int X, int Y, int graphic)
259 {
260   DDSpriteBuffer_BltImg(StretchWidth * X, StretchWidth * Y, graphic, 0);
261 }