1 /*
2 * IceBreaker
3 * Copyright (c) 2000-2002 Matthew Miller <mattdm@mattdm.org> and
4 * Enrico Tassi <gareuselesinge@infinito.it>
5 *
6 * <http://www.mattdm.org/icebreaker/>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc., 59
20 * Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24 /* special thanks to Enrico for the grid coloring stuff for themes */
25 /* and for the vastly improved circular scrolling code */
26
27
28 #include <SDL.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include "icebreaker.h"
32 #include "cursor.h"
33 #include "penguin.h"
34 #include "line.h"
35 #include "grid.h"
36 #include "sound.h"
37 #include "laundry.h"
38 #include "globals.h"
39 #include "level.h"
40 #include "status.h"
41 #include "text.h"
42 #include "hiscore.h"
43 #include "themes.h"
44 #include "event.h"
45 #include "fullscreen.h"
46 #include "options.h"
47
48 #define LXPOS(x) (BORDERLEFT+(BLOCKWIDTH*(x)))
49 #define LYPOS(y) (BORDERTOP+(BLOCKHEIGHT*(y)))
50
51 static void setupintro(void);
52 void circularblit(SDL_Surface* scoresurface,SDL_Rect* scrollrect,Uint16 hiscorescroll);
53 SDL_Surface* createscoresurface();
54
setupintro()55 void setupintro()
56 {
57 int x,y;
58
59 setcursor(CURSORARROW);
60 SDL_FillRect(screen,NULL,color.background);
61
62
63 for (x=0;x<WIDTH;x++)
64 for (y=0;y<HEIGHT;y++)
65 {
66 if (x<BORDERLEFT || x>=BORDERRIGHT || y <BORDERTOP || y>=BORDERBOTTOM)
67 grid[x][y]='X';
68 else
69 grid[x][y]='w';
70 }
71
72 /// Here's the fun part where we set up the letters.
73 // I
74 markgrid(LXPOS(1),LYPOS(2),BLOCKWIDTH*3,BLOCKHEIGHT ,' ');
75 markgrid(LXPOS(1),LYPOS(7),BLOCKWIDTH*3,BLOCKHEIGHT ,' ');
76 markgrid(LXPOS(2),LYPOS(2),BLOCKWIDTH ,BLOCKHEIGHT*6,' ');
77
78 //C
79 markgrid(LXPOS(5),LYPOS(2),BLOCKWIDTH*4,BLOCKHEIGHT ,' ');
80 markgrid(LXPOS(5),LYPOS(3),BLOCKWIDTH ,BLOCKHEIGHT*5,' ');
81 markgrid(LXPOS(6),LYPOS(7),BLOCKWIDTH*3,BLOCKHEIGHT, ' ');
82
83 //E
84 markgrid(LXPOS(10),LYPOS(2),BLOCKWIDTH*4,BLOCKHEIGHT ,' ');
85 markgrid(LXPOS(10),LYPOS(3),BLOCKWIDTH ,BLOCKHEIGHT*5,' ');
86 markgrid(LXPOS(11),LYPOS(7),BLOCKWIDTH*3,BLOCKHEIGHT, ' ');
87 markgrid(LXPOS(11),LYPOS(4),BLOCKWIDTH*2,BLOCKHEIGHT ,' ');
88
89 drawgridblocks();
90
91 updateall();
92 }
93
94
95
intro(void)96 int intro(void)
97 {
98 int penguincount=0;
99 int frozen=true;
100 int i;
101 int x,y;
102 int letterstep=0;
103 int hiscorescroll=0;
104 int hiscorestep=0;
105 int linedone1=false; int linedone2=false;
106
107 SDL_Rect labelrect;
108 SDL_Rect scrollrect;
109 SDL_Rect bigrect;
110 SDL_Rect rightmarginrect;
111 SDL_Rect leftmarginrect;
112 #ifdef DEVELRELEASE
113 SDL_Rect develdisclaimerrect;
114 #endif
115
116 int done = false;
117
118 Penguin flock[100];
119 Penguin tux;
120
121 SDL_Event event;
122
123 SDL_Surface* scoresurface;
124
125 setupintro();
126
127 #ifdef DEVELRELEASE
128 develdisclaimerrect.x=BORDERLEFT-3;
129 develdisclaimerrect.y=MARGINTOP+PLAYHEIGHT+CHARHEIGHT*2;
130 develdisclaimerrect.h=CHARHEIGHT*3;
131 develdisclaimerrect.w=WIDTH-develdisclaimerrect.x;
132 #endif
133
134 labelrect.x=BORDERLEFT;
135 labelrect.y=BORDERTOP-(4*CHARHEIGHT);
136 labelrect.h=CHARHEIGHT*2;
137 labelrect.w=CHARWIDTH*21;
138
139 scrollrect.x=BORDERLEFT+CHARWIDTH*21;
140 scrollrect.y=labelrect.y;
141 scrollrect.w=BORDERRIGHT-(BORDERLEFT+CHARWIDTH*21);
142 scrollrect.h=labelrect.h;
143
144 rightmarginrect.x=BORDERRIGHT;
145 rightmarginrect.y=labelrect.y;
146 rightmarginrect.w=MARGINRIGHT;
147 rightmarginrect.h=labelrect.h;
148
149 leftmarginrect.x=0;
150 leftmarginrect.y=labelrect.y;
151 leftmarginrect.w=BORDERLEFT;
152 leftmarginrect.h=labelrect.h;
153
154 bigrect.x=labelrect.x;
155 bigrect.y=labelrect.y;
156 bigrect.w=WIDTH-(BORDERLEFT);
157 bigrect.h=labelrect.h;
158
159 hiscorescroll=0;
160
161 puttext(labelrect.x,labelrect.y,2,color.normaltext,"HIGH SCORES:");
162 soil(labelrect);
163
164 #ifdef DEVELRELEASE
165 puttext(develdisclaimerrect.x,develdisclaimerrect.y,1,color.copyrighttext,"This is a development (beta) release meant for bug-testing only. Please check");
166 puttext(develdisclaimerrect.x+3,develdisclaimerrect.y+CHARHEIGHT*1.5,1,color.copyrighttext,"<http://www.mattdm.org/icebreaker/> for the latest stable release. Thanks!");
167 soil(develdisclaimerrect);
168 #endif
169
170 line1=createline(1);
171 line2=createline(2);
172
173 tux = createpenguin();
174
175 // create highscore surface
176 scoresurface = createscoresurface();
177
178 do
179 {
180 while (pollevent(&event))
181 {
182 if (event.type == SDL_QUIT)
183 {
184 return(true);
185 // fix -- should delete penguins here
186 }
187 else if (event.type == SDL_MOUSEBUTTONUP)
188 {
189 done=true;
190 }
191 else if (event.type == SDL_KEYUP)
192 {
193 switch(translatekeyevent(&event))
194 {
195 case KEYCANCEL:
196 if (gameflags.isfullscreen) makewindowed();
197 break;
198 case KEYSWITCHLINE: // falls through
199 case KEYMENU: // yep
200 case KEYSTARTLINE: // start game
201 if (letterstep>1) done=true; // kludge to keep from catching enter keystroke which launched app
202 default:
203 break;
204 }
205 }
206 }
207 if (letterstep < 10)
208 {
209 switch (letterstep)
210 {
211 // I
212 case 0:
213 if (!linedone1 && !line1.on) startline(&line1,LEFT,LXPOS(2),LYPOS(2));
214 if (!linedone2 && !line2.on) startline(&line2,RIGHT,LXPOS(2),LYPOS(2));
215 break;
216 case 1:
217 if (!linedone1 && !line1.on) startline(&line1,LEFT,LXPOS(2),LYPOS(7));
218 if (!linedone2 && !line2.on) startline(&line2,RIGHT,LXPOS(2),LYPOS(7));
219 break;
220 case 2:
221 if (!linedone1 && !line1.on) startline(&line1,UP,LXPOS(2),LYPOS(5));
222 if (!linedone2 && !line2.on) startline(&line2,DOWN,LXPOS(2),LYPOS(5));
223 break;
224 // C
225 case 3:
226 if (!linedone1 && !line1.on) startline(&line1,LEFT,LXPOS(7),LYPOS(2));
227 if (!linedone2 && !line2.on) startline(&line2,RIGHT,LXPOS(7),LYPOS(2));
228 break;
229 case 4:
230 if (!linedone1 && !line1.on) startline(&line1,UP,LXPOS(5),LYPOS(5));
231 if (!linedone2 && !line2.on) startline(&line2,DOWN,LXPOS(5),LYPOS(5));
232 break;
233 case 5:
234 if (!linedone1 && !line1.on) startline(&line1,LEFT,LXPOS(7),LYPOS(7));
235 if (!linedone2 && !line2.on) startline(&line2,RIGHT,LXPOS(7),LYPOS(7));
236 break;
237 // E
238 case 6:
239 if (!linedone1 && !line1.on) startline(&line1,LEFT,LXPOS(11),LYPOS(2));
240 if (!linedone2 && !line2.on) startline(&line2,RIGHT,LXPOS(11),LYPOS(2));
241 break;
242 case 7:
243 if (!linedone1 && !line1.on) startline(&line1,UP,LXPOS(10),LYPOS(5));
244 if (!linedone2 && !line2.on) startline(&line2,DOWN,LXPOS(10),LYPOS(5));
245 break;
246 case 8:
247 if (!linedone1 && !line1.on) startline(&line1,LEFT,LXPOS(13),LYPOS(7));
248 if (!linedone2 && !line2.on) startline(&line2,RIGHT,LXPOS(13),LYPOS(7));
249 break;
250 case 9:
251 if (!linedone1 && !line1.on) startline(&line1,LEFT,LXPOS(12),LYPOS(4));
252 if (!linedone2 && !line2.on) startline(&line2,RIGHT,LXPOS(12),LYPOS(4));
253 break;
254 }
255
256 }
257 else if (letterstep==10)
258 {
259 for (x=0;x<WIDTH;x++)
260 for (y=0;y<HEIGHT;y++)
261 if (grid[x][y]=='w')
262 {
263 grid[x][y]=' ';
264 }
265 // FIX: known bug -- if a line stops partway through a grid cell,
266 // the space left over is not cleared properly later. this isn't
267 // an issue in the game, as lines aways stop on cell boundaries, but
268 // sometimes shows up in the intro. this is a kludge
269 // which should fix it.
270 else if (((x-BORDERLEFT) % BLOCKWIDTH)==0 && ((y-BORDERTOP) % BLOCKHEIGHT)==0)
271 {
272 if (grid[x+BLOCKWIDTH-1][y+BLOCKHEIGHT-1]==' ')
273 grid[x][y]=' ';
274 }
275 letterstep++;
276 }
277 else if (letterstep==11)
278 {
279 //B
280 flock[penguincount]=createpenguinxy(LXPOS(0),LYPOS(11)); penguincount++;
281 flock[penguincount]=createpenguinxy(LXPOS(0),LYPOS(12)); penguincount++;
282 flock[penguincount]=createpenguinxy(LXPOS(0),LYPOS(13)); penguincount++;
283 flock[penguincount]=createpenguinxy(LXPOS(0),LYPOS(14)); penguincount++;
284 flock[penguincount]=createpenguinxy(LXPOS(0),LYPOS(15)); penguincount++;
285 flock[penguincount]=createpenguinxy(LXPOS(0),LYPOS(16)); penguincount++;
286
287 flock[penguincount]=createpenguinxy(LXPOS(1),LYPOS(11)); penguincount++;
288 flock[penguincount]=createpenguinxy(LXPOS(2),LYPOS(11)); penguincount++;
289
290 flock[penguincount]=createpenguinxy(LXPOS(1),LYPOS(13)); penguincount++;
291 flock[penguincount]=createpenguinxy(LXPOS(2),LYPOS(13)); penguincount++;
292
293 flock[penguincount]=createpenguinxy(LXPOS(1),LYPOS(16)); penguincount++;
294 flock[penguincount]=createpenguinxy(LXPOS(2),LYPOS(16)); penguincount++;
295
296 flock[penguincount]=createpenguinxy(LXPOS(3),LYPOS(12)); penguincount++;
297
298 flock[penguincount]=createpenguinxy(LXPOS(3),LYPOS(14)); penguincount++;
299 flock[penguincount]=createpenguinxy(LXPOS(3),LYPOS(15)); penguincount++;
300
301 //R
302 flock[penguincount]=createpenguinxy(LXPOS(5),LYPOS(11)); penguincount++;
303 flock[penguincount]=createpenguinxy(LXPOS(5),LYPOS(12)); penguincount++;
304 flock[penguincount]=createpenguinxy(LXPOS(5),LYPOS(13)); penguincount++;
305 flock[penguincount]=createpenguinxy(LXPOS(5),LYPOS(14)); penguincount++;
306 flock[penguincount]=createpenguinxy(LXPOS(5),LYPOS(15)); penguincount++;
307 flock[penguincount]=createpenguinxy(LXPOS(5),LYPOS(16)); penguincount++;
308
309 flock[penguincount]=createpenguinxy(LXPOS(6),LYPOS(11)); penguincount++;
310 flock[penguincount]=createpenguinxy(LXPOS(7),LYPOS(11)); penguincount++;
311
312 flock[penguincount]=createpenguinxy(LXPOS(6),LYPOS(13)); penguincount++;
313 flock[penguincount]=createpenguinxy(LXPOS(7),LYPOS(13)); penguincount++;
314
315 flock[penguincount]=createpenguinxy(LXPOS(8),LYPOS(12)); penguincount++;
316
317 flock[penguincount]=createpenguinxy(LXPOS(8),LYPOS(14)); penguincount++;
318 flock[penguincount]=createpenguinxy(LXPOS(8),LYPOS(15)); penguincount++;
319 flock[penguincount]=createpenguinxy(LXPOS(8),LYPOS(16)); penguincount++;
320
321 //E
322 flock[penguincount]=createpenguinxy(LXPOS(10),LYPOS(11)); penguincount++;
323 flock[penguincount]=createpenguinxy(LXPOS(10),LYPOS(12)); penguincount++;
324 flock[penguincount]=createpenguinxy(LXPOS(10),LYPOS(13)); penguincount++;
325 flock[penguincount]=createpenguinxy(LXPOS(10),LYPOS(14)); penguincount++;
326 flock[penguincount]=createpenguinxy(LXPOS(10),LYPOS(15)); penguincount++;
327 flock[penguincount]=createpenguinxy(LXPOS(10),LYPOS(16)); penguincount++;
328
329 flock[penguincount]=createpenguinxy(LXPOS(11),LYPOS(11)); penguincount++;
330 flock[penguincount]=createpenguinxy(LXPOS(12),LYPOS(11)); penguincount++;
331
332 flock[penguincount]=createpenguinxy(LXPOS(11),LYPOS(13)); penguincount++;
333 flock[penguincount]=createpenguinxy(LXPOS(12),LYPOS(13)); penguincount++;
334
335 flock[penguincount]=createpenguinxy(LXPOS(11),LYPOS(16)); penguincount++;
336 flock[penguincount]=createpenguinxy(LXPOS(12),LYPOS(16)); penguincount++;
337
338 //A
339 flock[penguincount]=createpenguinxy(LXPOS(14),LYPOS(12)); penguincount++;
340 flock[penguincount]=createpenguinxy(LXPOS(14),LYPOS(13)); penguincount++;
341 flock[penguincount]=createpenguinxy(LXPOS(14),LYPOS(14)); penguincount++;
342 flock[penguincount]=createpenguinxy(LXPOS(14),LYPOS(15)); penguincount++;
343 flock[penguincount]=createpenguinxy(LXPOS(14),LYPOS(16)); penguincount++;
344
345 flock[penguincount]=createpenguinxy(LXPOS(17),LYPOS(12)); penguincount++;
346 flock[penguincount]=createpenguinxy(LXPOS(17),LYPOS(13)); penguincount++;
347 flock[penguincount]=createpenguinxy(LXPOS(17),LYPOS(14)); penguincount++;
348 flock[penguincount]=createpenguinxy(LXPOS(17),LYPOS(15)); penguincount++;
349 flock[penguincount]=createpenguinxy(LXPOS(17),LYPOS(16)); penguincount++;
350
351 flock[penguincount]=createpenguinxy(LXPOS(15),LYPOS(11)); penguincount++;
352 flock[penguincount]=createpenguinxy(LXPOS(16),LYPOS(11)); penguincount++;
353
354 flock[penguincount]=createpenguinxy(LXPOS(15),LYPOS(13)); penguincount++;
355 flock[penguincount]=createpenguinxy(LXPOS(16),LYPOS(13)); penguincount++;
356
357 //K
358 flock[penguincount]=createpenguinxy(LXPOS(19),LYPOS(11)); penguincount++;
359 flock[penguincount]=createpenguinxy(LXPOS(19),LYPOS(12)); penguincount++;
360 flock[penguincount]=createpenguinxy(LXPOS(19),LYPOS(13)); penguincount++;
361 flock[penguincount]=createpenguinxy(LXPOS(19),LYPOS(14)); penguincount++;
362 flock[penguincount]=createpenguinxy(LXPOS(19),LYPOS(15)); penguincount++;
363 flock[penguincount]=createpenguinxy(LXPOS(19),LYPOS(16)); penguincount++;
364
365 flock[penguincount]=createpenguinxy(LXPOS(20),LYPOS(13)); penguincount++;
366 flock[penguincount]=createpenguinxy(LXPOS(21),LYPOS(12)); penguincount++;
367 flock[penguincount]=createpenguinxy(LXPOS(22),LYPOS(11)); penguincount++;
368
369 flock[penguincount]=createpenguinxy(LXPOS(21),LYPOS(14)); penguincount++;
370 flock[penguincount]=createpenguinxy(LXPOS(22),LYPOS(15)); penguincount++;
371 flock[penguincount]=createpenguinxy(LXPOS(22),LYPOS(16)); penguincount++;
372
373 //E
374 flock[penguincount]=createpenguinxy(LXPOS(24),LYPOS(11)); penguincount++;
375 flock[penguincount]=createpenguinxy(LXPOS(24),LYPOS(12)); penguincount++;
376 flock[penguincount]=createpenguinxy(LXPOS(24),LYPOS(13)); penguincount++;
377 flock[penguincount]=createpenguinxy(LXPOS(24),LYPOS(14)); penguincount++;
378 flock[penguincount]=createpenguinxy(LXPOS(24),LYPOS(15)); penguincount++;
379 flock[penguincount]=createpenguinxy(LXPOS(24),LYPOS(16)); penguincount++;
380
381 flock[penguincount]=createpenguinxy(LXPOS(25),LYPOS(11)); penguincount++;
382 flock[penguincount]=createpenguinxy(LXPOS(26),LYPOS(11)); penguincount++;
383
384 flock[penguincount]=createpenguinxy(LXPOS(25),LYPOS(13)); penguincount++;
385 flock[penguincount]=createpenguinxy(LXPOS(26),LYPOS(13)); penguincount++;
386
387 flock[penguincount]=createpenguinxy(LXPOS(25),LYPOS(16)); penguincount++;
388 flock[penguincount]=createpenguinxy(LXPOS(26),LYPOS(16)); penguincount++;
389
390 //R
391 flock[penguincount]=createpenguinxy(LXPOS(28),LYPOS(11)); penguincount++;
392 flock[penguincount]=createpenguinxy(LXPOS(28),LYPOS(12)); penguincount++;
393 flock[penguincount]=createpenguinxy(LXPOS(28),LYPOS(13)); penguincount++;
394 flock[penguincount]=createpenguinxy(LXPOS(28),LYPOS(14)); penguincount++;
395 flock[penguincount]=createpenguinxy(LXPOS(28),LYPOS(15)); penguincount++;
396 flock[penguincount]=createpenguinxy(LXPOS(28),LYPOS(16)); penguincount++;
397
398 flock[penguincount]=createpenguinxy(LXPOS(29),LYPOS(11)); penguincount++;
399 flock[penguincount]=createpenguinxy(LXPOS(30),LYPOS(11)); penguincount++;
400
401 flock[penguincount]=createpenguinxy(LXPOS(29),LYPOS(13)); penguincount++;
402 flock[penguincount]=createpenguinxy(LXPOS(30),LYPOS(13)); penguincount++;
403
404 flock[penguincount]=createpenguinxy(LXPOS(31),LYPOS(12)); penguincount++;
405
406 flock[penguincount]=createpenguinxy(LXPOS(31),LYPOS(14)); penguincount++;
407 flock[penguincount]=createpenguinxy(LXPOS(31),LYPOS(15)); penguincount++;
408 flock[penguincount]=createpenguinxy(LXPOS(31),LYPOS(16)); penguincount++;
409
410 if (penguincount>=MAXPENGUINS) { fprintf(stderr,"Too many penguins!\n"); }
411
412 for (i=0;i<penguincount;i++)
413 {
414 savebehindpenguin(&flock[i]);
415 markgrid(flock[i].geom.x,flock[i].geom.y,BLOCKWIDTH,BLOCKHEIGHT,'*');
416 drawpenguin(&flock[i]);
417 soil(flock[i].geom);
418 }
419
420
421 letterstep++;
422 }
423 else if (letterstep<300)
424 {
425 letterstep++;
426 }
427 else if (letterstep==300)
428 {
429 frozen=false;
430 for (i=0;i<penguincount;i++)
431 {
432 markgrid(flock[i].geom.x,flock[i].geom.y,BLOCKWIDTH,BLOCKHEIGHT,' ');
433 erasepenguin(&flock[i]);
434 soil(flock[i].geom);
435 }
436 letterstep++;
437 setcursor(CURSORCLICK);
438 }
439 else if (letterstep<400)
440 {
441 letterstep++;
442 }
443 else if (letterstep==400)
444 {
445 if (penguincount)
446 {
447 penguincount--;
448 markgrid(flock[penguincount].geom.x,flock[penguincount].geom.y,BLOCKWIDTH,BLOCKHEIGHT,' ');
449 erasepenguin(&flock[penguincount]);
450 soil(flock[penguincount].geom);
451 deletepenguin(&flock[penguincount]);
452 }
453 else
454 {
455 letterstep++;
456 }
457 }
458 else if (letterstep<800)
459 {
460 if (!line1.on && !line2.on)
461 {
462 x=LXPOS(random() % 32);
463 y=LYPOS(random() % 20);
464 if (random()%2)
465 {
466 startline(&line1,UP,x,y);
467 startline(&line2,DOWN,x,y);
468 }
469 else
470 {
471 startline(&line1,LEFT,x,y);
472 startline(&line2,RIGHT,x,y);
473 }
474
475 }
476 }
477 //else if (letterstep<2000)
478 //{
479 // letterstep++;
480 //}
481 //else
482 //{
483 // done=true;
484 //}
485
486
487 hiscorestep--;
488 if (hiscorestep<0)
489 {
490 circularblit(scoresurface,&scrollrect,hiscorescroll);
491 soil(scrollrect);
492 hiscorescroll++;
493 hiscorestep=2;
494 }
495 if (hiscorescroll >= scoresurface->w)
496 {
497 hiscorescroll=0;
498 }
499
500 // move split-lines
501 if (line1.on)
502 {
503 if (moveline(&line1))
504 {
505 linedone1=true;
506 }
507 if (line1.dead) // need a second check because moveline could change this
508 {
509 //no sound in intro?
510 //playsound(SNDBREAK);
511 killline(&line1);
512 linedone1=false;
513 }
514 }
515 if (line2.on)
516 {
517
518 if (moveline(&line2))
519 {
520 linedone2=true;
521
522 }
523 if (line2.dead)
524 {
525 // no sound in intro?
526 //playsound(SNDBREAK);
527 killline(&line2);
528 linedone2=false;
529 }
530 }
531 if (linedone1 && linedone2) { letterstep++; linedone1=false; linedone2=false; }
532
533
534 // move (and get old background)
535
536 if (!frozen)
537 {
538 for (i=0;i<penguincount;i+=2)
539 {
540 soil(flock[i].geom); // mark the penguin's old position as dirty
541 movepenguin(&flock[i]);
542 soil(flock[i].geom); // mark the penguin's new position as dirty too (it will be soon...)
543 savebehindpenguin(&flock[i]);
544 }
545 }
546 soil(tux.geom); // mark the penguin's old position as dirty
547 movepenguin(&tux);
548 soil(tux.geom); // mark the penguin's new position as dirty too (it will be soon...)
549 savebehindpenguin(&tux);
550
551 // actually draw
552 if (!frozen)
553 {
554 for (i=0;i<penguincount;i+=2)
555 {
556 drawpenguin(&flock[i]);
557 }
558 }
559 drawpenguin(&tux);
560
561 // update screen
562 clean();
563
564 // clear for next update
565 if (!frozen)
566 {
567 for (i=0;i<penguincount;i+=2)
568 {
569 erasepenguin(&flock[i]);
570 }
571 }
572 erasepenguin(&tux);
573
574 SDL_Delay(10);
575
576 } while (!done);
577
578 clean();
579
580 while (penguincount)
581 {
582 penguincount--;
583 deletepenguin(&flock[penguincount]);
584 }
585 deletepenguin(&tux);
586
587 // destroy highscore surface
588 SDL_FreeSurface(scoresurface);
589
590 return(false);
591 }
592
593 #define EXTRASCROLLSCORESPACE 30
594 // FIX -- the max username length is hardcoded at 50 in highscore.c, and as
595 // 12 in dialog.c. The 12 is so it fits in the dialog box nicely, and should
596 // be plenty long, but it's good to keep the buffer bigger. Anyway, the value
597 // in highscore.c should be a define, and this should be that-define + some
598 // reasonable value for the width of the score.
599 #define SCOREMAXLEN 70
600
createscoresurface()601 SDL_Surface* createscoresurface()
602 {
603 SDL_Surface* tmpsurface;
604 char scoretext[SCOREMAXLEN];
605 int i,len;
606
607 //caculate needed len
608 len=0;
609 for( i = 0 ; i < HISCORENUM ; i++)
610 {
611 snprintf(scoretext,SCOREMAXLEN,"#%d. %s: %ld",i+1,hiscorename[i],hiscoreval[i]);
612 len += gettextwidth(2,scoretext);
613 }
614
615 len += (HISCORENUM+1) * EXTRASCROLLSCORESPACE;
616
617 //alloc surface
618 tmpsurface = SDL_CreateRGBSurface(SDL_SWSURFACE,len,CHARHEIGHT*2,VIDEODEPTH,0,0,0,0);
619
620 // fill surface
621 SDL_FillRect(tmpsurface,NULL,color.background);
622 len=0;
623 for( i = 0 ; i < HISCORENUM ; i++)
624 {
625 snprintf(scoretext,SCOREMAXLEN,"#%d. %s: %ld",i+1,hiscorename[i],hiscoreval[i]);
626 sputtext(tmpsurface,len,0,2,color.normaltext,scoretext);
627 len += gettextwidth(2,scoretext) + EXTRASCROLLSCORESPACE;
628 }
629
630 return tmpsurface;
631 }
632
633 // this assumes that scoresurface->w > scrollrect->w
circularblit(SDL_Surface * scoresurface,SDL_Rect * scrollrect,Uint16 hiscorescroll)634 void circularblit(SDL_Surface* scoresurface,SDL_Rect* scrollrect,Uint16 hiscorescroll)
635 {
636 SDL_Rect from,to;
637 Sint32 len;
638
639 //calculate fiirst part w
640 if( scoresurface->w - hiscorescroll < scrollrect->w)
641 len = scoresurface->w - hiscorescroll;
642 else
643 len = scrollrect->w;
644
645 // draw first part to scoresurface
646 from.x=hiscorescroll;
647 from.y=0;
648 from.w=len;
649 from.h=scoresurface->h;
650
651 to.x=scrollrect->x;
652 to.y=scrollrect->y;
653 to.w=from.w;
654 to.h=from.h;
655
656 SDL_BlitSurface(scoresurface,&from,screen,&to);
657
658 //if needed, draw second part to scoresurface
659 if(len < scrollrect->w)
660 {
661 from.x=0;
662 from.y=0;
663 from.w=scrollrect->w - len;
664 from.h=scoresurface->h;
665
666 to.x=scrollrect->x + len;
667 to.y=scrollrect->y;
668 to.w=from.w;
669 to.h=from.h;
670
671 SDL_BlitSurface(scoresurface,&from,screen,&to);
672 }
673 }
674