huge CVS merge, see ChangeLog for details.
[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_keydown_event(&tux,key))
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_keyup_event(&tux,key))
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 2:
628                   loadgame(NULL);
629                   break;
630                 case 4:
631                   done = 1;
632                   break;
633                 }
634             }
635           else if(current_menu == &options_menu)
636             {
637               process_options_menu();
638             }
639         }
640
641
642       /* Handle actions: */
643
644       if(!game_pause && !show_menu)
645         {
646           if (game_action() == 0)
647             {
648               /* == 0: no more lives */
649               /* == -1: continues */
650               return 0;
651             }
652         }
653       else
654         {
655           ++pause_menu_frame;
656           SDL_Delay(50);
657         }
658
659       if(tux.input.down == DOWN)
660         SDL_Delay(30);
661
662       /*Draw the current scene to the screen */
663       /*If the machine running the game is too slow
664         skip the drawing of the frame (so the calculations are more precise and
665       the FPS aren't affected).*/
666       /*if( ! fps_fps < 50.0 )
667       game_draw();
668       else
669       jump = YES;*/ /*FIXME: Implement this tweak right.*/
670       game_draw();
671
672       /* Time stops in pause mode */
673       if(game_pause || show_menu )
674         {
675           continue;
676         }
677
678       /* Set the time the last update and the time of the current update */
679       last_update_time = update_time;
680       update_time = st_get_ticks();
681
682
683       /* Pause till next frame, if the machine running the game is too fast: */
684       /* FIXME: Works great for in OpenGl mode, where the CPU doesn't have to do that much. But
685                 the results in SDL mode aren't perfect (thought the 100 FPS are reached), even on an AMD2500+. */
686       if(last_update_time >= update_time - 12 && jump != YES )
687         SDL_Delay(10);
688       //if((update_time - last_update_time) < 10)
689       //  SDL_Delay((11 - (update_time - last_update_time))/2);
690
691
692
693       /* Handle time: */
694
695       if (timer_check(&time_left))
696         {
697           /* are we low on time ? */
698           if ((timer_get_left(&time_left) < TIME_WARNING)
699               && (current_music != HURRYUP_MUSIC))
700             {
701               current_music = HURRYUP_MUSIC;
702               /* stop the others music, prepare to play the fast music */
703               if (playing_music())
704                 {
705                   halt_music();
706                 }
707             }
708
709         }
710       else
711         player_kill(&tux,KILL);
712
713
714       /* Keep playing the correct music: */
715
716       if (!playing_music())
717         {
718           play_current_music();
719         }
720
721       /* Calculate frames per second */
722       if(show_fps)
723         {
724           ++fps_cnt;
725           fps_fps = (1000.0 / (float)timer_get_gone(&fps_timer)) * (float)fps_cnt;
726
727           if(!timer_check(&fps_timer))
728             {
729               timer_start(&fps_timer,1000);
730               fps_cnt = 0;
731             }
732         }
733
734     }
735   while (!done && !quit);
736
737   if (playing_music())
738     halt_music();
739
740   level_free_gfx();
741   level_free(&current_level);
742   level_free_song();
743   unloadshared();
744   arrays_free();
745
746   return(quit);
747 }
748
749
750 /* Initialize the game stuff: */
751
752 void initgame(void)
753 {
754   score = 0;
755   distros = 0;
756 }
757
758 /* Load graphics/sounds shared between all levels: */
759
760 void loadshared(void)
761 {
762   int i;
763   char * herring_song_path; /* for loading herring song*/
764
765   /* Tuxes: */
766
767   texture_load(&tux_right[0],DATA_PREFIX "/images/shared/tux-right-0.png", USE_ALPHA);
768   texture_load(&tux_right[1],DATA_PREFIX "/images/shared/tux-right-1.png", USE_ALPHA);
769   texture_load(&tux_right[2],DATA_PREFIX "/images/shared/tux-right-2.png", USE_ALPHA);
770
771   texture_load(&tux_left[0],DATA_PREFIX "/images/shared/tux-left-0.png", USE_ALPHA);
772   texture_load(&tux_left[1],DATA_PREFIX "/images/shared/tux-left-1.png", USE_ALPHA);
773   texture_load(&tux_left[2],DATA_PREFIX "/images/shared/tux-left-2.png", USE_ALPHA);
774
775   texture_load(&firetux_right[0],DATA_PREFIX "/images/shared/firetux-right-0.png", USE_ALPHA);
776   texture_load(&firetux_right[1],DATA_PREFIX "/images/shared/firetux-right-1.png", USE_ALPHA);
777   texture_load(&firetux_right[2],DATA_PREFIX "/images/shared/firetux-right-2.png", USE_ALPHA);
778
779   texture_load(&firetux_left[0],DATA_PREFIX "/images/shared/firetux-left-0.png", USE_ALPHA);
780   texture_load(&firetux_left[1],DATA_PREFIX "/images/shared/firetux-left-1.png", USE_ALPHA);
781   texture_load(&firetux_left[2],DATA_PREFIX "/images/shared/firetux-left-2.png", USE_ALPHA);
782
783
784   texture_load(&cape_right[0] ,DATA_PREFIX "/images/shared/cape-right-0.png",
785                USE_ALPHA);
786
787   texture_load(&cape_right[1] ,DATA_PREFIX "/images/shared/cape-right-1.png",
788                USE_ALPHA);
789
790   texture_load(&cape_left[0] ,DATA_PREFIX "/images/shared/cape-left-0.png",
791                USE_ALPHA);
792
793   texture_load(&cape_left[1] ,DATA_PREFIX "/images/shared/cape-left-1.png",
794                USE_ALPHA);
795
796   texture_load(&bigtux_right[0] ,DATA_PREFIX "/images/shared/bigtux-right-0.png",
797                USE_ALPHA);
798
799   texture_load(&bigtux_right[1] ,DATA_PREFIX "/images/shared/bigtux-right-1.png",
800                USE_ALPHA);
801
802   texture_load(&bigtux_right[2] ,DATA_PREFIX "/images/shared/bigtux-right-2.png",
803                USE_ALPHA);
804
805   texture_load(&bigtux_right_jump ,DATA_PREFIX "/images/shared/bigtux-right-jump.png", USE_ALPHA);
806
807   texture_load(&bigtux_left[0] ,DATA_PREFIX "/images/shared/bigtux-left-0.png",
808                USE_ALPHA);
809
810   texture_load(&bigtux_left[1] ,DATA_PREFIX "/images/shared/bigtux-left-1.png",
811                USE_ALPHA);
812
813   texture_load(&bigtux_left[2] ,DATA_PREFIX "/images/shared/bigtux-left-2.png",
814                USE_ALPHA);
815
816   texture_load(&bigtux_left_jump ,DATA_PREFIX "/images/shared/bigtux-left-jump.png", USE_ALPHA);
817
818   texture_load(&bigcape_right[0] ,DATA_PREFIX "/images/shared/bigcape-right-0.png",
819                USE_ALPHA);
820
821   texture_load(&bigcape_right[1] ,DATA_PREFIX "/images/shared/bigcape-right-1.png",
822                USE_ALPHA);
823
824   texture_load(&bigcape_left[0] ,DATA_PREFIX "/images/shared/bigcape-left-0.png",
825                USE_ALPHA);
826
827   texture_load(&bigcape_left[1] ,DATA_PREFIX "/images/shared/bigcape-left-1.png",
828                USE_ALPHA);
829
830   texture_load(&bigfiretux_right[0] ,DATA_PREFIX "/images/shared/bigfiretux-right-0.png",
831                USE_ALPHA);
832
833   texture_load(&bigfiretux_right[1] ,DATA_PREFIX "/images/shared/bigfiretux-right-1.png",
834                USE_ALPHA);
835
836   texture_load(&bigfiretux_right[2] ,DATA_PREFIX "/images/shared/bigfiretux-right-2.png",
837                USE_ALPHA);
838
839   texture_load(&bigfiretux_right_jump ,DATA_PREFIX "/images/shared/bigfiretux-right-jump.png", USE_ALPHA);
840
841   texture_load(&bigfiretux_left[0] ,DATA_PREFIX "/images/shared/bigfiretux-left-0.png",
842                USE_ALPHA);
843
844   texture_load(&bigfiretux_left[1] ,DATA_PREFIX "/images/shared/bigfiretux-left-1.png",
845                USE_ALPHA);
846
847   texture_load(&bigfiretux_left[2] ,DATA_PREFIX "/images/shared/bigfiretux-left-2.png",
848                USE_ALPHA);
849
850   texture_load(&bigfiretux_left_jump ,DATA_PREFIX "/images/shared/bigfiretux-left-jump.png", USE_ALPHA);
851
852   texture_load(&bigcape_right[0] ,DATA_PREFIX "/images/shared/bigcape-right-0.png",
853                USE_ALPHA);
854
855   texture_load(&bigcape_right[1] ,DATA_PREFIX "/images/shared/bigcape-right-1.png",
856                USE_ALPHA);
857
858   texture_load(&bigcape_left[0] ,DATA_PREFIX "/images/shared/bigcape-left-0.png",
859                USE_ALPHA);
860
861   texture_load(&bigcape_left[1] ,DATA_PREFIX "/images/shared/bigcape-left-1.png",
862                USE_ALPHA);
863
864
865   texture_load(&ducktux_right ,DATA_PREFIX
866                "/images/shared/ducktux-right.png",
867                USE_ALPHA);
868
869   texture_load(&ducktux_left ,DATA_PREFIX
870                "/images/shared/ducktux-left.png",
871                USE_ALPHA);
872
873   texture_load(&skidtux_right ,DATA_PREFIX
874                "/images/shared/skidtux-right.png",
875                USE_ALPHA);
876
877   texture_load(&skidtux_left ,DATA_PREFIX
878                "/images/shared/skidtux-left.png",
879                USE_ALPHA);
880
881   texture_load(&duckfiretux_right ,DATA_PREFIX
882                "/images/shared/duckfiretux-right.png",
883                USE_ALPHA);
884
885   texture_load(&duckfiretux_left ,DATA_PREFIX
886                "/images/shared/duckfiretux-left.png",
887                USE_ALPHA);
888
889   texture_load(&skidfiretux_right ,DATA_PREFIX
890                "/images/shared/skidfiretux-right.png",
891                USE_ALPHA);
892
893   texture_load(&skidfiretux_left ,DATA_PREFIX
894                "/images/shared/skidfiretux-left.png",
895                USE_ALPHA);
896
897
898   /* Boxes: */
899
900   texture_load(&img_box_full ,DATA_PREFIX "/images/shared/box-full.png",
901                IGNORE_ALPHA);
902   texture_load(&img_box_empty ,DATA_PREFIX "/images/shared/box-empty.png",
903                IGNORE_ALPHA);
904
905
906   /* Water: */
907
908
909   texture_load(&img_water ,DATA_PREFIX "/images/shared/water.png", IGNORE_ALPHA);
910
911   texture_load(&img_waves[0] ,DATA_PREFIX "/images/shared/waves-0.png",
912                USE_ALPHA);
913
914   texture_load(&img_waves[1] ,DATA_PREFIX "/images/shared/waves-1.png",
915                USE_ALPHA);
916
917   texture_load(&img_waves[2] ,DATA_PREFIX "/images/shared/waves-2.png",
918                USE_ALPHA);
919
920
921   /* Pole: */
922
923   texture_load(&img_pole ,DATA_PREFIX "/images/shared/pole.png", USE_ALPHA);
924   texture_load(&img_poletop ,DATA_PREFIX "/images/shared/poletop.png",
925                USE_ALPHA);
926
927
928   /* Flag: */
929
930   texture_load(&img_flag[0] ,DATA_PREFIX "/images/shared/flag-0.png",
931                USE_ALPHA);
932   texture_load(&img_flag[1] ,DATA_PREFIX "/images/shared/flag-1.png",
933                USE_ALPHA);
934
935
936   /* Cloud: */
937
938   texture_load(&img_cloud[0][0] ,DATA_PREFIX "/images/shared/cloud-00.png",
939                USE_ALPHA);
940
941   texture_load(&img_cloud[0][1] ,DATA_PREFIX "/images/shared/cloud-01.png",
942                USE_ALPHA);
943
944   texture_load(&img_cloud[0][2] ,DATA_PREFIX "/images/shared/cloud-02.png",
945                USE_ALPHA);
946
947   texture_load(&img_cloud[0][3] ,DATA_PREFIX "/images/shared/cloud-03.png",
948                USE_ALPHA);
949
950
951   texture_load(&img_cloud[1][0] ,DATA_PREFIX "/images/shared/cloud-10.png",
952                USE_ALPHA);
953
954   texture_load(&img_cloud[1][1] ,DATA_PREFIX "/images/shared/cloud-11.png",
955                USE_ALPHA);
956
957   texture_load(&img_cloud[1][2] ,DATA_PREFIX "/images/shared/cloud-12.png",
958                USE_ALPHA);
959
960   texture_load(&img_cloud[1][3] ,DATA_PREFIX "/images/shared/cloud-13.png",
961                USE_ALPHA);
962
963
964   /* Bad guys: */
965
966   /* (BSOD) */
967
968   texture_load(&img_bsod_left[0] ,DATA_PREFIX
969                "/images/shared/bsod-left-0.png",
970                USE_ALPHA);
971
972   texture_load(&img_bsod_left[1] ,DATA_PREFIX
973                "/images/shared/bsod-left-1.png",
974                USE_ALPHA);
975
976   texture_load(&img_bsod_left[2] ,DATA_PREFIX
977                "/images/shared/bsod-left-2.png",
978                USE_ALPHA);
979
980   texture_load(&img_bsod_left[3] ,DATA_PREFIX
981                "/images/shared/bsod-left-3.png",
982                USE_ALPHA);
983
984   texture_load(&img_bsod_right[0] ,DATA_PREFIX
985                "/images/shared/bsod-right-0.png",
986                USE_ALPHA);
987
988   texture_load(&img_bsod_right[1] ,DATA_PREFIX
989                "/images/shared/bsod-right-1.png",
990                USE_ALPHA);
991
992   texture_load(&img_bsod_right[2] ,DATA_PREFIX
993                "/images/shared/bsod-right-2.png",
994                USE_ALPHA);
995
996   texture_load(&img_bsod_right[3] ,DATA_PREFIX
997                "/images/shared/bsod-right-3.png",
998                USE_ALPHA);
999
1000   texture_load(&img_bsod_squished_left ,DATA_PREFIX
1001                "/images/shared/bsod-squished-left.png",
1002                USE_ALPHA);
1003
1004   texture_load(&img_bsod_squished_right ,DATA_PREFIX
1005                "/images/shared/bsod-squished-right.png",
1006                USE_ALPHA);
1007
1008   texture_load(&img_bsod_falling_left ,DATA_PREFIX
1009                "/images/shared/bsod-falling-left.png",
1010                USE_ALPHA);
1011
1012   texture_load(&img_bsod_falling_right ,DATA_PREFIX
1013                "/images/shared/bsod-falling-right.png",
1014                USE_ALPHA);
1015
1016
1017   /* (Laptop) */
1018
1019   texture_load(&img_laptop_left[0] ,DATA_PREFIX
1020                "/images/shared/laptop-left-0.png",
1021                USE_ALPHA);
1022
1023   texture_load(&img_laptop_left[1] ,DATA_PREFIX
1024                "/images/shared/laptop-left-1.png",
1025                USE_ALPHA);
1026
1027   texture_load(&img_laptop_left[2] ,DATA_PREFIX
1028                "/images/shared/laptop-left-2.png",
1029                USE_ALPHA);
1030
1031   texture_load(&img_laptop_right[0] ,DATA_PREFIX
1032                "/images/shared/laptop-right-0.png",
1033                USE_ALPHA);
1034
1035   texture_load(&img_laptop_right[1] ,DATA_PREFIX
1036                "/images/shared/laptop-right-1.png",
1037                USE_ALPHA);
1038
1039   texture_load(&img_laptop_right[2] ,DATA_PREFIX
1040                "/images/shared/laptop-right-2.png",
1041                USE_ALPHA);
1042
1043   texture_load(&img_laptop_flat_left ,DATA_PREFIX
1044                "/images/shared/laptop-flat-left.png",
1045                USE_ALPHA);
1046
1047   texture_load(&img_laptop_flat_right ,DATA_PREFIX
1048                "/images/shared/laptop-flat-right.png",
1049                USE_ALPHA);
1050
1051   texture_load(&img_laptop_falling_left ,DATA_PREFIX
1052                "/images/shared/laptop-falling-left.png",
1053                USE_ALPHA);
1054
1055   texture_load(&img_laptop_falling_right ,DATA_PREFIX
1056                "/images/shared/laptop-falling-right.png",
1057                USE_ALPHA);
1058
1059
1060   /* (Money) */
1061
1062   texture_load(&img_money_left[0] ,DATA_PREFIX
1063                "/images/shared/bag-left-0.png",
1064                USE_ALPHA);
1065
1066   texture_load(&img_money_left[1] ,DATA_PREFIX
1067                "/images/shared/bag-left-1.png",
1068                USE_ALPHA);
1069
1070   texture_load(&img_money_right[0] ,DATA_PREFIX
1071                "/images/shared/bag-right-0.png",
1072                USE_ALPHA);
1073
1074   texture_load(&img_money_right[1] ,DATA_PREFIX
1075                "/images/shared/bag-right-1.png",
1076                USE_ALPHA);
1077
1078
1079
1080   /* Upgrades: */
1081
1082   texture_load(&img_mints ,DATA_PREFIX "/images/shared/mints.png", USE_ALPHA);
1083   texture_load(&img_coffee ,DATA_PREFIX "/images/shared/coffee.png", USE_ALPHA);
1084
1085
1086   /* Weapons: */
1087
1088   texture_load(&img_bullet ,DATA_PREFIX "/images/shared/bullet.png", USE_ALPHA);
1089
1090   texture_load(&img_red_glow ,DATA_PREFIX "/images/shared/red-glow.png",
1091                USE_ALPHA);
1092
1093
1094
1095   /* Distros: */
1096
1097   texture_load(&img_distro[0] ,DATA_PREFIX "/images/shared/distro-0.png",
1098                USE_ALPHA);
1099
1100   texture_load(&img_distro[1] ,DATA_PREFIX "/images/shared/distro-1.png",
1101                USE_ALPHA);
1102
1103   texture_load(&img_distro[2] ,DATA_PREFIX "/images/shared/distro-2.png",
1104                USE_ALPHA);
1105
1106   texture_load(&img_distro[3] ,DATA_PREFIX "/images/shared/distro-3.png",
1107                USE_ALPHA);
1108
1109
1110   /* Tux life: */
1111
1112   texture_load(&tux_life ,DATA_PREFIX "/images/shared/tux-life.png",
1113                USE_ALPHA);
1114
1115   /* Herring: */
1116
1117   texture_load(&img_golden_herring, DATA_PREFIX "/images/shared/golden-herring.png",
1118                USE_ALPHA);
1119
1120
1121   /* Super background: */
1122
1123   texture_load(&img_super_bkgd ,DATA_PREFIX "/images/shared/super-bkgd.png",
1124                IGNORE_ALPHA);
1125
1126
1127   /* Sound effects: */
1128
1129   /* if (use_sound) // this will introduce SERIOUS bugs here ! because "load_sound"
1130                     // initialize sounds[i] with the correct pointer's value:
1131                     // NULL or something else. And it will be dangerous to
1132                     // play with not-initialized pointers.
1133                     // This is also true with if (use_music)
1134      Send a mail to me: neoneurone@users.sf.net, if you have another opinion. :)
1135   */
1136   for (i = 0; i < NUM_SOUNDS; i++)
1137     sounds[i] = load_sound(soundfilenames[i]);
1138
1139   /* Herring song */
1140   herring_song_path = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) +
1141                                       strlen("SALCON.MOD") + 8)); /* FIXME: We need a real herring_song! Thats a fake.:) */
1142
1143   sprintf(herring_song_path, "%s/music/%s", DATA_PREFIX, "SALCON.MOD");
1144
1145   herring_song = load_song(herring_song_path);
1146
1147   free(herring_song_path);
1148
1149 }
1150
1151
1152 /* Free shared data: */
1153
1154 void unloadshared(void)
1155 {
1156   int i;
1157
1158   for (i = 0; i < 3; i++)
1159     {
1160       texture_free(&tux_right[i]);
1161       texture_free(&tux_left[i]);
1162       texture_free(&bigtux_right[i]);
1163       texture_free(&bigtux_left[i]);
1164     }
1165
1166   texture_free(&bigtux_right_jump);
1167   texture_free(&bigtux_left_jump);
1168
1169   for (i = 0; i < 2; i++)
1170     {
1171       texture_free(&cape_right[i]);
1172       texture_free(&cape_left[i]);
1173       texture_free(&bigcape_right[i]);
1174       texture_free(&bigcape_left[i]);
1175     }
1176
1177   texture_free(&ducktux_left);
1178   texture_free(&ducktux_right);
1179
1180   texture_free(&skidtux_left);
1181   texture_free(&skidtux_right);
1182
1183   for (i = 0; i < 4; i++)
1184     {
1185       texture_free(&img_bsod_left[i]);
1186       texture_free(&img_bsod_right[i]);
1187     }
1188
1189   texture_free(&img_bsod_squished_left);
1190   texture_free(&img_bsod_squished_right);
1191
1192   texture_free(&img_bsod_falling_left);
1193   texture_free(&img_bsod_falling_right);
1194
1195   for (i = 0; i < 3; i++)
1196     {
1197       texture_free(&img_laptop_left[i]);
1198       texture_free(&img_laptop_right[i]);
1199     }
1200
1201   texture_free(&img_laptop_flat_left);
1202   texture_free(&img_laptop_flat_right);
1203
1204   texture_free(&img_laptop_falling_left);
1205   texture_free(&img_laptop_falling_right);
1206
1207   for (i = 0; i < 2; i++)
1208     {
1209       texture_free(&img_money_left[i]);
1210       texture_free(&img_money_right[i]);
1211     }
1212
1213   texture_free(&img_box_full);
1214   texture_free(&img_box_empty);
1215
1216   texture_free(&img_water);
1217   for (i = 0; i < 3; i++)
1218     texture_free(&img_waves[i]);
1219
1220   texture_free(&img_pole);
1221   texture_free(&img_poletop);
1222
1223   for (i = 0; i < 2; i++)
1224     texture_free(&img_flag[i]);
1225
1226   texture_free(&img_mints);
1227   texture_free(&img_coffee);
1228
1229   for (i = 0; i < 4; i++)
1230     {
1231       texture_free(&img_distro[i]);
1232       texture_free(&img_cloud[0][i]);
1233       texture_free(&img_cloud[1][i]);
1234     }
1235
1236   texture_free(&img_golden_herring);
1237
1238   for (i = 0; i < NUM_SOUNDS; i++)
1239     free_chunk(sounds[i]);
1240
1241   /* free the herring song */
1242   free_music( herring_song );
1243 }
1244
1245
1246 /* Draw a tile on the screen: */
1247
1248 void drawshape(float x, float y, unsigned char c)
1249 {
1250   int z;
1251
1252   if (c == 'X' || c == 'x')
1253     texture_draw(&img_brick[0], x, y, NO_UPDATE);
1254   else if (c == 'Y' || c == 'y')
1255     texture_draw(&img_brick[1], x, y, NO_UPDATE);
1256   else if (c == 'A' || c =='B' || c == '!')
1257     texture_draw(&img_box_full, x, y, NO_UPDATE);
1258   else if (c == 'a')
1259     texture_draw(&img_box_empty, x, y, NO_UPDATE);
1260   else if (c >= 'C' && c <= 'F')
1261     texture_draw(&img_cloud[0][c - 'C'], x, y, NO_UPDATE);
1262   else if (c >= 'c' && c <= 'f')
1263     texture_draw(&img_cloud[1][c - 'c'], x, y, NO_UPDATE);
1264   else if (c >= 'G' && c <= 'J')
1265     texture_draw(&img_bkgd_tile[0][c - 'G'], x, y, NO_UPDATE);
1266   else if (c >= 'g' && c <= 'j')
1267     texture_draw(&img_bkgd_tile[1][c - 'g'], x, y, NO_UPDATE);
1268   else if (c == '#')
1269     texture_draw(&img_solid[0], x, y, NO_UPDATE);
1270   else if (c == '[')
1271     texture_draw(&img_solid[1], x, y, NO_UPDATE);
1272   else if (c == '=')
1273     texture_draw(&img_solid[2], x, y, NO_UPDATE);
1274   else if (c == ']')
1275     texture_draw(&img_solid[3], x, y, NO_UPDATE);
1276   else if (c == '$')
1277     {
1278
1279       z = (frame / 2) % 6;
1280
1281       if (z < 4)
1282         texture_draw(&img_distro[z], x, y, NO_UPDATE);
1283       else if (z == 4)
1284         texture_draw(&img_distro[2], x, y, NO_UPDATE);
1285       else if (z == 5)
1286         texture_draw(&img_distro[1], x, y, NO_UPDATE);
1287     }
1288   else if (c == '^')
1289     {
1290       z = (frame / 3) % 3;
1291
1292       texture_draw(&img_waves[z], x, y, NO_UPDATE);
1293     }
1294   else if (c == '*')
1295     texture_draw(&img_poletop, x, y, NO_UPDATE);
1296   else if (c == '|')
1297     {
1298       texture_draw(&img_pole, x, y, NO_UPDATE);
1299
1300       /* Mark this as the end position of the level! */
1301
1302       endpos = (int)x;
1303     }
1304   else if (c == '\\')
1305     {
1306       z = (frame / 3) % 2;
1307
1308       texture_draw(&img_flag[z], x + 16, y, NO_UPDATE);
1309     }
1310   else if (c == '&')
1311     texture_draw(&img_water, x, y, NO_UPDATE);
1312 }
1313
1314
1315 /* What shape is at some position? */
1316
1317 unsigned char shape(float x, float y)
1318 {
1319
1320   int xx, yy;
1321   unsigned char c;
1322
1323   yy = ((int)y / 32);
1324   xx = ((int)x / 32);
1325
1326   if (yy >= 0 && yy < 15 && xx >= 0 && xx <= current_level.width)
1327     {
1328       c = current_level.tiles[yy][xx];
1329     }
1330   else
1331     c = '.';
1332
1333   return(c);
1334 }
1335
1336 /* Is is ground? */
1337
1338
1339 int issolid(float x, float y)
1340 {
1341   if (isbrick(x, y) ||
1342       isice(x, y) ||
1343       (shape(x, y) == '[') ||
1344       (shape(x, y) == '=') ||
1345       (shape(x, y) == ']') ||
1346       (shape(x, y) == 'A') ||
1347       (shape(x, y) == 'B') ||
1348       (shape(x, y) == '!') ||
1349       (shape(x, y) == 'a'))
1350     {
1351       return YES;
1352     }
1353
1354   return NO;
1355 }
1356
1357 /*
1358 int issolid(float x, float y)
1359 {
1360   if (isbrick(x, y) ||
1361       isbrick(x + 31, y) ||
1362       isice(x, y) ||
1363       isice(x + 31, y) ||
1364       (shape(x, y) == '[' ||
1365        shape(x + 31, y) == '[') ||
1366       (shape(x, y) == '=' ||
1367        shape(x + 31, y) == '=') ||
1368       (shape(x, y) == ']' ||
1369        shape(x + 31, y) == ']') ||
1370       (shape(x, y) == 'A' ||
1371        shape(x + 31, y) == 'A') ||
1372       (shape(x, y) == 'B' ||
1373        shape(x + 31, y) == 'B') ||
1374       (shape(x, y) == '!' ||
1375        shape(x + 31, y) == '!') ||
1376       (shape(x, y) == 'a' ||
1377        shape(x + 31, y) == 'a'))
1378     {
1379       return YES;
1380     }
1381
1382   return NO;
1383 }*/
1384
1385
1386 /* Is it a brick? */
1387
1388 int isbrick(float x, float y)
1389 {
1390   if (shape(x, y) == 'X' ||
1391       shape(x, y) == 'x' ||
1392       shape(x, y) == 'Y' ||
1393       shape(x, y) == 'y')
1394     {
1395       return YES;
1396     }
1397
1398   return NO;
1399 }
1400
1401
1402 /* Is it ice? */
1403
1404 int isice(float x, float y)
1405 {
1406   if (shape(x, y) == '#')
1407     {
1408       return YES;
1409     }
1410
1411   return NO;
1412 }
1413
1414
1415 /* Is it a full box? */
1416
1417 int isfullbox(float x, float y)
1418 {
1419   if (shape(x, y) == 'A' ||
1420       shape(x, y) == 'B' ||
1421       shape(x, y) == '!')
1422     {
1423       return YES;
1424     }
1425
1426   return NO;
1427 }
1428
1429 /* Break a brick: */
1430
1431 void trybreakbrick(float x, float y)
1432 {
1433   if (isbrick(x, y))
1434     {
1435       if (shape(x, y) == 'x' || shape(x, y) == 'y')
1436         {
1437           /* Get a distro from it: */
1438
1439           add_bouncy_distro(((x + 1) / 32) * 32,
1440                             (int)(y / 32) * 32);
1441
1442           if (counting_distros == NO)
1443             {
1444               counting_distros = YES;
1445               distro_counter = 50;
1446             }
1447
1448           if (distro_counter <= 0)
1449             level_change(&current_level,x, y, 'a');
1450
1451           play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
1452           score = score + SCORE_DISTRO;
1453           distros++;
1454         }
1455       else
1456         {
1457           /* Get rid of it: */
1458
1459           level_change(&current_level,x, y,'.');
1460         }
1461
1462
1463       /* Replace it with broken bits: */
1464
1465       add_broken_brick(((x + 1) / 32) * 32,
1466                        (int)(y / 32) * 32);
1467
1468
1469       /* Get some score: */
1470
1471       play_sound(sounds[SND_BRICK], SOUND_CENTER_SPEAKER);
1472       score = score + SCORE_BRICK;
1473     }
1474 }
1475
1476
1477 /* Bounce a brick: */
1478
1479 void bumpbrick(float x, float y)
1480 {
1481   add_bouncy_brick(((int)(x + 1) / 32) * 32,
1482                    (int)(y / 32) * 32);
1483
1484   play_sound(sounds[SND_BRICK], SOUND_CENTER_SPEAKER);
1485 }
1486
1487
1488 /* Empty a box: */
1489
1490 void tryemptybox(float x, float y)
1491 {
1492   if (isfullbox(x, y))
1493     {
1494       if (shape(x, y) == 'A')
1495         {
1496         
1497         DEBUG_MSG("Here I am");
1498         
1499           /* Box with a distro! */
1500
1501           add_bouncy_distro(((x + 1) / 32) * 32,
1502                             (int)(y / 32) * 32 - 32);
1503
1504           play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
1505           score = score + SCORE_DISTRO;
1506           distros++;
1507         }
1508       else if (shape(x, y) == 'B')
1509         {
1510           /* Add an upgrade! */
1511
1512           if (tux.size == SMALL)
1513             {
1514               /* Tux is small, add mints! */
1515
1516               add_upgrade(((x + 1) / 32) * 32,
1517                           (int)(y / 32) * 32 - 32,
1518                           UPGRADE_MINTS);
1519             }
1520           else
1521             {
1522               /* Tux is big, add coffee: */
1523
1524               add_upgrade(((x + 1) / 32) * 32,
1525                           (int)(y / 32) * 32 - 32,
1526                           UPGRADE_COFFEE);
1527             }
1528
1529           play_sound(sounds[SND_UPGRADE], SOUND_CENTER_SPEAKER);
1530         }
1531       else if (shape(x, y) == '!')
1532         {
1533           /* Add a golden herring */
1534
1535           add_upgrade(((x + 1) / 32) * 32,
1536                       (int)(y / 32) * 32 - 32,
1537                       UPGRADE_HERRING);
1538         }
1539
1540       /* Empty the box: */
1541
1542       level_change(&current_level,x, y, 'a');
1543     }
1544 }
1545
1546
1547 /* Try to grab a distro: */
1548
1549 void trygrabdistro(float x, float y, int bounciness)
1550 {
1551   if (shape(x, y) == '$')
1552     {
1553       level_change(&current_level,x, y, '.');
1554       play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
1555
1556       if (bounciness == BOUNCE)
1557         {
1558           add_bouncy_distro(((x + 1) / 32) * 32,
1559                             (int)(y / 32) * 32);
1560         }
1561
1562       score = score + SCORE_DISTRO;
1563       distros++;
1564     }
1565 }
1566
1567 /* Try to bump a bad guy from below: */
1568
1569 void trybumpbadguy(float x, float y)
1570 {
1571   int i;
1572
1573
1574   /* Bad guys: */
1575
1576   for (i = 0; i < num_bad_guys; i++)
1577     {
1578       if (bad_guys[i].base.alive &&
1579           bad_guys[i].base.x >= x - 32 && bad_guys[i].base.x <= x + 32 &&
1580           bad_guys[i].base.y >= y - 16 && bad_guys[i].base.y <= y + 16)
1581         {
1582           if (bad_guys[i].kind == BAD_BSOD ||
1583               bad_guys[i].kind == BAD_LAPTOP)
1584             {
1585               bad_guys[i].dying = FALLING;
1586               bad_guys[i].base.ym = -8;
1587               play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
1588             }
1589         }
1590     }
1591
1592
1593   /* Upgrades: */
1594
1595   for (i = 0; i < num_upgrades; i++)
1596     {
1597       if (upgrades[i].base.alive && upgrades[i].base.height == 32 &&
1598           upgrades[i].base.x >= x - 32 && upgrades[i].base.x <= x + 32 &&
1599           upgrades[i].base.y >= y - 16 && upgrades[i].base.y <= y + 16)
1600         {
1601           upgrades[i].base.xm = -upgrades[i].base.xm;
1602           upgrades[i].base.ym = -8;
1603           play_sound(sounds[SND_BUMP_UPGRADE], SOUND_CENTER_SPEAKER);
1604         }
1605     }
1606 }
1607
1608 /* (Status): */
1609 void drawstatus(void)
1610 {
1611   int i;
1612
1613   sprintf(str, "%d", score);
1614   text_draw(&white_text, "SCORE", 0, 0, 1, NO_UPDATE);
1615   text_draw(&gold_text, str, 96, 0, 1, NO_UPDATE);
1616
1617   if(st_gl_mode == ST_GL_PLAY)
1618     {
1619       sprintf(str, "%d", hs_score);
1620       text_draw(&white_text, "HIGH", 0, 20, 1, NO_UPDATE);
1621       text_draw(&gold_text, str, 96, 20, 1, NO_UPDATE);
1622     }
1623   else if(st_gl_mode == ST_GL_TEST)
1624     {
1625       text_draw(&white_text,"Press ESC To Return",0,20,1, NO_UPDATE);
1626     }
1627
1628   if (timer_get_left(&time_left) > TIME_WARNING || (frame % 10) < 5)
1629     {
1630       sprintf(str, "%d", timer_get_left(&time_left) / 1000 );
1631       text_draw(&white_text, "TIME", 224, 0, 1, NO_UPDATE);
1632       text_draw(&gold_text, str, 304, 0, 1, NO_UPDATE);
1633     }
1634
1635   sprintf(str, "%d", distros);
1636   text_draw(&white_text, "DISTROS", screen->h, 0, 1, NO_UPDATE);
1637   text_draw(&gold_text, str, 608, 0, 1, NO_UPDATE);
1638
1639   text_draw(&white_text, "LIVES", screen->h, 20, 1, NO_UPDATE);
1640
1641   if(show_fps)
1642     {
1643       sprintf(str, "%2.1f", fps_fps);
1644       text_draw(&white_text, "FPS", screen->h, 40, 1, NO_UPDATE);
1645       text_draw(&gold_text, str, screen->h + 60, 40, 1, NO_UPDATE);
1646     }
1647
1648   for(i=0; i < tux.lives; ++i)
1649     {
1650       texture_draw(&tux_life,565+(18*i),20,NO_UPDATE);
1651     }
1652 }
1653
1654
1655 void drawendscreen(void)
1656 {
1657   char str[80];
1658
1659   clearscreen(0, 0, 0);
1660
1661   text_drawf(&blue_text, "GAMEOVER", 0, 200, A_HMIDDLE, A_TOP, 1, NO_UPDATE);
1662
1663   sprintf(str, "SCORE: %d", score);
1664   text_drawf(&gold_text, str, 0, 224, A_HMIDDLE, A_TOP, 1, NO_UPDATE);
1665
1666   sprintf(str, "DISTROS: %d", distros);
1667   text_drawf(&gold_text, str, 0, 256, A_HMIDDLE, A_TOP, 1, NO_UPDATE);
1668
1669   flipscreen();
1670   SDL_Delay(2000);
1671 }
1672
1673 void drawresultscreen(void)
1674 {
1675   char str[80];
1676
1677   clearscreen(0, 0, 0);
1678
1679   text_drawf(&blue_text, "Result:", 0, 200, A_HMIDDLE, A_TOP, 1, NO_UPDATE);
1680
1681   sprintf(str, "SCORE: %d", score);
1682   text_drawf(&gold_text, str, 0, 224, A_HMIDDLE, A_TOP, 1, NO_UPDATE);
1683
1684   sprintf(str, "DISTROS: %d", distros);
1685   text_drawf(&gold_text, str, 0, 256, A_HMIDDLE, A_TOP, 1, NO_UPDATE);
1686
1687   flipscreen();
1688   SDL_Delay(2000);
1689 }
1690
1691 void savegame(void)
1692 {
1693   char savefile[300];
1694   time_t current_time = time(NULL);
1695   struct tm* time_struct;
1696   FILE* fi;
1697
1698   time_struct = localtime(&current_time);
1699   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);
1700   printf("%s",savefile);
1701
1702
1703   fi = fopen(savefile, "wb");
1704
1705   if (fi == NULL)
1706     {
1707       fprintf(stderr, "Warning: I could not open the high score file ");
1708
1709     }
1710   else
1711     {
1712       fwrite(&level,4,1,fi);
1713       fwrite(&score,4,1,fi);
1714       fwrite(&distros,4,1,fi);
1715       fwrite(&tux.base.x,4,1,fi);
1716       fwrite(&tux.base.y,4,1,fi);
1717       fwrite(&scroll_x,4,1,fi);
1718       fwrite(&current_level.time_left,4,1,fi);
1719     }
1720   fclose(fi);
1721
1722 }
1723
1724 void loadgame(char* filename)
1725 {
1726   char savefile[300];
1727   FILE* fi;
1728   time_t current_time = time(NULL);
1729   struct tm* time_struct;
1730
1731   time_struct = localtime(&current_time);
1732   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);
1733   printf("%s",savefile);
1734
1735
1736   fi = fopen(savefile, "rb");
1737
1738   if (fi == NULL)
1739     {
1740       fprintf(stderr, "Warning: I could not open the high score file ");
1741
1742     }
1743   else
1744     {
1745       player_level_begin(&tux);
1746       set_defaults();
1747       level_free(&current_level);
1748       if(level_load(&current_level,level_subset,level) != 0)
1749         exit(1);
1750       arrays_free();
1751       arrays_init();
1752       activate_bad_guys();
1753       level_free_gfx();
1754       level_load_gfx(&current_level);
1755       level_free_song();
1756       level_load_song(&current_level);
1757       levelintro();
1758       start_timers();
1759
1760       fread(&level,4,1,fi);
1761       fread(&score,4,1,fi);
1762       fread(&distros,4,1,fi);
1763       fread(&tux.base.x,4,1,fi);
1764       fread(&tux.base.y,4,1,fi);
1765       fread(&scroll_x,4,1,fi);
1766       fread(&current_level.time_left,4,1,fi);
1767       fclose(fi);
1768     }
1769
1770 }