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