moved the themes into their own directory
[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 <SDL.h>
19
20 #ifdef LINUX
21 #include <pwd.h>
22 #include <sys/types.h>
23 #include <ctype.h>
24 #endif
25
26 #include "defines.h"
27 #include "globals.h"
28 #include "gameloop.h"
29 #include "screen.h"
30 #include "setup.h"
31 #include "high_scores.h"
32 #include "menu.h"
33 #include "badguy.h"
34 #include "world.h"
35 #include "player.h"
36
37 /* extern variables */
38
39 extern char* soundfilenames[NUM_SOUNDS];
40
41 /* Local variables: */
42
43 int score, highscore, distros, level, lives, scroll_x, next_level, game_pause,
44 done, quit, tux_dir, tux_size, tux_duck, tux_x, tux_xm, tux_y, tux_ym,
45 tux_dying, tux_safe, jumping, jump_counter, frame, score_multiplier,
46 tux_frame_main, tux_frame, tux_got_coffee, tux_skidding,
47 super_bkgd_time, time_left, tux_invincible_time, endpos,
48 counting_distros, distro_counter;
49 int bkgd_red, bkgd_green, bkgd_blue, level_width;
50 int left, right, up, down, fire, old_fire;
51 SDL_Surface * img_brick[2], * img_solid[4], * img_distro[4],
52 * img_waves[3], * img_water, * img_pole, * img_poletop, * img_flag[2];
53 SDL_Surface * img_bkgd[2][4];
54 SDL_Surface * img_golden_herring;
55 SDL_Surface * img_bsod_left[4], * img_bsod_right[4],
56 * img_laptop_left[3], * img_laptop_right[3],
57 * img_money_left[2], * img_money_right[2];
58 SDL_Surface * img_bsod_squished_left, * img_bsod_squished_right,
59 * img_bsod_falling_left, * img_bsod_falling_right,
60 * img_laptop_flat_left, * img_laptop_flat_right,
61 * img_laptop_falling_left, * img_laptop_falling_right;
62 SDL_Surface * img_box_full, * img_box_empty, * img_mints, * img_coffee,
63 * img_super_bkgd, * img_bullet, * img_red_glow;
64 SDL_Surface * img_cloud[2][4];
65 SDL_Surface * tux_life,
66 * tux_right[3], * tux_left[3],
67 * bigtux_right[3], * bigtux_left[3],
68 * bigtux_right_jump, * bigtux_left_jump,
69 * ducktux_right, * ducktux_left,
70 * skidtux_right, * skidtux_left,
71 * firetux_right[3], * firetux_left[3],
72 * bigfiretux_right[3], * bigfiretux_left[3],
73 * bigfiretux_right_jump, * bigfiretux_left_jump,
74 * duckfiretux_right, * duckfiretux_left,
75 * skidfiretux_right, * skidfiretux_left,
76 * cape_right[2], * cape_left[2],
77 * bigcape_right[2], * bigcape_left[2];
78 SDL_Event event;
79 SDL_Rect src, dest;
80 SDLKey key;
81 unsigned char * tiles[15];
82 bouncy_distro_type bouncy_distros[NUM_BOUNCY_DISTROS];
83 broken_brick_type broken_bricks[NUM_BROKEN_BRICKS];
84 bouncy_brick_type bouncy_bricks[NUM_BOUNCY_BRICKS];
85 bad_guy_type bad_guys[NUM_BAD_GUYS];
86 floating_score_type floating_scores[NUM_FLOATING_SCORES];
87 upgrade_type upgrades[NUM_UPGRADES];
88 bullet_type bullets[NUM_BULLETS];
89 char song_title[60];
90 char levelname[60];
91 char leveltheme[60];
92 char str[60];
93
94
95 /* Local function prototypes: */
96
97 void initgame(void);
98 void loadlevel(void);
99 void loadlevelgfx(void);
100 void loadlevelsong(void);
101 void unloadlevelgfx(void);
102 void unloadlevelsong(void);
103 void loadshared(void);
104 void unloadshared(void);
105 void drawshape(int x, int y, unsigned char c);
106 void savegame(void);
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   loadlevel();
2272   loadlevelgfx();
2273   loadlevelsong();
2274   highscore = load_hs();
2275
2276
2277   /* --- MAIN GAME LOOP!!! --- */
2278
2279   done = 0;
2280   quit = 0;
2281   frame = 0;
2282   tux_frame_main = 0;
2283   tux_frame = 0;
2284   game_pause = 0;
2285
2286   game_draw();
2287   do
2288     {
2289       last_time = SDL_GetTicks();
2290       frame++;
2291
2292
2293       /* Handle events: */
2294
2295       old_fire = fire;
2296
2297       game_event();
2298
2299       /* Handle actions: */
2300
2301       if(!game_pause && !show_menu)
2302         {
2303           if (game_action() == 0)
2304             {
2305               /* == 0: no more lives */
2306               /* == -1: continues */
2307               return 0;
2308             }
2309         }
2310       else
2311         SDL_Delay(50);
2312
2313       /*Draw the current scene to the screen */
2314       game_draw();
2315
2316       /* Keep playing music: */
2317
2318
2319       if (!playing_music())
2320         {
2321           switch (current_music)
2322             {
2323             case LEVEL_MUSIC:
2324               if (time_left <= TIME_WARNING)
2325                 play_music(level_song_fast, 1);
2326               else
2327                 play_music(level_song, 1);
2328               break;
2329             case HERRING_MUSIC:
2330               play_music(herring_song, 1);
2331               break;
2332             case HURRYUP_MUSIC: // keep the compiler happy
2333             case NO_MUSIC:      // keep the compiler happy for the moment :-)
2334             {}
2335               /*default:*/
2336             }
2337         }
2338
2339       /* Time stops in pause mode */
2340       if(game_pause || show_menu )
2341         {
2342           continue;
2343         }
2344
2345       /* Pause til next frame: */
2346
2347       now_time = SDL_GetTicks();
2348       if (now_time < last_time + FPS)
2349         SDL_Delay(last_time + FPS - now_time);
2350
2351
2352       /* Handle time: */
2353
2354       if ((frame % 10) == 0 && time_left > 0)
2355         {
2356           time_left--;
2357
2358           /* Stop the music; it will start again, faster! */
2359           if (time_left == TIME_WARNING)
2360             halt_music();
2361
2362           if (time_left <= 0)
2363             killtux(KILL);
2364         }
2365     }
2366   while (!done && !quit);
2367
2368   if (playing_music())
2369     halt_music();
2370
2371   unloadlevelgfx();
2372   unloadlevelsong();
2373   unloadshared();
2374
2375   return(quit);
2376 }
2377
2378
2379 /* Initialize the game stuff: */
2380
2381 void initgame(void)
2382 {
2383   level = 1;
2384   score = 0;
2385   distros = 0;
2386   lives = 3;
2387 }
2388
2389
2390
2391 /* Load data for this level: */
2392
2393 void loadlevel(void)
2394 {
2395   int i, x, y;
2396   FILE * fi;
2397   char * filename;
2398   char str[80];
2399   char * line;
2400
2401
2402   /* Reset arrays: */
2403
2404   for (i = 0; i < NUM_BOUNCY_DISTROS; i++)
2405     bouncy_distros[i].alive = NO;
2406
2407   for (i = 0; i < NUM_BROKEN_BRICKS; i++)
2408     broken_bricks[i].alive = NO;
2409
2410   for (i = 0; i < NUM_BOUNCY_BRICKS; i++)
2411     bouncy_bricks[i].alive = NO;
2412
2413   for (i = 0; i < NUM_BAD_GUYS; i++)
2414     bad_guys[i].alive = NO;
2415
2416   for (i = 0; i < NUM_FLOATING_SCORES; i++)
2417     floating_scores[i].alive = NO;
2418
2419   for (i = 0; i < NUM_UPGRADES; i++)
2420     upgrades[i].alive = NO;
2421
2422   for (i = 0; i < NUM_BULLETS; i++)
2423     bullets[i].alive = NO;
2424
2425
2426   /* Load data file: */
2427
2428   filename = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) + 20));
2429   sprintf(filename, "%s/levels/level%d.dat", DATA_PREFIX, level);
2430   fi = fopen(filename, "r");
2431   if (fi == NULL)
2432     {
2433       perror(filename);
2434       st_shutdown();
2435       free(filename);
2436       exit(-1);
2437     }
2438   free(filename);
2439
2440
2441   /* Load header info: */
2442
2443
2444   /* (Level title) */
2445   fgets(str, 20, fi);
2446   strcpy(levelname, str);
2447   levelname[strlen(levelname)-1] = '\0';
2448
2449   /* (Level theme) */
2450   fgets(str, 20, fi);
2451   strcpy(leveltheme, str);
2452   leveltheme[strlen(leveltheme)-1] = '\0';
2453
2454
2455
2456   /* (Time to beat level) */
2457   fgets(str, 10, fi);
2458   time_left = atoi(str);
2459
2460   /* (Song file for this level) */
2461   fgets(str, sizeof(song_title), fi);
2462   strcpy(song_title, str);
2463   song_title[strlen(song_title)-1] = '\0';
2464
2465
2466
2467   /* (Level background color) */
2468   fgets(str, 10, fi);
2469   bkgd_red = atoi(str);
2470   fgets(str, 10, fi);
2471   bkgd_green= atoi(str);
2472   fgets(str, 10, fi);
2473   bkgd_blue = atoi(str);
2474
2475   /* (Level width) */
2476   fgets(str, 10, fi);
2477   level_width = atoi(str);
2478
2479
2480   /* Allocate some space for the line-reading! */
2481
2482   line = (char *) malloc(sizeof(char) * (level_width + 5));
2483   if (line == NULL)
2484     {
2485       fprintf(stderr, "Couldn't allocate space to load level data!");
2486       exit(1);
2487     }
2488
2489
2490   /* Load the level lines: */
2491
2492   for (y = 0; y < 15; y++)
2493     {
2494       if(fgets(line, level_width + 5, fi) == NULL)
2495         {
2496           fprintf(stderr, "Level %s isn't complete!\n",levelname);
2497           exit(1);
2498         }
2499       line[strlen(line) - 1] = '\0';
2500       tiles[y] = strdup(line);
2501     }
2502
2503   fclose(fi);
2504
2505
2506   /* Activate bad guys: */
2507
2508   for (y = 0; y < 15; y++)
2509     {
2510       for (x = 0; x < level_width; x++)
2511         {
2512           if (tiles[y][x] >= '0' && tiles[y][x] <= '9')
2513             {
2514               add_bad_guy(x * 32, y * 32, tiles[y][x] - '0');
2515               tiles[y][x] = '.';
2516             }
2517         }
2518     }
2519
2520
2521   /* Set defaults: */
2522
2523   tux_x = 0;
2524   tux_xm = 0;
2525   tux_y = 240;
2526   tux_ym = 0;
2527   tux_dir = RIGHT;
2528   tux_size = SMALL;
2529   tux_got_coffee = NO;
2530   tux_invincible_time = 0;
2531   tux_duck = NO;
2532
2533   tux_dying = NO;
2534   tux_safe = TUX_SAFE_TIME;
2535
2536   jumping = NO;
2537   jump_counter = 0;
2538
2539   tux_skidding = 0;
2540
2541   scroll_x = 0;
2542
2543   right = UP;
2544   left = UP;
2545   up = UP;
2546   down = UP;
2547   fire = UP;
2548   old_fire = UP;
2549
2550   score_multiplier = 1;
2551   super_bkgd_time = 0;
2552
2553   counting_distros = NO;
2554   distro_counter = 0;
2555
2556   endpos = 0;
2557
2558   /* set current song/music */
2559   current_music = LEVEL_MUSIC;
2560
2561   /* Level Intro: */
2562
2563   clearscreen(0, 0, 0);
2564
2565   sprintf(str, "LEVEL %d", level);
2566   drawcenteredtext(str, 200, letters_red, NO_UPDATE, 1);
2567
2568   sprintf(str, "%s", levelname);
2569   drawcenteredtext(str, 224, letters_gold, NO_UPDATE, 1);
2570
2571   sprintf(str, "TUX x %d", lives);
2572   drawcenteredtext(str, 256, letters_blue, NO_UPDATE, 1);
2573
2574   SDL_Flip(screen);
2575
2576   SDL_Delay(1000);
2577
2578
2579 }
2580
2581
2582 /* Load a level-specific graphic... */
2583
2584 SDL_Surface * load_level_image(char * file, int use_alpha)
2585 {
2586   char fname[1024];
2587
2588   snprintf(fname, 1024, "%s/images/%s/%s", DATA_PREFIX, leveltheme, file);
2589
2590   return(load_image(fname, use_alpha));
2591 }
2592
2593
2594 /* Load graphics: */
2595
2596 void loadlevelgfx(void)
2597 {
2598   img_brick[0] = load_level_image("brick0.png", IGNORE_ALPHA);
2599   img_brick[1] = load_level_image("brick1.png", IGNORE_ALPHA);
2600
2601   img_solid[0] = load_level_image("solid0.png", USE_ALPHA);
2602   img_solid[1] = load_level_image("solid1.png", USE_ALPHA);
2603   img_solid[2] = load_level_image("solid2.png", USE_ALPHA);
2604   img_solid[3] = load_level_image("solid3.png", USE_ALPHA);
2605
2606   img_bkgd[0][0] = load_level_image("bkgd-00.png", USE_ALPHA);
2607   img_bkgd[0][1] = load_level_image("bkgd-01.png", USE_ALPHA);
2608   img_bkgd[0][2] = load_level_image("bkgd-02.png", USE_ALPHA);
2609   img_bkgd[0][3] = load_level_image("bkgd-03.png", USE_ALPHA);
2610
2611   img_bkgd[1][0] = load_level_image("bkgd-10.png", USE_ALPHA);
2612   img_bkgd[1][1] = load_level_image("bkgd-11.png", USE_ALPHA);
2613   img_bkgd[1][2] = load_level_image("bkgd-12.png", USE_ALPHA);
2614   img_bkgd[1][3] = load_level_image("bkgd-13.png", USE_ALPHA);
2615 }
2616
2617
2618 /* Load music: */
2619
2620 void loadlevelsong(void)
2621 {
2622
2623   char * song_path;
2624   char * song_subtitle;
2625
2626   song_path = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) +
2627                               strlen(song_title) + 8));
2628   sprintf(song_path, "%s/music/%s", DATA_PREFIX, song_title);
2629   level_song = load_song(song_path);
2630   free(song_path);
2631
2632
2633   song_path = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) +
2634                               strlen(song_title) + 8 + 5));
2635   song_subtitle = strdup(song_title);
2636   strcpy(strstr(song_subtitle, "."), "\0");
2637   sprintf(song_path, "%s/music/%s-fast%s", DATA_PREFIX, song_subtitle, strstr(song_title, "."));
2638   level_song_fast = load_song(song_path);
2639   free(song_subtitle);
2640   free(song_path);
2641 }
2642
2643
2644 /* Free graphics data for this level: */
2645
2646 void unloadlevelgfx(void)
2647 {
2648   int i;
2649
2650   for (i = 0; i < 2; i++)
2651     {
2652       SDL_FreeSurface(img_brick[i]);
2653     }
2654   for (i = 0; i < 4; i++)
2655     {
2656       SDL_FreeSurface(img_solid[i]);
2657       SDL_FreeSurface(img_bkgd[0][i]);
2658       SDL_FreeSurface(img_bkgd[1][i]);
2659     }
2660 }
2661
2662
2663 /* Free music data for this level: */
2664
2665 void unloadlevelsong(void)
2666 {
2667   free_music(level_song);
2668 }
2669
2670
2671 /* Load graphics/sounds shared between all levels: */
2672
2673 void loadshared(void)
2674 {
2675   int i;
2676   char * herring_song_path; /* for loading herring song*/
2677
2678   /* Tuxes: */
2679
2680   tux_right[0] = load_image(DATA_PREFIX "/images/shared/tux-right-0.png",
2681                             USE_ALPHA);
2682
2683   tux_right[1] = load_image(DATA_PREFIX "/images/shared/tux-right-1.png",
2684                             USE_ALPHA);
2685
2686   tux_right[2] = load_image(DATA_PREFIX "/images/shared/tux-right-2.png",
2687                             USE_ALPHA);
2688
2689   tux_left[0] = load_image(DATA_PREFIX "/images/shared/tux-left-0.png",
2690                            USE_ALPHA);
2691
2692   tux_left[1] = load_image(DATA_PREFIX "/images/shared/tux-left-1.png",
2693                            USE_ALPHA);
2694
2695   tux_left[2] = load_image(DATA_PREFIX "/images/shared/tux-left-2.png",
2696                            USE_ALPHA);
2697
2698   firetux_right[0] = load_image(DATA_PREFIX "/images/shared/firetux-right-0.png",
2699                                 USE_ALPHA);
2700
2701   firetux_right[1] = load_image(DATA_PREFIX "/images/shared/firetux-right-1.png",
2702                                 USE_ALPHA);
2703
2704   firetux_right[2] = load_image(DATA_PREFIX "/images/shared/firetux-right-2.png",
2705                                 USE_ALPHA);
2706
2707   firetux_left[0] = load_image(DATA_PREFIX "/images/shared/firetux-left-0.png",
2708                                USE_ALPHA);
2709
2710   firetux_left[1] = load_image(DATA_PREFIX "/images/shared/firetux-left-1.png",
2711                                USE_ALPHA);
2712
2713   firetux_left[2] = load_image(DATA_PREFIX "/images/shared/firetux-left-2.png",
2714                                USE_ALPHA);
2715
2716   cape_right[0] = load_image(DATA_PREFIX "/images/shared/cape-right-0.png",
2717                              USE_ALPHA);
2718
2719   cape_right[1] = load_image(DATA_PREFIX "/images/shared/cape-right-1.png",
2720                              USE_ALPHA);
2721
2722   cape_left[0] = load_image(DATA_PREFIX "/images/shared/cape-left-0.png",
2723                             USE_ALPHA);
2724
2725   cape_left[1] = load_image(DATA_PREFIX "/images/shared/cape-left-1.png",
2726                             USE_ALPHA);
2727
2728   bigtux_right[0] = load_image(DATA_PREFIX "/images/shared/bigtux-right-0.png",
2729                                USE_ALPHA);
2730
2731   bigtux_right[1] = load_image(DATA_PREFIX "/images/shared/bigtux-right-1.png",
2732                                USE_ALPHA);
2733
2734   bigtux_right[2] = load_image(DATA_PREFIX "/images/shared/bigtux-right-2.png",
2735                                USE_ALPHA);
2736
2737   bigtux_right_jump =
2738     load_image(DATA_PREFIX "/images/shared/bigtux-right-jump.png", USE_ALPHA);
2739
2740   bigtux_left[0] = load_image(DATA_PREFIX "/images/shared/bigtux-left-0.png",
2741                               USE_ALPHA);
2742
2743   bigtux_left[1] = load_image(DATA_PREFIX "/images/shared/bigtux-left-1.png",
2744                               USE_ALPHA);
2745
2746   bigtux_left[2] = load_image(DATA_PREFIX "/images/shared/bigtux-left-2.png",
2747                               USE_ALPHA);
2748
2749   bigtux_left_jump =
2750     load_image(DATA_PREFIX "/images/shared/bigtux-left-jump.png", USE_ALPHA);
2751
2752   bigcape_right[0] =
2753     load_image(DATA_PREFIX "/images/shared/bigcape-right-0.png",
2754                USE_ALPHA);
2755
2756   bigcape_right[1] =
2757     load_image(DATA_PREFIX "/images/shared/bigcape-right-1.png",
2758                USE_ALPHA);
2759
2760   bigcape_left[0] =
2761     load_image(DATA_PREFIX "/images/shared/bigcape-left-0.png",
2762                USE_ALPHA);
2763
2764   bigcape_left[1] =
2765     load_image(DATA_PREFIX "/images/shared/bigcape-left-1.png",
2766                USE_ALPHA);
2767
2768   bigfiretux_right[0] = load_image(DATA_PREFIX "/images/shared/bigfiretux-right-0.png",
2769                                    USE_ALPHA);
2770
2771   bigfiretux_right[1] = load_image(DATA_PREFIX "/images/shared/bigfiretux-right-1.png",
2772                                    USE_ALPHA);
2773
2774   bigfiretux_right[2] = load_image(DATA_PREFIX "/images/shared/bigfiretux-right-2.png",
2775                                    USE_ALPHA);
2776
2777   bigfiretux_right_jump =
2778     load_image(DATA_PREFIX "/images/shared/bigfiretux-right-jump.png", USE_ALPHA);
2779
2780   bigfiretux_left[0] = load_image(DATA_PREFIX "/images/shared/bigfiretux-left-0.png",
2781                                   USE_ALPHA);
2782
2783   bigfiretux_left[1] = load_image(DATA_PREFIX "/images/shared/bigfiretux-left-1.png",
2784                                   USE_ALPHA);
2785
2786   bigfiretux_left[2] = load_image(DATA_PREFIX "/images/shared/bigfiretux-left-2.png",
2787                                   USE_ALPHA);
2788
2789   bigfiretux_left_jump =
2790     load_image(DATA_PREFIX "/images/shared/bigfiretux-left-jump.png", USE_ALPHA);
2791
2792   bigcape_right[0] =
2793     load_image(DATA_PREFIX "/images/shared/bigcape-right-0.png",
2794                USE_ALPHA);
2795
2796   bigcape_right[1] =
2797     load_image(DATA_PREFIX "/images/shared/bigcape-right-1.png",
2798                USE_ALPHA);
2799
2800   bigcape_left[0] =
2801     load_image(DATA_PREFIX "/images/shared/bigcape-left-0.png",
2802                USE_ALPHA);
2803
2804   bigcape_left[1] =
2805     load_image(DATA_PREFIX "/images/shared/bigcape-left-1.png",
2806                USE_ALPHA);
2807
2808
2809   ducktux_right = load_image(DATA_PREFIX
2810                              "/images/shared/ducktux-right.png",
2811                              USE_ALPHA);
2812
2813   ducktux_left = load_image(DATA_PREFIX
2814                             "/images/shared/ducktux-left.png",
2815                             USE_ALPHA);
2816
2817   skidtux_right = load_image(DATA_PREFIX
2818                              "/images/shared/skidtux-right.png",
2819                              USE_ALPHA);
2820
2821   skidtux_left = load_image(DATA_PREFIX
2822                             "/images/shared/skidtux-left.png",
2823                             USE_ALPHA);
2824
2825   duckfiretux_right = load_image(DATA_PREFIX
2826                                  "/images/shared/duckfiretux-right.png",
2827                                  USE_ALPHA);
2828
2829   duckfiretux_left = load_image(DATA_PREFIX
2830                                 "/images/shared/duckfiretux-left.png",
2831                                 USE_ALPHA);
2832
2833   skidfiretux_right = load_image(DATA_PREFIX
2834                                  "/images/shared/skidfiretux-right.png",
2835                                  USE_ALPHA);
2836
2837   skidfiretux_left = load_image(DATA_PREFIX
2838                                 "/images/shared/skidfiretux-left.png",
2839                                 USE_ALPHA);
2840
2841
2842   /* Boxes: */
2843
2844   img_box_full = load_image(DATA_PREFIX "/images/shared/box-full.png",
2845                             IGNORE_ALPHA);
2846   img_box_empty = load_image(DATA_PREFIX "/images/shared/box-empty.png",
2847                              IGNORE_ALPHA);
2848
2849
2850   /* Water: */
2851
2852
2853   img_water = load_image(DATA_PREFIX "/images/shared/water.png", IGNORE_ALPHA);
2854
2855   img_waves[0] = load_image(DATA_PREFIX "/images/shared/waves-0.png",
2856                             USE_ALPHA);
2857
2858   img_waves[1] = load_image(DATA_PREFIX "/images/shared/waves-1.png",
2859                             USE_ALPHA);
2860
2861   img_waves[2] = load_image(DATA_PREFIX "/images/shared/waves-2.png",
2862                             USE_ALPHA);
2863
2864
2865   /* Pole: */
2866
2867   img_pole = load_image(DATA_PREFIX "/images/shared/pole.png", USE_ALPHA);
2868   img_poletop = load_image(DATA_PREFIX "/images/shared/poletop.png",
2869                            USE_ALPHA);
2870
2871
2872   /* Flag: */
2873
2874   img_flag[0] = load_image(DATA_PREFIX "/images/shared/flag-0.png",
2875                            USE_ALPHA);
2876   img_flag[1] = load_image(DATA_PREFIX "/images/shared/flag-1.png",
2877                            USE_ALPHA);
2878
2879
2880   /* Cloud: */
2881
2882   img_cloud[0][0] = load_image(DATA_PREFIX "/images/shared/cloud-00.png",
2883                                USE_ALPHA);
2884
2885   img_cloud[0][1] = load_image(DATA_PREFIX "/images/shared/cloud-01.png",
2886                                USE_ALPHA);
2887
2888   img_cloud[0][2] = load_image(DATA_PREFIX "/images/shared/cloud-02.png",
2889                                USE_ALPHA);
2890
2891   img_cloud[0][3] = load_image(DATA_PREFIX "/images/shared/cloud-03.png",
2892                                USE_ALPHA);
2893
2894
2895   img_cloud[1][0] = load_image(DATA_PREFIX "/images/shared/cloud-10.png",
2896                                USE_ALPHA);
2897
2898   img_cloud[1][1] = load_image(DATA_PREFIX "/images/shared/cloud-11.png",
2899                                USE_ALPHA);
2900
2901   img_cloud[1][2] = load_image(DATA_PREFIX "/images/shared/cloud-12.png",
2902                                USE_ALPHA);
2903
2904   img_cloud[1][3] = load_image(DATA_PREFIX "/images/shared/cloud-13.png",
2905                                USE_ALPHA);
2906
2907
2908   /* Bad guys: */
2909
2910   /* (BSOD) */
2911
2912   img_bsod_left[0] = load_image(DATA_PREFIX
2913                                 "/images/shared/bsod-left-0.png",
2914                                 USE_ALPHA);
2915
2916   img_bsod_left[1] = load_image(DATA_PREFIX
2917                                 "/images/shared/bsod-left-1.png",
2918                                 USE_ALPHA);
2919
2920   img_bsod_left[2] = load_image(DATA_PREFIX
2921                                 "/images/shared/bsod-left-2.png",
2922                                 USE_ALPHA);
2923
2924   img_bsod_left[3] = load_image(DATA_PREFIX
2925                                 "/images/shared/bsod-left-3.png",
2926                                 USE_ALPHA);
2927
2928   img_bsod_right[0] = load_image(DATA_PREFIX
2929                                  "/images/shared/bsod-right-0.png",
2930                                  USE_ALPHA);
2931
2932   img_bsod_right[1] = load_image(DATA_PREFIX
2933                                  "/images/shared/bsod-right-1.png",
2934                                  USE_ALPHA);
2935
2936   img_bsod_right[2] = load_image(DATA_PREFIX
2937                                  "/images/shared/bsod-right-2.png",
2938                                  USE_ALPHA);
2939
2940   img_bsod_right[3] = load_image(DATA_PREFIX
2941                                  "/images/shared/bsod-right-3.png",
2942                                  USE_ALPHA);
2943
2944   img_bsod_squished_left = load_image(DATA_PREFIX
2945                                       "/images/shared/bsod-squished-left.png",
2946                                       USE_ALPHA);
2947
2948   img_bsod_squished_right = load_image(DATA_PREFIX
2949                                        "/images/shared/bsod-squished-right.png",
2950                                        USE_ALPHA);
2951
2952   img_bsod_falling_left = load_image(DATA_PREFIX
2953                                      "/images/shared/bsod-falling-left.png",
2954                                      USE_ALPHA);
2955
2956   img_bsod_falling_right = load_image(DATA_PREFIX
2957                                       "/images/shared/bsod-falling-right.png",
2958                                       USE_ALPHA);
2959
2960
2961   /* (Laptop) */
2962
2963   img_laptop_left[0] = load_image(DATA_PREFIX
2964                                   "/images/shared/laptop-left-0.png",
2965                                   USE_ALPHA);
2966
2967   img_laptop_left[1] = load_image(DATA_PREFIX
2968                                   "/images/shared/laptop-left-1.png",
2969                                   USE_ALPHA);
2970
2971   img_laptop_left[2] = load_image(DATA_PREFIX
2972                                   "/images/shared/laptop-left-2.png",
2973                                   USE_ALPHA);
2974
2975   img_laptop_right[0] = load_image(DATA_PREFIX
2976                                    "/images/shared/laptop-right-0.png",
2977                                    USE_ALPHA);
2978
2979   img_laptop_right[1] = load_image(DATA_PREFIX
2980                                    "/images/shared/laptop-right-1.png",
2981                                    USE_ALPHA);
2982
2983   img_laptop_right[2] = load_image(DATA_PREFIX
2984                                    "/images/shared/laptop-right-2.png",
2985                                    USE_ALPHA);
2986
2987   img_laptop_flat_left = load_image(DATA_PREFIX
2988                                     "/images/shared/laptop-flat-left.png",
2989                                     USE_ALPHA);
2990
2991   img_laptop_flat_right = load_image(DATA_PREFIX
2992                                      "/images/shared/laptop-flat-right.png",
2993                                      USE_ALPHA);
2994
2995   img_laptop_falling_left =
2996     load_image(DATA_PREFIX
2997                "/images/shared/laptop-falling-left.png",
2998                USE_ALPHA);
2999
3000   img_laptop_falling_right =
3001     load_image(DATA_PREFIX
3002                "/images/shared/laptop-falling-right.png",
3003                USE_ALPHA);
3004
3005
3006   /* (Money) */
3007
3008   img_money_left[0] = load_image(DATA_PREFIX
3009                                  "/images/shared/bag-left-0.png",
3010                                  USE_ALPHA);
3011
3012   img_money_left[1] = load_image(DATA_PREFIX
3013                                  "/images/shared/bag-left-1.png",
3014                                  USE_ALPHA);
3015
3016   img_money_right[0] = load_image(DATA_PREFIX
3017                                   "/images/shared/bag-right-0.png",
3018                                   USE_ALPHA);
3019
3020   img_money_right[1] = load_image(DATA_PREFIX
3021                                   "/images/shared/bag-right-1.png",
3022                                   USE_ALPHA);
3023
3024
3025
3026   /* Upgrades: */
3027
3028   img_mints = load_image(DATA_PREFIX "/images/shared/mints.png", USE_ALPHA);
3029   img_coffee = load_image(DATA_PREFIX "/images/shared/coffee.png", USE_ALPHA);
3030
3031
3032   /* Weapons: */
3033
3034   img_bullet = load_image(DATA_PREFIX "/images/shared/bullet.png", USE_ALPHA);
3035
3036   img_red_glow = load_image(DATA_PREFIX "/images/shared/red-glow.png",
3037                             USE_ALPHA);
3038
3039
3040
3041   /* Distros: */
3042
3043   img_distro[0] = load_image(DATA_PREFIX "/images/shared/distro-0.png",
3044                              USE_ALPHA);
3045
3046   img_distro[1] = load_image(DATA_PREFIX "/images/shared/distro-1.png",
3047                              USE_ALPHA);
3048
3049   img_distro[2] = load_image(DATA_PREFIX "/images/shared/distro-2.png",
3050                              USE_ALPHA);
3051
3052   img_distro[3] = load_image(DATA_PREFIX "/images/shared/distro-3.png",
3053                              USE_ALPHA);
3054
3055
3056   /* Tux life: */
3057
3058   tux_life = load_image(DATA_PREFIX "/images/shared/tux-life.png",
3059                         USE_ALPHA);
3060
3061   /* Herring: */
3062
3063   img_golden_herring =
3064     load_image(DATA_PREFIX "/images/shared/golden-herring.png",
3065                USE_ALPHA);
3066
3067
3068   /* Super background: */
3069
3070   img_super_bkgd = load_image(DATA_PREFIX "/images/shared/super-bkgd.png",
3071                               IGNORE_ALPHA);
3072
3073
3074   /* Sound effects: */
3075
3076   /* if (use_sound) // this will introduce SERIOUS bugs here ! because "load_sound"
3077                     // initialize sounds[i] with the correct pointer's value:
3078                     // NULL or something else. And it will be dangerous to
3079                     // play with not-initialized pointers.
3080                     // This is also true with if (use_music)
3081      Send a mail to me: neoneurone@users.sf.net, if you have another opinion. :)
3082   */
3083   for (i = 0; i < NUM_SOUNDS; i++)
3084     sounds[i] = load_sound(soundfilenames[i]);
3085
3086   /* Herring song */
3087   herring_song_path = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) +
3088                                       strlen("SALCON.MOD") + 8)); /* FIXME: We need a real herring_song! Thats a fake.:) */
3089
3090   sprintf(herring_song_path, "%s/music/%s", DATA_PREFIX, "SALCON.MOD");
3091
3092   herring_song = load_song(herring_song_path);
3093
3094   free(herring_song_path);
3095
3096 }
3097
3098
3099 /* Free shared data: */
3100
3101 void unloadshared(void)
3102 {
3103   int i;
3104
3105   for (i = 0; i < 3; i++)
3106     {
3107       SDL_FreeSurface(tux_right[i]);
3108       SDL_FreeSurface(tux_left[i]);
3109       SDL_FreeSurface(bigtux_right[i]);
3110       SDL_FreeSurface(bigtux_left[i]);
3111     }
3112
3113   SDL_FreeSurface(bigtux_right_jump);
3114   SDL_FreeSurface(bigtux_left_jump);
3115
3116   for (i = 0; i < 2; i++)
3117     {
3118       SDL_FreeSurface(cape_right[i]);
3119       SDL_FreeSurface(cape_left[i]);
3120       SDL_FreeSurface(bigcape_right[i]);
3121       SDL_FreeSurface(bigcape_left[i]);
3122     }
3123
3124   SDL_FreeSurface(ducktux_left);
3125   SDL_FreeSurface(ducktux_right);
3126
3127   SDL_FreeSurface(skidtux_left);
3128   SDL_FreeSurface(skidtux_right);
3129
3130   for (i = 0; i < 4; i++)
3131     {
3132       SDL_FreeSurface(img_bsod_left[i]);
3133       SDL_FreeSurface(img_bsod_right[i]);
3134     }
3135
3136   SDL_FreeSurface(img_bsod_squished_left);
3137   SDL_FreeSurface(img_bsod_squished_right);
3138
3139   SDL_FreeSurface(img_bsod_falling_left);
3140   SDL_FreeSurface(img_bsod_falling_right);
3141
3142   for (i = 0; i < 3; i++)
3143     {
3144       SDL_FreeSurface(img_laptop_left[i]);
3145       SDL_FreeSurface(img_laptop_right[i]);
3146     }
3147
3148   SDL_FreeSurface(img_laptop_flat_left);
3149   SDL_FreeSurface(img_laptop_flat_right);
3150
3151   SDL_FreeSurface(img_laptop_falling_left);
3152   SDL_FreeSurface(img_laptop_falling_right);
3153
3154   for (i = 0; i < 2; i++)
3155     {
3156       SDL_FreeSurface(img_money_left[i]);
3157       SDL_FreeSurface(img_money_right[i]);
3158     }
3159
3160   SDL_FreeSurface(img_box_full);
3161   SDL_FreeSurface(img_box_empty);
3162
3163   SDL_FreeSurface(img_water);
3164   for (i = 0; i < 3; i++)
3165     SDL_FreeSurface(img_waves[i]);
3166
3167   SDL_FreeSurface(img_pole);
3168   SDL_FreeSurface(img_poletop);
3169
3170   for (i = 0; i < 2; i++)
3171     SDL_FreeSurface(img_flag[i]);
3172
3173   SDL_FreeSurface(img_mints);
3174   SDL_FreeSurface(img_coffee);
3175
3176   for (i = 0; i < 4; i++)
3177     {
3178       SDL_FreeSurface(img_distro[i]);
3179       SDL_FreeSurface(img_cloud[0][i]);
3180       SDL_FreeSurface(img_cloud[1][i]);
3181     }
3182
3183   SDL_FreeSurface(img_golden_herring);
3184
3185   for (i = 0; i < NUM_SOUNDS; i++)
3186     free_chunk(sounds[i]);
3187
3188   /* free the herring song */
3189   free_music( herring_song );
3190 }
3191
3192
3193 /* Draw a tile on the screen: */
3194
3195 void drawshape(int x, int y, unsigned char c)
3196 {
3197   int z;
3198
3199   if (c == 'X' || c == 'x')
3200     drawimage(img_brick[0], x, y, NO_UPDATE);
3201   else if (c == 'Y' || c == 'y')
3202     drawimage(img_brick[1], x, y, NO_UPDATE);
3203   else if (c == 'A' || c =='B' || c == '!')
3204     drawimage(img_box_full, x, y, NO_UPDATE);
3205   else if (c == 'a')
3206     drawimage(img_box_empty, x, y, NO_UPDATE);
3207   else if (c >= 'C' && c <= 'F')
3208     drawimage(img_cloud[0][c - 'C'], x, y, NO_UPDATE);
3209   else if (c >= 'c' && c <= 'f')
3210     drawimage(img_cloud[1][c - 'c'], x, y, NO_UPDATE);
3211   else if (c >= 'G' && c <= 'J')
3212     drawimage(img_bkgd[0][c - 'G'], x, y, NO_UPDATE);
3213   else if (c >= 'g' && c <= 'j')
3214     drawimage(img_bkgd[1][c - 'g'], x, y, NO_UPDATE);
3215   else if (c == '#')
3216     drawimage(img_solid[0], x, y, NO_UPDATE);
3217   else if (c == '[')
3218     drawimage(img_solid[1], x, y, NO_UPDATE);
3219   else if (c == '=')
3220     drawimage(img_solid[2], x, y, NO_UPDATE);
3221   else if (c == ']')
3222     drawimage(img_solid[3], x, y, NO_UPDATE);
3223   else if (c == '$')
3224     {
3225       z = (frame / 2) % 6;
3226
3227       if (z < 4)
3228         drawimage(img_distro[z], x, y, NO_UPDATE);
3229       else if (z == 4)
3230         drawimage(img_distro[2], x, y, NO_UPDATE);
3231       else if (z == 5)
3232         drawimage(img_distro[1], x, y, NO_UPDATE);
3233     }
3234   else if (c == '^')
3235     {
3236       z = (frame / 3) % 3;
3237
3238       drawimage(img_waves[z], x, y, NO_UPDATE);
3239     }
3240   else if (c == '*')
3241     drawimage(img_poletop, x, y, NO_UPDATE);
3242   else if (c == '|')
3243     {
3244       drawimage(img_pole, x, y, NO_UPDATE);
3245
3246       /* Mark this as the end position of the level! */
3247
3248       endpos = x;
3249     }
3250   else if (c == '\\')
3251     {
3252       z = (frame / 3) % 2;
3253
3254       drawimage(img_flag[z], x + 16, y, NO_UPDATE);
3255     }
3256   else if (c == '&')
3257     drawimage(img_water, x, y, NO_UPDATE);
3258 }
3259
3260
3261 /* What shape is at some position? */
3262
3263 unsigned char shape(int x, int y, int sx)
3264 {
3265   int xx, yy;
3266   unsigned char c;
3267
3268   yy = (y / 32);
3269   xx = ((x + sx) / 32);
3270
3271   if (yy >= 0 && yy <= 15 && xx >= 0 && xx <= level_width)
3272     c = tiles[yy][xx];
3273   else
3274     c = '.';
3275
3276   return(c);
3277 }
3278
3279
3280 /* Is is ground? */
3281
3282 int issolid(int x, int y, int sx)
3283 {
3284   int v;
3285
3286   v = 0;
3287
3288   if (isbrick(x, y, sx) ||
3289       isbrick(x + 31, y, sx) ||
3290       isice(x, y, sx) ||
3291       isice(x + 31, y, sx) ||
3292       (shape(x, y, sx) == '[' ||
3293        shape(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) == 'A' ||
3299        shape(x + 31, y, sx) == 'A') ||
3300       (shape(x, y, sx) == 'B' ||
3301        shape(x + 31, y, sx) == 'B') ||
3302       (shape(x, y, sx) == '!' ||
3303        shape(x + 31, y, sx) == '!') ||
3304       (shape(x, y, sx) == 'a' ||
3305        shape(x + 31, y, sx) == 'a'))
3306     {
3307       v = 1;
3308     }
3309
3310   return(v);
3311 }
3312
3313
3314 /* Is it a brick? */
3315
3316 int isbrick(int x, int y, int sx)
3317 {
3318   int v;
3319
3320   v = 0;
3321
3322   if (shape(x, y, sx) == 'X' ||
3323       shape(x, y, sx) == 'x' ||
3324       shape(x, y, sx) == 'Y' ||
3325       shape(x, y, sx) == 'y')
3326     {
3327       v = 1;
3328     }
3329
3330   return(v);
3331 }
3332
3333
3334 /* Is it ice? */
3335
3336 int isice(int x, int y, int sx)
3337 {
3338   int v;
3339
3340   v = 0;
3341
3342   if (shape(x, y, sx) == '#')
3343     {
3344       v = 1;
3345     }
3346
3347   return(v);
3348 }
3349
3350
3351 /* Is it a full box? */
3352
3353 int isfullbox(int x, int y, int sx)
3354 {
3355   int v;
3356
3357   v = 0;
3358
3359   if (shape(x, y, sx) == 'A' ||
3360       shape(x, y, sx) == 'B' ||
3361       shape(x, y, sx) == '!')
3362     {
3363       v = 1;
3364     }
3365
3366   return(v);
3367 }
3368
3369
3370 /* Edit a piece of the map! */
3371
3372 void change(int x, int y, int sx, unsigned char c)
3373 {
3374   int xx, yy;
3375
3376   yy = (y / 32);
3377   xx = ((x + sx) / 32);
3378
3379   if (yy >= 0 && yy <= 15 && xx >= 0 && xx <= level_width)
3380     tiles[yy][xx] = c;
3381 }
3382
3383
3384 /* Break a brick: */
3385
3386 void trybreakbrick(int x, int y, int sx)
3387 {
3388   if (isbrick(x, y, sx))
3389     {
3390       if (shape(x, y, sx) == 'x' || shape(x, y, sx) == 'y')
3391         {
3392           /* Get a distro from it: */
3393
3394           add_bouncy_distro(((x + sx + 1) / 32) * 32,
3395                             (y / 32) * 32);
3396
3397           if (counting_distros == NO)
3398             {
3399               counting_distros = YES;
3400               distro_counter = 50;
3401             }
3402
3403           if (distro_counter <= 0)
3404             change(x, y, sx, 'a');
3405
3406           play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
3407           score = score + SCORE_DISTRO;
3408           distros++;
3409         }
3410       else
3411         {
3412           /* Get rid of it: */
3413
3414           change(x, y, sx, '.');
3415         }
3416
3417
3418       /* Replace it with broken bits: */
3419
3420       add_broken_brick(((x + sx + 1) / 32) * 32,
3421                        (y / 32) * 32);
3422
3423
3424       /* Get some score: */
3425
3426       play_sound(sounds[SND_BRICK], SOUND_CENTER_SPEAKER);
3427       score = score + SCORE_BRICK;
3428     }
3429 }
3430
3431
3432 /* Bounce a brick: */
3433
3434 void bumpbrick(int x, int y, int sx)
3435 {
3436   add_bouncy_brick(((x + sx + 1) / 32) * 32,
3437                    (y / 32) * 32);
3438
3439   play_sound(sounds[SND_BRICK], SOUND_CENTER_SPEAKER);
3440 }
3441
3442
3443 /* Empty a box: */
3444
3445 void tryemptybox(int x, int y, int sx)
3446 {
3447   if (isfullbox(x, y, sx))
3448     {
3449       if (shape(x, y, sx) == 'A')
3450         {
3451           /* Box with a distro! */
3452
3453           add_bouncy_distro(((x + sx + 1) / 32) * 32,
3454                             (y / 32) * 32 - 32);
3455
3456           play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
3457           score = score + SCORE_DISTRO;
3458           distros++;
3459         }
3460       else if (shape(x, y, sx) == 'B')
3461         {
3462           /* Add an upgrade! */
3463
3464           if (tux_size == SMALL)
3465             {
3466               /* Tux is small, add mints! */
3467
3468               add_upgrade(((x + sx + 1) / 32) * 32,
3469                           (y / 32) * 32 - 32,
3470                           UPGRADE_MINTS);
3471             }
3472           else
3473             {
3474               /* Tux is big, add coffee: */
3475
3476               add_upgrade(((x + sx + 1) / 32) * 32,
3477                           (y / 32) * 32 - 32,
3478                           UPGRADE_COFFEE);
3479             }
3480
3481           play_sound(sounds[SND_UPGRADE], SOUND_CENTER_SPEAKER);
3482         }
3483       else if (shape(x, y, sx) == '!')
3484         {
3485           /* Add a golden herring */
3486
3487           add_upgrade(((x + sx + 1) / 32) * 32,
3488                       (y / 32) * 32 - 32,
3489                       UPGRADE_HERRING);
3490         }
3491
3492       /* Empty the box: */
3493
3494       change(x, y, sx, 'a');
3495     }
3496 }
3497
3498
3499 /* Try to grab a distro: */
3500
3501 void trygrabdistro(int x, int y, int sx, int bounciness)
3502 {
3503   if (shape(x, y, sx) == '$')
3504     {
3505       change(x, y, sx, '.');
3506       play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
3507
3508       if (bounciness == BOUNCE)
3509         {
3510           add_bouncy_distro(((x + sx + 1) / 32) * 32,
3511                             (y / 32) * 32);
3512         }
3513
3514       score = score + SCORE_DISTRO;
3515       distros++;
3516     }
3517 }
3518
3519
3520 /* Add a bouncy distro: */
3521
3522 void add_bouncy_distro(int x, int y)
3523 {
3524   int i, found;
3525
3526   found = -1;
3527
3528   for (i = 0; i < NUM_BOUNCY_DISTROS && found == -1; i++)
3529     {
3530       if (!bouncy_distros[i].alive)
3531         found = i;
3532     }
3533
3534   if (found != -1)
3535     {
3536       bouncy_distros[found].alive = YES;
3537       bouncy_distros[found].x = x;
3538       bouncy_distros[found].y = y;
3539       bouncy_distros[found].ym = -6;
3540     }
3541 }
3542
3543
3544 /* Add broken brick pieces: */
3545
3546 void add_broken_brick(int x, int y)
3547 {
3548   add_broken_brick_piece(x, y, -4, -16);
3549   add_broken_brick_piece(x, y + 16, -6, -12);
3550
3551   add_broken_brick_piece(x + 16, y, 4, -16);
3552   add_broken_brick_piece(x + 16, y + 16, 6, -12);
3553 }
3554
3555
3556 /* Add a broken brick piece: */
3557
3558 void add_broken_brick_piece(int x, int y, int xm, int ym)
3559 {
3560   int i, found;
3561
3562   found = -1;
3563
3564   for (i = 0; i < NUM_BROKEN_BRICKS && found == -1; i++)
3565     {
3566       if (!broken_bricks[i].alive)
3567         found = i;
3568     }
3569
3570   if (found != -1)
3571     {
3572       broken_bricks[found].alive = YES;
3573       broken_bricks[found].x = x;
3574       broken_bricks[found].y = y;
3575       broken_bricks[found].xm = xm;
3576       broken_bricks[found].ym = ym;
3577     }
3578 }
3579
3580
3581 /* Add a bouncy brick piece: */
3582
3583 void add_bouncy_brick(int x, int y)
3584 {
3585   int i, found;
3586
3587   found = -1;
3588
3589   for (i = 0; i < NUM_BOUNCY_BRICKS && found == -1; i++)
3590     {
3591       if (!bouncy_bricks[i].alive)
3592         found = i;
3593     }
3594
3595   if (found != -1)
3596     {
3597       bouncy_bricks[found].alive = YES;
3598       bouncy_bricks[found].x = x;
3599       bouncy_bricks[found].y = y;
3600       bouncy_bricks[found].offset = 0;
3601       bouncy_bricks[found].offset_m = -BOUNCY_BRICK_SPEED;
3602       bouncy_bricks[found].shape = shape(x, y, 0);
3603     }
3604 }
3605
3606
3607 /* Add a bad guy: */
3608
3609 void add_bad_guy(int x, int y, int kind)
3610 {
3611   int i, found;
3612
3613   found = -1;
3614
3615   for (i = 0; i < NUM_BAD_GUYS && found == -1; i++)
3616     {
3617       if (!bad_guys[i].alive)
3618         found = i;
3619     }
3620
3621   if (found != -1)
3622     {
3623       bad_guys[found].alive = YES;
3624       bad_guys[found].mode = NORMAL;
3625       bad_guys[found].dying = NO;
3626       bad_guys[found].timer = 0;
3627       bad_guys[found].kind = kind;
3628       bad_guys[found].x = x;
3629       bad_guys[found].y = y;
3630       bad_guys[found].xm = 0;
3631       bad_guys[found].ym = 0;
3632       bad_guys[found].dir = LEFT;
3633       bad_guys[found].seen = NO;
3634     }
3635 }
3636
3637
3638 /* Add score: */
3639
3640 void add_score(int x, int y, int s)
3641 {
3642   int i, found;
3643
3644
3645   /* Add the score: */
3646
3647   score = score + s;
3648
3649
3650   /* Add a floating score thing to the game: */
3651
3652   found = -1;
3653
3654   for (i = 0; i < NUM_FLOATING_SCORES && found == -1; i++)
3655     {
3656       if (!floating_scores[i].alive)
3657         found = i;
3658     }
3659
3660
3661   if (found != -1)
3662     {
3663       floating_scores[found].alive = YES;
3664       floating_scores[found].x = x;
3665       floating_scores[found].y = y - 16;
3666       floating_scores[found].timer = 8;
3667       floating_scores[found].value = s;
3668     }
3669 }
3670
3671
3672 /* Try to bump a bad guy from below: */
3673
3674 void trybumpbadguy(int x, int y, int sx)
3675 {
3676   int i;
3677
3678
3679   /* Bad guys: */
3680
3681   for (i = 0; i < NUM_BAD_GUYS; i++)
3682     {
3683       if (bad_guys[i].alive &&
3684           bad_guys[i].x >= x + sx - 32 && bad_guys[i].x <= x + sx + 32 &&
3685           bad_guys[i].y >= y - 16 && bad_guys[i].y <= y + 16)
3686         {
3687           if (bad_guys[i].kind == BAD_BSOD ||
3688               bad_guys[i].kind == BAD_LAPTOP)
3689             {
3690               bad_guys[i].dying = FALLING;
3691               bad_guys[i].ym = -8;
3692               play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
3693             }
3694         }
3695     }
3696
3697
3698   /* Upgrades: */
3699
3700   for (i = 0; i < NUM_UPGRADES; i++)
3701     {
3702       if (upgrades[i].alive && upgrades[i].height == 32 &&
3703           upgrades[i].x >= x + sx - 32 && upgrades[i].x <= x + sx + 32 &&
3704           upgrades[i].y >= y - 16 && upgrades[i].y <= y + 16)
3705         {
3706           upgrades[i].xm = -upgrades[i].xm;
3707           upgrades[i].ym = -8;
3708           play_sound(sounds[SND_BUMP_UPGRADE], SOUND_CENTER_SPEAKER);
3709         }
3710     }
3711 }
3712
3713
3714 /* Add an upgrade: */
3715
3716 void add_upgrade(int x, int y, int kind)
3717 {
3718   int i, found;
3719
3720   found = -1;
3721
3722   for (i = 0; i < NUM_UPGRADES && found == -1; i++)
3723     {
3724       if (!upgrades[i].alive)
3725         found = i;
3726     }
3727
3728   if (found != -1)
3729     {
3730       upgrades[found].alive = YES;
3731       upgrades[found].kind = kind;
3732       upgrades[found].x = x;
3733       upgrades[found].y = y;
3734       upgrades[found].xm = 4;
3735       upgrades[found].ym = -4;
3736       upgrades[found].height = 0;
3737     }
3738 }
3739
3740
3741 /* Kill tux! */
3742
3743 void killtux(int mode)
3744 {
3745   tux_ym = -16;
3746
3747   play_sound(sounds[SND_HURT], SOUND_CENTER_SPEAKER);
3748
3749   if (tux_dir == RIGHT)
3750     tux_xm = -8;
3751   else if (tux_dir == LEFT)
3752     tux_xm = 8;
3753
3754   if (mode == SHRINK && tux_size == BIG)
3755     {
3756       if (tux_got_coffee)
3757         tux_got_coffee = NO;
3758
3759       tux_size = SMALL;
3760
3761       tux_safe = TUX_SAFE_TIME;
3762     }
3763   else
3764     {
3765       tux_dying = 1;
3766     }
3767 }
3768
3769
3770 /* Add a bullet: */
3771
3772 void add_bullet(int x, int y, int dir, int xm)
3773 {
3774   int i, found;
3775
3776   found = -1;
3777
3778   for (i = 0; i < NUM_BULLETS && found == -1; i++)
3779     {
3780       if (!bullets[i].alive)
3781         found = i;
3782     }
3783
3784   if (found != -1)
3785     {
3786       bullets[found].alive = YES;
3787
3788       if (dir == RIGHT)
3789         {
3790           bullets[found].x = x + 32;
3791           bullets[found].xm = BULLET_XM + xm;
3792         }
3793       else
3794         {
3795           bullets[found].x = x;
3796           bullets[found].xm = -BULLET_XM + xm;
3797         }
3798
3799       bullets[found].y = y;
3800       bullets[found].ym = BULLET_STARTING_YM;
3801
3802       play_sound(sounds[SND_SHOOT], SOUND_CENTER_SPEAKER);
3803     }
3804 }
3805
3806
3807 void drawendscreen(void)
3808 {
3809   char str[80];
3810
3811   clearscreen(0, 0, 0);
3812
3813   drawcenteredtext("GAMEOVER", 200, letters_red, NO_UPDATE, 1);
3814
3815   sprintf(str, "SCORE: %d", score);
3816   drawcenteredtext(str, 224, letters_gold, NO_UPDATE, 1);
3817
3818   sprintf(str, "DISTROS: %d", distros);
3819   drawcenteredtext(str, 256, letters_blue, NO_UPDATE, 1);
3820
3821   SDL_Flip(screen);
3822   SDL_Delay(2000);
3823 }
3824
3825 void drawresultscreen(void)
3826 {
3827   char str[80];
3828
3829   clearscreen(0, 0, 0);
3830
3831   drawcenteredtext("Result:", 200, letters_red, NO_UPDATE, 1);
3832
3833   sprintf(str, "SCORE: %d", score);
3834   drawcenteredtext(str, 224, letters_gold, NO_UPDATE, 1);
3835
3836   sprintf(str, "DISTROS: %d", distros);
3837   drawcenteredtext(str, 256, letters_blue, NO_UPDATE, 1);
3838
3839   SDL_Flip(screen);
3840   /*SDL_Delay(2000);*/
3841   sleep(2);
3842 }
3843
3844 void savegame(void)
3845 {}