1 /*
2 * GNUjump
3 * =======
4 *
5 * Copyright (C) 2005-2008, Juan Pedro Bolivar Puente
6 *
7 * GNUjump is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * GNUjump is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "gnujump.h"
22 #include "game.h"
23 #include "effects.h"
24 #include "tools.h"
25
26 extern L_gblOptions gblOps;
27 extern SDL_Surface *screen;
28
29 void
playHeroSound(data_t * gfx,int sound,replay_t * rep)30 playHeroSound (data_t * gfx, int sound, replay_t * rep)
31 {
32 if (sound == S_JUMP && gfx->gjump)
33 Mix_PlayChannel (-1, gfx->gjump, 0);
34 if (sound == S_FALL && gfx->gfall)
35 Mix_PlayChannel (-1, gfx->gfall, 0);
36 if (sound == S_DIE && gfx->gdie)
37 Mix_PlayChannel (-1, gfx->gdie, 0);
38 if (gblOps.recReplay)
39 rep->sounds |= sound;
40 }
41
42 void
drawHero(data_t * gfx,hero_t * hero)43 drawHero (data_t * gfx, hero_t * hero)
44 {
45 SDL_Rect dest;
46
47 /* In rotating surface, X and Y refer to the centre of the image */
48 dest.x =
49 hero->x + gfx->gameX - (getFrameRot (&hero->sprite[hero->id], 0)->w -
50 HEROSIZE) / 2 +
51 getFrameRot (&hero->sprite[hero->id], 0)->w / 2;
52 dest.y =
53 hero->y + gfx->gameY - (getFrameRot (&hero->sprite[hero->id], 0)->h -
54 HEROSIZE) + getFrameRot (&hero->sprite[hero->id],
55 0)->h / 2;
56
57 printSpriteRot (&hero->sprite[hero->id], NULL, &dest, hero->dir,
58 hero->angle);
59 }
60
61 void
drawScrolledBgPart(data_t * gfx,int x,int y,int w,int h,int th,int sc)62 drawScrolledBgPart (data_t * gfx, int x, int y, int w, int h, int th, int sc)
63 {
64 SDL_Rect src, dest;
65
66 sc = th - sc;
67 src.x = x;
68 src.y = y + sc;
69 src.w = w;
70 src.h = th - sc;
71 dest.x = x;
72 dest.y = y;
73 dest.w = w;
74 dest.h = th - sc;
75 JPB_PrintSurface (gfx->gameBg, &src, &dest);
76
77 dest.y += dest.h;
78 src.y = y;
79 dest.h = src.h = th;
80
81 for (; dest.y < y + h - th; dest.y += dest.h)
82 {
83 //printf("TH:%d Y:%d SC: %d\n", th, dest.y, sc);
84 JPB_PrintSurface (gfx->gameBg, &src, &dest);
85 }
86
87 src.h = dest.h = y + h - dest.y;
88 JPB_PrintSurface (gfx->gameBg, &src, &dest);
89
90 }
91
92 void
drawGame(data_t * gfx,game_t * game)93 drawGame (data_t * gfx, game_t * game)
94 {
95 int i, y, x, width;
96
97 //printf("%d\n", gblOps.scrollBg);
98 if (gblOps.scrollBg && gfx->gameTileH)
99 {
100 drawScrolledBgPart (gfx, gfx->gameX + BLOCKSIZE, gfx->gameY,
101 BLOCKSIZE * (GRIDWIDTH - 2), BLOCKSIZE * GRIDHEIGHT,
102 gfx->gameTileH,
103 (int) (game->scrollTotal / 2) % gfx->gameTileH);
104 //printf("Total: %f\n", game->scrollTotal);
105 if (gfx->borderTileH)
106 {
107 drawScrolledBgPart (gfx, gfx->gameX + BLOCKSIZE - gfx->borderTileW,
108 gfx->gameY, gfx->borderTileW,
109 BLOCKSIZE * GRIDHEIGHT, gfx->borderTileH,
110 (int) (game->scrollTotal * 2) %
111 gfx->borderTileH);
112 drawScrolledBgPart (gfx, gfx->gameX + (GRIDWIDTH - 1) * BLOCKSIZE,
113 gfx->gameY, gfx->borderTileW,
114 BLOCKSIZE * GRIDHEIGHT, gfx->borderTileH,
115 (int) (game->scrollTotal * 2) %
116 gfx->borderTileH);
117 }
118 else
119 {
120 drawBg (gfx->gameBg,
121 gfx->gameX, gfx->gameY,
122 BLOCKSIZE, BLOCKSIZE * GRIDHEIGHT);
123
124 drawBg (gfx->gameBg,
125 gfx->gameX + BLOCKSIZE * (GRIDWIDTH - 1), gfx->gameY,
126 BLOCKSIZE, BLOCKSIZE * GRIDHEIGHT);
127 }
128 }
129 else
130 {
131 drawBg (gfx->gameBg, gfx->gameX, gfx->gameY, BLOCKSIZE * GRIDWIDTH,
132 BLOCKSIZE * GRIDHEIGHT);
133 }
134
135 for (y = game->floorTop % 5; y < GRIDHEIGHT; y += 5)
136 {
137 x = game->floor_l[(y + game->mapIndex) % GRIDHEIGHT];
138 width = game->floor_r[(y + game->mapIndex) % GRIDHEIGHT] - x + 1;
139 if ((y * BLOCKSIZE + game->scrollCount) < (GRIDHEIGHT - 1) * BLOCKSIZE)
140 drawFloor (gfx, x, y * BLOCKSIZE + game->scrollCount, width);
141 }
142
143 for (i = 0; i < game->numHeros; i++)
144 {
145 drawTrail (gfx, game->heros[i].trail, i);
146 drawBlur (gfx, game->heros[i].blur, i);
147 }
148
149 for (i = 0; i < game->numHeros; i++)
150 if (game->heros[i].y < BLOCKSIZE * GRIDHEIGHT - HEROSIZE)
151 drawHero (gfx, &(game->heros[i]));
152 }
153
154 int
drawBg(JPB_surface * surf,int x,int y,int w,int h)155 drawBg (JPB_surface * surf, int x, int y, int w, int h)
156 {
157 SDL_Rect rect;
158 rect.x = x;
159 rect.h = h;
160 rect.w = w;
161 rect.y = y;
162 JPB_PrintSurface (surf, &rect, &rect);
163 return TRUE;
164 }
165
166 int
drawFloor(data_t * gfx,int x,int y,int bw)167 drawFloor (data_t * gfx, int x, int y, int bw)
168 {
169 SDL_Rect rect;
170 SDL_Rect src;
171 int j;
172
173 rect.x = x * BLOCKSIZE + gfx->gameX;
174 rect.y = y + gfx->gameY;
175 src.x = src.y = 0;
176
177 src.w = gfx->floorL->w;
178 src.h =
179 MIN (gfx->floorL->h, (gfx->gameY + (GRIDHEIGHT) * BLOCKSIZE) - rect.y);
180 JPB_PrintSurface (gfx->floorL, &src, &rect);
181
182 for (j = 1; j < bw - 1; j++)
183 {
184 src.w = gfx->floorC->w;
185 src.h =
186 MIN (gfx->floorC->h,
187 (gfx->gameY + (GRIDHEIGHT) * BLOCKSIZE) - rect.y);
188 rect.x = j * BLOCKSIZE + x * BLOCKSIZE + gfx->gameX;
189 JPB_PrintSurface (gfx->floorC, &src, &rect);
190 }
191 src.w = gfx->floorR->w;
192 src.h =
193 MIN (gfx->floorR->h, (gfx->gameY + (GRIDHEIGHT) * BLOCKSIZE) - rect.y);
194 rect.x =
195 j * BLOCKSIZE + x * BLOCKSIZE + gfx->gameX + BLOCKSIZE - gfx->floorR->w;
196 JPB_PrintSurface (gfx->floorR, &src, &rect);
197
198 return TRUE;
199 }
200
201 void
drawAnimatedSquare(data_t * gfx,Uint32 color,Uint8 alpha,int x,int y,int w,int h,int time)202 drawAnimatedSquare (data_t * gfx, Uint32 color, Uint8 alpha, int x, int y,
203 int w, int h, int time)
204 {
205 fader_t fader;
206 L_timer timer;
207 int xc = 0;
208 int ret = 0;
209
210 if (gfx->gquestion)
211 Mix_PlayChannel (-1, gfx->gquestion, 0);
212
213 x += w / 2;
214 initTimer (&timer, getFps ());
215 updateTimer (&timer);
216 setFader (&fader, 1, w / 2 + 1, time, 0);
217
218 do
219 {
220 updateTimer (&timer);
221 ret = updateFader (&fader, timer.ms);
222 JPB_drawSquare (color, alpha, x + xc, y, fader.value - xc, h);
223 JPB_drawSquare (color, alpha, x - xc, y, xc - fader.value, h);
224 xc = fader.value;
225 FlipScreen ();
226 }
227 while (!ret);
228
229 }
230
231 void
drawScore(data_t * gfx,game_t * game,Uint32 currtime)232 drawScore (data_t * gfx, game_t * game, Uint32 currtime)
233 {
234 int i, j;
235 int x, y;
236 SDL_Rect rect;
237 char score[32];
238 char time[32];
239
240 x = gfx->timeX;
241 y = gfx->timeY;
242 sprintf (time, "%d", currtime);
243 SFont_Write (gfx->timefont, x, y, time);
244
245 for (i = 0; i < game->numHeros; i++)
246 {
247 sprintf (score, "%d", game->heros[i].floor);
248
249 x = gfx->scoreX[i];
250 y = gfx->scoreY[i];
251
252 SFont_Write (gfx->scorefont, x, y, score);
253
254 rect.x = x = gfx->livesX[i];
255 rect.y = y = gfx->livesY[i];
256 rect.w = gfx->livePic->w;
257 rect.h = gfx->livePic->h;
258
259 for (j = 0; j <= game->heros[i].lives; j++)
260 {
261 JPB_PrintSurface (gfx->livePic, NULL, &rect);
262 if (gfx->liveAlign)
263 {
264 y += gfx->livePic->h;
265 rect.y = y;
266 }
267 else
268 {
269 x += gfx->livePic->w;
270 rect.x = x;
271 }
272 }
273
274 game->heros[i].prevLives = game->heros[i].lives;
275 }
276 }
277
278 void
updateScore(data_t * gfx,game_t * game,Uint32 currtime)279 updateScore (data_t * gfx, game_t * game, Uint32 currtime)
280 {
281 int i, j;
282 int x, y;
283 SDL_Rect rect;
284 char score[32];
285 char prevscore[32];
286 char time[32];
287 char prevtime[32];
288 static int lastsec = -1;
289
290 if ((currtime /= 1000) != lastsec)
291 {
292 sprintf (time, "%d", currtime);
293 sprintf (prevtime, "%d", lastsec);
294 lastsec = currtime;
295 x = gfx->timeX;
296 y = gfx->timeY;
297
298 drawBg (gfx->gameBg, x - 1, y - 1,
299 SFont_TextWidth (gfx->timefont, prevtime) + 2,
300 SFont_TextHeight (gfx->timefont) + 2);
301
302 SFont_Write (gfx->timefont, x, y, time);
303 }
304
305 for (i = 0; i < game->numHeros; i++)
306 {
307 if (game->heros[i].floor != game->heros[i].prevFloor)
308 {
309 sprintf (score, "%d", game->heros[i].floor);
310 sprintf (prevscore, "%d", game->heros[i].prevFloor);
311
312 x = gfx->scoreX[i];
313 y = gfx->scoreY[i];
314
315 drawBg (gfx->gameBg, x - 1, y - 1,
316 SFont_TextWidth (gfx->scorefont, prevscore) + 2,
317 SFont_TextHeight (gfx->scorefont) + 2);
318
319 SFont_Write (gfx->scorefont, x, y, score);
320 }
321 if (game->heros[i].prevLives != game->heros[i].lives)
322 {
323 rect.x = x = gfx->livesX[i];
324 rect.y = y = gfx->livesY[i];
325 rect.w = gfx->livePic->w;
326 rect.h = gfx->livePic->h;
327
328 if (gfx->liveAlign)
329 {
330 drawBg (gfx->gameBg, x, y,
331 gfx->livePic->w,
332 gfx->livePic->h * (game->heros[i].lives + 2));
333 }
334 else
335 {
336 drawBg (gfx->gameBg, x, y,
337 gfx->livePic->w * (game->heros[i].lives + 2),
338 gfx->livePic->h);
339 }
340
341 for (j = 0; j <= game->heros[i].lives; j++)
342 {
343 JPB_PrintSurface (gfx->livePic, NULL, &rect);
344 if (gfx->liveAlign)
345 {
346 y += gfx->livePic->h;
347 rect.y = y;
348 }
349 else
350 {
351 x += gfx->livePic->w;
352 rect.x = x;
353 }
354 }
355
356 game->heros[i].prevLives = game->heros[i].lives;
357 }
358 }
359 }
360