Huge code merge. This reflects the current status of my rewrite/restructuring. A...
[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 - January 1st, 2004
11  */
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <errno.h>
17 #include <unistd.h>
18 #include <time.h>
19 #include <SDL.h>
20
21 #ifdef LINUX
22 #include <pwd.h>
23 #include <sys/types.h>
24 #include <ctype.h>
25 #endif
26
27 #include "defines.h"
28 #include "globals.h"
29 #include "gameloop.h"
30 #include "screen.h"
31 #include "setup.h"
32 #include "high_scores.h"
33 #include "menu.h"
34 #include "badguy.h"
35 #include "world.h"
36 #include "special.h"
37 #include "player.h"
38 #include "level.h"
39 #include "scene.h"
40 #include "collision.h"
41
42 /* extern variables */
43
44 extern char* soundfilenames[NUM_SOUNDS];
45
46 /* Local variables: */
47
48 texture_type img_waves[3], img_water, img_pole, img_poletop, img_flag[2];
49 texture_type img_cloud[2][4];
50 SDL_Event event;
51 SDLKey key;
52 char level_subset[100];
53 char str[60];
54 timer_type time_left;
55
56 /* Local function prototypes: */
57
58 void levelintro(void);
59 void initgame(void);
60 void loadlevelsong(void);
61 void unloadlevelsong(void);
62 void loadshared(void);
63 void unloadshared(void);
64 void drawstatus(void);
65 void drawendscreen(void);
66 void drawresultscreen(void);
67
68 void levelintro(void)
69 {
70   /* Level Intro: */
71
72   clearscreen(0, 0, 0);
73
74   sprintf(str, "LEVEL %d", level);
75   drawcenteredtext(str, 200, letters_red, NO_UPDATE, 1);
76
77   sprintf(str, "%s", current_level.name);
78   drawcenteredtext(str, 224, letters_gold, NO_UPDATE, 1);
79
80   sprintf(str, "TUX x %d", tux.lives);
81   drawcenteredtext(str, 256, letters_blue, NO_UPDATE, 1);
82
83   flipscreen();
84
85   SDL_Delay(1000);
86 }
87
88 /* Reset Timers */
89 void start_timers(void)
90 {
91   timer_start(&time_left,current_level.time_left*1000);
92 }
93
94 void activate_bad_guys(void)
95 {
96   int x,y;
97
98   /* Activate bad guys: */
99
100   for (y = 0; y < 15; y++)
101     {
102       for (x = 0; x < current_level.width; x++)
103         {
104           if (current_level.tiles[y][x] >= '0' && current_level.tiles[y][x] <= '9')
105             {
106               add_bad_guy(x * 32, y * 32, current_level.tiles[y][x] - '0');
107               current_level.tiles[y][x] = '.';
108             }
109         }
110     }
111
112 }
113
114 /* --- GAME EVENT! --- */
115
116 void game_event(void)
117 {
118
119   while (SDL_PollEvent(&event))
120     {
121
122       if (event.type == SDL_QUIT)
123         {
124           /* Quit event - quit: */
125
126           quit = 1;
127         }
128       else if (event.type == SDL_KEYDOWN)
129         {
130           /* A keypress! */
131
132           key = event.key.keysym.sym;
133
134           /* Check for menu-events, if the menu is shown */
135           if(show_menu)
136             menu_event(key);
137
138           if (key == SDLK_ESCAPE)
139             {
140               /* Escape: Open/Close the menu: */
141               if(!game_pause)
142                 {
143                   if(show_menu)
144                     show_menu = 0;
145                   else
146                     show_menu = 1;
147                 }
148             }
149           else if (key == SDLK_RIGHT)
150             {
151               tux.input.right = DOWN;
152             }
153           else if (key == SDLK_LEFT)
154             {
155               tux.input.left = DOWN;
156             }
157           else if (key == SDLK_UP)
158             {
159               tux.input.up = DOWN;
160             }
161           else if (key == SDLK_DOWN)
162             {
163               tux.input.down = DOWN;
164             }
165           else if (key == SDLK_LCTRL)
166             {
167               tux.input.fire = DOWN;
168             }
169         }
170       else if (event.type == SDL_KEYUP)
171         {
172           /* A keyrelease! */
173
174           key = event.key.keysym.sym;
175
176           if (key == SDLK_RIGHT)
177             {
178               tux.input.right = UP;
179             }
180           else if (key == SDLK_LEFT)
181             {
182               tux.input.left = UP;
183             }
184           else if (key == SDLK_UP)
185             {
186               tux.input.up = UP;
187             }
188           else if (key == SDLK_DOWN)
189             {
190               tux.input.down = UP;
191             }
192           else if (key == SDLK_LCTRL)
193             {
194               tux.input.fire = UP;
195             }
196           else if (key == SDLK_p)
197             {
198               if(!show_menu)
199                 {
200                   if(game_pause)
201                     game_pause = 0;
202                   else
203                     game_pause = 1;
204                 }
205             }
206           else if (key == SDLK_TAB && debug_mode == YES)
207             {
208               tux.size = !tux.size;
209             }
210           else if (key == SDLK_END && debug_mode == YES)
211             {
212               distros += 50;
213             }
214           else if (key == SDLK_SPACE && debug_mode == YES)
215             {
216               next_level = 1;
217             }
218           else if (key == SDLK_DELETE && debug_mode == YES)
219             {
220               tux.got_coffee = 1;
221             }
222           else if (key == SDLK_INSERT && debug_mode == YES)
223             {
224               timer_start(&tux.invincible_timer,TUX_INVINCIBLE_TIME);
225             }
226         }
227 #ifdef JOY_YES
228       else if (event.type == SDL_JOYAXISMOTION)
229         {
230           if (event.jaxis.axis == JOY_X)
231             {
232               if (event.jaxis.value < -256)
233                 tux.input.left = DOWN;
234               else
235                 tux.input.left = UP;
236
237               if (event.jaxis.value > 256)
238                 tux.input.right = DOWN;
239               else
240                 tux.input.right = UP;
241             }
242           else if (event.jaxis.axis == JOY_Y)
243             {
244               if (event.jaxis.value > 256)
245                 tux.input.down = DOWN;
246               else
247                 tux.input.down = UP;
248
249               /* Handle joystick for the menu */
250               if(show_menu)
251                 {
252                   if(tux.input.down == DOWN)
253                     menuaction = MN_DOWN;
254                   else
255                     menuaction = MN_UP;
256                 }
257             }
258         }
259       else if (event.type == SDL_JOYBUTTONDOWN)
260         {
261           if (event.jbutton.button == JOY_A)
262             tux.input.up = DOWN;
263           else if (event.jbutton.button == JOY_B)
264             tux.input.fire = DOWN;
265         }
266       else if (event.type == SDL_JOYBUTTONUP)
267         {
268           if (event.jbutton.button == JOY_A)
269             tux.input.up = UP;
270           else if (event.jbutton.button == JOY_B)
271             tux.input.fire = UP;
272
273           if(show_menu)
274             menuaction = MN_HIT;
275
276         }
277 #endif
278
279     }
280
281 }
282
283 /* --- GAME ACTION! --- */
284
285 int game_action(void)
286 {
287 int i;
288
289   /* (tux_dying || next_level) */
290   if (tux.dying || next_level)
291     {
292       /* Tux either died, or reached the end of a level! */
293
294
295       if (playing_music())
296         halt_music();
297
298
299       if (next_level)
300         {
301           /* End of a level! */
302           level++;
303           next_level = 0;
304           drawresultscreen();
305         }
306       else
307         {
308
309         player_dying(&tux);
310         
311           /* No more lives!? */
312
313           if (tux.lives < 0)
314             {
315               drawendscreen();
316
317               if (score > highscore)
318                 save_hs(score);
319               unloadlevelgfx();
320               unloadlevelsong();
321               unloadshared();
322               return(0);
323             } /* if (lives < 0) */
324         }
325
326       /* Either way, (re-)load the (next) level... */
327
328       player_level_begin(&tux);
329       set_defaults();
330       loadlevel(&current_level,"default",level);
331       activate_bad_guys();
332       unloadlevelgfx();
333       loadlevelgfx(&current_level);
334       unloadlevelsong();
335       loadlevelsong();
336       levelintro();
337       start_timers();
338     }
339
340   player_action(&tux);
341
342   /* Handle bouncy distros: */
343
344   for (i = 0; i < NUM_BOUNCY_DISTROS; i++)
345     {
346       bouncy_distro_action(&bouncy_distros[i]);
347     }
348
349
350   /* Handle broken bricks: */
351
352   for (i = 0; i < NUM_BROKEN_BRICKS; i++)
353     {
354       broken_brick_action(&broken_bricks[i]);
355     }
356
357
358   /* Handle distro counting: */
359
360   if (counting_distros == YES)
361     {
362       distro_counter--;
363
364       if (distro_counter <= 0)
365         counting_distros = -1;
366     }
367
368
369   /* Handle bouncy bricks: */
370
371   for (i = 0; i < NUM_BOUNCY_BRICKS; i++)
372     {
373       bouncy_brick_action(&bouncy_bricks[i]);
374     }
375
376
377   /* Handle floating scores: */
378
379   for (i = 0; i < NUM_FLOATING_SCORES; i++)
380     {
381       floating_score_action(&floating_scores[i]);
382     }
383
384
385   /* Handle bullets: */
386
387   for (i = 0; i < NUM_BULLETS; ++i)
388     {
389       bullet_action(&bullets[i]);
390     }
391
392
393   /* Handle background timer: */
394
395   if (super_bkgd_time)
396     super_bkgd_time--;
397
398
399   /* Handle upgrades: */
400
401   for (i = 0; i < NUM_UPGRADES; i++)
402     {
403         upgrade_action(&upgrades[i]);
404     } /* for (i = 0; i < NUM_UPGRADES; i++) */
405
406
407   /* Handle bad guys: */
408
409   for (i = 0; i < NUM_BAD_GUYS; i++)
410     {
411         badguy_action(&bad_guys[i]);
412     }
413
414   /* Handle all possible collisions. */
415   collision_handler();
416
417   return -1;
418 }
419
420 /* --- GAME DRAW! --- */
421
422 void game_draw()
423 {
424   int  x, y, i;
425
426   /* Draw screen: */
427
428   if (tux.dying && (frame % 4) == 0)
429     clearscreen(255, 255, 255);
430   else
431     {
432       if (super_bkgd_time == 0)
433         clearscreen(current_level.bkgd_red, current_level.bkgd_green, current_level.bkgd_blue);
434       else
435         texture_draw(&img_super_bkgd, 0, 0, NO_UPDATE);
436     }
437
438   /* Draw background: */
439
440   for (y = 0; y < 15; y++)
441     {
442       for (x = 0; x < 21; x++)
443         {
444           drawshape(x * 32 - ((int)scroll_x % 32), y * 32,
445                     current_level.tiles[(int)y][(int)x + (int)(scroll_x / 32)]);
446         }
447     }
448
449
450   /* (Bouncy bricks): */
451
452   for (i = 0; i < NUM_BOUNCY_BRICKS; i++)
453     {
454         bouncy_brick_draw(&bouncy_bricks[i]);
455     }
456
457
458   /* (Bad guys): */
459
460   for (i = 0; i < NUM_BAD_GUYS; i++)
461     {
462         badguy_draw(&bad_guys[i]);
463     }
464
465   /* (Tux): */
466   
467   player_draw(&tux);
468
469   /* (Bullets): */
470
471   for (i = 0; i < NUM_BULLETS; i++)
472     {
473        bullet_draw(&bullets[i]);
474     }
475
476   /* (Floating scores): */
477
478   for (i = 0; i < NUM_FLOATING_SCORES; i++)
479     {
480         floating_score_draw(&floating_scores[i]);
481     }
482
483
484   /* (Upgrades): */
485
486   for (i = 0; i < NUM_UPGRADES; i++)
487     {
488         upgrade_draw(&upgrades[i]);
489     }
490
491
492   /* (Bouncy distros): */
493
494   for (i = 0; i < NUM_BOUNCY_DISTROS; i++)
495     {
496       bouncy_distro_draw(&bouncy_distros[i]);
497     }
498
499
500   /* (Broken bricks): */
501
502   for (i = 0; i < NUM_BROKEN_BRICKS; i++)
503     {
504         broken_brick_draw(&broken_bricks[i]);
505     }
506
507   drawstatus();
508
509
510   if(game_pause)
511     drawcenteredtext("PAUSE",230,letters_red, NO_UPDATE, 1);
512
513   if(show_menu)
514     done = drawmenu();
515
516   /* (Update it all!) */
517
518   updatescreen();
519
520
521 }
522
523 /* --- GAME LOOP! --- */
524
525 int gameloop(void)
526 {
527
528   Uint32 last_time, now_time;
529
530   /* Clear screen: */
531
532   clearscreen(0, 0, 0);
533   updatescreen();
534
535
536   /* Init the game: */
537
538   initmenu();
539   menumenu = MENU_GAME;
540   initgame();
541   loadshared();
542   set_defaults();
543   
544   loadlevel(&current_level,"default",level);
545   loadlevelgfx(&current_level);
546   activate_bad_guys();
547   loadlevelsong();
548   highscore = load_hs();
549
550   player_init(&tux);
551   
552   levelintro();
553   start_timers();
554     
555   /* --- MAIN GAME LOOP!!! --- */
556
557   done = 0;
558   quit = 0;
559   frame = 0;
560   game_pause = 0;
561   
562   game_draw();
563   do
564     {
565       last_time = SDL_GetTicks();
566       frame++;
567
568
569       /* Handle events: */
570
571       tux.input.old_fire = tux.input.fire;
572
573       game_event();
574
575      
576       /* Handle actions: */
577
578       if(!game_pause && !show_menu)
579         {
580           if (game_action() == 0)
581             {
582               /* == 0: no more lives */
583               /* == -1: continues */
584               return 0;
585             }
586         }
587       else
588         SDL_Delay(50);
589
590       /*Draw the current scene to the screen */
591       game_draw();
592
593       /* Time stops in pause mode */
594       if(game_pause || show_menu )
595         {
596           continue;
597         }
598
599       /* Pause til next frame: */
600
601       now_time = SDL_GetTicks();
602       /*if (now_time < last_time + FPS)
603         SDL_Delay(last_time + FPS - now_time);*/
604         SDL_Delay(10);
605
606
607       /* Handle time: */
608
609       if (timer_check(&time_left))
610         {
611               /* are we low on time ? */
612       if ((timer_get_left(&time_left) < TIME_WARNING)
613           && (current_music != HURRYUP_MUSIC))
614         {
615           current_music = HURRYUP_MUSIC;
616           /* stop the others music, prepare to play the fast music */
617           if (playing_music())
618             {
619               halt_music();
620             }
621         }
622
623         }
624         else
625         player_kill(&tux,KILL);
626         
627
628       /* Keep playing the correct music: */
629
630       if (!playing_music())
631         {
632            play_current_music();
633         }
634
635         
636     }
637   while (!done && !quit);
638
639   if (playing_music())
640     halt_music();
641
642   unloadlevelgfx();
643   unloadlevelsong();
644   unloadshared();
645
646   return(quit);
647 }
648
649
650 /* Initialize the game stuff: */
651
652 void initgame(void)
653 {
654   level = 1;
655   score = 0;
656   distros = 0;
657 }
658
659 /* Free music data for this level: */
660
661 void unloadlevelsong(void)
662 {
663   free_music(level_song);
664   free_music(level_song_fast);
665 }
666
667 /* Load music: */
668
669 void loadlevelsong(void)
670 {
671
672   char * song_path;
673   char * song_subtitle;
674
675   song_path = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) +
676                               strlen(current_level.song_title) + 8));
677   sprintf(song_path, "%s/music/%s", DATA_PREFIX, current_level.song_title);
678   level_song = load_song(song_path);
679   free(song_path);
680
681   
682   song_path = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) +
683                               strlen(current_level.song_title) + 8 + 5));
684   song_subtitle = strdup(current_level.song_title);
685   strcpy(strstr(song_subtitle, "."), "\0");
686   sprintf(song_path, "%s/music/%s-fast%s", DATA_PREFIX, song_subtitle, strstr(current_level.song_title, "."));
687   level_song_fast = load_song(song_path);
688   free(song_subtitle);
689   free(song_path);
690 }
691
692 /* Load graphics/sounds shared between all levels: */
693
694 void loadshared(void)
695 {
696   int i;
697   char * herring_song_path; /* for loading herring song*/
698
699   /* Tuxes: */
700
701   texture_load(&tux_right[0],DATA_PREFIX "/images/shared/tux-right-0.png", USE_ALPHA);
702   texture_load(&tux_right[1],DATA_PREFIX "/images/shared/tux-right-1.png", USE_ALPHA);
703   texture_load(&tux_right[2],DATA_PREFIX "/images/shared/tux-right-2.png", USE_ALPHA);  
704
705   texture_load(&tux_left[0],DATA_PREFIX "/images/shared/tux-left-0.png", USE_ALPHA);
706   texture_load(&tux_left[1],DATA_PREFIX "/images/shared/tux-left-1.png", USE_ALPHA);
707   texture_load(&tux_left[2],DATA_PREFIX "/images/shared/tux-left-2.png", USE_ALPHA);  
708   
709   texture_load(&firetux_right[0],DATA_PREFIX "/images/shared/firetux-right-0.png", USE_ALPHA);  
710   texture_load(&firetux_right[1],DATA_PREFIX "/images/shared/firetux-right-1.png", USE_ALPHA); 
711   texture_load(&firetux_right[2],DATA_PREFIX "/images/shared/firetux-right-2.png", USE_ALPHA); 
712
713   texture_load(&firetux_left[0],DATA_PREFIX "/images/shared/firetux-left-0.png", USE_ALPHA);  
714   texture_load(&firetux_left[1],DATA_PREFIX "/images/shared/firetux-left-1.png", USE_ALPHA); 
715   texture_load(&firetux_left[2],DATA_PREFIX "/images/shared/firetux-left-2.png", USE_ALPHA); 
716
717
718   texture_load(&cape_right[0] ,DATA_PREFIX "/images/shared/cape-right-0.png",
719                              USE_ALPHA);
720
721   texture_load(&cape_right[1] ,DATA_PREFIX "/images/shared/cape-right-1.png",
722                              USE_ALPHA);
723
724   texture_load(&cape_left[0] ,DATA_PREFIX "/images/shared/cape-left-0.png",
725                             USE_ALPHA);
726
727   texture_load(&cape_left[1] ,DATA_PREFIX "/images/shared/cape-left-1.png",
728                             USE_ALPHA);
729
730   texture_load(&bigtux_right[0] ,DATA_PREFIX "/images/shared/bigtux-right-0.png",
731                                USE_ALPHA);
732
733   texture_load(&bigtux_right[1] ,DATA_PREFIX "/images/shared/bigtux-right-1.png",
734                                USE_ALPHA);
735
736   texture_load(&bigtux_right[2] ,DATA_PREFIX "/images/shared/bigtux-right-2.png",
737                                USE_ALPHA);
738
739   texture_load(&bigtux_right_jump ,DATA_PREFIX "/images/shared/bigtux-right-jump.png", USE_ALPHA);
740
741   texture_load(&bigtux_left[0] ,DATA_PREFIX "/images/shared/bigtux-left-0.png",
742                               USE_ALPHA);
743
744   texture_load(&bigtux_left[1] ,DATA_PREFIX "/images/shared/bigtux-left-1.png",
745                               USE_ALPHA);
746
747   texture_load(&bigtux_left[2] ,DATA_PREFIX "/images/shared/bigtux-left-2.png",
748                               USE_ALPHA);
749
750   texture_load(&bigtux_left_jump ,DATA_PREFIX "/images/shared/bigtux-left-jump.png", USE_ALPHA);
751
752   texture_load(&bigcape_right[0] ,DATA_PREFIX "/images/shared/bigcape-right-0.png",
753                USE_ALPHA);
754
755   texture_load(&bigcape_right[1] ,DATA_PREFIX "/images/shared/bigcape-right-1.png",
756                USE_ALPHA);
757
758   texture_load(&bigcape_left[0] ,DATA_PREFIX "/images/shared/bigcape-left-0.png",
759                USE_ALPHA);
760
761   texture_load(&bigcape_left[1] ,DATA_PREFIX "/images/shared/bigcape-left-1.png",
762                USE_ALPHA);
763
764   texture_load(&bigfiretux_right[0] ,DATA_PREFIX "/images/shared/bigfiretux-right-0.png",
765                                    USE_ALPHA);
766
767   texture_load(&bigfiretux_right[1] ,DATA_PREFIX "/images/shared/bigfiretux-right-1.png",
768                                    USE_ALPHA);
769
770   texture_load(&bigfiretux_right[2] ,DATA_PREFIX "/images/shared/bigfiretux-right-2.png",
771                                    USE_ALPHA);
772
773   texture_load(&bigfiretux_right_jump ,DATA_PREFIX "/images/shared/bigfiretux-right-jump.png", USE_ALPHA);
774
775   texture_load(&bigfiretux_left[0] ,DATA_PREFIX "/images/shared/bigfiretux-left-0.png",
776                                   USE_ALPHA);
777
778   texture_load(&bigfiretux_left[1] ,DATA_PREFIX "/images/shared/bigfiretux-left-1.png",
779                                   USE_ALPHA);
780
781   texture_load(&bigfiretux_left[2] ,DATA_PREFIX "/images/shared/bigfiretux-left-2.png",
782                                   USE_ALPHA);
783
784   texture_load(&bigfiretux_left_jump ,DATA_PREFIX "/images/shared/bigfiretux-left-jump.png", USE_ALPHA);
785
786   texture_load(&bigcape_right[0] ,DATA_PREFIX "/images/shared/bigcape-right-0.png",
787                USE_ALPHA);
788
789   texture_load(&bigcape_right[1] ,DATA_PREFIX "/images/shared/bigcape-right-1.png",
790                USE_ALPHA);
791
792   texture_load(&bigcape_left[0] ,DATA_PREFIX "/images/shared/bigcape-left-0.png",
793                USE_ALPHA);
794
795   texture_load(&bigcape_left[1] ,DATA_PREFIX "/images/shared/bigcape-left-1.png",
796                USE_ALPHA);
797
798
799   texture_load(&ducktux_right ,DATA_PREFIX
800                              "/images/shared/ducktux-right.png",
801                              USE_ALPHA);
802
803   texture_load(&ducktux_left ,DATA_PREFIX
804                             "/images/shared/ducktux-left.png",
805                             USE_ALPHA);
806
807   texture_load(&skidtux_right ,DATA_PREFIX
808                              "/images/shared/skidtux-right.png",
809                              USE_ALPHA);
810
811   texture_load(&skidtux_left ,DATA_PREFIX
812                             "/images/shared/skidtux-left.png",
813                             USE_ALPHA);
814
815   texture_load(&duckfiretux_right ,DATA_PREFIX
816                                  "/images/shared/duckfiretux-right.png",
817                                  USE_ALPHA);
818
819   texture_load(&duckfiretux_left ,DATA_PREFIX
820                                 "/images/shared/duckfiretux-left.png",
821                                 USE_ALPHA);
822
823   texture_load(&skidfiretux_right ,DATA_PREFIX
824                                  "/images/shared/skidfiretux-right.png",
825                                  USE_ALPHA);
826
827   texture_load(&skidfiretux_left ,DATA_PREFIX
828                                 "/images/shared/skidfiretux-left.png",
829                                 USE_ALPHA);
830
831
832   /* Boxes: */
833
834   texture_load(&img_box_full ,DATA_PREFIX "/images/shared/box-full.png",
835                             IGNORE_ALPHA);
836   texture_load(&img_box_empty ,DATA_PREFIX "/images/shared/box-empty.png",
837                              IGNORE_ALPHA);
838
839
840   /* Water: */
841
842
843   texture_load(&img_water ,DATA_PREFIX "/images/shared/water.png", IGNORE_ALPHA);
844
845   texture_load(&img_waves[0] ,DATA_PREFIX "/images/shared/waves-0.png",
846                             USE_ALPHA);
847
848   texture_load(&img_waves[1] ,DATA_PREFIX "/images/shared/waves-1.png",
849                             USE_ALPHA);
850
851   texture_load(&img_waves[2] ,DATA_PREFIX "/images/shared/waves-2.png",
852                             USE_ALPHA);
853
854
855   /* Pole: */
856
857   texture_load(&img_pole ,DATA_PREFIX "/images/shared/pole.png", USE_ALPHA);
858   texture_load(&img_poletop ,DATA_PREFIX "/images/shared/poletop.png",
859                            USE_ALPHA);
860
861
862   /* Flag: */
863
864   texture_load(&img_flag[0] ,DATA_PREFIX "/images/shared/flag-0.png",
865                            USE_ALPHA);
866   texture_load(&img_flag[1] ,DATA_PREFIX "/images/shared/flag-1.png",
867                            USE_ALPHA);
868
869
870   /* Cloud: */
871
872   texture_load(&img_cloud[0][0] ,DATA_PREFIX "/images/shared/cloud-00.png",
873                                USE_ALPHA);
874
875   texture_load(&img_cloud[0][1] ,DATA_PREFIX "/images/shared/cloud-01.png",
876                                USE_ALPHA);
877
878   texture_load(&img_cloud[0][2] ,DATA_PREFIX "/images/shared/cloud-02.png",
879                                USE_ALPHA);
880
881   texture_load(&img_cloud[0][3] ,DATA_PREFIX "/images/shared/cloud-03.png",
882                                USE_ALPHA);
883
884
885   texture_load(&img_cloud[1][0] ,DATA_PREFIX "/images/shared/cloud-10.png",
886                                USE_ALPHA);
887
888   texture_load(&img_cloud[1][1] ,DATA_PREFIX "/images/shared/cloud-11.png",
889                                USE_ALPHA);
890
891   texture_load(&img_cloud[1][2] ,DATA_PREFIX "/images/shared/cloud-12.png",
892                                USE_ALPHA);
893
894   texture_load(&img_cloud[1][3] ,DATA_PREFIX "/images/shared/cloud-13.png",
895                                USE_ALPHA);
896
897
898   /* Bad guys: */
899
900   /* (BSOD) */
901
902   texture_load(&img_bsod_left[0] ,DATA_PREFIX
903                                 "/images/shared/bsod-left-0.png",
904                                 USE_ALPHA);
905
906   texture_load(&img_bsod_left[1] ,DATA_PREFIX
907                                 "/images/shared/bsod-left-1.png",
908                                 USE_ALPHA);
909
910   texture_load(&img_bsod_left[2] ,DATA_PREFIX
911                                 "/images/shared/bsod-left-2.png",
912                                 USE_ALPHA);
913
914   texture_load(&img_bsod_left[3] ,DATA_PREFIX
915                                 "/images/shared/bsod-left-3.png",
916                                 USE_ALPHA);
917
918   texture_load(&img_bsod_right[0] ,DATA_PREFIX
919                                  "/images/shared/bsod-right-0.png",
920                                  USE_ALPHA);
921
922   texture_load(&img_bsod_right[1] ,DATA_PREFIX
923                                  "/images/shared/bsod-right-1.png",
924                                  USE_ALPHA);
925
926   texture_load(&img_bsod_right[2] ,DATA_PREFIX
927                                  "/images/shared/bsod-right-2.png",
928                                  USE_ALPHA);
929
930   texture_load(&img_bsod_right[3] ,DATA_PREFIX
931                                  "/images/shared/bsod-right-3.png",
932                                  USE_ALPHA);
933
934   texture_load(&img_bsod_squished_left ,DATA_PREFIX
935                                       "/images/shared/bsod-squished-left.png",
936                                       USE_ALPHA);
937
938   texture_load(&img_bsod_squished_right ,DATA_PREFIX
939                                        "/images/shared/bsod-squished-right.png",
940                                        USE_ALPHA);
941
942   texture_load(&img_bsod_falling_left ,DATA_PREFIX
943                                      "/images/shared/bsod-falling-left.png",
944                                      USE_ALPHA);
945
946   texture_load(&img_bsod_falling_right ,DATA_PREFIX
947                                       "/images/shared/bsod-falling-right.png",
948                                       USE_ALPHA);
949
950
951   /* (Laptop) */
952
953   texture_load(&img_laptop_left[0] ,DATA_PREFIX
954                                   "/images/shared/laptop-left-0.png",
955                                   USE_ALPHA);
956
957   texture_load(&img_laptop_left[1] ,DATA_PREFIX
958                                   "/images/shared/laptop-left-1.png",
959                                   USE_ALPHA);
960
961   texture_load(&img_laptop_left[2] ,DATA_PREFIX
962                                   "/images/shared/laptop-left-2.png",
963                                   USE_ALPHA);
964
965   texture_load(&img_laptop_right[0] ,DATA_PREFIX
966                                    "/images/shared/laptop-right-0.png",
967                                    USE_ALPHA);
968
969   texture_load(&img_laptop_right[1] ,DATA_PREFIX
970                                    "/images/shared/laptop-right-1.png",
971                                    USE_ALPHA);
972
973   texture_load(&img_laptop_right[2] ,DATA_PREFIX
974                                    "/images/shared/laptop-right-2.png",
975                                    USE_ALPHA);
976
977   texture_load(&img_laptop_flat_left ,DATA_PREFIX
978                                     "/images/shared/laptop-flat-left.png",
979                                     USE_ALPHA);
980
981   texture_load(&img_laptop_flat_right ,DATA_PREFIX
982                                      "/images/shared/laptop-flat-right.png",
983                                      USE_ALPHA);
984
985   texture_load(&img_laptop_falling_left ,DATA_PREFIX
986                "/images/shared/laptop-falling-left.png",
987                USE_ALPHA);
988
989   texture_load(&img_laptop_falling_right ,DATA_PREFIX
990                "/images/shared/laptop-falling-right.png",
991                USE_ALPHA);
992
993
994   /* (Money) */
995
996   texture_load(&img_money_left[0] ,DATA_PREFIX
997                                  "/images/shared/bag-left-0.png",
998                                  USE_ALPHA);
999
1000   texture_load(&img_money_left[1] ,DATA_PREFIX
1001                                  "/images/shared/bag-left-1.png",
1002                                  USE_ALPHA);
1003
1004   texture_load(&img_money_right[0] ,DATA_PREFIX
1005                                   "/images/shared/bag-right-0.png",
1006                                   USE_ALPHA);
1007
1008   texture_load(&img_money_right[1] ,DATA_PREFIX
1009                                   "/images/shared/bag-right-1.png",
1010                                   USE_ALPHA);
1011
1012
1013
1014   /* Upgrades: */
1015
1016   texture_load(&img_mints ,DATA_PREFIX "/images/shared/mints.png", USE_ALPHA);
1017   texture_load(&img_coffee ,DATA_PREFIX "/images/shared/coffee.png", USE_ALPHA);
1018
1019
1020   /* Weapons: */
1021
1022   texture_load(&img_bullet ,DATA_PREFIX "/images/shared/bullet.png", USE_ALPHA);
1023
1024   texture_load(&img_red_glow ,DATA_PREFIX "/images/shared/red-glow.png",
1025                             USE_ALPHA);
1026
1027
1028
1029   /* Distros: */
1030
1031   texture_load(&img_distro[0] ,DATA_PREFIX "/images/shared/distro-0.png",
1032                              USE_ALPHA);
1033
1034   texture_load(&img_distro[1] ,DATA_PREFIX "/images/shared/distro-1.png",
1035                              USE_ALPHA);
1036
1037   texture_load(&img_distro[2] ,DATA_PREFIX "/images/shared/distro-2.png",
1038                              USE_ALPHA);
1039
1040   texture_load(&img_distro[3] ,DATA_PREFIX "/images/shared/distro-3.png",
1041                              USE_ALPHA);
1042
1043
1044   /* Tux life: */
1045
1046   texture_load(&tux_life ,DATA_PREFIX "/images/shared/tux-life.png",
1047                         USE_ALPHA);
1048
1049   /* Herring: */
1050
1051   texture_load(&img_golden_herring, DATA_PREFIX "/images/shared/golden-herring.png",
1052                USE_ALPHA);
1053
1054
1055   /* Super background: */
1056
1057   texture_load(&img_super_bkgd ,DATA_PREFIX "/images/shared/super-bkgd.png",
1058                               IGNORE_ALPHA);
1059
1060
1061   /* Sound effects: */
1062
1063   /* if (use_sound) // this will introduce SERIOUS bugs here ! because "load_sound"
1064                     // initialize sounds[i] with the correct pointer's value:
1065                     // NULL or something else. And it will be dangerous to
1066                     // play with not-initialized pointers.
1067                     // This is also true with if (use_music)
1068      Send a mail to me: neoneurone@users.sf.net, if you have another opinion. :)
1069   */
1070   for (i = 0; i < NUM_SOUNDS; i++)
1071     sounds[i] = load_sound(soundfilenames[i]);
1072
1073   /* Herring song */
1074   herring_song_path = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) +
1075                                       strlen("SALCON.MOD") + 8)); /* FIXME: We need a real herring_song! Thats a fake.:) */
1076
1077   sprintf(herring_song_path, "%s/music/%s", DATA_PREFIX, "SALCON.MOD");
1078
1079   herring_song = load_song(herring_song_path);
1080
1081   free(herring_song_path);
1082
1083 }
1084
1085
1086 /* Free shared data: */
1087
1088 void unloadshared(void)
1089 {
1090   int i;
1091
1092   for (i = 0; i < 3; i++)
1093     {
1094       texture_free(&tux_right[i]);
1095       texture_free(&tux_left[i]);
1096       texture_free(&bigtux_right[i]);
1097       texture_free(&bigtux_left[i]);
1098     }
1099
1100   texture_free(&bigtux_right_jump);
1101   texture_free(&bigtux_left_jump);
1102
1103   for (i = 0; i < 2; i++)
1104     {
1105       texture_free(&cape_right[i]);
1106       texture_free(&cape_left[i]);
1107       texture_free(&bigcape_right[i]);
1108       texture_free(&bigcape_left[i]);
1109     }
1110
1111   texture_free(&ducktux_left);
1112   texture_free(&ducktux_right);
1113
1114   texture_free(&skidtux_left);
1115   texture_free(&skidtux_right);
1116
1117   for (i = 0; i < 4; i++)
1118     {
1119       texture_free(&img_bsod_left[i]);
1120       texture_free(&img_bsod_right[i]);
1121     }
1122
1123   texture_free(&img_bsod_squished_left);
1124   texture_free(&img_bsod_squished_right);
1125
1126   texture_free(&img_bsod_falling_left);
1127   texture_free(&img_bsod_falling_right);
1128
1129   for (i = 0; i < 3; i++)
1130     {
1131       texture_free(&img_laptop_left[i]);
1132       texture_free(&img_laptop_right[i]);
1133     }
1134
1135   texture_free(&img_laptop_flat_left);
1136   texture_free(&img_laptop_flat_right);
1137
1138   texture_free(&img_laptop_falling_left);
1139   texture_free(&img_laptop_falling_right);
1140
1141   for (i = 0; i < 2; i++)
1142     {
1143       texture_free(&img_money_left[i]);
1144       texture_free(&img_money_right[i]);
1145     }
1146
1147   texture_free(&img_box_full);
1148   texture_free(&img_box_empty);
1149
1150   texture_free(&img_water);
1151   for (i = 0; i < 3; i++)
1152     texture_free(&img_waves[i]);
1153
1154   texture_free(&img_pole);
1155   texture_free(&img_poletop);
1156
1157   for (i = 0; i < 2; i++)
1158     texture_free(&img_flag[i]);
1159
1160   texture_free(&img_mints);
1161   texture_free(&img_coffee);
1162
1163   for (i = 0; i < 4; i++)
1164     {
1165       texture_free(&img_distro[i]);
1166       texture_free(&img_cloud[0][i]);
1167       texture_free(&img_cloud[1][i]);
1168     }
1169
1170   texture_free(&img_golden_herring);
1171
1172   for (i = 0; i < NUM_SOUNDS; i++)
1173     free_chunk(sounds[i]);
1174
1175   /* free the herring song */
1176   free_music( herring_song );
1177 }
1178
1179
1180 /* Draw a tile on the screen: */
1181
1182 void drawshape(float x, float y, unsigned char c)
1183 {
1184   int z;
1185
1186   if (c == 'X' || c == 'x')
1187     texture_draw(&img_brick[0], x, y, NO_UPDATE);
1188   else if (c == 'Y' || c == 'y')
1189     texture_draw(&img_brick[1], x, y, NO_UPDATE);
1190   else if (c == 'A' || c =='B' || c == '!')
1191     texture_draw(&img_box_full, x, y, NO_UPDATE);
1192   else if (c == 'a')
1193     texture_draw(&img_box_empty, x, y, NO_UPDATE);
1194   else if (c >= 'C' && c <= 'F')
1195     texture_draw(&img_cloud[0][c - 'C'], x, y, NO_UPDATE);
1196   else if (c >= 'c' && c <= 'f')
1197     texture_draw(&img_cloud[1][c - 'c'], x, y, NO_UPDATE);
1198   else if (c >= 'G' && c <= 'J')
1199     texture_draw(&img_bkgd[0][c - 'G'], x, y, NO_UPDATE);
1200   else if (c >= 'g' && c <= 'j')
1201     texture_draw(&img_bkgd[1][c - 'g'], x, y, NO_UPDATE);
1202   else if (c == '#')
1203     texture_draw(&img_solid[0], x, y, NO_UPDATE);
1204   else if (c == '[')
1205     texture_draw(&img_solid[1], x, y, NO_UPDATE);
1206   else if (c == '=')
1207     texture_draw(&img_solid[2], x, y, NO_UPDATE);
1208   else if (c == ']')
1209     texture_draw(&img_solid[3], x, y, NO_UPDATE);
1210   else if (c == '$')
1211     {
1212       
1213       z = (frame / 2) % 6;
1214
1215       if (z < 4)
1216         texture_draw(&img_distro[z], x, y, NO_UPDATE);
1217       else if (z == 4)
1218         texture_draw(&img_distro[2], x, y, NO_UPDATE);
1219       else if (z == 5)
1220         texture_draw(&img_distro[1], x, y, NO_UPDATE);
1221     }
1222   else if (c == '^')
1223     {
1224       z = (frame / 3) % 3;
1225
1226       texture_draw(&img_waves[z], x, y, NO_UPDATE);
1227     }
1228   else if (c == '*')
1229     texture_draw(&img_poletop, x, y, NO_UPDATE);
1230   else if (c == '|')
1231     {
1232       texture_draw(&img_pole, x, y, NO_UPDATE);
1233
1234       /* Mark this as the end position of the level! */
1235
1236       endpos = x;
1237     }
1238   else if (c == '\\')
1239     {
1240       z = (frame / 3) % 2;
1241
1242       texture_draw(&img_flag[z], x + 16, y, NO_UPDATE);
1243     }
1244   else if (c == '&')
1245     texture_draw(&img_water, x, y, NO_UPDATE);
1246 }
1247
1248
1249 /* What shape is at some position? */
1250
1251 unsigned char shape(float x, float y)
1252 {
1253
1254   int xx, yy;
1255   unsigned char c;
1256
1257   yy = ((int)y / 32);
1258   xx = ((int)x / 32);
1259
1260   if (yy >= 0 && yy < 15 && xx >= 0 && xx <= current_level.width)
1261   {
1262     c = current_level.tiles[yy][xx];
1263     }
1264   else
1265     c = '.';
1266     
1267   return(c);
1268 }
1269
1270 /* Is is ground? */
1271
1272 int issolid(float x, float y)
1273 {
1274   if (isbrick(x, y) ||
1275       isbrick(x + 31, y) ||
1276       isice(x, y) ||
1277       isice(x + 31, y) ||
1278       (shape(x, y) == '[' ||
1279        shape(x + 31, y) == '[') ||
1280       (shape(x, y) == '=' ||
1281        shape(x + 31, y) == '=') ||
1282       (shape(x, y) == ']' ||
1283        shape(x + 31, y) == ']') ||
1284       (shape(x, y) == 'A' ||
1285        shape(x + 31, y) == 'A') ||
1286       (shape(x, y) == 'B' ||
1287        shape(x + 31, y) == 'B') ||
1288       (shape(x, y) == '!' ||
1289        shape(x + 31, y) == '!') ||
1290       (shape(x, y) == 'a' ||
1291        shape(x + 31, y) == 'a'))
1292     {
1293       return YES;
1294     }
1295
1296   return NO;
1297 }
1298
1299
1300 /* Is it a brick? */
1301
1302 int isbrick(float x, float y)
1303 {
1304   if (shape(x, y) == 'X' ||
1305       shape(x, y) == 'x' ||
1306       shape(x, y) == 'Y' ||
1307       shape(x, y) == 'y')
1308     {
1309       return YES;
1310     }
1311
1312   return NO;
1313 }
1314
1315
1316 /* Is it ice? */
1317
1318 int isice(float x, float y)
1319 {
1320   if (shape(x, y) == '#')
1321     {
1322       return YES;
1323     }
1324
1325   return NO;
1326 }
1327
1328
1329 /* Is it a full box? */
1330
1331 int isfullbox(float x, float y)
1332 {
1333   if (shape(x, y) == 'A' ||
1334       shape(x, y) == 'B' ||
1335       shape(x, y) == '!')
1336     {
1337       return YES;
1338     }
1339
1340   return NO;
1341 }
1342
1343 /* Break a brick: */
1344
1345 void trybreakbrick(float x, float y)
1346 {
1347   if (isbrick(x, y))
1348     {
1349       if (shape(x, y) == 'x' || shape(x, y) == 'y')
1350         {
1351           /* Get a distro from it: */
1352
1353           add_bouncy_distro(((x + 1) / 32) * 32,
1354                             (int)(y / 32) * 32);
1355
1356           if (counting_distros == NO)
1357             {
1358               counting_distros = YES;
1359               distro_counter = 50;
1360             }
1361
1362           if (distro_counter <= 0)
1363             level_change(&current_level,x, y, 'a');
1364
1365           play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
1366           score = score + SCORE_DISTRO;
1367           distros++;
1368         }
1369       else
1370         {
1371           /* Get rid of it: */
1372
1373           level_change(&current_level,x, y,'.');
1374         }
1375
1376
1377       /* Replace it with broken bits: */
1378
1379       add_broken_brick(((x + 1) / 32) * 32,
1380                        (int)(y / 32) * 32);
1381
1382
1383       /* Get some score: */
1384
1385       play_sound(sounds[SND_BRICK], SOUND_CENTER_SPEAKER);
1386       score = score + SCORE_BRICK;
1387     }
1388 }
1389
1390
1391 /* Bounce a brick: */
1392
1393 void bumpbrick(float x, float y)
1394 {
1395   add_bouncy_brick(((int)(x + 1) / 32) * 32,
1396                    (int)(y / 32) * 32);
1397
1398   play_sound(sounds[SND_BRICK], SOUND_CENTER_SPEAKER);
1399 }
1400
1401
1402 /* Empty a box: */
1403
1404 void tryemptybox(float x, float y)
1405 {
1406   if (isfullbox(x, y))
1407     {
1408       if (shape(x, y) == 'A')
1409         {
1410           /* Box with a distro! */
1411
1412           add_bouncy_distro(((x + 1) / 32) * 32,
1413                             (int)(y / 32) * 32 - 32);
1414
1415           play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
1416           score = score + SCORE_DISTRO;
1417           distros++;
1418         }
1419       else if (shape(x, y) == 'B')
1420         {
1421           /* Add an upgrade! */
1422
1423           if (tux.size == SMALL)
1424             {
1425               /* Tux is small, add mints! */
1426
1427               add_upgrade(((x + 1) / 32) * 32,
1428                           (int)(y / 32) * 32 - 32,
1429                           UPGRADE_MINTS);
1430             }
1431           else
1432             {
1433               /* Tux is big, add coffee: */
1434
1435               add_upgrade(((x + 1) / 32) * 32,
1436                           (int)(y / 32) * 32 - 32,
1437                           UPGRADE_COFFEE);
1438             }
1439
1440           play_sound(sounds[SND_UPGRADE], SOUND_CENTER_SPEAKER);
1441         }
1442       else if (shape(x, y) == '!')
1443         {
1444           /* Add a golden herring */
1445
1446           add_upgrade(((x + 1) / 32) * 32,
1447                       (int)(y / 32) * 32 - 32,
1448                       UPGRADE_HERRING);
1449         }
1450
1451       /* Empty the box: */
1452
1453       level_change(&current_level,x, y, 'a');
1454     }
1455 }
1456
1457
1458 /* Try to grab a distro: */
1459
1460 void trygrabdistro(float x, float y, int bounciness)
1461 {
1462   if (shape(x, y) == '$')
1463     {
1464       level_change(&current_level,x, y, '.');
1465       play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
1466
1467       if (bounciness == BOUNCE)
1468         {
1469           add_bouncy_distro(((x + 1) / 32) * 32,
1470                             (int)(y / 32) * 32);
1471         }
1472
1473       score = score + SCORE_DISTRO;
1474       distros++;
1475     }
1476 }
1477
1478 /* Try to bump a bad guy from below: */
1479
1480 void trybumpbadguy(float x, float y)
1481 {
1482   int i;
1483
1484
1485   /* Bad guys: */
1486
1487   for (i = 0; i < NUM_BAD_GUYS; i++)
1488     {
1489       if (bad_guys[i].alive &&
1490           bad_guys[i].x >= x - 32 && bad_guys[i].x <= x + 32 &&
1491           bad_guys[i].y >= y - 16 && bad_guys[i].y <= y + 16)
1492         {
1493           if (bad_guys[i].kind == BAD_BSOD ||
1494               bad_guys[i].kind == BAD_LAPTOP)
1495             {
1496               bad_guys[i].dying = FALLING;
1497               bad_guys[i].ym = -8;
1498               play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
1499             }
1500         }
1501     }
1502
1503
1504   /* Upgrades: */
1505
1506   for (i = 0; i < NUM_UPGRADES; i++)
1507     {
1508       if (upgrades[i].alive && upgrades[i].height == 32 &&
1509           upgrades[i].x >= x - 32 && upgrades[i].x <= x + 32 &&
1510           upgrades[i].y >= y - 16 && upgrades[i].y <= y + 16)
1511         {
1512           upgrades[i].xm = -upgrades[i].xm;
1513           upgrades[i].ym = -8;
1514           play_sound(sounds[SND_BUMP_UPGRADE], SOUND_CENTER_SPEAKER);
1515         }
1516     }
1517 }
1518
1519
1520 /* Add an upgrade: */
1521
1522 void add_upgrade(float x, float y, int kind)
1523 {
1524   int i, found;
1525
1526   found = -1;
1527
1528   for (i = 0; i < NUM_UPGRADES && found == -1; i++)
1529     {
1530       if (!upgrades[i].alive)
1531         found = i;
1532     }
1533
1534   if (found != -1)
1535     {
1536       upgrades[found].alive = YES;
1537       upgrades[found].kind = kind;
1538       upgrades[found].x = x;
1539       upgrades[found].y = y;
1540       upgrades[found].xm = 2;
1541       upgrades[found].ym = -2;
1542       upgrades[found].height = 0;
1543     }
1544 }
1545
1546 /* Add a bullet: */
1547
1548 void add_bullet(float x, float y, float xm, int dir)
1549 {
1550   int i, found;
1551   
1552   printf("X: %f Y: %f -- YOOYOYOYO\n",x,y);
1553
1554   found = -1;
1555
1556   for (i = 0; i < NUM_BULLETS && found == -1; i++)
1557     {
1558       if (!bullets[i].alive)
1559         found = i;
1560     }
1561
1562   if (found != -1)
1563     {
1564       bullets[found].alive = YES;
1565
1566       if (dir == RIGHT)
1567         {
1568           bullets[found].x = x + 32;
1569           bullets[found].xm = BULLET_XM + xm;
1570         }
1571       else
1572         {
1573           bullets[found].x = x;
1574           bullets[found].xm = -BULLET_XM + xm;
1575         }
1576
1577       bullets[found].y = y;
1578       bullets[found].ym = BULLET_STARTING_YM;
1579
1580       play_sound(sounds[SND_SHOOT], SOUND_CENTER_SPEAKER);
1581     }
1582 }
1583
1584
1585 /* (Status): */
1586 void drawstatus(void)
1587 {
1588 int i;
1589
1590   sprintf(str, "%d", score);
1591   drawtext("SCORE", 0, 0, letters_blue, NO_UPDATE, 1);
1592   drawtext(str, 96, 0, letters_gold, NO_UPDATE, 1);
1593
1594   sprintf(str, "%d", highscore);
1595   drawtext("HIGH", 0, 20, letters_blue, NO_UPDATE, 1);
1596   drawtext(str, 96, 20, letters_gold, NO_UPDATE, 1);
1597
1598   if (timer_get_left(&time_left) > TIME_WARNING || (frame % 10) < 5)
1599     {
1600       sprintf(str, "%d", timer_get_left(&time_left) / 1000 );
1601       drawtext("TIME", 224, 0, letters_blue, NO_UPDATE, 1);
1602       drawtext(str, 304, 0, letters_gold, NO_UPDATE, 1);
1603     }
1604
1605   sprintf(str, "%d", distros);
1606   drawtext("DISTROS", screen->h, 0, letters_blue, NO_UPDATE, 1);
1607   drawtext(str, 608, 0, letters_gold, NO_UPDATE, 1);
1608
1609   drawtext("LIVES", screen->h, 20, letters_blue, NO_UPDATE, 1);
1610
1611   for(i=0; i < tux.lives; ++i)
1612     {
1613       texture_draw(&tux_life,565+(18*i),20,NO_UPDATE);
1614     }
1615 }
1616
1617
1618 void drawendscreen(void)
1619 {
1620   char str[80];
1621
1622   clearscreen(0, 0, 0);
1623
1624   drawcenteredtext("GAMEOVER", 200, letters_red, NO_UPDATE, 1);
1625
1626   sprintf(str, "SCORE: %d", score);
1627   drawcenteredtext(str, 224, letters_gold, NO_UPDATE, 1);
1628
1629   sprintf(str, "DISTROS: %d", distros);
1630   drawcenteredtext(str, 256, letters_blue, NO_UPDATE, 1);
1631
1632   flipscreen();
1633   SDL_Delay(2000);
1634 }
1635
1636 void drawresultscreen(void)
1637 {
1638   char str[80];
1639
1640   clearscreen(0, 0, 0);
1641
1642   drawcenteredtext("Result:", 200, letters_red, NO_UPDATE, 1);
1643
1644   sprintf(str, "SCORE: %d", score);
1645   drawcenteredtext(str, 224, letters_gold, NO_UPDATE, 1);
1646
1647   sprintf(str, "DISTROS: %d", distros);
1648   drawcenteredtext(str, 256, letters_blue, NO_UPDATE, 1);
1649
1650   flipscreen();
1651   SDL_Delay(2000);
1652 }
1653
1654 void savegame(void)
1655 {
1656   char savefile[300];
1657   time_t current_time = time(NULL);
1658   struct tm* time_struct;
1659   FILE* fi;
1660
1661   time_struct = localtime(&current_time);
1662   sprintf(savefile,"%s/%d-%d-%d-%d.save",st_save_dir,time_struct->tm_year+1900,time_struct->tm_mon,time_struct->tm_mday,time_struct->tm_hour);
1663   printf("%s",savefile);
1664
1665
1666   fi = fopen(savefile, "wb");
1667
1668   if (fi == NULL)
1669     {
1670       fprintf(stderr, "Warning: I could not open the high score file ");
1671
1672     }
1673   else
1674     {
1675       fwrite(&level,4,1,fi);
1676       fwrite(&score,4,1,fi);
1677       fwrite(&distros,4,1,fi);
1678       fwrite(&tux.x,4,1,fi);
1679       fwrite(&tux.y,4,1,fi);
1680       fwrite(&scroll_x,4,1,fi);
1681       fwrite(&current_level.time_left,4,1,fi);
1682     }
1683   fclose(fi);
1684
1685 }
1686
1687 void loadgame(char* filename)
1688 {
1689   char savefile[300];
1690   FILE* fi;
1691   time_t current_time = time(NULL);
1692   struct tm* time_struct;
1693
1694   time_struct = localtime(&current_time);
1695   sprintf(savefile,"%s/%d-%d-%d-%d.save",st_save_dir,time_struct->tm_year+1900,time_struct->tm_mon,time_struct->tm_mday,time_struct->tm_hour);
1696   printf("%s",savefile);
1697
1698
1699   fi = fopen(savefile, "rb");
1700
1701   if (fi == NULL)
1702     {
1703       fprintf(stderr, "Warning: I could not open the high score file ");
1704
1705     }
1706   else
1707     {
1708     player_level_begin(&tux);
1709       set_defaults();
1710       loadlevel(&current_level,"default",level);
1711       activate_bad_guys();
1712       unloadlevelgfx();
1713       loadlevelgfx(&current_level);
1714       unloadlevelsong();
1715       loadlevelsong();
1716       levelintro();
1717       start_timers();
1718
1719       fread(&level,4,1,fi);
1720       fread(&score,4,1,fi);
1721       fread(&distros,4,1,fi);
1722       fread(&tux.x,4,1,fi);
1723       fread(&tux.y,4,1,fi);
1724       fread(&scroll_x,4,1,fi);
1725       fread(&current_level.time_left,4,1,fi);
1726       fclose(fi);
1727     }
1728
1729 }