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