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