Tux doesn't lose mints or coffee upgrade when finishing a level.
[supertux.git] / src / gameloop.c
1 /*
2   gameloop.c
3   
4   Super Tux - Game Loop!
5   
6   by Bill Kendrick
7   bill@newbreedsoftware.com
8   http://www.newbreedsoftware.com/supertux/
9   
10   April 11, 2000 - December 29, 2003
11 */
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <errno.h>
17 #include <unistd.h>
18 #include <time.h>
19 #include <SDL.h>
20
21 #ifdef LINUX
22 #include <pwd.h>
23 #include <sys/types.h>
24 #include <ctype.h>
25 #endif
26
27 #include "defines.h"
28 #include "globals.h"
29 #include "gameloop.h"
30 #include "screen.h"
31 #include "setup.h"
32 #include "high_scores.h"
33 #include "menu.h"
34 #include "badguy.h"
35 #include "world.h"
36 #include "player.h"
37
38 /* extern variables */
39
40 extern char* soundfilenames[NUM_SOUNDS];
41
42 /* Local variables: */
43
44 int score, highscore, distros, level, lives, scroll_x, next_level, game_pause,
45 done, quit, tux_dir, tux_size, tux_duck, tux_x, tux_xm, tux_y, tux_ym,
46 tux_dying, tux_safe, jumping, jump_counter, frame, score_multiplier,
47 tux_frame_main, tux_frame, tux_got_coffee, tux_skidding,
48 super_bkgd_time, time_left, tux_invincible_time, endpos,
49 counting_distros, distro_counter;
50 int bkgd_red, bkgd_green, bkgd_blue, level_width;
51 int left, right, up, down, fire, old_fire;
52 SDL_Surface * img_brick[2], * img_solid[4], * img_distro[4],
53 * img_waves[3], * img_water, * img_pole, * img_poletop, * img_flag[2];
54 SDL_Surface * img_bkgd[2][4];
55 SDL_Surface * img_golden_herring;
56 SDL_Surface * img_bsod_left[4], * img_bsod_right[4],
57 * img_laptop_left[3], * img_laptop_right[3],
58 * img_money_left[2], * img_money_right[2];
59 SDL_Surface * img_bsod_squished_left, * img_bsod_squished_right,
60 * img_bsod_falling_left, * img_bsod_falling_right,
61 * img_laptop_flat_left, * img_laptop_flat_right,
62 * img_laptop_falling_left, * img_laptop_falling_right;
63 SDL_Surface * img_box_full, * img_box_empty, * img_mints, * img_coffee,
64 * img_super_bkgd, * img_bullet, * img_red_glow;
65 SDL_Surface * img_cloud[2][4];
66 SDL_Surface * tux_life,
67 * tux_right[3], * tux_left[3],
68 * bigtux_right[3], * bigtux_left[3],
69 * bigtux_right_jump, * bigtux_left_jump,
70 * ducktux_right, * ducktux_left,
71 * skidtux_right, * skidtux_left,
72 * firetux_right[3], * firetux_left[3],
73 * bigfiretux_right[3], * bigfiretux_left[3],
74 * bigfiretux_right_jump, * bigfiretux_left_jump,
75 * duckfiretux_right, * duckfiretux_left,
76 * skidfiretux_right, * skidfiretux_left,
77 * cape_right[2], * cape_left[2],
78 * bigcape_right[2], * bigcape_left[2];
79 SDL_Event event;
80 SDL_Rect src, dest;
81 SDLKey key;
82 unsigned char * tiles[15];
83 bouncy_distro_type bouncy_distros[NUM_BOUNCY_DISTROS];
84 broken_brick_type broken_bricks[NUM_BROKEN_BRICKS];
85 bouncy_brick_type bouncy_bricks[NUM_BOUNCY_BRICKS];
86 bad_guy_type bad_guys[NUM_BAD_GUYS];
87 floating_score_type floating_scores[NUM_FLOATING_SCORES];
88 upgrade_type upgrades[NUM_UPGRADES];
89 bullet_type bullets[NUM_BULLETS];
90 char song_title[60];
91 char levelname[60];
92 char leveltheme[60];
93 char str[60];
94
95
96 /* Local function prototypes: */
97
98 void initgame(void);
99 void loadlevel(void);
100 void loadlevelgfx(void);
101 void loadlevelsong(void);
102 void unloadlevelgfx(void);
103 void unloadlevelsong(void);
104 void loadshared(void);
105 void unloadshared(void);
106 void drawshape(int x, int y, unsigned char c);
107 unsigned char shape(int x, int y, int sx);
108 int issolid(int x, int y, int sx);
109 int isbrick(int x, int y, int sx);
110 int isice(int x, int y, int sx);
111 int isfullbox(int x, int y, int sx);
112 void change(int x, int y, int sx, unsigned char c);
113 void trybreakbrick(int x, int y, int sx);
114 void bumpbrick(int x, int y, int sx);
115 void tryemptybox(int x, int y, int sx);
116 void trygrabdistro(int x, int y, int sx, int bounciness);
117 void add_bouncy_distro(int x, int y);
118 void add_broken_brick(int x, int y);
119 void add_broken_brick_piece(int x, int y, int xm, int ym);
120 void add_bouncy_brick(int x, int y);
121 void add_bad_guy(int x, int y, int kind);
122 void add_score(int x, int y, int s);
123 void trybumpbadguy(int x, int y, int sx);
124 void add_upgrade(int x, int y, int kind);
125 void killtux(int mode);
126 void add_bullet(int x, int y, int dir, int xm);
127 void drawendscreen(void);
128 void drawresultscreen(void);
129
130 /* --- GAME EVENT! --- */
131
132 void game_event(void)
133 {
134
135   while (SDL_PollEvent(&event))
136     {
137
138       if (event.type == SDL_QUIT)
139         {
140           /* Quit event - quit: */
141
142           quit = 1;
143         }
144       else if (event.type == SDL_KEYDOWN)
145         {
146           /* A keypress! */
147
148           key = event.key.keysym.sym;
149
150           /* Check for menu-events, if the menu is shown */
151           if(show_menu)
152             menu_event(key);
153
154           if (key == SDLK_ESCAPE)
155             {
156               /* Escape: Open/Close the menu: */
157               if(!game_pause)
158                 {
159                   if(show_menu)
160                     show_menu = 0;
161                   else
162                     show_menu = 1;
163                 }
164             }
165           else if (key == SDLK_RIGHT)
166             {
167               right = DOWN;
168             }
169           else if (key == SDLK_LEFT)
170             {
171               left = DOWN;
172             }
173           else if (key == SDLK_UP)
174             {
175               up = DOWN;
176             }
177           else if (key == SDLK_DOWN)
178             {
179               down = DOWN;
180             }
181           else if (key == SDLK_LCTRL)
182             {
183               fire = DOWN;
184             }
185         }
186       else if (event.type == SDL_KEYUP)
187         {
188           /* A keyrelease! */
189
190           key = event.key.keysym.sym;
191
192           if (key == SDLK_RIGHT)
193             {
194               right = UP;
195             }
196           else if (key == SDLK_LEFT)
197             {
198               left = UP;
199             }
200           else if (key == SDLK_UP)
201             {
202               up = UP;
203             }
204           else if (key == SDLK_DOWN)
205             {
206               down = UP;
207             }
208           else if (key == SDLK_LCTRL)
209             {
210               fire = UP;
211             }
212           else if (key == SDLK_p)
213             {
214               if(!show_menu)
215                 {
216                   if(game_pause)
217                     game_pause = 0;
218                   else
219                     game_pause = 1;
220                 }
221             }
222           else if (key == SDLK_TAB && debug_mode == YES)
223             {
224               tux_size = !tux_size;
225             }
226           else if (key == SDLK_END && debug_mode == YES)
227             {
228               distros += 50;
229             }
230           else if (key == SDLK_SPACE && debug_mode == YES)
231             {
232               next_level = 1;
233             }
234         }
235 #ifdef JOY_YES
236       else if (event.type == SDL_JOYAXISMOTION)
237         {
238           if (event.jaxis.axis == JOY_X)
239             {
240               if (event.jaxis.value < -256)
241                 left = DOWN;
242               else
243                 left = UP;
244
245               if (event.jaxis.value > 256)
246                 right = DOWN;
247               else
248                 right = UP;
249             }
250           else if (event.jaxis.axis == JOY_Y)
251             {
252               if (event.jaxis.value > 256)
253                 down = DOWN;
254               else
255                 down = UP;
256
257               /* Handle joystick for the menu */
258               if(show_menu)
259                 {
260                   if(down == DOWN)
261                     menuaction = MN_DOWN;
262                   else
263                     menuaction = MN_UP;
264                 }
265             }
266         }
267       else if (event.type == SDL_JOYBUTTONDOWN)
268         {
269           if (event.jbutton.button == JOY_A)
270             up = DOWN;
271           else if (event.jbutton.button == JOY_B)
272             fire = DOWN;
273         }
274       else if (event.type == SDL_JOYBUTTONUP)
275         {
276           if (event.jbutton.button == JOY_A)
277             up = UP;
278           else if (event.jbutton.button == JOY_B)
279             fire = UP;
280
281           if(show_menu)
282             menuaction = MN_HIT;
283
284         }
285 #endif
286
287     }
288
289 }
290
291 /* --- GAME ACTION! --- */
292
293 int game_action(void)
294 {
295   int i,j;
296
297   /* --- HANDLE TUX! --- */
298
299   /* Handle key and joystick state: */
300
301   if (!(tux_dying || next_level))
302     {
303       if (right == DOWN && left == UP)
304         {
305           if (jumping == NO)
306             {
307               if (tux_xm < -SKID_XM && !tux_skidding &&
308                   tux_dir == LEFT)
309                 {
310                   tux_skidding = SKID_TIME;
311
312                   play_sound(sounds[SND_SKID], SOUND_CENTER_SPEAKER);
313
314                 }
315               tux_dir = RIGHT;
316             }
317
318           if (tux_xm < 0 && !isice(tux_x, tux_y + 32, scroll_x) &&
319               !tux_skidding)
320             {
321               tux_xm = 0;
322             }
323
324           if (!tux_duck)
325             {
326               if (tux_dir == RIGHT)
327                 {
328                   /* Facing the direction we're jumping?  Go full-speed: */
329
330                   if (fire == UP)
331                     {
332                       tux_xm = tux_xm + WALK_SPEED;
333
334                       if (tux_xm > MAX_WALK_XM)
335                         tux_xm = MAX_WALK_XM;
336                     }
337                   else if (fire == DOWN)
338                     {
339                       tux_xm = tux_xm + RUN_SPEED;
340
341                       if (tux_xm > MAX_RUN_XM)
342                         tux_xm = MAX_RUN_XM;
343                     }
344                 }
345               else
346                 {
347                   /* Not facing the direction we're jumping?
348                   Go half-speed: */
349
350                   tux_xm = tux_xm + WALK_SPEED / 2;
351
352                   if (tux_xm > MAX_WALK_XM / 2)
353                     tux_xm = MAX_WALK_XM / 2;
354                 }
355             }
356         }
357       else if (left == DOWN && right == UP)
358         {
359           if (jumping == NO)
360             {
361               if (tux_xm > SKID_XM && !tux_skidding &&
362                   tux_dir == RIGHT)
363                 {
364                   tux_skidding = SKID_TIME;
365                   play_sound(sounds[SND_SKID], SOUND_CENTER_SPEAKER);
366                 }
367               tux_dir = LEFT;
368             }
369
370           if (tux_xm > 0 && !isice(tux_x, tux_y + 32, scroll_x) &&
371               !tux_skidding)
372             {
373               tux_xm = 0;
374             }
375
376           if (!tux_duck)
377             {
378               if (tux_dir == LEFT)
379                 {
380                   /* Facing the direction we're jumping?  Go full-speed: */
381
382                   if (fire == UP)
383                     {
384                       tux_xm = tux_xm - WALK_SPEED;
385
386                       if (tux_xm < -MAX_WALK_XM)
387                         tux_xm = -MAX_WALK_XM;
388                     }
389                   else if (fire == DOWN)
390                     {
391                       tux_xm = tux_xm - RUN_SPEED;
392
393                       if (tux_xm < -MAX_RUN_XM)
394                         tux_xm = -MAX_RUN_XM;
395                     }
396                 }
397               else
398                 {
399                   /* Not facing the direction we're jumping?
400                   Go half-speed: */
401
402                   tux_xm = tux_xm - WALK_SPEED / 2;
403
404                   if (tux_xm < -MAX_WALK_XM / 2)
405                     tux_xm = -MAX_WALK_XM / 2;
406                 }
407             }
408         }
409
410
411       /* End of level? */
412
413       if (tux_x >= endpos && endpos != 0)
414         {
415           next_level = 1;
416         }
417
418
419       /* Jump/jumping? */
420
421       if (up == DOWN)
422         {
423           if (jump_counter == 0)
424             {
425               /* Taking off? */
426
427               if (!issolid(tux_x, tux_y + 32, scroll_x) ||
428                   tux_ym != 0)
429                 {
430                   /* If they're not on the ground, or are currently moving
431                   vertically, don't jump! */
432
433                   jump_counter = MAX_JUMP_COUNT;
434                 }
435               else
436                 {
437                   /* Make sure we're not standing back up into a solid! */
438
439                   if (tux_size == SMALL || tux_duck == NO ||
440                       !issolid(tux_x, tux_y, scroll_x))
441                     {
442                       jumping = YES;
443
444                       if (tux_size == SMALL)
445                         play_sound(sounds[SND_JUMP], SOUND_CENTER_SPEAKER);
446                       else
447                         play_sound(sounds[SND_BIGJUMP], SOUND_CENTER_SPEAKER);
448                     }
449                 }
450             }
451
452
453           /* Keep jumping for a while: */
454
455           if (jump_counter < MAX_JUMP_COUNT)
456             {
457               tux_ym = tux_ym - JUMP_SPEED;
458               jump_counter++;
459             }
460         }
461       else
462         jump_counter = 0;
463
464
465       /* Shoot! */
466
467       if (fire == DOWN && old_fire == UP && tux_got_coffee)
468         {
469           add_bullet(tux_x + scroll_x, tux_y, tux_dir, tux_xm);
470         }
471
472
473       /* Duck! */
474
475       if (down == DOWN)
476         {
477           if (tux_size == BIG)
478             tux_duck = YES;
479         }
480       else
481         {
482           if (tux_size == BIG && tux_duck == YES)
483             {
484               /* Make sure we're not standing back up into a solid! */
485
486               if (!issolid(tux_x, tux_y - 32, scroll_x))
487                 tux_duck = NO;
488             }
489           else
490             tux_duck = NO;
491         }
492     } /* (tux_dying || next_level) */
493   else
494     {
495       /* Tux either died, or reached the end of a level! */
496
497
498       if (playing_music())
499         halt_music();
500
501
502       if (next_level)
503         {
504           /* End of a level! */
505           level++;
506           next_level = 0;
507           drawresultscreen();
508         }
509       else
510         {
511
512           tux_ym = tux_ym + GRAVITY;
513
514
515
516           /* He died :^( */
517
518           lives--;
519
520           /* No more lives!? */
521
522           if (lives < 0)
523             {
524               drawendscreen();
525
526               if (score > highscore)
527                 save_hs(score);
528
529               unloadlevelgfx();
530               unloadlevelsong();
531               unloadshared();
532               return(0);
533             } /* if (lives < 0) */
534         }
535
536       /* Either way, (re-)load the (next) level... */
537
538       loadlevel();
539       unloadlevelgfx();
540       loadlevelgfx();
541       unloadlevelsong();
542       loadlevelsong();
543     }
544
545   /* Move tux: */
546
547   tux_x = tux_x + tux_xm;
548   tux_y = tux_y + tux_ym;
549
550
551   /* Keep tux in bounds: */
552   if (tux_x < 0)
553     tux_x = 0;
554   else if (tux_x < 160 && scroll_x > 0 && debug_mode == YES)
555     {
556       scroll_x = scroll_x - ( 160 - tux_x);
557       tux_x = 160;
558
559       if(scroll_x < 0)
560         scroll_x = 0;
561
562     }
563   else if (tux_x > 320 && scroll_x < ((level_width * 32) - 640))
564     {
565       /* Scroll the screen in past center: */
566
567       scroll_x = scroll_x + (tux_x - 320);
568       tux_x = 320;
569
570       if (scroll_x > ((level_width * 32) - 640))
571         scroll_x = ((level_width * 32) - 640);
572     }
573   else if (tux_x > 608)
574     {
575       /* ... unless there's no more to scroll! */
576
577       tux_x = 608;
578     }
579
580
581   /* Land: */
582
583   if (!tux_dying)
584     {
585       if (issolid(tux_x, tux_y + 31, scroll_x) &&
586           !issolid(tux_x - tux_xm, tux_y + 31, scroll_x))
587         {
588           while (issolid(tux_x, tux_y + 31, scroll_x))
589             {
590               if (tux_xm < 0)
591                 tux_x++;
592               else if (tux_xm > 0)
593                 tux_x--;
594             }
595
596           tux_xm = 0;
597         }
598
599       if (issolid(tux_x, tux_y, scroll_x) &&
600           !issolid(tux_x - tux_xm, tux_y, scroll_x))
601         {
602           while (issolid(tux_x, tux_y, scroll_x))
603             {
604               if (tux_xm < 0)
605                 tux_x++;
606               else if (tux_xm > 0)
607                 tux_x--;
608             }
609
610           tux_xm = 0;
611         }
612
613       if (issolid(tux_x, tux_y + 31, scroll_x))
614         {
615           /* Set down properly: */
616
617           while (issolid(tux_x, tux_y + 31, scroll_x))
618             {
619               if (tux_ym < 0)
620                 tux_y++;
621               else if (tux_ym > 0)
622                 tux_y--;
623             }
624
625
626           /* Reset score multiplier (for mutli-hits): */
627
628           if (tux_ym > 0)
629             score_multiplier = 1;
630
631
632           /* Stop jumping! */
633
634           tux_ym = 0;
635           jumping = NO;
636         }
637
638
639       /* Bump into things: */
640
641       if (issolid(tux_x, tux_y, scroll_x) ||
642           (tux_size == BIG && !tux_duck &&
643            (issolid(tux_x, tux_y - 32, scroll_x))))
644         {
645           if (!issolid(tux_x - tux_xm, tux_y, scroll_x) &&
646               (tux_size == SMALL || tux_duck ||
647                !issolid(tux_x - tux_xm, tux_y - 32, scroll_x)))
648             {
649               tux_x = tux_x - tux_xm;
650               tux_xm = 0;
651             }
652           else if (!issolid(tux_x, tux_y - tux_ym, scroll_x) &&
653                    (tux_size == SMALL || tux_duck ||
654                     !issolid(tux_x, tux_y - 32 - tux_ym, scroll_x)))
655             {
656               if (tux_ym <= 0)
657                 {
658                   /* Jumping up? */
659
660                   if (tux_size == BIG)
661                     {
662                       /* Break bricks and empty boxes: */
663
664                       if (!tux_duck)
665                         {
666                           if (isbrick(tux_x, tux_y - 32, scroll_x) ||
667                               isfullbox(tux_x, tux_y - 32, scroll_x))
668                             {
669                               trygrabdistro(tux_x, tux_y - 64, scroll_x,
670                                             BOUNCE);
671                               trybumpbadguy(tux_x, tux_y - 96, scroll_x);
672
673                               if (isfullbox(tux_x, tux_y - 32,
674                                             scroll_x))
675                                 {
676                                   bumpbrick(tux_x, tux_y - 32,
677                                             scroll_x);
678                                 }
679
680                               trybreakbrick(tux_x, tux_y - 32, scroll_x);
681                               tryemptybox(tux_x, tux_y - 32, scroll_x);
682                             }
683
684                           if (isbrick(tux_x + 31, tux_y - 32, scroll_x) ||
685                               isfullbox(tux_x + 31, tux_y - 32, scroll_x))
686                             {
687                               trygrabdistro(tux_x + 31,
688                                             tux_y - 64,
689                                             scroll_x,
690                                             BOUNCE);
691                               trybumpbadguy(tux_x + 31,
692                                             tux_y - 96,
693                                             scroll_x);
694
695                               if (isfullbox(tux_x + 31, tux_y - 32,
696                                             scroll_x))
697                                 {
698                                   bumpbrick(tux_x + 31, tux_y - 32,
699                                             scroll_x);
700                                 }
701
702                               trybreakbrick(tux_x + 31,
703                                             tux_y - 32,
704                                             scroll_x);
705                               tryemptybox(tux_x + 31,
706                                           tux_y - 32,
707                                           scroll_x);
708                             }
709                         }
710                       else /* ducking */
711                         {
712                           if (isbrick(tux_x, tux_y, scroll_x) ||
713                               isfullbox(tux_x, tux_y, scroll_x))
714                             {
715                               trygrabdistro(tux_x, tux_y - 32, scroll_x,
716                                             BOUNCE);
717                               trybumpbadguy(tux_x, tux_y - 64, scroll_x);
718                               if (isfullbox(tux_x, tux_y, scroll_x))
719                                 bumpbrick(tux_x, tux_y, scroll_x);
720                               trybreakbrick(tux_x, tux_y, scroll_x);
721                               tryemptybox(tux_x, tux_y, scroll_x);
722                             }
723
724                           if (isbrick(tux_x + 31, tux_y, scroll_x) ||
725                               isfullbox(tux_x + 31, tux_y, scroll_x))
726                             {
727                               trygrabdistro(tux_x + 31,
728                                             tux_y - 32,
729                                             scroll_x,
730                                             BOUNCE);
731                               trybumpbadguy(tux_x + 31,
732                                             tux_y - 64,
733                                             scroll_x);
734                               if (isfullbox(tux_x + 31, tux_y, scroll_x))
735                                 bumpbrick(tux_x + 31, tux_y, scroll_x);
736                               trybreakbrick(tux_x + 31, tux_y, scroll_x);
737                               tryemptybox(tux_x + 31, tux_y, scroll_x);
738                             }
739                         }
740                     }
741                   else
742                     {
743                       /* It's a brick and we're small, make the brick
744                          bounce, and grab any distros above it: */
745
746                       if (isbrick(tux_x, tux_y, scroll_x) ||
747                           isfullbox(tux_x, tux_y, scroll_x))
748                         {
749                           trygrabdistro(tux_x, tux_y - 32, scroll_x,
750                                         BOUNCE);
751                           trybumpbadguy(tux_x, tux_y - 64, scroll_x);
752                           bumpbrick(tux_x, tux_y, scroll_x);
753                           tryemptybox(tux_x, tux_y, scroll_x);
754                         }
755
756                       if (isbrick(tux_x + 31, tux_y, scroll_x) ||
757                           isfullbox(tux_x + 31, tux_y, scroll_x))
758                         {
759                           trygrabdistro(tux_x + 31, tux_y - 32, scroll_x,
760                                         BOUNCE);
761                           trybumpbadguy(tux_x + 31, tux_y - 64, scroll_x);
762                           bumpbrick(tux_x + 31, tux_y, scroll_x);
763                           tryemptybox(tux_x + 31, tux_y, scroll_x);
764                         }
765
766
767                       /* Get a distro from a brick? */
768
769                       if (shape(tux_x, tux_y, scroll_x) == 'x' ||
770                           shape(tux_x, tux_y, scroll_x) == 'y')
771                         {
772                           add_bouncy_distro(((tux_x + scroll_x + 1)
773                                              / 32) * 32,
774                                             (tux_y / 32) * 32);
775
776                           if (counting_distros == NO)
777                             {
778                               counting_distros = YES;
779                               distro_counter = 100;
780                             }
781
782                           if (distro_counter <= 0)
783                             change(tux_x, tux_y, scroll_x, 'a');
784
785                           play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
786                           score = score + SCORE_DISTRO;
787                           distros++;
788                         }
789                       else if (shape(tux_x + 31, tux_y, scroll_x) == 'x' ||
790                                shape(tux_x + 31, tux_y, scroll_x) == 'y')
791                         {
792                           add_bouncy_distro(((tux_x + scroll_x + 1 + 31)
793                                              / 32) * 32,
794                                             (tux_y / 32) * 32);
795
796                           if (counting_distros == NO)
797                             {
798                               counting_distros = YES;
799                               distro_counter = 100;
800                             }
801
802                           if (distro_counter <= 0)
803                             change(tux_x + 31, tux_y, scroll_x, 'a');
804
805                           play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
806                           score = score + SCORE_DISTRO;
807                           distros++;
808                         }
809                     }
810
811
812                   /* Bump head: */
813
814                   tux_y = (tux_y / 32) * 32 + 30;
815                 }
816               else
817                 {
818                   /* Land on feet: */
819
820                   tux_y = (tux_y / 32) * 32 - 32;
821                 }
822
823               tux_ym = 0;
824               jumping = NO;
825               jump_counter = MAX_JUMP_COUNT;
826             }
827         }
828     }
829
830
831   /* Grab distros: */
832
833   if (!tux_dying)
834     {
835       trygrabdistro(tux_x, tux_y, scroll_x, NO_BOUNCE);
836       trygrabdistro(tux_x + 31, tux_y, scroll_x, NO_BOUNCE);
837
838       if (tux_size == BIG && !tux_duck)
839         {
840           trygrabdistro(tux_x, tux_y - 32, scroll_x, NO_BOUNCE);
841           trygrabdistro(tux_x + 31, tux_y - 32, scroll_x, NO_BOUNCE);
842         }
843     }
844
845
846   /* Enough distros for a One-up? */
847
848   if (distros >= DISTROS_LIFEUP)
849     {
850       distros = distros - DISTROS_LIFEUP;
851       if(lives < MAX_LIVES)
852         lives++;
853       /*We want to hear the sound even, if MAX_LIVES is reached*/
854       play_sound(sounds[SND_LIFEUP], SOUND_CENTER_SPEAKER);
855     }
856
857
858   /* Keep in-bounds, vertically: */
859
860   if (tux_y < 0)
861     tux_y = 0;
862   else if (tux_y > 480)
863     {
864       killtux(KILL);
865     }
866
867
868   /* Slow down horizontally: */
869
870   if (!tux_dying)
871     {
872       if (right == UP && left == UP)
873         {
874           if (isice(tux_x, tux_y + 32, scroll_x) ||
875               !issolid(tux_x, tux_y + 32, scroll_x))
876             {
877               /* Slowly on ice or in air: */
878
879               if (tux_xm > 0)
880                 tux_xm--;
881               else if (tux_xm < 0)
882                 tux_xm++;
883             }
884           else
885             {
886               /* Quickly, otherwise: */
887
888               tux_xm = tux_xm / 2;
889             }
890         }
891
892
893       /* Drop vertically: */
894
895       if (!issolid(tux_x, tux_y + 32, scroll_x))
896         {
897           tux_ym = tux_ym + GRAVITY;
898
899           if (tux_ym > MAX_YM)
900             tux_ym = MAX_YM;
901         }
902     }
903
904
905   if (tux_safe > 0)
906     tux_safe--;
907
908
909   /* ---- DONE HANDLING TUX! --- */
910
911
912   /* Handle bouncy distros: */
913
914   for (i = 0; i < NUM_BOUNCY_DISTROS; i++)
915     {
916       if (bouncy_distros[i].alive)
917         {
918           bouncy_distros[i].y = bouncy_distros[i].y + bouncy_distros[i].ym;
919
920           bouncy_distros[i].ym++;
921
922           if (bouncy_distros[i].ym >= 0)
923             bouncy_distros[i].alive = NO;
924         }
925     }
926
927
928   /* Handle broken bricks: */
929
930   for (i = 0; i < NUM_BROKEN_BRICKS; i++)
931     {
932       if (broken_bricks[i].alive)
933         {
934           broken_bricks[i].x = broken_bricks[i].x + broken_bricks[i].xm;
935           broken_bricks[i].y = broken_bricks[i].y + broken_bricks[i].ym;
936
937           broken_bricks[i].ym++;
938
939           if (broken_bricks[i].ym >= 0)
940             broken_bricks[i].alive = NO;
941         }
942     }
943
944
945   /* Handle distro counting: */
946
947   if (counting_distros == YES)
948     {
949       distro_counter--;
950
951       if (distro_counter <= 0)
952         counting_distros = -1;
953     }
954
955
956   /* Handle bouncy bricks: */
957
958   for (i = 0; i < NUM_BOUNCY_BRICKS; i++)
959     {
960       if (bouncy_bricks[i].alive)
961         {
962           bouncy_bricks[i].offset = (bouncy_bricks[i].offset +
963                                      bouncy_bricks[i].offset_m);
964
965           /* Go back down? */
966
967           if (bouncy_bricks[i].offset < -BOUNCY_BRICK_MAX_OFFSET)
968             bouncy_bricks[i].offset_m = BOUNCY_BRICK_SPEED;
969
970
971           /* Stop bouncing? */
972
973           if (bouncy_bricks[i].offset == 0)
974             bouncy_bricks[i].alive = NO;
975         }
976     }
977
978
979   /* Handle floating scores: */
980
981   for (i = 0; i < NUM_FLOATING_SCORES; i++)
982     {
983       if (floating_scores[i].alive)
984         {
985           floating_scores[i].y = floating_scores[i].y - 2;
986           floating_scores[i].timer--;
987
988           if (floating_scores[i].timer <= 0)
989             floating_scores[i].alive = NO;
990         }
991     }
992
993
994   /* Handle bullets: */
995
996   for (i = 0; i < NUM_BULLETS; i++)
997     {
998       if (bullets[i].alive)
999         {
1000           bullets[i].x = bullets[i].x + bullets[i].xm;
1001           bullets[i].y = bullets[i].y + bullets[i].ym;
1002
1003           if (issolid(bullets[i].x, bullets[i].y, 0))
1004             {
1005               if (issolid(bullets[i].x, bullets[i].y - bullets[i].ym, 0))
1006                 bullets[i].alive = NO;
1007               else
1008                 {
1009                   if (bullets[i].ym >= 0)
1010                     {
1011                       bullets[i].y = (bullets[i].y / 32) * 32 - 8;
1012                     }
1013                   bullets[i].ym = -bullets[i].ym;
1014                 }
1015             }
1016
1017           bullets[i].ym = bullets[i].ym + GRAVITY;
1018
1019           if (bullets[i].x < scroll_x ||
1020               bullets[i].x > scroll_x + 640)
1021             {
1022               bullets[i].alive = NO;
1023             }
1024         }
1025
1026
1027       if (bullets[i].alive)
1028         {
1029           for (j = 0; j < NUM_BAD_GUYS; j++)
1030             {
1031               if (bad_guys[j].alive && !bad_guys[j].dying)
1032                 {
1033                   if (bullets[i].x >= bad_guys[j].x - 4 &&
1034                       bullets[i].x <= bad_guys[j].x + 32 + 4 &&
1035                       bullets[i].y >= bad_guys[j].y - 4 &&
1036                       bullets[i].y <= bad_guys[j].y + 32 + 4)
1037                     {
1038                       /* Kill the bad guy! */
1039
1040                       bullets[i].alive = 0;
1041                       bad_guys[j].dying = FALLING;
1042                       bad_guys[j].ym = -8;
1043
1044
1045                       /* Gain some points: */
1046
1047                       if (bad_guys[j].kind == BAD_BSOD)
1048                         {
1049                           add_score(bad_guys[j].x - scroll_x, bad_guys[j].y,
1050                                     50 * score_multiplier);
1051                         }
1052                       else if (bad_guys[j].kind == BAD_LAPTOP)
1053                         {
1054                           add_score(bad_guys[j].x - scroll_x, bad_guys[j].y,
1055                                     25 * score_multiplier);
1056                         }
1057
1058
1059                       /* Play death sound: */
1060                       play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
1061                     }
1062                 }
1063             }
1064         }
1065     }
1066
1067
1068   /* Handle background timer: */
1069
1070   if (super_bkgd_time)
1071     super_bkgd_time--;
1072
1073
1074   /* Handle invincibility timer: */
1075
1076
1077   if (tux_invincible_time > 50)
1078     {
1079       tux_invincible_time--;
1080
1081
1082       if (!playing_music())
1083         play_music( herring_song, 1 );
1084     }
1085   else
1086     {
1087       if (current_music == HERRING_MUSIC)
1088         {
1089           /* stop the herring_song, now play the level_song ! */
1090           current_music = LEVEL_MUSIC;
1091           halt_music();
1092         }
1093
1094       if (!playing_music())
1095         {
1096           if (time_left <= TIME_WARNING)
1097             play_music( level_song_fast, 1 );
1098           else
1099             play_music( level_song, 1 );
1100         }
1101
1102       if (tux_invincible_time > 0)
1103         tux_invincible_time--;
1104     }
1105
1106
1107   /* Handle upgrades: */
1108
1109   for (i = 0; i < NUM_UPGRADES; i++)
1110     {
1111       if (upgrades[i].alive)
1112         {
1113           if (upgrades[i].height < 32)
1114             {
1115               /* Rise up! */
1116
1117               upgrades[i].height++;
1118             }
1119           else
1120             {
1121               /* Move around? */
1122
1123               if (upgrades[i].kind == UPGRADE_MINTS ||
1124                   upgrades[i].kind == UPGRADE_HERRING)
1125                 {
1126                   upgrades[i].x = upgrades[i].x + upgrades[i].xm;
1127                   upgrades[i].y = upgrades[i].y + upgrades[i].ym;
1128
1129                   if (issolid(upgrades[i].x, upgrades[i].y + 31, 0) ||
1130                       issolid(upgrades[i].x + 31, upgrades[i].y + 31, 0))
1131                     {
1132                       if (upgrades[i].ym > 0)
1133                         {
1134                           if (upgrades[i].kind == UPGRADE_MINTS)
1135                             {
1136                               upgrades[i].ym = 0;
1137                             }
1138                           else if (upgrades[i].kind == UPGRADE_HERRING)
1139                             {
1140                               upgrades[i].ym = -24;
1141                             }
1142
1143                           upgrades[i].y = (upgrades[i].y / 32) * 32;
1144                         }
1145                     }
1146                   else
1147                     upgrades[i].ym = upgrades[i].ym + GRAVITY;
1148
1149                   if (issolid(upgrades[i].x, upgrades[i].y, 0))
1150                     {
1151                       upgrades[i].xm = -upgrades[i].xm;
1152                     }
1153                 }
1154
1155
1156               /* Off the screen?  Kill it! */
1157
1158               if (upgrades[i].x < scroll_x)
1159                 upgrades[i].alive = NO;
1160
1161
1162               /* Did the player grab it? */
1163
1164               if (tux_x + scroll_x >= upgrades[i].x - 32 &&
1165                   tux_x + scroll_x <= upgrades[i].x + 32 &&
1166                   tux_y >= upgrades[i].y - 32 &&
1167                   tux_y <= upgrades[i].y + 32)
1168                 {
1169                   /* Remove the upgrade: */
1170
1171                   upgrades[i].alive = NO;
1172
1173
1174                   /* Affect the player: */
1175
1176                   if (upgrades[i].kind == UPGRADE_MINTS)
1177                     {
1178                       play_sound(sounds[SND_EXCELLENT], SOUND_CENTER_SPEAKER);
1179                       tux_size = BIG;
1180                       super_bkgd_time = 8;
1181                     }
1182                   else if (upgrades[i].kind == UPGRADE_COFFEE)
1183                     {
1184                       play_sound(sounds[SND_COFFEE], SOUND_CENTER_SPEAKER);
1185                       tux_got_coffee = YES;
1186                       super_bkgd_time = 4;
1187                     }
1188                   else if (upgrades[i].kind == UPGRADE_HERRING)
1189                     {
1190                       play_sound(sounds[SND_HERRING], SOUND_CENTER_SPEAKER);
1191                       tux_invincible_time = TUX_INVINCIBLE_TIME;
1192                       super_bkgd_time = 4;
1193                       /* play the herring song ^^ */
1194                       current_music = HERRING_MUSIC;
1195                       if (playing_music())
1196                         halt_music();
1197                       play_music( herring_song, 1 );
1198                     }
1199                 }
1200             }
1201         }
1202     }
1203
1204
1205   /* Handle bad guys: */
1206
1207   for (i = 0; i < NUM_BAD_GUYS; i++)
1208     {
1209       if (bad_guys[i].alive)
1210         {
1211           if (bad_guys[i].seen)
1212             {
1213               if (bad_guys[i].kind == BAD_BSOD)
1214                 {
1215                   /* --- BLUE SCREEN OF DEATH MONSTER: --- */
1216
1217                   /* Move left/right: */
1218
1219                   if (bad_guys[i].dying == NO ||
1220                       bad_guys[i].dying == FALLING)
1221                     {
1222                       if (bad_guys[i].dir == RIGHT)
1223                         bad_guys[i].x = bad_guys[i].x + 4;
1224                       else if (bad_guys[i].dir == LEFT)
1225                         bad_guys[i].x = bad_guys[i].x - 4;
1226                     }
1227
1228
1229                   /* Move vertically: */
1230
1231                   bad_guys[i].y = bad_guys[i].y + bad_guys[i].ym;
1232
1233
1234                   /* Bump into things horizontally: */
1235
1236                   if (!bad_guys[i].dying)
1237                     {
1238                       if (issolid(bad_guys[i].x, bad_guys[i].y, 0))
1239                         bad_guys[i].dir = !bad_guys[i].dir;
1240                     }
1241
1242
1243                   /* Bump into other bad guys: */
1244
1245                   for (j = 0; j < NUM_BAD_GUYS; j++)
1246                     {
1247                       if (j != i && bad_guys[j].alive &&
1248                           !bad_guys[j].dying && !bad_guys[i].dying &&
1249                           bad_guys[i].x >= bad_guys[j].x - 32 &&
1250                           bad_guys[i].x <= bad_guys[j].x + 32 &&
1251                           bad_guys[i].y >= bad_guys[j].y - 32 &&
1252                           bad_guys[i].y <= bad_guys[j].y + 32)
1253                         {
1254                           bad_guys[i].dir = !bad_guys[i].dir;
1255                         }
1256                     }
1257
1258
1259                   /* Fall if we get off the ground: */
1260
1261                   if (bad_guys[i].dying != FALLING)
1262                     {
1263                       if (!issolid(bad_guys[i].x, bad_guys[i].y + 32, 0) &&
1264                           bad_guys[i].ym < MAX_YM)
1265                         {
1266                           bad_guys[i].ym = bad_guys[i].ym + GRAVITY;
1267                         }
1268                       else
1269                         {
1270                           /* Land: */
1271
1272                           if (bad_guys[i].ym > 0)
1273                             {
1274                               bad_guys[i].y = (bad_guys[i].y / 32) * 32;
1275                               bad_guys[i].ym = 0;
1276                             }
1277                         }
1278                     }
1279                   else
1280                     bad_guys[i].ym = bad_guys[i].ym + GRAVITY;
1281
1282                   if (bad_guys[i].y > 480)
1283                     bad_guys[i].alive = NO;
1284                 }
1285               else if (bad_guys[i].kind == BAD_LAPTOP)
1286                 {
1287                   /* --- LAPTOP MONSTER: --- */
1288
1289                   /* Move left/right: */
1290
1291                   if (bad_guys[i].mode != FLAT && bad_guys[i].mode != KICK)
1292                     {
1293                       if (bad_guys[i].dying == NO ||
1294                           bad_guys[i].dying == FALLING)
1295                         {
1296                           if (bad_guys[i].dir == RIGHT)
1297                             bad_guys[i].x = bad_guys[i].x + 4;
1298                           else if (bad_guys[i].dir == LEFT)
1299                             bad_guys[i].x = bad_guys[i].x - 4;
1300                         }
1301                     }
1302                   else if (bad_guys[i].mode == KICK)
1303                     {
1304                       if (bad_guys[i].dir == RIGHT)
1305                         bad_guys[i].x = bad_guys[i].x + 16;
1306                       else if (bad_guys[i].dir == LEFT)
1307                         bad_guys[i].x = bad_guys[i].x - 16;
1308                     }
1309
1310
1311                   /* Move vertically: */
1312
1313                   bad_guys[i].y = bad_guys[i].y + bad_guys[i].ym;
1314
1315
1316                   /* Bump into things horizontally: */
1317
1318                   if (!bad_guys[i].dying)
1319                     {
1320                       if (issolid(bad_guys[i].x, bad_guys[i].y, 0))
1321                         {
1322                           bad_guys[i].dir = !bad_guys[i].dir;
1323
1324                           if (bad_guys[i].mode == KICK)
1325                             {
1326                               /* handle stereo sound */
1327                               if (tux_x + scroll_x > bad_guys[i].x)
1328                                 play_sound(sounds[SND_RICOCHET], SOUND_LEFT_SPEAKER);
1329                               else if (tux_x + scroll_x < bad_guys[i].x)
1330                                 play_sound(sounds[SND_RICOCHET], SOUND_RIGHT_SPEAKER);
1331                               else
1332                                 play_sound(sounds[SND_RICOCHET], SOUND_CENTER_SPEAKER);
1333                             }
1334                         }
1335                     }
1336
1337
1338                   /* Bump into other bad guys: */
1339
1340                   for (j = 0; j < NUM_BAD_GUYS; j++)
1341                     {
1342                       if (j != i && bad_guys[j].alive &&
1343                           !bad_guys[j].dying && !bad_guys[i].dying &&
1344                           bad_guys[i].x >= bad_guys[j].x - 32 &&
1345                           bad_guys[i].x <= bad_guys[j].x + 32 &&
1346                           bad_guys[i].y >= bad_guys[j].y - 32 &&
1347                           bad_guys[i].y <= bad_guys[j].y + 32)
1348                         {
1349                           if (bad_guys[i].mode != KICK)
1350                             bad_guys[i].dir = !bad_guys[i].dir;
1351                           else
1352                             {
1353                               /* We're in kick mode, kill the other guy: */
1354
1355                               bad_guys[j].dying = FALLING;
1356                               bad_guys[j].ym = -8;
1357                               play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
1358
1359                               add_score(bad_guys[i].x - scroll_x,
1360                                         bad_guys[i].y, 100);
1361                             }
1362                         }
1363                     }
1364
1365
1366                   /* Fall if we get off the ground: */
1367
1368                   if (bad_guys[i].dying != FALLING)
1369                     {
1370                       if (!issolid(bad_guys[i].x, bad_guys[i].y + 32, 0) &&
1371                           bad_guys[i].ym < MAX_YM)
1372                         {
1373                           bad_guys[i].ym = bad_guys[i].ym + GRAVITY;
1374                         }
1375                       else
1376                         {
1377                           /* Land: */
1378
1379                           if (bad_guys[i].ym > 0)
1380                             {
1381                               bad_guys[i].y = (bad_guys[i].y / 32) * 32;
1382                               bad_guys[i].ym = 0;
1383                             }
1384                         }
1385                     }
1386                   else
1387                     bad_guys[i].ym = bad_guys[i].ym + GRAVITY;
1388
1389                   if (bad_guys[i].y > 480)
1390                     bad_guys[i].alive = NO;
1391                 }
1392               else if (bad_guys[i].kind == BAD_MONEY)
1393                 {
1394                   /* --- MONEY BAGS: --- */
1395
1396
1397                   /* Move vertically: */
1398
1399                   bad_guys[i].y = bad_guys[i].y + bad_guys[i].ym;
1400
1401
1402                   /* Fall if we get off the ground: */
1403
1404                   if (bad_guys[i].dying != FALLING)
1405                     {
1406                       if (!issolid(bad_guys[i].x, bad_guys[i].y + 32, 0))
1407                         {
1408                           if (bad_guys[i].ym < MAX_YM)
1409                             {
1410                               bad_guys[i].ym = bad_guys[i].ym + GRAVITY;
1411                             }
1412                         }
1413                       else
1414                         {
1415                           /* Land: */
1416
1417                           if (bad_guys[i].ym > 0)
1418                             {
1419                               bad_guys[i].y = (bad_guys[i].y / 32) * 32;
1420                               bad_guys[i].ym = -MAX_YM;
1421                             }
1422                         }
1423                     }
1424                   else
1425                     bad_guys[i].ym = bad_guys[i].ym + GRAVITY;
1426
1427                   if (bad_guys[i].y > 480)
1428                     bad_guys[i].alive = NO;
1429                 }
1430               else if (bad_guys[i].kind == -1)
1431               {}
1432
1433
1434               /* Kill it if the player jumped on it: */
1435
1436               if (!bad_guys[i].dying && !tux_dying && !tux_safe &&
1437                   tux_x + scroll_x >= bad_guys[i].x - 32 &&
1438                   tux_x + scroll_x <= bad_guys[i].x + 32 &&
1439                   tux_y >= bad_guys[i].y - 32 &&
1440                   tux_y <= bad_guys[i].y - 8
1441                   /* &&
1442                   tux_ym >= 0 */)
1443                 {
1444                   if (bad_guys[i].kind == BAD_BSOD)
1445                     {
1446                       bad_guys[i].dying = SQUISHED;
1447                       bad_guys[i].timer = 16;
1448                       tux_ym = -KILL_BOUNCE_YM;
1449
1450                       add_score(bad_guys[i].x - scroll_x, bad_guys[i].y,
1451                                 50 * score_multiplier);
1452
1453                       play_sound(sounds[SND_SQUISH], SOUND_CENTER_SPEAKER);
1454                     }
1455                   else if (bad_guys[i].kind == BAD_LAPTOP)
1456                     {
1457                       if (bad_guys[i].mode != FLAT)
1458                         {
1459                           /* Flatten! */
1460
1461                           play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER);
1462                           bad_guys[i].mode = FLAT;
1463
1464                           bad_guys[i].timer = 64;
1465
1466                           tux_y = tux_y - 32;
1467                         }
1468                       else
1469                         {
1470                           /* Kick! */
1471
1472                           bad_guys[i].mode = KICK;
1473                           play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
1474
1475                           if (tux_x + scroll_x <= bad_guys[i].x)
1476                             bad_guys[i].dir = RIGHT;
1477                           else
1478                             bad_guys[i].dir = LEFT;
1479
1480                           bad_guys[i].timer = 8;
1481                         }
1482
1483                       tux_ym = -KILL_BOUNCE_YM;
1484
1485                       add_score(bad_guys[i].x - scroll_x,
1486                                 bad_guys[i].y,
1487                                 25 * score_multiplier);
1488
1489                       /* play_sound(sounds[SND_SQUISH]); */
1490                     }
1491                   else if (bad_guys[i].kind == -1)
1492                   {}
1493
1494                   score_multiplier++;
1495                 }
1496
1497
1498               /* Hurt the player if he just touched it: */
1499
1500               if (!bad_guys[i].dying && !tux_dying &&
1501                   !tux_safe &&
1502                   tux_x + scroll_x >= bad_guys[i].x - 32 &&
1503                   tux_x + scroll_x <= bad_guys[i].x + 32 &&
1504                   tux_y >= bad_guys[i].y - 32 &&
1505                   tux_y <= bad_guys[i].y + 32)
1506                 {
1507                   if (bad_guys[i].mode == FLAT)
1508                     {
1509                       /* Kick: */
1510
1511                       bad_guys[i].mode = KICK;
1512                       play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
1513
1514                       if (tux_x + scroll_x <= bad_guys[i].x)
1515                         {
1516                           bad_guys[i].dir = RIGHT;
1517                           bad_guys[i].x = bad_guys[i].x + 16;
1518                         }
1519                       else
1520                         {
1521                           bad_guys[i].dir = LEFT;
1522                           bad_guys[i].x = bad_guys[i].x - 16;
1523                         }
1524
1525                       bad_guys[i].timer = 8;
1526                     }
1527                   else if (bad_guys[i].mode == KICK)
1528                     {
1529                       if (tux_y < bad_guys[i].y - 16 &&
1530                           bad_guys[i].timer == 0)
1531                         {
1532                           /* Step on (stop being kicked) */
1533
1534                           bad_guys[i].mode = FLAT;
1535                           play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER);
1536                           bad_guys[i].timer = 64;
1537                         }
1538                       else
1539                         {
1540                           /* Hurt if you get hit by kicked laptop: */
1541
1542                           if (bad_guys[i].timer == 0)
1543                             {
1544                               if (tux_invincible_time == 0)
1545                                 {
1546                                   killtux(SHRINK);
1547                                 }
1548                               else
1549                                 {
1550                                   bad_guys[i].dying = FALLING;
1551                                   bad_guys[i].ym = -8;
1552                                   play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
1553                                 }
1554                             }
1555                         }
1556                     }
1557                   else
1558                     {
1559                       if (tux_invincible_time == 0)
1560                         {
1561                           killtux(SHRINK);
1562                         }
1563                       else
1564                         {
1565                           bad_guys[i].dying = FALLING;
1566                           bad_guys[i].ym = -8;
1567                           play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
1568                         }
1569                     }
1570                 }
1571
1572
1573               /* Handle mode timer: */
1574
1575               if (bad_guys[i].mode == FLAT)
1576                 {
1577                   bad_guys[i].timer--;
1578
1579                   if (bad_guys[i].timer <= 0)
1580                     bad_guys[i].mode = NORMAL;
1581                 }
1582               else if (bad_guys[i].mode == KICK)
1583                 {
1584                   if (bad_guys[i].timer > 0)
1585                     bad_guys[i].timer--;
1586                 }
1587
1588
1589               /* Handle dying timer: */
1590
1591               if (bad_guys[i].dying == SQUISHED)
1592                 {
1593                   bad_guys[i].timer--;
1594
1595
1596                   /* Remove it if time's up: */
1597
1598                   if (bad_guys[i].timer <= 0)
1599                     bad_guys[i].alive = NO;
1600                 }
1601
1602
1603               /* Remove if it's far off the screen: */
1604
1605               if (bad_guys[i].x < scroll_x - OFFSCREEN_DISTANCE)
1606                 bad_guys[i].alive = NO;
1607             }
1608           else /* !seen */
1609             {
1610               /* Once it's on screen, it's activated! */
1611
1612               if (bad_guys[i].x <= scroll_x + 640 + OFFSCREEN_DISTANCE)
1613                 bad_guys[i].seen = YES;
1614             }
1615         }
1616     }
1617
1618
1619   /* Handle skidding: */
1620
1621   if (tux_skidding > 0)
1622     {
1623       tux_skidding--;
1624     }
1625
1626   return -1;
1627 }
1628
1629 /* --- GAME DRAW! --- */
1630
1631 void game_draw()
1632 {
1633   int  x, y, i;
1634
1635   /* Draw screen: */
1636
1637   if (tux_dying && (frame % 4) == 0)
1638     clearscreen(255, 255, 255);
1639   else
1640     {
1641       if (super_bkgd_time == 0)
1642         clearscreen(bkgd_red, bkgd_green, bkgd_blue);
1643       else
1644         drawimage(img_super_bkgd, 0, 0, NO_UPDATE);
1645     }
1646
1647
1648   /* Draw background: */
1649
1650   for (y = 0; y < 15; y++)
1651     {
1652       for (x = 0; x < 21; x++)
1653         {
1654           drawshape(x * 32 - (scroll_x % 32), y * 32,
1655                     tiles[y][x + (scroll_x / 32)]);
1656         }
1657     }
1658
1659
1660   /* (Bouncy bricks): */
1661
1662   for (i = 0; i < NUM_BOUNCY_BRICKS; i++)
1663     {
1664       if (bouncy_bricks[i].alive)
1665         {
1666           if (bouncy_bricks[i].x >= scroll_x - 32 &&
1667               bouncy_bricks[i].x <= scroll_x + 640)
1668             {
1669               dest.x = bouncy_bricks[i].x - scroll_x;
1670               dest.y = bouncy_bricks[i].y;
1671               dest.w = 32;
1672               dest.h = 32;
1673
1674               SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format,
1675                                                      bkgd_red,
1676                                                      bkgd_green,
1677                                                      bkgd_blue));
1678
1679               drawshape(bouncy_bricks[i].x - scroll_x,
1680                         bouncy_bricks[i].y + bouncy_bricks[i].offset,
1681                         bouncy_bricks[i].shape);
1682             }
1683         }
1684     }
1685
1686
1687   /* (Bad guys): */
1688
1689   for (i = 0; i < NUM_BAD_GUYS; i++)
1690     {
1691       if (bad_guys[i].alive &&
1692           bad_guys[i].x > scroll_x - 32 &&
1693           bad_guys[i].x < scroll_x + 640)
1694         {
1695           if (bad_guys[i].kind == BAD_BSOD)
1696             {
1697               /* --- BLUE SCREEN OF DEATH MONSTER: --- */
1698
1699               if (bad_guys[i].dying == NO)
1700                 {
1701                   /* Alive: */
1702
1703                   if (bad_guys[i].dir == LEFT)
1704                     {
1705                       drawimage(img_bsod_left[(frame / 5) % 4],
1706                                 bad_guys[i].x - scroll_x,
1707                                 bad_guys[i].y,
1708                                 NO_UPDATE);
1709                     }
1710                   else
1711                     {
1712                       drawimage(img_bsod_right[(frame / 5) % 4],
1713                                 bad_guys[i].x - scroll_x,
1714                                 bad_guys[i].y,
1715                                 NO_UPDATE);
1716                     }
1717                 }
1718               else if (bad_guys[i].dying == FALLING)
1719                 {
1720                   /* Falling: */
1721
1722                   if (bad_guys[i].dir == LEFT)
1723                     {
1724                       drawimage(img_bsod_falling_left,
1725                                 bad_guys[i].x - scroll_x,
1726                                 bad_guys[i].y,
1727                                 NO_UPDATE);
1728                     }
1729                   else
1730                     {
1731                       drawimage(img_bsod_falling_right,
1732                                 bad_guys[i].x - scroll_x,
1733                                 bad_guys[i].y,
1734                                 NO_UPDATE);
1735                     }
1736                 }
1737               else if (bad_guys[i].dying == SQUISHED)
1738                 {
1739                   /* Dying - Squished: */
1740
1741                   if (bad_guys[i].dir == LEFT)
1742                     {
1743                       drawimage(img_bsod_squished_left,
1744                                 bad_guys[i].x - scroll_x,
1745                                 bad_guys[i].y + 24,
1746                                 NO_UPDATE);
1747                     }
1748                   else
1749                     {
1750                       drawimage(img_bsod_squished_right,
1751                                 bad_guys[i].x - scroll_x,
1752                                 bad_guys[i].y + 24,
1753                                 NO_UPDATE);
1754                     }
1755                 }
1756             }
1757           else if (bad_guys[i].kind == BAD_LAPTOP)
1758             {
1759               /* --- LAPTOP MONSTER: --- */
1760
1761               if (bad_guys[i].dying == NO)
1762                 {
1763                   /* Alive: */
1764
1765                   if (bad_guys[i].mode == NORMAL)
1766                     {
1767                       /* Not flat: */
1768
1769                       if (bad_guys[i].dir == LEFT)
1770                         {
1771                           drawimage(img_laptop_left[(frame / 5) % 3],
1772                                     bad_guys[i].x - scroll_x,
1773                                     bad_guys[i].y,
1774                                     NO_UPDATE);
1775                         }
1776                       else
1777                         {
1778                           drawimage(img_laptop_right[(frame / 5) % 3],
1779                                     bad_guys[i].x - scroll_x,
1780                                     bad_guys[i].y,
1781                                     NO_UPDATE);
1782                         }
1783                     }
1784                   else
1785                     {
1786                       /* Flat: */
1787
1788                       if (bad_guys[i].dir == LEFT)
1789                         {
1790                           drawimage(img_laptop_flat_left,
1791                                     bad_guys[i].x - scroll_x,
1792                                     bad_guys[i].y,
1793                                     NO_UPDATE);
1794                         }
1795                       else
1796                         {
1797                           drawimage(img_laptop_flat_right,
1798                                     bad_guys[i].x - scroll_x,
1799                                     bad_guys[i].y,
1800                                     NO_UPDATE);
1801                         }
1802                     }
1803                 }
1804               else if (bad_guys[i].dying == FALLING)
1805                 {
1806                   /* Falling: */
1807
1808                   if (bad_guys[i].dir == LEFT)
1809                     {
1810                       drawimage(img_laptop_falling_left,
1811                                 bad_guys[i].x - scroll_x,
1812                                 bad_guys[i].y,
1813                                 NO_UPDATE);
1814                     }
1815                   else
1816                     {
1817                       drawimage(img_laptop_falling_right,
1818                                 bad_guys[i].x - scroll_x,
1819                                 bad_guys[i].y,
1820                                 NO_UPDATE);
1821                     }
1822                 }
1823             }
1824           else if (bad_guys[i].kind == BAD_MONEY)
1825             {
1826               if (bad_guys[i].ym > -16)
1827                 {
1828                   if (bad_guys[i].dir == LEFT)
1829                     {
1830                       drawimage(img_money_left[0],
1831                                 bad_guys[i].x - scroll_x,
1832                                 bad_guys[i].y,
1833                                 NO_UPDATE);
1834                     }
1835                   else
1836                     {
1837                       drawimage(img_money_right[0],
1838                                 bad_guys[i].x - scroll_x,
1839                                 bad_guys[i].y,
1840                                 NO_UPDATE);
1841                     }
1842                 }
1843               else
1844                 {
1845                   if (bad_guys[i].dir == LEFT)
1846                     {
1847                       drawimage(img_money_left[1],
1848                                 bad_guys[i].x - scroll_x,
1849                                 bad_guys[i].y,
1850                                 NO_UPDATE);
1851                     }
1852                   else
1853                     {
1854                       drawimage(img_money_right[1],
1855                                 bad_guys[i].x - scroll_x,
1856                                 bad_guys[i].y,
1857                                 NO_UPDATE);
1858                     }
1859                 }
1860             }
1861           else if (bad_guys[i].kind == -1)
1862           {}
1863         }
1864     }
1865
1866
1867   /* (Tux): */
1868
1869   if (right == UP && left == UP)
1870     {
1871       tux_frame_main = 1;
1872       tux_frame = 1;
1873     }
1874   else
1875     {
1876       if ((fire == DOWN && (frame % 2) == 0) ||
1877           (frame % 4) == 0)
1878         tux_frame_main = (tux_frame_main + 1) % 4;
1879
1880       tux_frame = tux_frame_main;
1881
1882       if (tux_frame == 3)
1883         tux_frame = 1;
1884     }
1885
1886
1887   if (tux_safe == 0 || (frame % 2) == 0)
1888     {
1889       if (tux_size == SMALL)
1890         {
1891           if (tux_invincible_time)
1892             {
1893               /* Draw cape: */
1894
1895               if (tux_dir == RIGHT)
1896                 {
1897                   drawimage(cape_right[frame % 2],
1898                             tux_x, tux_y,
1899                             NO_UPDATE);
1900                 }
1901               else
1902                 {
1903                   drawimage(cape_left[frame % 2],
1904                             tux_x, tux_y,
1905                             NO_UPDATE);
1906                 }
1907             }
1908
1909
1910           if (!tux_got_coffee)
1911             {
1912               if (tux_dir == RIGHT)
1913                 {
1914                   drawimage(tux_right[tux_frame], tux_x, tux_y, NO_UPDATE);
1915                 }
1916               else
1917                 {
1918                   drawimage(tux_left[tux_frame], tux_x, tux_y, NO_UPDATE);
1919                 }
1920             }
1921           else
1922             {
1923               /* Tux got coffee! */
1924
1925               if (tux_dir == RIGHT)
1926                 {
1927                   drawimage(firetux_right[tux_frame], tux_x, tux_y, NO_UPDATE);
1928                 }
1929               else
1930                 {
1931                   drawimage(firetux_left[tux_frame], tux_x, tux_y, NO_UPDATE);
1932                 }
1933             }
1934         }
1935       else
1936         {
1937           if (tux_invincible_time)
1938             {
1939               /* Draw cape: */
1940
1941               if (tux_dir == RIGHT)
1942                 {
1943                   drawimage(bigcape_right[frame % 2],
1944                             tux_x - 8 - 16, tux_y - 32,
1945                             NO_UPDATE);
1946                 }
1947               else
1948                 {
1949                   drawimage(bigcape_left[frame % 2],
1950                             tux_x - 8, tux_y - 32,
1951                             NO_UPDATE);
1952                 }
1953             }
1954
1955           if (!tux_got_coffee)
1956             {
1957               if (!tux_duck)
1958                 {
1959                   if (!tux_skidding)
1960                     {
1961                       if (!jumping || tux_ym > 0)
1962                         {
1963                           if (tux_dir == RIGHT)
1964                             {
1965                               drawimage(bigtux_right[tux_frame],
1966                                         tux_x - 8, tux_y - 32,
1967                                         NO_UPDATE);
1968                             }
1969                           else
1970                             {
1971                               drawimage(bigtux_left[tux_frame],
1972                                         tux_x - 8, tux_y - 32,
1973                                         NO_UPDATE);
1974                             }
1975                         }
1976                       else
1977                         {
1978                           if (tux_dir == RIGHT)
1979                             {
1980                               drawimage(bigtux_right_jump,
1981                                         tux_x - 8, tux_y - 32,
1982                                         NO_UPDATE);
1983                             }
1984                           else
1985                             {
1986                               drawimage(bigtux_left_jump,
1987                                         tux_x - 8, tux_y - 32,
1988                                         NO_UPDATE);
1989                             }
1990                         }
1991                     }
1992                   else
1993                     {
1994                       if (tux_dir == RIGHT)
1995                         {
1996                           drawimage(skidtux_right,
1997                                     tux_x - 8, tux_y - 32,
1998                                     NO_UPDATE);
1999                         }
2000                       else
2001                         {
2002                           drawimage(skidtux_left,
2003                                     tux_x - 8, tux_y - 32,
2004                                     NO_UPDATE);
2005                         }
2006                     }
2007                 }
2008               else
2009                 {
2010                   if (tux_dir == RIGHT)
2011                     {
2012                       drawimage(ducktux_right, tux_x - 8, tux_y - 16,
2013                                 NO_UPDATE);
2014                     }
2015                   else
2016                     {
2017                       drawimage(ducktux_left, tux_x - 8, tux_y - 16,
2018                                 NO_UPDATE);
2019                     }
2020                 }
2021             }
2022           else
2023             {
2024               /* Tux has coffee! */
2025
2026               if (!tux_duck)
2027                 {
2028                   if (!tux_skidding)
2029                     {
2030                       if (!jumping || tux_ym > 0)
2031                         {
2032                           if (tux_dir == RIGHT)
2033                             {
2034                               drawimage(bigfiretux_right[tux_frame],
2035                                         tux_x - 8, tux_y - 32,
2036                                         NO_UPDATE);
2037                             }
2038                           else
2039                             {
2040                               drawimage(bigfiretux_left[tux_frame],
2041                                         tux_x - 8, tux_y - 32,
2042                                         NO_UPDATE);
2043                             }
2044                         }
2045                       else
2046                         {
2047                           if (tux_dir == RIGHT)
2048                             {
2049                               drawimage(bigfiretux_right_jump,
2050                                         tux_x - 8, tux_y - 32,
2051                                         NO_UPDATE);
2052                             }
2053                           else
2054                             {
2055                               drawimage(bigfiretux_left_jump,
2056                                         tux_x - 8, tux_y - 32,
2057                                         NO_UPDATE);
2058                             }
2059                         }
2060                     }
2061                   else
2062                     {
2063                       if (tux_dir == RIGHT)
2064                         {
2065                           drawimage(skidfiretux_right,
2066                                     tux_x - 8, tux_y - 32,
2067                                     NO_UPDATE);
2068                         }
2069                       else
2070                         {
2071                           drawimage(skidfiretux_left,
2072                                     tux_x - 8, tux_y - 32,
2073                                     NO_UPDATE);
2074                         }
2075                     }
2076                 }
2077               else
2078                 {
2079                   if (tux_dir == RIGHT)
2080                     {
2081                       drawimage(duckfiretux_right, tux_x - 8, tux_y - 16,
2082                                 NO_UPDATE);
2083                     }
2084                   else
2085                     {
2086                       drawimage(duckfiretux_left, tux_x - 8, tux_y - 16,
2087                                 NO_UPDATE);
2088                     }
2089                 }
2090             }
2091         }
2092     }
2093
2094
2095   /* (Bullets): */
2096
2097   for (i = 0; i < NUM_BULLETS; i++)
2098     {
2099       if (bullets[i].alive &&
2100           bullets[i].x >= scroll_x - 4 &&
2101           bullets[i].x <= scroll_x + 640)
2102         {
2103           drawimage(img_bullet, bullets[i].x - scroll_x, bullets[i].y,
2104                     NO_UPDATE);
2105         }
2106     }
2107
2108
2109   /* (Floating scores): */
2110
2111   for (i = 0; i < NUM_FLOATING_SCORES; i++)
2112     {
2113       if (floating_scores[i].alive)
2114         {
2115           sprintf(str, "%d", floating_scores[i].value);
2116           drawtext(str,
2117                    floating_scores[i].x + 16 - strlen(str) * 8,
2118                    floating_scores[i].y,
2119                    letters_gold, NO_UPDATE, 1);
2120         }
2121     }
2122
2123
2124   /* (Upgrades): */
2125
2126   for (i = 0; i < NUM_UPGRADES; i++)
2127     {
2128       if (upgrades[i].alive)
2129         {
2130           if (upgrades[i].height < 32)
2131             {
2132               /* Rising up... */
2133
2134               dest.x = upgrades[i].x - scroll_x;
2135               dest.y = upgrades[i].y + 32 - upgrades[i].height;
2136               dest.w = 32;
2137               dest.h = upgrades[i].height;
2138
2139               src.x = 0;
2140               src.y = 0;
2141               src.w = 32;
2142               src.h = upgrades[i].height;
2143
2144               if (upgrades[i].kind == UPGRADE_MINTS)
2145                 SDL_BlitSurface(img_mints, &src, screen, &dest);
2146               else if (upgrades[i].kind == UPGRADE_COFFEE)
2147                 SDL_BlitSurface(img_coffee, &src, screen, &dest);
2148               else if (upgrades[i].kind == UPGRADE_HERRING)
2149                 SDL_BlitSurface(img_golden_herring, &src, screen, &dest);
2150             }
2151           else
2152             {
2153               if (upgrades[i].kind == UPGRADE_MINTS)
2154                 {
2155                   drawimage(img_mints,
2156                             upgrades[i].x - scroll_x, upgrades[i].y,
2157                             NO_UPDATE);
2158                 }
2159               else if (upgrades[i].kind == UPGRADE_COFFEE)
2160                 {
2161                   drawimage(img_coffee,
2162                             upgrades[i].x - scroll_x, upgrades[i].y,
2163                             NO_UPDATE);
2164                 }
2165               else if (upgrades[i].kind == UPGRADE_HERRING)
2166                 {
2167                   drawimage(img_golden_herring,
2168                             upgrades[i].x - scroll_x, upgrades[i].y,
2169                             NO_UPDATE);
2170                 }
2171             }
2172         }
2173     }
2174
2175
2176   /* (Bouncy distros): */
2177
2178   for (i = 0; i < NUM_BOUNCY_DISTROS; i++)
2179     {
2180       if (bouncy_distros[i].alive)
2181         {
2182           drawimage(img_distro[0],
2183                     bouncy_distros[i].x - scroll_x,
2184                     bouncy_distros[i].y,
2185                     NO_UPDATE);
2186         }
2187     }
2188
2189
2190   /* (Broken bricks): */
2191
2192   for (i = 0; i < NUM_BROKEN_BRICKS; i++)
2193     {
2194       if (broken_bricks[i].alive)
2195         {
2196           src.x = rand() % 16;
2197           src.y = rand() % 16;
2198           src.w = 16;
2199           src.h = 16;
2200
2201           dest.x = broken_bricks[i].x - scroll_x;
2202           dest.y = broken_bricks[i].y;
2203           dest.w = 16;
2204           dest.h = 16;
2205
2206           SDL_BlitSurface(img_brick[0], &src, screen, &dest);
2207         }
2208     }
2209
2210
2211   /* (Status): */
2212
2213   sprintf(str, "%d", score);
2214   drawtext("SCORE", 0, 0, letters_blue, NO_UPDATE, 1);
2215   drawtext(str, 96, 0, letters_gold, NO_UPDATE, 1);
2216
2217   sprintf(str, "%d", highscore);
2218   drawtext("HIGH", 0, 20, letters_blue, NO_UPDATE, 1);
2219   drawtext(str, 96, 20, letters_gold, NO_UPDATE, 1);
2220
2221   if (time_left >= TIME_WARNING || (frame % 10) < 5)
2222     {
2223       sprintf(str, "%d", time_left);
2224       drawtext("TIME", 224, 0, letters_blue, NO_UPDATE, 1);
2225       drawtext(str, 304, 0, letters_gold, NO_UPDATE, 1);
2226     }
2227
2228   sprintf(str, "%d", distros);
2229   drawtext("DISTROS", 480, 0, letters_blue, NO_UPDATE, 1);
2230   drawtext(str, 608, 0, letters_gold, NO_UPDATE, 1);
2231
2232   drawtext("LIVES", 480, 20, letters_blue, NO_UPDATE, 1);
2233
2234   for(i=0; i < lives; ++i)
2235     {
2236       drawimage(tux_life,565+(18*i),20,NO_UPDATE);
2237     }
2238
2239   if(game_pause)
2240     drawcenteredtext("PAUSE",230,letters_red, NO_UPDATE, 1);
2241
2242   if(show_menu)
2243     done = drawmenu();
2244
2245   /* (Update it all!) */
2246
2247   updatescreen();
2248
2249
2250 }
2251
2252 /* --- GAME LOOP! --- */
2253
2254 int gameloop(void)
2255 {
2256
2257   Uint32 last_time, now_time;
2258
2259   /* Clear screen: */
2260
2261   clearscreen(0, 0, 0);
2262   updatescreen();
2263
2264
2265   /* Init the game: */
2266
2267   initmenu();
2268   menumenu = MENU_GAME;
2269   initgame();
2270   loadshared();
2271   
2272   tux_size = SMALL;
2273   tux_got_coffee = NO;
2274
2275   loadlevel();
2276   loadlevelgfx();
2277   loadlevelsong();
2278   highscore = load_hs();
2279
2280
2281   /* --- MAIN GAME LOOP!!! --- */
2282
2283   done = 0;
2284   quit = 0;
2285   frame = 0;
2286   tux_frame_main = 0;
2287   tux_frame = 0;
2288   game_pause = 0;
2289
2290   game_draw();
2291   do
2292     {
2293       last_time = SDL_GetTicks();
2294       frame++;
2295
2296
2297       /* Handle events: */
2298
2299       old_fire = fire;
2300
2301       game_event();
2302
2303       /* Handle actions: */
2304
2305       if(!game_pause && !show_menu)
2306         {
2307           if (game_action() == 0)
2308             {
2309               /* == 0: no more lives */
2310               /* == -1: continues */
2311               return 0;
2312             }
2313         }
2314       else
2315         SDL_Delay(50);
2316
2317       /*Draw the current scene to the screen */
2318       game_draw();
2319
2320       /* Keep playing music: */
2321
2322
2323       if (!playing_music())
2324         {
2325           switch (current_music)
2326             {
2327             case LEVEL_MUSIC:
2328               if (time_left <= TIME_WARNING)
2329                 play_music(level_song_fast, 1);
2330               else
2331                 play_music(level_song, 1);
2332               break;
2333             case HERRING_MUSIC:
2334               play_music(herring_song, 1);
2335               break;
2336             case HURRYUP_MUSIC: // keep the compiler happy
2337             case NO_MUSIC:      // keep the compiler happy for the moment :-)
2338             {}
2339               /*default:*/
2340             }
2341         }
2342
2343       /* Time stops in pause mode */
2344       if(game_pause || show_menu )
2345         {
2346           continue;
2347         }
2348
2349       /* Pause til next frame: */
2350
2351       now_time = SDL_GetTicks();
2352       if (now_time < last_time + FPS)
2353         SDL_Delay(last_time + FPS - now_time);
2354
2355
2356       /* Handle time: */
2357
2358       if ((frame % 10) == 0 && time_left > 0)
2359         {
2360           time_left--;
2361
2362           /* Stop the music; it will start again, faster! */
2363           if (time_left == TIME_WARNING)
2364             halt_music();
2365
2366           if (time_left <= 0)
2367             killtux(KILL);
2368         }
2369     }
2370   while (!done && !quit);
2371
2372   if (playing_music())
2373     halt_music();
2374
2375   unloadlevelgfx();
2376   unloadlevelsong();
2377   unloadshared();
2378
2379   return(quit);
2380 }
2381
2382
2383 /* Initialize the game stuff: */
2384
2385 void initgame(void)
2386 {
2387   level = 1;
2388   score = 0;
2389   distros = 0;
2390   lives = 3;
2391 }
2392
2393
2394
2395 /* Load data for this level: */
2396
2397 void loadlevel(void)
2398 {
2399   int i, x, y;
2400   FILE * fi;
2401   char * filename;
2402   char str[80];
2403   char * line;
2404
2405
2406   /* Reset arrays: */
2407
2408   for (i = 0; i < NUM_BOUNCY_DISTROS; i++)
2409     bouncy_distros[i].alive = NO;
2410
2411   for (i = 0; i < NUM_BROKEN_BRICKS; i++)
2412     broken_bricks[i].alive = NO;
2413
2414   for (i = 0; i < NUM_BOUNCY_BRICKS; i++)
2415     bouncy_bricks[i].alive = NO;
2416
2417   for (i = 0; i < NUM_BAD_GUYS; i++)
2418     bad_guys[i].alive = NO;
2419
2420   for (i = 0; i < NUM_FLOATING_SCORES; i++)
2421     floating_scores[i].alive = NO;
2422
2423   for (i = 0; i < NUM_UPGRADES; i++)
2424     upgrades[i].alive = NO;
2425
2426   for (i = 0; i < NUM_BULLETS; i++)
2427     bullets[i].alive = NO;
2428
2429
2430   /* Load data file: */
2431
2432   filename = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) + 20));
2433   sprintf(filename, "%s/levels/level%d.dat", DATA_PREFIX, level);
2434   fi = fopen(filename, "r");
2435   if (fi == NULL)
2436     {
2437       perror(filename);
2438       st_shutdown();
2439       free(filename);
2440       exit(-1);
2441     }
2442   free(filename);
2443
2444
2445   /* Load header info: */
2446
2447
2448   /* (Level title) */
2449   fgets(str, 20, fi);
2450   strcpy(levelname, str);
2451   levelname[strlen(levelname)-1] = '\0';
2452
2453   /* (Level theme) */
2454   fgets(str, 20, fi);
2455   strcpy(leveltheme, str);
2456   leveltheme[strlen(leveltheme)-1] = '\0';
2457
2458
2459
2460   /* (Time to beat level) */
2461   fgets(str, 10, fi);
2462   time_left = atoi(str);
2463
2464   /* (Song file for this level) */
2465   fgets(str, sizeof(song_title), fi);
2466   strcpy(song_title, str);
2467   song_title[strlen(song_title)-1] = '\0';
2468
2469
2470
2471   /* (Level background color) */
2472   fgets(str, 10, fi);
2473   bkgd_red = atoi(str);
2474   fgets(str, 10, fi);
2475   bkgd_green= atoi(str);
2476   fgets(str, 10, fi);
2477   bkgd_blue = atoi(str);
2478
2479   /* (Level width) */
2480   fgets(str, 10, fi);
2481   level_width = atoi(str);
2482
2483
2484   /* Allocate some space for the line-reading! */
2485
2486   line = (char *) malloc(sizeof(char) * (level_width + 5));
2487   if (line == NULL)
2488     {
2489       fprintf(stderr, "Couldn't allocate space to load level data!");
2490       exit(1);
2491     }
2492
2493
2494   /* Load the level lines: */
2495
2496   for (y = 0; y < 15; y++)
2497     {
2498       if(fgets(line, level_width + 5, fi) == NULL)
2499         {
2500           fprintf(stderr, "Level %s isn't complete!\n",levelname);
2501           exit(1);
2502         }
2503       line[strlen(line) - 1] = '\0';
2504       tiles[y] = strdup(line);
2505     }
2506
2507   fclose(fi);
2508
2509
2510   /* Activate bad guys: */
2511
2512   for (y = 0; y < 15; y++)
2513     {
2514       for (x = 0; x < level_width; x++)
2515         {
2516           if (tiles[y][x] >= '0' && tiles[y][x] <= '9')
2517             {
2518               add_bad_guy(x * 32, y * 32, tiles[y][x] - '0');
2519               tiles[y][x] = '.';
2520             }
2521         }
2522     }
2523
2524
2525   /* Set defaults: */
2526
2527   tux_x = 0;
2528   tux_xm = 0;
2529   tux_y = 240;
2530   tux_ym = 0;
2531   tux_dir = RIGHT;
2532   tux_invincible_time = 0;
2533   tux_duck = NO;
2534
2535   tux_dying = NO;
2536   tux_safe = TUX_SAFE_TIME;
2537
2538   jumping = NO;
2539   jump_counter = 0;
2540
2541   tux_skidding = 0;
2542
2543   scroll_x = 0;
2544
2545   right = UP;
2546   left = UP;
2547   up = UP;
2548   down = UP;
2549   fire = UP;
2550   old_fire = UP;
2551
2552   score_multiplier = 1;
2553   super_bkgd_time = 0;
2554
2555   counting_distros = NO;
2556   distro_counter = 0;
2557
2558   endpos = 0;
2559
2560   /* set current song/music */
2561   current_music = LEVEL_MUSIC;
2562
2563   /* Level Intro: */
2564
2565   clearscreen(0, 0, 0);
2566
2567   sprintf(str, "LEVEL %d", level);
2568   drawcenteredtext(str, 200, letters_red, NO_UPDATE, 1);
2569
2570   sprintf(str, "%s", levelname);
2571   drawcenteredtext(str, 224, letters_gold, NO_UPDATE, 1);
2572
2573   sprintf(str, "TUX x %d", lives);
2574   drawcenteredtext(str, 256, letters_blue, NO_UPDATE, 1);
2575
2576   SDL_Flip(screen);
2577
2578   SDL_Delay(1000);
2579
2580
2581 }
2582
2583
2584 /* Load a level-specific graphic... */
2585
2586 SDL_Surface * load_level_image(char * file, int use_alpha)
2587 {
2588   char fname[1024];
2589
2590   snprintf(fname, 1024, "%s/images/themes/%s/%s", DATA_PREFIX, leveltheme, file);
2591
2592   return(load_image(fname, use_alpha));
2593 }
2594
2595
2596 /* Load graphics: */
2597
2598 void loadlevelgfx(void)
2599 {
2600   img_brick[0] = load_level_image("brick0.png", IGNORE_ALPHA);
2601   img_brick[1] = load_level_image("brick1.png", IGNORE_ALPHA);
2602
2603   img_solid[0] = load_level_image("solid0.png", USE_ALPHA);
2604   img_solid[1] = load_level_image("solid1.png", USE_ALPHA);
2605   img_solid[2] = load_level_image("solid2.png", USE_ALPHA);
2606   img_solid[3] = load_level_image("solid3.png", USE_ALPHA);
2607
2608   img_bkgd[0][0] = load_level_image("bkgd-00.png", USE_ALPHA);
2609   img_bkgd[0][1] = load_level_image("bkgd-01.png", USE_ALPHA);
2610   img_bkgd[0][2] = load_level_image("bkgd-02.png", USE_ALPHA);
2611   img_bkgd[0][3] = load_level_image("bkgd-03.png", USE_ALPHA);
2612
2613   img_bkgd[1][0] = load_level_image("bkgd-10.png", USE_ALPHA);
2614   img_bkgd[1][1] = load_level_image("bkgd-11.png", USE_ALPHA);
2615   img_bkgd[1][2] = load_level_image("bkgd-12.png", USE_ALPHA);
2616   img_bkgd[1][3] = load_level_image("bkgd-13.png", USE_ALPHA);
2617 }
2618
2619
2620 /* Load music: */
2621
2622 void loadlevelsong(void)
2623 {
2624
2625   char * song_path;
2626   char * song_subtitle;
2627
2628   song_path = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) +
2629                               strlen(song_title) + 8));
2630   sprintf(song_path, "%s/music/%s", DATA_PREFIX, song_title);
2631   level_song = load_song(song_path);
2632   free(song_path);
2633
2634
2635   song_path = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) +
2636                               strlen(song_title) + 8 + 5));
2637   song_subtitle = strdup(song_title);
2638   strcpy(strstr(song_subtitle, "."), "\0");
2639   sprintf(song_path, "%s/music/%s-fast%s", DATA_PREFIX, song_subtitle, strstr(song_title, "."));
2640   level_song_fast = load_song(song_path);
2641   free(song_subtitle);
2642   free(song_path);
2643 }
2644
2645
2646 /* Free graphics data for this level: */
2647
2648 void unloadlevelgfx(void)
2649 {
2650   int i;
2651
2652   for (i = 0; i < 2; i++)
2653     {
2654       SDL_FreeSurface(img_brick[i]);
2655     }
2656   for (i = 0; i < 4; i++)
2657     {
2658       SDL_FreeSurface(img_solid[i]);
2659       SDL_FreeSurface(img_bkgd[0][i]);
2660       SDL_FreeSurface(img_bkgd[1][i]);
2661     }
2662 }
2663
2664
2665 /* Free music data for this level: */
2666
2667 void unloadlevelsong(void)
2668 {
2669   free_music(level_song);
2670 }
2671
2672
2673 /* Load graphics/sounds shared between all levels: */
2674
2675 void loadshared(void)
2676 {
2677   int i;
2678   char * herring_song_path; /* for loading herring song*/
2679
2680   /* Tuxes: */
2681
2682   tux_right[0] = load_image(DATA_PREFIX "/images/shared/tux-right-0.png",
2683                             USE_ALPHA);
2684
2685   tux_right[1] = load_image(DATA_PREFIX "/images/shared/tux-right-1.png",
2686                             USE_ALPHA);
2687
2688   tux_right[2] = load_image(DATA_PREFIX "/images/shared/tux-right-2.png",
2689                             USE_ALPHA);
2690
2691   tux_left[0] = load_image(DATA_PREFIX "/images/shared/tux-left-0.png",
2692                            USE_ALPHA);
2693
2694   tux_left[1] = load_image(DATA_PREFIX "/images/shared/tux-left-1.png",
2695                            USE_ALPHA);
2696
2697   tux_left[2] = load_image(DATA_PREFIX "/images/shared/tux-left-2.png",
2698                            USE_ALPHA);
2699
2700   firetux_right[0] = load_image(DATA_PREFIX "/images/shared/firetux-right-0.png",
2701                                 USE_ALPHA);
2702
2703   firetux_right[1] = load_image(DATA_PREFIX "/images/shared/firetux-right-1.png",
2704                                 USE_ALPHA);
2705
2706   firetux_right[2] = load_image(DATA_PREFIX "/images/shared/firetux-right-2.png",
2707                                 USE_ALPHA);
2708
2709   firetux_left[0] = load_image(DATA_PREFIX "/images/shared/firetux-left-0.png",
2710                                USE_ALPHA);
2711
2712   firetux_left[1] = load_image(DATA_PREFIX "/images/shared/firetux-left-1.png",
2713                                USE_ALPHA);
2714
2715   firetux_left[2] = load_image(DATA_PREFIX "/images/shared/firetux-left-2.png",
2716                                USE_ALPHA);
2717
2718   cape_right[0] = load_image(DATA_PREFIX "/images/shared/cape-right-0.png",
2719                              USE_ALPHA);
2720
2721   cape_right[1] = load_image(DATA_PREFIX "/images/shared/cape-right-1.png",
2722                              USE_ALPHA);
2723
2724   cape_left[0] = load_image(DATA_PREFIX "/images/shared/cape-left-0.png",
2725                             USE_ALPHA);
2726
2727   cape_left[1] = load_image(DATA_PREFIX "/images/shared/cape-left-1.png",
2728                             USE_ALPHA);
2729
2730   bigtux_right[0] = load_image(DATA_PREFIX "/images/shared/bigtux-right-0.png",
2731                                USE_ALPHA);
2732
2733   bigtux_right[1] = load_image(DATA_PREFIX "/images/shared/bigtux-right-1.png",
2734                                USE_ALPHA);
2735
2736   bigtux_right[2] = load_image(DATA_PREFIX "/images/shared/bigtux-right-2.png",
2737                                USE_ALPHA);
2738
2739   bigtux_right_jump =
2740     load_image(DATA_PREFIX "/images/shared/bigtux-right-jump.png", USE_ALPHA);
2741
2742   bigtux_left[0] = load_image(DATA_PREFIX "/images/shared/bigtux-left-0.png",
2743                               USE_ALPHA);
2744
2745   bigtux_left[1] = load_image(DATA_PREFIX "/images/shared/bigtux-left-1.png",
2746                               USE_ALPHA);
2747
2748   bigtux_left[2] = load_image(DATA_PREFIX "/images/shared/bigtux-left-2.png",
2749                               USE_ALPHA);
2750
2751   bigtux_left_jump =
2752     load_image(DATA_PREFIX "/images/shared/bigtux-left-jump.png", USE_ALPHA);
2753
2754   bigcape_right[0] =
2755     load_image(DATA_PREFIX "/images/shared/bigcape-right-0.png",
2756                USE_ALPHA);
2757
2758   bigcape_right[1] =
2759     load_image(DATA_PREFIX "/images/shared/bigcape-right-1.png",
2760                USE_ALPHA);
2761
2762   bigcape_left[0] =
2763     load_image(DATA_PREFIX "/images/shared/bigcape-left-0.png",
2764                USE_ALPHA);
2765
2766   bigcape_left[1] =
2767     load_image(DATA_PREFIX "/images/shared/bigcape-left-1.png",
2768                USE_ALPHA);
2769
2770   bigfiretux_right[0] = load_image(DATA_PREFIX "/images/shared/bigfiretux-right-0.png",
2771                                    USE_ALPHA);
2772
2773   bigfiretux_right[1] = load_image(DATA_PREFIX "/images/shared/bigfiretux-right-1.png",
2774                                    USE_ALPHA);
2775
2776   bigfiretux_right[2] = load_image(DATA_PREFIX "/images/shared/bigfiretux-right-2.png",
2777                                    USE_ALPHA);
2778
2779   bigfiretux_right_jump =
2780     load_image(DATA_PREFIX "/images/shared/bigfiretux-right-jump.png", USE_ALPHA);
2781
2782   bigfiretux_left[0] = load_image(DATA_PREFIX "/images/shared/bigfiretux-left-0.png",
2783                                   USE_ALPHA);
2784
2785   bigfiretux_left[1] = load_image(DATA_PREFIX "/images/shared/bigfiretux-left-1.png",
2786                                   USE_ALPHA);
2787
2788   bigfiretux_left[2] = load_image(DATA_PREFIX "/images/shared/bigfiretux-left-2.png",
2789                                   USE_ALPHA);
2790
2791   bigfiretux_left_jump =
2792     load_image(DATA_PREFIX "/images/shared/bigfiretux-left-jump.png", USE_ALPHA);
2793
2794   bigcape_right[0] =
2795     load_image(DATA_PREFIX "/images/shared/bigcape-right-0.png",
2796                USE_ALPHA);
2797
2798   bigcape_right[1] =
2799     load_image(DATA_PREFIX "/images/shared/bigcape-right-1.png",
2800                USE_ALPHA);
2801
2802   bigcape_left[0] =
2803     load_image(DATA_PREFIX "/images/shared/bigcape-left-0.png",
2804                USE_ALPHA);
2805
2806   bigcape_left[1] =
2807     load_image(DATA_PREFIX "/images/shared/bigcape-left-1.png",
2808                USE_ALPHA);
2809
2810
2811   ducktux_right = load_image(DATA_PREFIX
2812                              "/images/shared/ducktux-right.png",
2813                              USE_ALPHA);
2814
2815   ducktux_left = load_image(DATA_PREFIX
2816                             "/images/shared/ducktux-left.png",
2817                             USE_ALPHA);
2818
2819   skidtux_right = load_image(DATA_PREFIX
2820                              "/images/shared/skidtux-right.png",
2821                              USE_ALPHA);
2822
2823   skidtux_left = load_image(DATA_PREFIX
2824                             "/images/shared/skidtux-left.png",
2825                             USE_ALPHA);
2826
2827   duckfiretux_right = load_image(DATA_PREFIX
2828                                  "/images/shared/duckfiretux-right.png",
2829                                  USE_ALPHA);
2830
2831   duckfiretux_left = load_image(DATA_PREFIX
2832                                 "/images/shared/duckfiretux-left.png",
2833                                 USE_ALPHA);
2834
2835   skidfiretux_right = load_image(DATA_PREFIX
2836                                  "/images/shared/skidfiretux-right.png",
2837                                  USE_ALPHA);
2838
2839   skidfiretux_left = load_image(DATA_PREFIX
2840                                 "/images/shared/skidfiretux-left.png",
2841                                 USE_ALPHA);
2842
2843
2844   /* Boxes: */
2845
2846   img_box_full = load_image(DATA_PREFIX "/images/shared/box-full.png",
2847                             IGNORE_ALPHA);
2848   img_box_empty = load_image(DATA_PREFIX "/images/shared/box-empty.png",
2849                              IGNORE_ALPHA);
2850
2851
2852   /* Water: */
2853
2854
2855   img_water = load_image(DATA_PREFIX "/images/shared/water.png", IGNORE_ALPHA);
2856
2857   img_waves[0] = load_image(DATA_PREFIX "/images/shared/waves-0.png",
2858                             USE_ALPHA);
2859
2860   img_waves[1] = load_image(DATA_PREFIX "/images/shared/waves-1.png",
2861                             USE_ALPHA);
2862
2863   img_waves[2] = load_image(DATA_PREFIX "/images/shared/waves-2.png",
2864                             USE_ALPHA);
2865
2866
2867   /* Pole: */
2868
2869   img_pole = load_image(DATA_PREFIX "/images/shared/pole.png", USE_ALPHA);
2870   img_poletop = load_image(DATA_PREFIX "/images/shared/poletop.png",
2871                            USE_ALPHA);
2872
2873
2874   /* Flag: */
2875
2876   img_flag[0] = load_image(DATA_PREFIX "/images/shared/flag-0.png",
2877                            USE_ALPHA);
2878   img_flag[1] = load_image(DATA_PREFIX "/images/shared/flag-1.png",
2879                            USE_ALPHA);
2880
2881
2882   /* Cloud: */
2883
2884   img_cloud[0][0] = load_image(DATA_PREFIX "/images/shared/cloud-00.png",
2885                                USE_ALPHA);
2886
2887   img_cloud[0][1] = load_image(DATA_PREFIX "/images/shared/cloud-01.png",
2888                                USE_ALPHA);
2889
2890   img_cloud[0][2] = load_image(DATA_PREFIX "/images/shared/cloud-02.png",
2891                                USE_ALPHA);
2892
2893   img_cloud[0][3] = load_image(DATA_PREFIX "/images/shared/cloud-03.png",
2894                                USE_ALPHA);
2895
2896
2897   img_cloud[1][0] = load_image(DATA_PREFIX "/images/shared/cloud-10.png",
2898                                USE_ALPHA);
2899
2900   img_cloud[1][1] = load_image(DATA_PREFIX "/images/shared/cloud-11.png",
2901                                USE_ALPHA);
2902
2903   img_cloud[1][2] = load_image(DATA_PREFIX "/images/shared/cloud-12.png",
2904                                USE_ALPHA);
2905
2906   img_cloud[1][3] = load_image(DATA_PREFIX "/images/shared/cloud-13.png",
2907                                USE_ALPHA);
2908
2909
2910   /* Bad guys: */
2911
2912   /* (BSOD) */
2913
2914   img_bsod_left[0] = load_image(DATA_PREFIX
2915                                 "/images/shared/bsod-left-0.png",
2916                                 USE_ALPHA);
2917
2918   img_bsod_left[1] = load_image(DATA_PREFIX
2919                                 "/images/shared/bsod-left-1.png",
2920                                 USE_ALPHA);
2921
2922   img_bsod_left[2] = load_image(DATA_PREFIX
2923                                 "/images/shared/bsod-left-2.png",
2924                                 USE_ALPHA);
2925
2926   img_bsod_left[3] = load_image(DATA_PREFIX
2927                                 "/images/shared/bsod-left-3.png",
2928                                 USE_ALPHA);
2929
2930   img_bsod_right[0] = load_image(DATA_PREFIX
2931                                  "/images/shared/bsod-right-0.png",
2932                                  USE_ALPHA);
2933
2934   img_bsod_right[1] = load_image(DATA_PREFIX
2935                                  "/images/shared/bsod-right-1.png",
2936                                  USE_ALPHA);
2937
2938   img_bsod_right[2] = load_image(DATA_PREFIX
2939                                  "/images/shared/bsod-right-2.png",
2940                                  USE_ALPHA);
2941
2942   img_bsod_right[3] = load_image(DATA_PREFIX
2943                                  "/images/shared/bsod-right-3.png",
2944                                  USE_ALPHA);
2945
2946   img_bsod_squished_left = load_image(DATA_PREFIX
2947                                       "/images/shared/bsod-squished-left.png",
2948                                       USE_ALPHA);
2949
2950   img_bsod_squished_right = load_image(DATA_PREFIX
2951                                        "/images/shared/bsod-squished-right.png",
2952                                        USE_ALPHA);
2953
2954   img_bsod_falling_left = load_image(DATA_PREFIX
2955                                      "/images/shared/bsod-falling-left.png",
2956                                      USE_ALPHA);
2957
2958   img_bsod_falling_right = load_image(DATA_PREFIX
2959                                       "/images/shared/bsod-falling-right.png",
2960                                       USE_ALPHA);
2961
2962
2963   /* (Laptop) */
2964
2965   img_laptop_left[0] = load_image(DATA_PREFIX
2966                                   "/images/shared/laptop-left-0.png",
2967                                   USE_ALPHA);
2968
2969   img_laptop_left[1] = load_image(DATA_PREFIX
2970                                   "/images/shared/laptop-left-1.png",
2971                                   USE_ALPHA);
2972
2973   img_laptop_left[2] = load_image(DATA_PREFIX
2974                                   "/images/shared/laptop-left-2.png",
2975                                   USE_ALPHA);
2976
2977   img_laptop_right[0] = load_image(DATA_PREFIX
2978                                    "/images/shared/laptop-right-0.png",
2979                                    USE_ALPHA);
2980
2981   img_laptop_right[1] = load_image(DATA_PREFIX
2982                                    "/images/shared/laptop-right-1.png",
2983                                    USE_ALPHA);
2984
2985   img_laptop_right[2] = load_image(DATA_PREFIX
2986                                    "/images/shared/laptop-right-2.png",
2987                                    USE_ALPHA);
2988
2989   img_laptop_flat_left = load_image(DATA_PREFIX
2990                                     "/images/shared/laptop-flat-left.png",
2991                                     USE_ALPHA);
2992
2993   img_laptop_flat_right = load_image(DATA_PREFIX
2994                                      "/images/shared/laptop-flat-right.png",
2995                                      USE_ALPHA);
2996
2997   img_laptop_falling_left =
2998     load_image(DATA_PREFIX
2999                "/images/shared/laptop-falling-left.png",
3000                USE_ALPHA);
3001
3002   img_laptop_falling_right =
3003     load_image(DATA_PREFIX
3004                "/images/shared/laptop-falling-right.png",
3005                USE_ALPHA);
3006
3007
3008   /* (Money) */
3009
3010   img_money_left[0] = load_image(DATA_PREFIX
3011                                  "/images/shared/bag-left-0.png",
3012                                  USE_ALPHA);
3013
3014   img_money_left[1] = load_image(DATA_PREFIX
3015                                  "/images/shared/bag-left-1.png",
3016                                  USE_ALPHA);
3017
3018   img_money_right[0] = load_image(DATA_PREFIX
3019                                   "/images/shared/bag-right-0.png",
3020                                   USE_ALPHA);
3021
3022   img_money_right[1] = load_image(DATA_PREFIX
3023                                   "/images/shared/bag-right-1.png",
3024                                   USE_ALPHA);
3025
3026
3027
3028   /* Upgrades: */
3029
3030   img_mints = load_image(DATA_PREFIX "/images/shared/mints.png", USE_ALPHA);
3031   img_coffee = load_image(DATA_PREFIX "/images/shared/coffee.png", USE_ALPHA);
3032
3033
3034   /* Weapons: */
3035
3036   img_bullet = load_image(DATA_PREFIX "/images/shared/bullet.png", USE_ALPHA);
3037
3038   img_red_glow = load_image(DATA_PREFIX "/images/shared/red-glow.png",
3039                             USE_ALPHA);
3040
3041
3042
3043   /* Distros: */
3044
3045   img_distro[0] = load_image(DATA_PREFIX "/images/shared/distro-0.png",
3046                              USE_ALPHA);
3047
3048   img_distro[1] = load_image(DATA_PREFIX "/images/shared/distro-1.png",
3049                              USE_ALPHA);
3050
3051   img_distro[2] = load_image(DATA_PREFIX "/images/shared/distro-2.png",
3052                              USE_ALPHA);
3053
3054   img_distro[3] = load_image(DATA_PREFIX "/images/shared/distro-3.png",
3055                              USE_ALPHA);
3056
3057
3058   /* Tux life: */
3059
3060   tux_life = load_image(DATA_PREFIX "/images/shared/tux-life.png",
3061                         USE_ALPHA);
3062
3063   /* Herring: */
3064
3065   img_golden_herring =
3066     load_image(DATA_PREFIX "/images/shared/golden-herring.png",
3067                USE_ALPHA);
3068
3069
3070   /* Super background: */
3071
3072   img_super_bkgd = load_image(DATA_PREFIX "/images/shared/super-bkgd.png",
3073                               IGNORE_ALPHA);
3074
3075
3076   /* Sound effects: */
3077
3078   /* if (use_sound) // this will introduce SERIOUS bugs here ! because "load_sound"
3079                     // initialize sounds[i] with the correct pointer's value:
3080                     // NULL or something else. And it will be dangerous to
3081                     // play with not-initialized pointers.
3082                     // This is also true with if (use_music)
3083      Send a mail to me: neoneurone@users.sf.net, if you have another opinion. :)
3084   */
3085   for (i = 0; i < NUM_SOUNDS; i++)
3086     sounds[i] = load_sound(soundfilenames[i]);
3087
3088   /* Herring song */
3089   herring_song_path = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) +
3090                                       strlen("SALCON.MOD") + 8)); /* FIXME: We need a real herring_song! Thats a fake.:) */
3091
3092   sprintf(herring_song_path, "%s/music/%s", DATA_PREFIX, "SALCON.MOD");
3093
3094   herring_song = load_song(herring_song_path);
3095
3096   free(herring_song_path);
3097
3098 }
3099
3100
3101 /* Free shared data: */
3102
3103 void unloadshared(void)
3104 {
3105   int i;
3106
3107   for (i = 0; i < 3; i++)
3108     {
3109       SDL_FreeSurface(tux_right[i]);
3110       SDL_FreeSurface(tux_left[i]);
3111       SDL_FreeSurface(bigtux_right[i]);
3112       SDL_FreeSurface(bigtux_left[i]);
3113     }
3114
3115   SDL_FreeSurface(bigtux_right_jump);
3116   SDL_FreeSurface(bigtux_left_jump);
3117
3118   for (i = 0; i < 2; i++)
3119     {
3120       SDL_FreeSurface(cape_right[i]);
3121       SDL_FreeSurface(cape_left[i]);
3122       SDL_FreeSurface(bigcape_right[i]);
3123       SDL_FreeSurface(bigcape_left[i]);
3124     }
3125
3126   SDL_FreeSurface(ducktux_left);
3127   SDL_FreeSurface(ducktux_right);
3128
3129   SDL_FreeSurface(skidtux_left);
3130   SDL_FreeSurface(skidtux_right);
3131
3132   for (i = 0; i < 4; i++)
3133     {
3134       SDL_FreeSurface(img_bsod_left[i]);
3135       SDL_FreeSurface(img_bsod_right[i]);
3136     }
3137
3138   SDL_FreeSurface(img_bsod_squished_left);
3139   SDL_FreeSurface(img_bsod_squished_right);
3140
3141   SDL_FreeSurface(img_bsod_falling_left);
3142   SDL_FreeSurface(img_bsod_falling_right);
3143
3144   for (i = 0; i < 3; i++)
3145     {
3146       SDL_FreeSurface(img_laptop_left[i]);
3147       SDL_FreeSurface(img_laptop_right[i]);
3148     }
3149
3150   SDL_FreeSurface(img_laptop_flat_left);
3151   SDL_FreeSurface(img_laptop_flat_right);
3152
3153   SDL_FreeSurface(img_laptop_falling_left);
3154   SDL_FreeSurface(img_laptop_falling_right);
3155
3156   for (i = 0; i < 2; i++)
3157     {
3158       SDL_FreeSurface(img_money_left[i]);
3159       SDL_FreeSurface(img_money_right[i]);
3160     }
3161
3162   SDL_FreeSurface(img_box_full);
3163   SDL_FreeSurface(img_box_empty);
3164
3165   SDL_FreeSurface(img_water);
3166   for (i = 0; i < 3; i++)
3167     SDL_FreeSurface(img_waves[i]);
3168
3169   SDL_FreeSurface(img_pole);
3170   SDL_FreeSurface(img_poletop);
3171
3172   for (i = 0; i < 2; i++)
3173     SDL_FreeSurface(img_flag[i]);
3174
3175   SDL_FreeSurface(img_mints);
3176   SDL_FreeSurface(img_coffee);
3177
3178   for (i = 0; i < 4; i++)
3179     {
3180       SDL_FreeSurface(img_distro[i]);
3181       SDL_FreeSurface(img_cloud[0][i]);
3182       SDL_FreeSurface(img_cloud[1][i]);
3183     }
3184
3185   SDL_FreeSurface(img_golden_herring);
3186
3187   for (i = 0; i < NUM_SOUNDS; i++)
3188     free_chunk(sounds[i]);
3189
3190   /* free the herring song */
3191   free_music( herring_song );
3192 }
3193
3194
3195 /* Draw a tile on the screen: */
3196
3197 void drawshape(int x, int y, unsigned char c)
3198 {
3199   int z;
3200
3201   if (c == 'X' || c == 'x')
3202     drawimage(img_brick[0], x, y, NO_UPDATE);
3203   else if (c == 'Y' || c == 'y')
3204     drawimage(img_brick[1], x, y, NO_UPDATE);
3205   else if (c == 'A' || c =='B' || c == '!')
3206     drawimage(img_box_full, x, y, NO_UPDATE);
3207   else if (c == 'a')
3208     drawimage(img_box_empty, x, y, NO_UPDATE);
3209   else if (c >= 'C' && c <= 'F')
3210     drawimage(img_cloud[0][c - 'C'], x, y, NO_UPDATE);
3211   else if (c >= 'c' && c <= 'f')
3212     drawimage(img_cloud[1][c - 'c'], x, y, NO_UPDATE);
3213   else if (c >= 'G' && c <= 'J')
3214     drawimage(img_bkgd[0][c - 'G'], x, y, NO_UPDATE);
3215   else if (c >= 'g' && c <= 'j')
3216     drawimage(img_bkgd[1][c - 'g'], x, y, NO_UPDATE);
3217   else if (c == '#')
3218     drawimage(img_solid[0], x, y, NO_UPDATE);
3219   else if (c == '[')
3220     drawimage(img_solid[1], x, y, NO_UPDATE);
3221   else if (c == '=')
3222     drawimage(img_solid[2], x, y, NO_UPDATE);
3223   else if (c == ']')
3224     drawimage(img_solid[3], x, y, NO_UPDATE);
3225   else if (c == '$')
3226     {
3227       z = (frame / 2) % 6;
3228
3229       if (z < 4)
3230         drawimage(img_distro[z], x, y, NO_UPDATE);
3231       else if (z == 4)
3232         drawimage(img_distro[2], x, y, NO_UPDATE);
3233       else if (z == 5)
3234         drawimage(img_distro[1], x, y, NO_UPDATE);
3235     }
3236   else if (c == '^')
3237     {
3238       z = (frame / 3) % 3;
3239
3240       drawimage(img_waves[z], x, y, NO_UPDATE);
3241     }
3242   else if (c == '*')
3243     drawimage(img_poletop, x, y, NO_UPDATE);
3244   else if (c == '|')
3245     {
3246       drawimage(img_pole, x, y, NO_UPDATE);
3247
3248       /* Mark this as the end position of the level! */
3249
3250       endpos = x;
3251     }
3252   else if (c == '\\')
3253     {
3254       z = (frame / 3) % 2;
3255
3256       drawimage(img_flag[z], x + 16, y, NO_UPDATE);
3257     }
3258   else if (c == '&')
3259     drawimage(img_water, x, y, NO_UPDATE);
3260 }
3261
3262
3263 /* What shape is at some position? */
3264
3265 unsigned char shape(int x, int y, int sx)
3266 {
3267   int xx, yy;
3268   unsigned char c;
3269
3270   yy = (y / 32);
3271   xx = ((x + sx) / 32);
3272
3273   if (yy >= 0 && yy <= 15 && xx >= 0 && xx <= level_width)
3274     c = tiles[yy][xx];
3275   else
3276     c = '.';
3277
3278   return(c);
3279 }
3280
3281
3282 /* Is is ground? */
3283
3284 int issolid(int x, int y, int sx)
3285 {
3286   int v;
3287
3288   v = 0;
3289
3290   if (isbrick(x, y, sx) ||
3291       isbrick(x + 31, y, sx) ||
3292       isice(x, y, sx) ||
3293       isice(x + 31, y, sx) ||
3294       (shape(x, y, sx) == '[' ||
3295        shape(x + 31, y, sx) == '[') ||
3296       (shape(x, y, sx) == '=' ||
3297        shape(x + 31, y, sx) == '=') ||
3298       (shape(x, y, sx) == ']' ||
3299        shape(x + 31, y, sx) == ']') ||
3300       (shape(x, y, sx) == 'A' ||
3301        shape(x + 31, y, sx) == 'A') ||
3302       (shape(x, y, sx) == 'B' ||
3303        shape(x + 31, y, sx) == 'B') ||
3304       (shape(x, y, sx) == '!' ||
3305        shape(x + 31, y, sx) == '!') ||
3306       (shape(x, y, sx) == 'a' ||
3307        shape(x + 31, y, sx) == 'a'))
3308     {
3309       v = 1;
3310     }
3311
3312   return(v);
3313 }
3314
3315
3316 /* Is it a brick? */
3317
3318 int isbrick(int x, int y, int sx)
3319 {
3320   int v;
3321
3322   v = 0;
3323
3324   if (shape(x, y, sx) == 'X' ||
3325       shape(x, y, sx) == 'x' ||
3326       shape(x, y, sx) == 'Y' ||
3327       shape(x, y, sx) == 'y')
3328     {
3329       v = 1;
3330     }
3331
3332   return(v);
3333 }
3334
3335
3336 /* Is it ice? */
3337
3338 int isice(int x, int y, int sx)
3339 {
3340   int v;
3341
3342   v = 0;
3343
3344   if (shape(x, y, sx) == '#')
3345     {
3346       v = 1;
3347     }
3348
3349   return(v);
3350 }
3351
3352
3353 /* Is it a full box? */
3354
3355 int isfullbox(int x, int y, int sx)
3356 {
3357   int v;
3358
3359   v = 0;
3360
3361   if (shape(x, y, sx) == 'A' ||
3362       shape(x, y, sx) == 'B' ||
3363       shape(x, y, sx) == '!')
3364     {
3365       v = 1;
3366     }
3367
3368   return(v);
3369 }
3370
3371
3372 /* Edit a piece of the map! */
3373
3374 void change(int x, int y, int sx, unsigned char c)
3375 {
3376   int xx, yy;
3377
3378   yy = (y / 32);
3379   xx = ((x + sx) / 32);
3380
3381   if (yy >= 0 && yy <= 15 && xx >= 0 && xx <= level_width)
3382     tiles[yy][xx] = c;
3383 }
3384
3385
3386 /* Break a brick: */
3387
3388 void trybreakbrick(int x, int y, int sx)
3389 {
3390   if (isbrick(x, y, sx))
3391     {
3392       if (shape(x, y, sx) == 'x' || shape(x, y, sx) == 'y')
3393         {
3394           /* Get a distro from it: */
3395
3396           add_bouncy_distro(((x + sx + 1) / 32) * 32,
3397                             (y / 32) * 32);
3398
3399           if (counting_distros == NO)
3400             {
3401               counting_distros = YES;
3402               distro_counter = 50;
3403             }
3404
3405           if (distro_counter <= 0)
3406             change(x, y, sx, 'a');
3407
3408           play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
3409           score = score + SCORE_DISTRO;
3410           distros++;
3411         }
3412       else
3413         {
3414           /* Get rid of it: */
3415
3416           change(x, y, sx, '.');
3417         }
3418
3419
3420       /* Replace it with broken bits: */
3421
3422       add_broken_brick(((x + sx + 1) / 32) * 32,
3423                        (y / 32) * 32);
3424
3425
3426       /* Get some score: */
3427
3428       play_sound(sounds[SND_BRICK], SOUND_CENTER_SPEAKER);
3429       score = score + SCORE_BRICK;
3430     }
3431 }
3432
3433
3434 /* Bounce a brick: */
3435
3436 void bumpbrick(int x, int y, int sx)
3437 {
3438   add_bouncy_brick(((x + sx + 1) / 32) * 32,
3439                    (y / 32) * 32);
3440
3441   play_sound(sounds[SND_BRICK], SOUND_CENTER_SPEAKER);
3442 }
3443
3444
3445 /* Empty a box: */
3446
3447 void tryemptybox(int x, int y, int sx)
3448 {
3449   if (isfullbox(x, y, sx))
3450     {
3451       if (shape(x, y, sx) == 'A')
3452         {
3453           /* Box with a distro! */
3454
3455           add_bouncy_distro(((x + sx + 1) / 32) * 32,
3456                             (y / 32) * 32 - 32);
3457
3458           play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
3459           score = score + SCORE_DISTRO;
3460           distros++;
3461         }
3462       else if (shape(x, y, sx) == 'B')
3463         {
3464           /* Add an upgrade! */
3465
3466           if (tux_size == SMALL)
3467             {
3468               /* Tux is small, add mints! */
3469
3470               add_upgrade(((x + sx + 1) / 32) * 32,
3471                           (y / 32) * 32 - 32,
3472                           UPGRADE_MINTS);
3473             }
3474           else
3475             {
3476               /* Tux is big, add coffee: */
3477
3478               add_upgrade(((x + sx + 1) / 32) * 32,
3479                           (y / 32) * 32 - 32,
3480                           UPGRADE_COFFEE);
3481             }
3482
3483           play_sound(sounds[SND_UPGRADE], SOUND_CENTER_SPEAKER);
3484         }
3485       else if (shape(x, y, sx) == '!')
3486         {
3487           /* Add a golden herring */
3488
3489           add_upgrade(((x + sx + 1) / 32) * 32,
3490                       (y / 32) * 32 - 32,
3491                       UPGRADE_HERRING);
3492         }
3493
3494       /* Empty the box: */
3495
3496       change(x, y, sx, 'a');
3497     }
3498 }
3499
3500
3501 /* Try to grab a distro: */
3502
3503 void trygrabdistro(int x, int y, int sx, int bounciness)
3504 {
3505   if (shape(x, y, sx) == '$')
3506     {
3507       change(x, y, sx, '.');
3508       play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
3509
3510       if (bounciness == BOUNCE)
3511         {
3512           add_bouncy_distro(((x + sx + 1) / 32) * 32,
3513                             (y / 32) * 32);
3514         }
3515
3516       score = score + SCORE_DISTRO;
3517       distros++;
3518     }
3519 }
3520
3521
3522 /* Add a bouncy distro: */
3523
3524 void add_bouncy_distro(int x, int y)
3525 {
3526   int i, found;
3527
3528   found = -1;
3529
3530   for (i = 0; i < NUM_BOUNCY_DISTROS && found == -1; i++)
3531     {
3532       if (!bouncy_distros[i].alive)
3533         found = i;
3534     }
3535
3536   if (found != -1)
3537     {
3538       bouncy_distros[found].alive = YES;
3539       bouncy_distros[found].x = x;
3540       bouncy_distros[found].y = y;
3541       bouncy_distros[found].ym = -6;
3542     }
3543 }
3544
3545
3546 /* Add broken brick pieces: */
3547
3548 void add_broken_brick(int x, int y)
3549 {
3550   add_broken_brick_piece(x, y, -4, -16);
3551   add_broken_brick_piece(x, y + 16, -6, -12);
3552
3553   add_broken_brick_piece(x + 16, y, 4, -16);
3554   add_broken_brick_piece(x + 16, y + 16, 6, -12);
3555 }
3556
3557
3558 /* Add a broken brick piece: */
3559
3560 void add_broken_brick_piece(int x, int y, int xm, int ym)
3561 {
3562   int i, found;
3563
3564   found = -1;
3565
3566   for (i = 0; i < NUM_BROKEN_BRICKS && found == -1; i++)
3567     {
3568       if (!broken_bricks[i].alive)
3569         found = i;
3570     }
3571
3572   if (found != -1)
3573     {
3574       broken_bricks[found].alive = YES;
3575       broken_bricks[found].x = x;
3576       broken_bricks[found].y = y;
3577       broken_bricks[found].xm = xm;
3578       broken_bricks[found].ym = ym;
3579     }
3580 }
3581
3582
3583 /* Add a bouncy brick piece: */
3584
3585 void add_bouncy_brick(int x, int y)
3586 {
3587   int i, found;
3588
3589   found = -1;
3590
3591   for (i = 0; i < NUM_BOUNCY_BRICKS && found == -1; i++)
3592     {
3593       if (!bouncy_bricks[i].alive)
3594         found = i;
3595     }
3596
3597   if (found != -1)
3598     {
3599       bouncy_bricks[found].alive = YES;
3600       bouncy_bricks[found].x = x;
3601       bouncy_bricks[found].y = y;
3602       bouncy_bricks[found].offset = 0;
3603       bouncy_bricks[found].offset_m = -BOUNCY_BRICK_SPEED;
3604       bouncy_bricks[found].shape = shape(x, y, 0);
3605     }
3606 }
3607
3608
3609 /* Add a bad guy: */
3610
3611 void add_bad_guy(int x, int y, int kind)
3612 {
3613   int i, found;
3614
3615   found = -1;
3616
3617   for (i = 0; i < NUM_BAD_GUYS && found == -1; i++)
3618     {
3619       if (!bad_guys[i].alive)
3620         found = i;
3621     }
3622
3623   if (found != -1)
3624     {
3625       bad_guys[found].alive = YES;
3626       bad_guys[found].mode = NORMAL;
3627       bad_guys[found].dying = NO;
3628       bad_guys[found].timer = 0;
3629       bad_guys[found].kind = kind;
3630       bad_guys[found].x = x;
3631       bad_guys[found].y = y;
3632       bad_guys[found].xm = 0;
3633       bad_guys[found].ym = 0;
3634       bad_guys[found].dir = LEFT;
3635       bad_guys[found].seen = NO;
3636     }
3637 }
3638
3639
3640 /* Add score: */
3641
3642 void add_score(int x, int y, int s)
3643 {
3644   int i, found;
3645
3646
3647   /* Add the score: */
3648
3649   score = score + s;
3650
3651
3652   /* Add a floating score thing to the game: */
3653
3654   found = -1;
3655
3656   for (i = 0; i < NUM_FLOATING_SCORES && found == -1; i++)
3657     {
3658       if (!floating_scores[i].alive)
3659         found = i;
3660     }
3661
3662
3663   if (found != -1)
3664     {
3665       floating_scores[found].alive = YES;
3666       floating_scores[found].x = x;
3667       floating_scores[found].y = y - 16;
3668       floating_scores[found].timer = 8;
3669       floating_scores[found].value = s;
3670     }
3671 }
3672
3673
3674 /* Try to bump a bad guy from below: */
3675
3676 void trybumpbadguy(int x, int y, int sx)
3677 {
3678   int i;
3679
3680
3681   /* Bad guys: */
3682
3683   for (i = 0; i < NUM_BAD_GUYS; i++)
3684     {
3685       if (bad_guys[i].alive &&
3686           bad_guys[i].x >= x + sx - 32 && bad_guys[i].x <= x + sx + 32 &&
3687           bad_guys[i].y >= y - 16 && bad_guys[i].y <= y + 16)
3688         {
3689           if (bad_guys[i].kind == BAD_BSOD ||
3690               bad_guys[i].kind == BAD_LAPTOP)
3691             {
3692               bad_guys[i].dying = FALLING;
3693               bad_guys[i].ym = -8;
3694               play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
3695             }
3696         }
3697     }
3698
3699
3700   /* Upgrades: */
3701
3702   for (i = 0; i < NUM_UPGRADES; i++)
3703     {
3704       if (upgrades[i].alive && upgrades[i].height == 32 &&
3705           upgrades[i].x >= x + sx - 32 && upgrades[i].x <= x + sx + 32 &&
3706           upgrades[i].y >= y - 16 && upgrades[i].y <= y + 16)
3707         {
3708           upgrades[i].xm = -upgrades[i].xm;
3709           upgrades[i].ym = -8;
3710           play_sound(sounds[SND_BUMP_UPGRADE], SOUND_CENTER_SPEAKER);
3711         }
3712     }
3713 }
3714
3715
3716 /* Add an upgrade: */
3717
3718 void add_upgrade(int x, int y, int kind)
3719 {
3720   int i, found;
3721
3722   found = -1;
3723
3724   for (i = 0; i < NUM_UPGRADES && found == -1; i++)
3725     {
3726       if (!upgrades[i].alive)
3727         found = i;
3728     }
3729
3730   if (found != -1)
3731     {
3732       upgrades[found].alive = YES;
3733       upgrades[found].kind = kind;
3734       upgrades[found].x = x;
3735       upgrades[found].y = y;
3736       upgrades[found].xm = 4;
3737       upgrades[found].ym = -4;
3738       upgrades[found].height = 0;
3739     }
3740 }
3741
3742
3743 /* Kill tux! */
3744
3745 void killtux(int mode)
3746 {
3747   tux_ym = -16;
3748
3749   play_sound(sounds[SND_HURT], SOUND_CENTER_SPEAKER);
3750
3751   if (tux_dir == RIGHT)
3752     tux_xm = -8;
3753   else if (tux_dir == LEFT)
3754     tux_xm = 8;
3755
3756   if (mode == SHRINK && tux_size == BIG)
3757     {
3758       if (tux_got_coffee)
3759         tux_got_coffee = NO;
3760
3761       tux_size = SMALL;
3762
3763       tux_safe = TUX_SAFE_TIME;
3764     }
3765   else
3766     {
3767       tux_dying = 1;
3768     }
3769 }
3770
3771
3772 /* Add a bullet: */
3773
3774 void add_bullet(int x, int y, int dir, int xm)
3775 {
3776   int i, found;
3777
3778   found = -1;
3779
3780   for (i = 0; i < NUM_BULLETS && found == -1; i++)
3781     {
3782       if (!bullets[i].alive)
3783         found = i;
3784     }
3785
3786   if (found != -1)
3787     {
3788       bullets[found].alive = YES;
3789
3790       if (dir == RIGHT)
3791         {
3792           bullets[found].x = x + 32;
3793           bullets[found].xm = BULLET_XM + xm;
3794         }
3795       else
3796         {
3797           bullets[found].x = x;
3798           bullets[found].xm = -BULLET_XM + xm;
3799         }
3800
3801       bullets[found].y = y;
3802       bullets[found].ym = BULLET_STARTING_YM;
3803
3804       play_sound(sounds[SND_SHOOT], SOUND_CENTER_SPEAKER);
3805     }
3806 }
3807
3808
3809 void drawendscreen(void)
3810 {
3811   char str[80];
3812
3813   clearscreen(0, 0, 0);
3814
3815   drawcenteredtext("GAMEOVER", 200, letters_red, NO_UPDATE, 1);
3816
3817   sprintf(str, "SCORE: %d", score);
3818   drawcenteredtext(str, 224, letters_gold, NO_UPDATE, 1);
3819
3820   sprintf(str, "DISTROS: %d", distros);
3821   drawcenteredtext(str, 256, letters_blue, NO_UPDATE, 1);
3822
3823   SDL_Flip(screen);
3824   SDL_Delay(2000);
3825 }
3826
3827 void drawresultscreen(void)
3828 {
3829   char str[80];
3830
3831   clearscreen(0, 0, 0);
3832
3833   drawcenteredtext("Result:", 200, letters_red, NO_UPDATE, 1);
3834
3835   sprintf(str, "SCORE: %d", score);
3836   drawcenteredtext(str, 224, letters_gold, NO_UPDATE, 1);
3837
3838   sprintf(str, "DISTROS: %d", distros);
3839   drawcenteredtext(str, 256, letters_blue, NO_UPDATE, 1);
3840
3841   SDL_Flip(screen);
3842   /*SDL_Delay(2000);*/
3843   sleep(2);
3844 }
3845
3846 void savegame(void)
3847 {
3848   char savefile[300];
3849   time_t current_time = time(NULL);
3850   struct tm* time_struct;
3851   FILE* fi;
3852
3853   time_struct = localtime(&current_time);
3854   sprintf(savefile,"%s/%d-%d-%d-%d.save",st_save_dir,time_struct->tm_year+1900,time_struct->tm_mon,time_struct->tm_mday,time_struct->tm_hour);
3855   printf("%s",savefile);
3856
3857
3858   fi = fopen(savefile, "wb");
3859
3860   if (fi == NULL)
3861     {
3862       fprintf(stderr, "Warning: I could not open the high score file ");
3863
3864     }
3865   else
3866   {
3867    fwrite(&level,4,1,fi);
3868    fwrite(&score,4,1,fi);
3869    fwrite(&distros,4,1,fi);
3870    fwrite(&tux_x,4,1,fi);
3871    fwrite(&tux_y,4,1,fi);
3872    fwrite(&scroll_x,4,1,fi);
3873   }
3874   fclose(fi);
3875
3876 }
3877
3878 void loadgame(char* filename)
3879 {
3880   char savefile[300];
3881   FILE* fi;
3882   time_t current_time = time(NULL);
3883   struct tm* time_struct;
3884   
3885   time_struct = localtime(&current_time);
3886   sprintf(savefile,"%s/%d-%d-%d-%d.save",st_save_dir,time_struct->tm_year+1900,time_struct->tm_mon,time_struct->tm_mday,time_struct->tm_hour);
3887   printf("%s",savefile);
3888
3889
3890   fi = fopen(savefile, "rb");
3891
3892   if (fi == NULL)
3893     {
3894       fprintf(stderr, "Warning: I could not open the high score file ");
3895
3896     }
3897   else
3898   {
3899    fread(&level,4,1,fi);
3900    fread(&score,4,1,fi);
3901    fread(&distros,4,1,fi);
3902    fread(&tux_x,4,1,fi);
3903    fread(&tux_y,4,1,fi);
3904    fread(&scroll_x,4,1,fi);
3905    fclose(fi);
3906   }
3907
3908 }