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