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