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