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