huge CVS merge, see ChangeLog for details.
authorTobias Gläßer <tobi.web@gmx.de>
Wed, 18 Feb 2004 00:09:55 +0000 (00:09 +0000)
committerTobias Gläßer <tobi.web@gmx.de>
Wed, 18 Feb 2004 00:09:55 +0000 (00:09 +0000)
SVN-Revision: 125

40 files changed:
src/badguy.c
src/badguy.h
src/bitmask.c
src/collision.c
src/gameloop.c
src/gameloop.h
src/globals.h
src/high_scores.c
src/high_scores.h
src/intro.c
src/level.c
src/level.h
src/leveleditor.c
src/leveleditor.h
src/menu.c
src/menu.h
src/player.c
src/player.h
src/scene.c
src/scene.h
src/screen.c
src/screen.h
src/setup.c
src/setup.h
src/sound.c
src/sound.h
src/special.c
src/special.h
src/supertux.c
src/supertux.h
src/text.c
src/text.h
src/texture.c
src/texture.h
src/timer.c
src/timer.h
src/title.c
src/type.h
src/world.c
src/world.h

index 71dcda6..fe5b7e3 100644 (file)
 #include "scene.h"
 #include "screen.h"
 
+texture_type img_bsod_squished_left, img_bsod_squished_right,
+img_bsod_falling_left, img_bsod_falling_right,
+img_laptop_flat_left, img_laptop_flat_right,
+img_laptop_falling_left, img_laptop_falling_right;
+texture_type img_bsod_left[4], img_bsod_right[4],
+img_laptop_left[3], img_laptop_right[3],
+img_money_left[2], img_money_right[2];
+bitmask *bm_bsod;
+
 void badguy_create_bitmasks()
 {
   /*bm_bsod = img_bsod_left[0];*/
@@ -36,6 +45,7 @@ void badguy_init(bad_guy_type* pbad, float x, float y, int kind)
   pbad->dir = LEFT;
   pbad->seen = NO;
   timer_init(&pbad->timer);
+  physic_init(&pbad->physic);
 }
 
 void badguy_action(bad_guy_type* pbad)
@@ -70,8 +80,14 @@ void badguy_action(bad_guy_type* pbad)
 
               if (!pbad->dying)
                 {
-                  if (issolid(pbad->base.x, pbad->base.y))
-                    pbad->dir = !pbad->dir;
+                  if (issolid( pbad->base.x - 1, (int) pbad->base.y))
+                    {
+                      pbad->dir = RIGHT;
+                    }
+                   else if (issolid( pbad->base.x + pbad->base.width-1, (int) pbad->base.y))
+                   {
+                      pbad->dir = LEFT;
+                   }
                 }
 
               /* Fall if we get off the ground: */
@@ -213,31 +229,22 @@ void badguy_action(bad_guy_type* pbad)
 
               pbad->base.y = pbad->base.y + pbad->base.ym * frame_ratio;
 
-
-              /* Fall if we get off the ground: */
-
-              if (pbad->dying != FALLING)
-                {
-                  if (!issolid(pbad->base.x, pbad->base.y + 32))
-                    {
-                      if (pbad->base.ym < MAX_YM)
-                        {
-                          pbad->base.ym = pbad->base.ym + GRAVITY * frame_ratio;
-                        }
-                    }
-                  else
-                    {
-                      /* Land: */
-
-                      if (pbad->base.ym > 0)
-                        {
-                          pbad->base.y = (int)(pbad->base.y / 32) * 32;
-                          pbad->base.ym = -MAX_YM;
-                        }
-                    }
-                }
-              else
-                pbad->base.ym = pbad->base.ym + GRAVITY * frame_ratio;
+             if(physic_get_state(&pbad->physic) == -1)
+             physic_set_state(&pbad->physic,PH_VTU);
+             
+               if(issolid(pbad->base.x, pbad->base.y + 32))
+               {
+               physic_set_state(&pbad->physic,PH_VTU);
+               pbad->base.ym = -0.6;
+               }
+               else if(issolid(pbad->base.x, pbad->base.y - 1))
+               { /* This works, but isn't the best solution imagineable */
+               pbad->base.ym = physic_get_velocity(&pbad->physic,-6.);
+               }
+               else
+               {
+               pbad->base.ym = physic_get_velocity(&pbad->physic,6.);
+               }
 
               if (pbad->base.y > screen->h)
                 pbad->base.alive = NO;
@@ -427,7 +434,7 @@ void badguy_draw(bad_guy_type* pbad)
         }
       else if (pbad->kind == BAD_MONEY)
         {
-          if (pbad->base.ym > -16)
+          if (pbad->base.ym != 300 /* > -16*/)
             {
               if (pbad->dir == LEFT)
                 {
@@ -491,7 +498,7 @@ void badguy_collision(bad_guy_type* pbad, void *p_c_object, int c_object)
       play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
       break;
     case CO_BADGUY:
-      pbad_c = p_c_object;
+      pbad_c = (bad_guy_type*) p_c_object;
       if (pbad->mode != FLAT)
         pbad->dir = !pbad->dir;
       else
@@ -508,7 +515,7 @@ void badguy_collision(bad_guy_type* pbad, void *p_c_object, int c_object)
       pbad->dir = !pbad->dir;
       break;
     case CO_PLAYER:
-      pplayer_c = p_c_object;
+      pplayer_c = (player_type*) p_c_object;
       if (pbad->kind == BAD_BSOD)
         {
           pbad->dying = SQUISHED;
index 1d04a3c..258e12a 100644 (file)
@@ -18,6 +18,7 @@
 #include "type.h"
 #include "timer.h"
 #include "texture.h"
+#include "physic.h"
 #include "collision.h"
 
 /* Enemy modes: */
@@ -39,6 +40,7 @@ typedef struct bad_guy_type
     int frame;
     base_type base;
     timer_type timer;
+    physic_type physic;
   }
 bad_guy_type;
 
@@ -50,15 +52,15 @@ enum {
   BAD_MONEY
 };
 
-texture_type img_bsod_squished_left, img_bsod_squished_right,
+extern texture_type img_bsod_squished_left, img_bsod_squished_right,
 img_bsod_falling_left, img_bsod_falling_right,
 img_laptop_flat_left, img_laptop_flat_right,
 img_laptop_falling_left, img_laptop_falling_right;
-texture_type img_bsod_left[4], img_bsod_right[4],
+extern texture_type img_bsod_left[4], img_bsod_right[4],
 img_laptop_left[3], img_laptop_right[3],
 img_money_left[2], img_money_right[2];
 
-bitmask *bm_bsod;
+extern bitmask *bm_bsod;
 
 void badguy_create_bitmasks();
 
index b3be499..3607f01 100644 (file)
 
 bitmask *bitmask_create(int w, int h)
 {
-  bitmask *temp = malloc(sizeof(bitmask));
+  bitmask *temp = (bitmask*) malloc(sizeof(bitmask));
   if (! temp)
     return 0;
   temp->w = w;
   temp->h = h;
-  temp->bits = calloc(h*((w - 1)/BITW_LEN + 1),sizeof(BITW));
+  temp->bits = (long unsigned int*) calloc(h*((w - 1)/BITW_LEN + 1),sizeof(BITW));
   if (! temp->bits)
     {
       free(temp);
@@ -51,12 +51,12 @@ bitmask *bitmask_create_SDL(SDL_Surface* surf)
   int bpp;
   Uint8* p;
 
-  bitmask *temp = malloc(sizeof(bitmask));
+  bitmask *temp = (bitmask*) malloc(sizeof(bitmask));
   if (! temp)
     return 0;
   temp->w = surf->w;
   temp->h = surf->h;
-  temp->bits = calloc(surf->h*((surf->w - 1)/BITW_LEN + 1),sizeof(BITW));
+  temp->bits = (long unsigned int*) calloc(surf->h*((surf->w - 1)/BITW_LEN + 1),sizeof(BITW));
   if (! temp->bits)
     {
       free(temp);
index 6e2a393..de8a536 100644 (file)
@@ -62,16 +62,16 @@ void collision_handler()
                 {
                   if(rectcollision(&bullets[i].base,&bad_guys[j].base) == YES)
                     {
-                   /* We have detected a collision and now call the collision functions of the collided objects. */
-                     bullet_collision(&bullets[i], CO_BADGUY);
-                     badguy_collision(&bad_guys[j], &bullets[i], CO_BULLET);
+                      /* We have detected a collision and now call the collision functions of the collided objects. */
+                      bullet_collision(&bullets[i], CO_BADGUY);
+                      badguy_collision(&bad_guys[j], &bullets[i], CO_BULLET);
                     }
                 }
             }
         }
     }
-    
-    /* CO_BADGUY & CO_BADGUY check */
+
+  /* CO_BADGUY & CO_BADGUY check */
   for(i = 0; i < num_bad_guys; ++i)
     {
       if(bad_guys[i].base.alive)
@@ -82,47 +82,49 @@ void collision_handler()
                 {
                   if(rectcollision(&bad_guys[i].base,&bad_guys[j].base) == YES)
                     {
-                   /* We have detected a collision and now call the collision functions of the collided objects. */
-                     badguy_collision(&bad_guys[j], &bad_guys[i], CO_BADGUY);
-                     badguy_collision(&bad_guys[i], &bad_guys[j], CO_BADGUY);                    
-                   }
+                      /* We have detected a collision and now call the collision functions of the collided objects. */
+                      badguy_collision(&bad_guys[j], &bad_guys[i], CO_BADGUY);
+                      badguy_collision(&bad_guys[i], &bad_guys[j], CO_BADGUY);
+                    }
                 }
             }
         }
     }
 
-    /* CO_BADGUY & CO_PLAYER check */
+  /* CO_BADGUY & CO_PLAYER check */
   for(i = 0; i < num_bad_guys; ++i)
     {
       if(bad_guys[i].base.alive)
         {
-                 if(bad_guys[i].dying == NO && rectcollision_offset(&bad_guys[i].base,&tux.base,0,0) == YES && tux.base.ym > 0)
-                    {
-                   /* We have detected a collision and now call the collision functions of the collided objects. */
-                     badguy_collision(&bad_guys[i], &tux, CO_PLAYER);
-                     }
-                  if(rectcollision(&bad_guys[i].base,&tux.base) == YES)
-                  {
-                     player_collision(&tux, &bad_guys[i], CO_BADGUY);
-                  }
-
+          if(bad_guys[i].dying == NO && rectcollision_offset(&bad_guys[i].base,&tux.base,0,0) == YES )
+            {
+              /* We have detected a collision and now call the collision functions of the collided objects. */
+              if (tux.base.ym > 0)
+                {
+                  badguy_collision(&bad_guys[i], &tux, CO_PLAYER);
+                }
+              else
+                {
+                  player_collision(&tux, &bad_guys[i], CO_BADGUY);
+                }
+            }
         }
     }
 
-    /* CO_UPGRADE & CO_PLAYER check */
+  /* CO_UPGRADE & CO_PLAYER check */
   for(i = 0; i < num_upgrades; ++i)
     {
       if(upgrades[i].base.alive)
         {
-                 if(rectcollision(&upgrades[i].base,&tux.base) == YES)
-                    {
-                   /* We have detected a collision and now call the collision functions of the collided objects. */
-                     upgrade_collision(&upgrades[i], &tux, CO_PLAYER);
-                     }
+          if(rectcollision(&upgrades[i].base,&tux.base) == YES)
+            {
+              /* We have detected a collision and now call the collision functions of the collided objects. */
+              upgrade_collision(&upgrades[i], &tux, CO_PLAYER);
+            }
 
         }
     }
-    
+
 }
 
 
index b1b550e..ce373b1 100644 (file)
@@ -42,6 +42,7 @@
 /* extern variables */
 
 extern char* soundfilenames[NUM_SOUNDS];
+st_level current_level;
 
 /* Local variables: */
 
@@ -52,13 +53,15 @@ SDLKey key;
 char level_subset[100];
 char str[60];
 float fps_fps;
+int st_gl_mode;
+unsigned int last_update_time;
+unsigned int update_time;
+int pause_menu_frame;
 
 /* Local function prototypes: */
 
 void levelintro(void);
 void initgame(void);
-void loadlevelsong(void);
-void unloadlevelsong(void);
 void loadshared(void);
 void unloadshared(void);
 void drawstatus(void);
@@ -72,13 +75,13 @@ void levelintro(void)
   clearscreen(0, 0, 0);
 
   sprintf(str, "LEVEL %d", level);
-  text_drawf(&red_text, str, 0, 200, A_HMIDDLE, A_TOP, 1, NO_UPDATE);
+  text_drawf(&blue_text, str, 0, 200, A_HMIDDLE, A_TOP, 1, NO_UPDATE);
 
   sprintf(str, "%s", current_level.name);
   text_drawf(&gold_text, str, 0, 224, A_HMIDDLE, A_TOP, 1, NO_UPDATE);
 
   sprintf(str, "TUX x %d", tux.lives);
-  text_drawf(&blue_text, str, 0, 256, A_HMIDDLE, A_TOP, 1, NO_UPDATE);
+  text_drawf(&white_text, str, 0, 256, A_HMIDDLE, A_TOP, 1, NO_UPDATE);
 
   flipscreen();
 
@@ -139,16 +142,18 @@ void game_event(void)
             case SDLK_ESCAPE:    /* Escape: Open/Close the menu: */
               if(!game_pause)
                 {
-                  if(show_menu)
-                 {
-                    show_menu = 0;
-                   st_pause_ticks_stop();
-                   }
+                  if(st_gl_mode == ST_GL_TEST)
+                    quit = 1;
+                  else if(show_menu)
+                    {
+                      show_menu = 0;
+                      st_pause_ticks_stop();
+                    }
                   else
-                 {
-                    show_menu = 1;
-                   st_pause_ticks_start();
-                   }
+                    {
+                      show_menu = 1;
+                      st_pause_ticks_start();
+                    }
                 }
               break;
             default:
@@ -167,15 +172,15 @@ void game_event(void)
               if(!show_menu)
                 {
                   if(game_pause)
-                 {
-                    game_pause = 0;
-                   st_pause_ticks_stop();
-                   }
+                    {
+                      game_pause = 0;
+                      st_pause_ticks_stop();
+                    }
                   else
-                 {
-                    game_pause = 1;
-                   st_pause_ticks_start();
-                   }
+                    {
+                      game_pause = 1;
+                      st_pause_ticks_start();
+                    }
                 }
               break;
             case SDLK_TAB:
@@ -200,11 +205,11 @@ void game_event(void)
               break;
             case SDLK_l:
               if(debug_mode == YES)
-              --tux.lives;
+                --tux.lives;
               break;
             case SDLK_s:
               if(debug_mode == YES)
-              score += 1000;
+                score += 1000;
               break;
             default:
               break;
@@ -281,7 +286,6 @@ int game_action(void)
     {
       /* Tux either died, or reached the end of a level! */
 
-
       if (playing_music())
         halt_music();
 
@@ -291,24 +295,29 @@ int game_action(void)
           /* End of a level! */
           level++;
           next_level = 0;
-          drawresultscreen();
+          if(st_gl_mode == ST_GL_PLAY)
+            drawresultscreen();
           player_level_begin(&tux);
         }
       else
         {
-
           player_dying(&tux);
 
           /* No more lives!? */
 
           if (tux.lives < 0)
             {
-              drawendscreen();
+              if(st_gl_mode == ST_GL_PLAY)
+                drawendscreen();
 
-              if (score > hs_score)
-                save_hs(score);
-              unloadlevelgfx();
-              unloadlevelsong();
+              if(st_gl_mode == ST_GL_PLAY)
+                {
+                  if (score > hs_score)
+                    save_hs(score);
+                }
+              level_free_gfx();
+              level_free(&current_level);
+              level_free_song();
               unloadshared();
               arrays_free();
               return(0);
@@ -319,15 +328,18 @@ int game_action(void)
 
       player_level_begin(&tux);
       set_defaults();
-      loadlevel(&current_level,"default",level);
+      level_free(&current_level);
+      if(level_load(&current_level,level_subset,level) != 0)
+        exit(1);
       arrays_free();
       arrays_init();
       activate_bad_guys();
-      unloadlevelgfx();
-      loadlevelgfx(&current_level);
-      unloadlevelsong();
-      loadlevelsong();
-      levelintro();
+      level_free_gfx();
+      level_load_gfx(&current_level);
+      level_free_song();
+      level_load_song(&current_level);
+      if(st_gl_mode == ST_GL_PLAY)
+        levelintro();
       start_timers();
     }
 
@@ -421,7 +433,7 @@ void game_draw(void)
       /* Draw the real background */
       if(current_level.bkgd_image[0] != '\0')
         {
-          s = scroll_x / 30;
+          s = (int)scroll_x / 30;
           texture_draw_part(&img_bkgd,s,0,0,0,img_bkgd.w - s, img_bkgd.h, NO_UPDATE);
           texture_draw_part(&img_bkgd,0,0,screen->w - s ,0,s,img_bkgd.h, NO_UPDATE);
         }
@@ -504,10 +516,18 @@ void game_draw(void)
 
 
   if(game_pause)
-  text_drawf(&red_text, "PAUSE", 0, 230, A_HMIDDLE, A_TOP, 1, NO_UPDATE);
+    {
+      x = screen->h / 20;
+      for(i = 0; i < x; ++i)
+        {
+          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);
+        }
+      fillrect(0,0,screen->w,screen->h,rand() % 50, rand() % 50, rand() % 50, 128);
+      text_drawf(&blue_text, "PAUSE - Press 'P' To Play", 0, 230, A_HMIDDLE, A_TOP, 1, NO_UPDATE);
+    }
 
   if(show_menu)
-    done = drawmenu();
+    menu_process_current();
 
   /* (Update it all!) */
 
@@ -518,13 +538,15 @@ void game_draw(void)
 
 /* --- GAME LOOP! --- */
 
-int gameloop(void)
+int gameloop(char * subset, int levelnb, int mode)
 {
-
-  /*Uint32 last_time, now_time*/
-  int fps_cnt, jump;
+  int fps_cnt, jump, done;
   timer_type fps_timer, frame_timer;
 
+  level = levelnb;
+  st_gl_mode = mode;
+  strcpy(level_subset,subset);
+
   /* Clear screen: */
 
   clearscreen(0, 0, 0);
@@ -534,21 +556,26 @@ int gameloop(void)
   /* Init the game: */
   arrays_init();
 
-  initmenu();
-  menumenu = MENU_GAME;
+  menu_reset();
+  menu_set_current(&game_menu);
+
   initgame();
   loadshared();
   set_defaults();
 
-  loadlevel(&current_level,"default",level);
-  loadlevelgfx(&current_level);
+  if(level_load(&current_level,level_subset,level) != 0)
+    exit(1);
+  level_load_gfx(&current_level);
   activate_bad_guys();
-  loadlevelsong();
-  load_hs();
+  level_load_song(&current_level);
+  if(st_gl_mode == ST_GL_PLAY)
+    load_hs();
 
   player_init(&tux);
 
-  levelintro();
+  if(st_gl_mode == ST_GL_PLAY)
+    levelintro();
+
   start_timers();
 
   /* --- MAIN GAME LOOP!!! --- */
@@ -565,12 +592,8 @@ int gameloop(void)
   game_draw();
   do
     {
-    jump = NO;
-    
-      /* Set the time the last update and the time of the current update */
-      last_update_time = update_time;
-      update_time = st_get_ticks();
-      
+      jump = NO;
+
       /* Calculate the movement-factor */
       frame_ratio = ((double)(update_time-last_update_time))/((double)FRAME_RATE);
 
@@ -585,10 +608,36 @@ int gameloop(void)
 
       tux.input.old_fire = tux.input.fire;
 
-      printf("%lf\n",frame_ratio);
-      
+      /*printf("%lf\n",frame_ratio);*/
+
       game_event();
 
+      if(show_menu)
+        {
+          if(current_menu == &game_menu)
+            {
+              switch (menu_check(&game_menu))
+                {
+                case 0:
+                  st_pause_ticks_stop();
+                  break;
+                case 1:
+                  savegame();
+                  break;
+                case 2:
+                  loadgame(NULL);
+                  break;
+                case 4:
+                  done = 1;
+                  break;
+                }
+            }
+          else if(current_menu == &options_menu)
+            {
+              process_options_menu();
+            }
+        }
+
 
       /* Handle actions: */
 
@@ -602,15 +651,18 @@ int gameloop(void)
             }
         }
       else
-        SDL_Delay(50);
-       
-       if(tux.input.down == DOWN)
-       SDL_Delay(30);
-       
+        {
+          ++pause_menu_frame;
+          SDL_Delay(50);
+        }
+
+      if(tux.input.down == DOWN)
+        SDL_Delay(30);
+
       /*Draw the current scene to the screen */
       /*If the machine running the game is too slow
         skip the drawing of the frame (so the calculations are more precise and
-       the FPS aren't affected).*/
+      the FPS aren't affected).*/
       /*if( ! fps_fps < 50.0 )
       game_draw();
       else
@@ -623,11 +675,18 @@ int gameloop(void)
           continue;
         }
 
+      /* Set the time the last update and the time of the current update */
+      last_update_time = update_time;
+      update_time = st_get_ticks();
+
+
       /* Pause till next frame, if the machine running the game is too fast: */
       /* FIXME: Works great for in OpenGl mode, where the CPU doesn't have to do that much. But
-                the results in SDL mode aren't perfect (thought the 100 FPS are reached), even on an AMD2500+. */      
+                the results in SDL mode aren't perfect (thought the 100 FPS are reached), even on an AMD2500+. */
       if(last_update_time >= update_time - 12 && jump != YES )
         SDL_Delay(10);
+      //if((update_time - last_update_time) < 10)
+      //  SDL_Delay((11 - (update_time - last_update_time))/2);
 
 
 
@@ -662,7 +721,7 @@ int gameloop(void)
       /* Calculate frames per second */
       if(show_fps)
         {
-         ++fps_cnt;
+          ++fps_cnt;
           fps_fps = (1000.0 / (float)timer_get_gone(&fps_timer)) * (float)fps_cnt;
 
           if(!timer_check(&fps_timer))
@@ -678,8 +737,9 @@ int gameloop(void)
   if (playing_music())
     halt_music();
 
-  unloadlevelgfx();
-  unloadlevelsong();
+  level_free_gfx();
+  level_free(&current_level);
+  level_free_song();
   unloadshared();
   arrays_free();
 
@@ -691,44 +751,10 @@ int gameloop(void)
 
 void initgame(void)
 {
-  level = 1;
   score = 0;
   distros = 0;
 }
 
-/* Free music data for this level: */
-
-void unloadlevelsong(void)
-{
-  free_music(level_song);
-  free_music(level_song_fast);
-}
-
-/* Load music: */
-
-void loadlevelsong(void)
-{
-
-  char * song_path;
-  char * song_subtitle;
-
-  song_path = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) +
-                              strlen(current_level.song_title) + 8));
-  sprintf(song_path, "%s/music/%s", DATA_PREFIX, current_level.song_title);
-  level_song = load_song(song_path);
-  free(song_path);
-
-
-  song_path = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) +
-                              strlen(current_level.song_title) + 8 + 5));
-  song_subtitle = strdup(current_level.song_title);
-  strcpy(strstr(song_subtitle, "."), "\0");
-  sprintf(song_path, "%s/music/%s-fast%s", DATA_PREFIX, song_subtitle, strstr(current_level.song_title, "."));
-  level_song_fast = load_song(song_path);
-  free(song_subtitle);
-  free(song_path);
-}
-
 /* Load graphics/sounds shared between all levels: */
 
 void loadshared(void)
@@ -1273,7 +1299,7 @@ void drawshape(float x, float y, unsigned char c)
 
       /* Mark this as the end position of the level! */
 
-      endpos = x;
+      endpos = (int)x;
     }
   else if (c == '\\')
     {
@@ -1309,6 +1335,26 @@ unsigned char shape(float x, float y)
 
 /* Is is ground? */
 
+
+int issolid(float x, float y)
+{
+  if (isbrick(x, y) ||
+      isice(x, y) ||
+      (shape(x, y) == '[') ||
+      (shape(x, y) == '=') ||
+      (shape(x, y) == ']') ||
+      (shape(x, y) == 'A') ||
+      (shape(x, y) == 'B') ||
+      (shape(x, y) == '!') ||
+      (shape(x, y) == 'a'))
+    {
+      return YES;
+    }
+
+  return NO;
+}
+
+/*
 int issolid(float x, float y)
 {
   if (isbrick(x, y) ||
@@ -1334,7 +1380,7 @@ int issolid(float x, float y)
     }
 
   return NO;
-}
+}*/
 
 
 /* Is it a brick? */
@@ -1447,6 +1493,9 @@ void tryemptybox(float x, float y)
     {
       if (shape(x, y) == 'A')
         {
+       
+       DEBUG_MSG("Here I am");
+       
           /* Box with a distro! */
 
           add_bouncy_distro(((x + 1) / 32) * 32,
@@ -1562,31 +1611,38 @@ void drawstatus(void)
   int i;
 
   sprintf(str, "%d", score);
-  text_draw(&blue_text, "SCORE", 0, 0, 1, NO_UPDATE);
+  text_draw(&white_text, "SCORE", 0, 0, 1, NO_UPDATE);
   text_draw(&gold_text, str, 96, 0, 1, NO_UPDATE);
 
-  sprintf(str, "%d", hs_score);
-  text_draw(&blue_text, "HIGH", 0, 20, 1, NO_UPDATE);
-  text_draw(&gold_text, str, 96, 20, 1, NO_UPDATE);
-  
+  if(st_gl_mode == ST_GL_PLAY)
+    {
+      sprintf(str, "%d", hs_score);
+      text_draw(&white_text, "HIGH", 0, 20, 1, NO_UPDATE);
+      text_draw(&gold_text, str, 96, 20, 1, NO_UPDATE);
+    }
+  else if(st_gl_mode == ST_GL_TEST)
+    {
+      text_draw(&white_text,"Press ESC To Return",0,20,1, NO_UPDATE);
+    }
+
   if (timer_get_left(&time_left) > TIME_WARNING || (frame % 10) < 5)
     {
       sprintf(str, "%d", timer_get_left(&time_left) / 1000 );
-  text_draw(&blue_text, "TIME", 224, 0, 1, NO_UPDATE);
-  text_draw(&gold_text, str, 304, 0, 1, NO_UPDATE);
+      text_draw(&white_text, "TIME", 224, 0, 1, NO_UPDATE);
+      text_draw(&gold_text, str, 304, 0, 1, NO_UPDATE);
     }
 
   sprintf(str, "%d", distros);
-  text_draw(&blue_text, "DISTROS", screen->h, 0, 1, NO_UPDATE);
+  text_draw(&white_text, "DISTROS", screen->h, 0, 1, NO_UPDATE);
   text_draw(&gold_text, str, 608, 0, 1, NO_UPDATE);
 
-  text_draw(&blue_text, "LIVES", screen->h, 20, 1, NO_UPDATE);
+  text_draw(&white_text, "LIVES", screen->h, 20, 1, NO_UPDATE);
 
   if(show_fps)
     {
-      sprintf(str, "%f", fps_fps);
-      text_draw(&blue_text, "FPS", screen->h, 40, 1, NO_UPDATE);
-      text_draw(&blue_text, str, screen->h + 60, 40, 1, NO_UPDATE);
+      sprintf(str, "%2.1f", fps_fps);
+      text_draw(&white_text, "FPS", screen->h, 40, 1, NO_UPDATE);
+      text_draw(&gold_text, str, screen->h + 60, 40, 1, NO_UPDATE);
     }
 
   for(i=0; i < tux.lives; ++i)
@@ -1620,7 +1676,7 @@ void drawresultscreen(void)
 
   clearscreen(0, 0, 0);
 
-  text_drawf(&red_text, "Result:", 0, 200, A_HMIDDLE, A_TOP, 1, NO_UPDATE);
+  text_drawf(&blue_text, "Result:", 0, 200, A_HMIDDLE, A_TOP, 1, NO_UPDATE);
 
   sprintf(str, "SCORE: %d", score);
   text_drawf(&gold_text, str, 0, 224, A_HMIDDLE, A_TOP, 1, NO_UPDATE);
@@ -1688,14 +1744,16 @@ void loadgame(char* filename)
     {
       player_level_begin(&tux);
       set_defaults();
-      loadlevel(&current_level,"default",level);
+      level_free(&current_level);
+      if(level_load(&current_level,level_subset,level) != 0)
+        exit(1);
       arrays_free();
       arrays_init();
       activate_bad_guys();
-      unloadlevelgfx();
-      loadlevelgfx(&current_level);
-      unloadlevelsong();
-      loadlevelsong();
+      level_free_gfx();
+      level_load_gfx(&current_level);
+      level_free_song();
+      level_load_song(&current_level);
       levelintro();
       start_timers();
 
index 2a1ab16..21b9e36 100644 (file)
@@ -15,6 +15,7 @@
 
 #include "sound.h"
 #include "type.h"
+#include "level.h"
 
 /* Bounciness of distros: */
 
@@ -35,14 +36,21 @@ enum {
   UPGRADE_HERRING
 };
 
+extern st_level current_level;
+
 /* Scores: */
 
 #define SCORE_BRICK 5
 #define SCORE_DISTRO 25
 
+/* GameLoop modes */
+
+#define ST_GL_PLAY 0
+#define ST_GL_TEST 1
+
 /* Function prototypes: */
 
-int gameloop(void);
+int gameloop(char * subset, int levelnb, int mode);
 void savegame(void);
 void loadgame(char* filename);
 int issolid(float x, float y);
index 65f9c22..9d9fc1c 100644 (file)
 
 #include <SDL.h>
 #include "text.h"
+#include "menu.h"
 
-SDL_Surface * screen;
-text_type black_text, gold_text, blue_text, red_text;
+extern SDL_Surface * screen;
+extern text_type black_text, gold_text, white_text, white_small_text, blue_text, red_text, yellow_nums;
 
-int use_gl, use_joystick, use_fullscreen, debug_mode, show_fps;
-
-int game_started, level_editor_started;
+extern int use_gl, use_joystick, use_fullscreen, debug_mode, show_fps;
 
 /* SuperTux directory ($HOME/.supertux) and save directory($HOME/.supertux/save) */
-char *st_dir, *st_save_dir;
+extern char *st_dir, *st_save_dir;
 
 #ifdef JOY_YES
-SDL_Joystick * js;
+extern SDL_Joystick * js;
 #endif
 
 #endif /* SUPERTUX_GLOBALS_H */
index 22210c0..c209148 100644 (file)
 #include "screen.h"
 #include "texture.h"
 
+int hs_score;
+char hs_name[62]; /* highscores global variables*/
+
 FILE * opendata(char * mode)
 {
-  char * filename;
+  char * filename = NULL;
   FILE * fi;
 
 
@@ -64,12 +67,12 @@ void load_hs(void)
 {
   FILE * fi;
   char temp[128];
-  int c, strl;
+  int c, i, strl;
   
   hs_score = 100;
   strcpy(hs_name, "Grandma\0");
   c = 0;
-  
+
   /* Try to open file: */
 
   fi = opendata("r");
@@ -97,9 +100,9 @@ void load_hs(void)
                 {
                   fprintf(stderr, "name found\n");
                   strl = strlen("name=");
-                 hs_name[strl-1]='\0';
-                  for(c = strl; c < strlen(temp); c++)
-                    hs_name[c-strl] = temp[c];
+                  for(c = strl, i = 0; c < strlen(temp); ++c, ++i)
+                    hs_name[i] = temp[c];
+                 hs_name[i]= '\0';
                 }
             }
         }
@@ -111,6 +114,8 @@ void load_hs(void)
 
 void save_hs(int score)
 {
+  char str[80];
+
   texture_type bkgd;
   SDL_Event event;
   FILE * fi;
@@ -120,18 +125,41 @@ void save_hs(int score)
 
   hs_score = score;
 
+  menu_reset();
+  menu_set_current(&highscore_menu);
+
+  if(!highscore_menu.item[0].input)
+  highscore_menu.item[0].input = (char*) malloc(strlen(hs_name) + 1);
+  
+  strcpy(highscore_menu.item[0].input,hs_name);
+
   /* ask for player's name */
-  menumenu = MENU_HIGHSCORE;
   show_menu = 1;
   while(show_menu)
     {
       texture_draw_bg(&bkgd, NO_UPDATE);
-      drawmenu();
+
+      text_drawf(&blue_text, "Congratulations", 0, 130, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
+      text_draw(&blue_text, "Your score:", 150, 180, 1, NO_UPDATE);
+      sprintf(str, "%d", hs_score);
+      text_draw(&yellow_nums, str, 350, 170, 1, NO_UPDATE);
+
+      menu_process_current();
       flipscreen();
 
       while(SDL_PollEvent(&event))
         if(event.type == SDL_KEYDOWN)
           menu_event(&event.key.keysym);
+
+      switch (menu_check(&highscore_menu))
+        {
+        case 0:
+          if(highscore_menu.item[0].input != NULL)
+            strcpy(hs_name, highscore_menu.item[0].input);
+          break;
+        }
+
+      SDL_Delay(25);
     }
 
 
index 0b8d91a..c15ade6 100644 (file)
@@ -7,8 +7,8 @@
 
 # include <stdio.h>
 
-int hs_score;
-char hs_name[62]; /* highscores global variables*/
+extern int hs_score;
+extern char hs_name[62]; /* highscores global variables*/
 
 void save_hs(int score);
 void load_hs();
index 0efb9b5..d60f088 100644 (file)
@@ -70,8 +70,8 @@ int intro(void)
   
   /* Allocate buffer for height array: */
   
-  height = malloc(sizeof(int) * (gown_upset.w));
-  height_speed = malloc(sizeof(int) * (gown_upset.w));
+  height = (int*) malloc(sizeof(int) * (gown_upset.w));
+  height_speed = (int*) malloc(sizeof(int) * (gown_upset.w));
   
   
   /* Initialize height arrays: */
@@ -137,7 +137,7 @@ int intro(void)
          texture_draw(&tux_sit, 270, 400, UPDATE);
          texture_draw(&gown_sit, 320, 400, UPDATE);
          
-         text_drawf(&blue_text, intro_text[0], 0, -8, A_HMIDDLE, A_BOTTOM, 0, NO_UPDATE);
+         text_drawf(&white_text, intro_text[0], 0, -8, A_HMIDDLE, A_BOTTOM, 0, NO_UPDATE);
        }
       
       
@@ -146,8 +146,8 @@ int intro(void)
          ++scene;
          /* Helicopter begins to fly in: */
          
-         erasecenteredtext(intro_text[0], 456, &bkgd, NO_UPDATE, 1);
-         text_drawf(&blue_text, intro_text[1], 0,-8, A_HMIDDLE, A_BOTTOM, 0, NO_UPDATE);
+         erasecenteredtext(intro_text[0], 454, &bkgd, NO_UPDATE, 1);
+         text_drawf(&white_text, intro_text[1], 0,-8, A_HMIDDLE, A_BOTTOM, 0, NO_UPDATE);
        }
 
       
@@ -200,8 +200,8 @@ int intro(void)
          texture_draw(&tux_upset, 270, 400, UPDATE);
          
          
-         erasecenteredtext(intro_text[1], 456, &bkgd, UPDATE, 1);
-         text_drawf(&blue_text, intro_text[2], 0,-8, A_HMIDDLE, A_BOTTOM, 0, NO_UPDATE);
+         erasecenteredtext(intro_text[1], 454, &bkgd, UPDATE, 1);
+         text_drawf(&white_text, intro_text[2], 0,-8, A_HMIDDLE, A_BOTTOM, 0, NO_UPDATE);
        }
       
       
@@ -254,8 +254,8 @@ int intro(void)
          
          texture_draw(&tux_mad, 270, 400, UPDATE);
          
-         erasecenteredtext(intro_text[2], 456, &bkgd, UPDATE, 1);
-         text_drawf(&blue_text, intro_text[3], 0,-8, A_HMIDDLE, A_BOTTOM, 0, NO_UPDATE);
+         erasecenteredtext(intro_text[2], 454, &bkgd, UPDATE, 1);
+         text_drawf(&white_text, intro_text[3], 0,-8, A_HMIDDLE, A_BOTTOM, 0, NO_UPDATE);
        }
       
       
index b9f0ea4..db92a4c 100644 (file)
 #include "screen.h"
 #include "level.h"
 
-/* Load data for this level: */
+texture_type img_bkgd, img_bkgd_tile[2][4], img_solid[4], img_brick[2];
+
+void subset_init(st_subset* st_subset)
+{
+  st_subset->title = NULL;
+  st_subset->description = NULL;
+  st_subset->levels = 0;
+}
 
-void loadlevel(st_level* plevel, char *subset, int level)
+void subset_load(st_subset* st_subset, char *subset)
+{
+  FILE* fi;
+  char filename[1024];
+  char str[1024];
+  int len,i;
+
+  st_subset->name = (char*) malloc(sizeof(char)*(strlen(subset)+1));
+  strcpy(st_subset->name,subset);
+
+  snprintf(filename, 1024, "%s/levels/%s/info", st_dir, subset);
+  if(!faccessible(filename))
+    snprintf(filename, 1024, "%s/levels/%s/info", DATA_PREFIX, subset);
+  if(faccessible(filename))
+    {
+      fi = fopen(filename, "r");
+      if (fi == NULL)
+        {
+          perror(filename);
+        }
+
+      /* Load title info: */
+      fgets(str, 40, fi);
+      st_subset->title = (char*) malloc(sizeof(char)*(strlen(str)+1));
+      strcpy(st_subset->title, str);
+
+      /* Load the description: */
+
+      str[0] = '\0';
+      st_subset->description = NULL;
+      len = 0;
+      while(fgets(str, 300, fi) != NULL)
+        {
+          len += strlen(str);
+          if(st_subset->description == NULL)
+            st_subset->description = (char*) calloc(len+1,sizeof(char));
+          else
+            st_subset->description = (char*) realloc(st_subset->description, sizeof(char) * (len+1));
+          strcat(st_subset->description,str);
+        }
+      fclose(fi);
+
+      snprintf(str, 1024, "%s.png", filename);
+      if(faccessible(str))
+        {
+          texture_load(&st_subset->image,str,IGNORE_ALPHA);
+        }
+      else
+        {
+          snprintf(filename, 1024, "%s/images/status/level-subset-info.png", DATA_PREFIX);
+          texture_load(&st_subset->image,filename,IGNORE_ALPHA);
+        }
+    }
+
+  for(i=1; i != -1; ++i)
+    {
+      /* Get the number of levels in this subset */
+      snprintf(filename, 1024, "%s/levels/%s/level%d.dat", st_dir, subset,i);
+      if(!faccessible(filename))
+        {
+          snprintf(filename, 1024, "%s/levels/%s/level%d.dat", DATA_PREFIX, subset,i);
+          if(!faccessible(filename))
+            break;
+        }
+    }
+    st_subset->levels = --i;
+}
+
+void subset_free(st_subset* st_subset)
+{
+  free(st_subset->title);
+  free(st_subset->description);
+  free(st_subset->name);
+  texture_free(&st_subset->image);
+  st_subset->levels = 0;
+}
+
+/* Load data for this level: */
+/* Returns -1, if the loading of the level failed. */
+int level_load(st_level* plevel, char *subset, int level)
 {
   int y;
   FILE * fi;
   char str[80];
-  char * filename;
+  char filename[1024];
   char * line;
 
   /* Load data file: */
 
-  filename = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) + 20) + strlen(subset));
-  sprintf(filename, "%s/levels/%s/level%d.dat", DATA_PREFIX, subset, level);
+  snprintf(filename, 1024, "%s/levels/%s/level%d.dat", st_dir, subset, level);
+  if(!faccessible(filename))
+    snprintf(filename, 1024, "%s/levels/%s/level%d.dat", DATA_PREFIX, subset, level);
   fi = fopen(filename, "r");
   if (fi == NULL)
     {
       perror(filename);
-      st_shutdown();
-      free(filename);
-      exit(-1);
+      return -1;
     }
-  free(filename);
 
 
   /* Load header info: */
@@ -92,7 +176,7 @@ void loadlevel(st_level* plevel, char *subset, int level)
     {
       fprintf(stderr, "Couldn't allocate space to load level data!");
       fclose(fi);
-      exit(1);
+      return -1;
     }
 
 
@@ -105,39 +189,40 @@ void loadlevel(st_level* plevel, char *subset, int level)
           fprintf(stderr, "Level %s isn't complete!\n",plevel->name);
           free(line);
           fclose(fi);
-          exit(1);
+          return -1;
         }
       line[strlen(line) - 1] = '\0';
-      plevel->tiles[y] = strdup(line);
+      plevel->tiles[y] = (unsigned char*) strdup(line);
     }
 
   free(line);
   fclose(fi);
-
+  return 0;
 }
 
 /* Save data for level: */
 
-void savelevel(st_level* plevel, char * subset, int level)
+void level_save(st_level* plevel, char * subset, int level)
 {
   FILE * fi;
-  char * filename;
+  char filename[1024];
   int y;
   char str[80];
 
   /* Save data file: */
+  sprintf(str, "/levels/%s/", subset);
+  fcreatedir(str);
+  snprintf(filename, 1024, "%s/levels/%s/level%d.dat", st_dir, subset, level);
+  if(!fwriteable(filename))
+    snprintf(filename, 1024, "%s/levels/%s/level%d.dat", DATA_PREFIX, subset, level);
 
-  filename = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) + 20) + strlen(subset));
-  sprintf(filename, "%s/levels/%s/level%d.dat", DATA_PREFIX, subset, level);
   fi = fopen(filename, "w");
   if (fi == NULL)
     {
       perror(filename);
       st_shutdown();
-      free(filename);
       exit(-1);
     }
-  free(filename);
 
   fputs(plevel->name, fi);
   fputs("\n", fi);
@@ -147,7 +232,7 @@ void savelevel(st_level* plevel, char * subset, int level)
   fputs(str, fi);
   fputs(plevel->song_title, fi);       /* song filename */
   fputs("\n",fi);
-  fputs(plevel->bkgd_image, fi);       /* background image */  
+  fputs(plevel->bkgd_image, fi);       /* background image */
   sprintf(str, "\n%d\n", plevel->bkgd_red);    /* red background color */
   fputs(str, fi);
   sprintf(str, "%d\n", plevel->bkgd_green);    /* green background color */
@@ -159,7 +244,7 @@ void savelevel(st_level* plevel, char * subset, int level)
 
   for(y = 0; y < 15; ++y)
     {
-      fputs(plevel->tiles[y], fi);
+      fputs((const char*)plevel->tiles[y], fi);
       fputs("\n", fi);
     }
 
@@ -169,9 +254,12 @@ void savelevel(st_level* plevel, char * subset, int level)
 
 /* Unload data for this level: */
 
-void unloadlevel(st_level* plevel)
+void level_free(st_level* plevel)
 {
-  free(plevel->tiles);
+  int i;
+  for(i=0; i < 15; ++i)
+    free(plevel->tiles[i]);
+
   plevel->name[0] = '\0';
   plevel->theme[0] = '\0';
   plevel->song_title[0] = '\0';
@@ -180,26 +268,26 @@ void unloadlevel(st_level* plevel)
 
 /* Load graphics: */
 
-void loadlevelgfx(st_level *plevel)
+void level_load_gfx(st_level *plevel)
 {
 
-  load_level_image(&img_brick[0],plevel->theme,"brick0.png", IGNORE_ALPHA);
-  load_level_image(&img_brick[1],plevel->theme,"brick1.png", IGNORE_ALPHA);
+  level_load_image(&img_brick[0],plevel->theme,"brick0.png", IGNORE_ALPHA);
+  level_load_image(&img_brick[1],plevel->theme,"brick1.png", IGNORE_ALPHA);
 
-  load_level_image(&img_solid[0],plevel->theme,"solid0.png", USE_ALPHA);
-  load_level_image(&img_solid[1],plevel->theme,"solid1.png", USE_ALPHA);
-  load_level_image(&img_solid[2],plevel->theme,"solid2.png", USE_ALPHA);
-  load_level_image(&img_solid[3],plevel->theme,"solid3.png", USE_ALPHA);
+  level_load_image(&img_solid[0],plevel->theme,"solid0.png", USE_ALPHA);
+  level_load_image(&img_solid[1],plevel->theme,"solid1.png", USE_ALPHA);
+  level_load_image(&img_solid[2],plevel->theme,"solid2.png", USE_ALPHA);
+  level_load_image(&img_solid[3],plevel->theme,"solid3.png", USE_ALPHA);
 
-  load_level_image(&img_bkgd_tile[0][0],plevel->theme,"bkgd-00.png", USE_ALPHA);
-  load_level_image(&img_bkgd_tile[0][1],plevel->theme,"bkgd-01.png", USE_ALPHA);
-  load_level_image(&img_bkgd_tile[0][2],plevel->theme,"bkgd-02.png", USE_ALPHA);
-  load_level_image(&img_bkgd_tile[0][3],plevel->theme,"bkgd-03.png", USE_ALPHA);
+  level_load_image(&img_bkgd_tile[0][0],plevel->theme,"bkgd-00.png", USE_ALPHA);
+  level_load_image(&img_bkgd_tile[0][1],plevel->theme,"bkgd-01.png", USE_ALPHA);
+  level_load_image(&img_bkgd_tile[0][2],plevel->theme,"bkgd-02.png", USE_ALPHA);
+  level_load_image(&img_bkgd_tile[0][3],plevel->theme,"bkgd-03.png", USE_ALPHA);
 
-  load_level_image(&img_bkgd_tile[1][0],plevel->theme,"bkgd-10.png", USE_ALPHA);
-  load_level_image(&img_bkgd_tile[1][1],plevel->theme,"bkgd-11.png", USE_ALPHA);
-  load_level_image(&img_bkgd_tile[1][2],plevel->theme,"bkgd-12.png", USE_ALPHA);
-  load_level_image(&img_bkgd_tile[1][3],plevel->theme,"bkgd-13.png", USE_ALPHA);
+  level_load_image(&img_bkgd_tile[1][0],plevel->theme,"bkgd-10.png", USE_ALPHA);
+  level_load_image(&img_bkgd_tile[1][1],plevel->theme,"bkgd-11.png", USE_ALPHA);
+  level_load_image(&img_bkgd_tile[1][2],plevel->theme,"bkgd-12.png", USE_ALPHA);
+  level_load_image(&img_bkgd_tile[1][3],plevel->theme,"bkgd-13.png", USE_ALPHA);
 
   if(strcmp(plevel->bkgd_image,"") != 0)
     {
@@ -208,13 +296,12 @@ void loadlevelgfx(st_level *plevel)
       if(!faccessible(fname))
         snprintf(fname, 1024, "%s/images/background/%s", DATA_PREFIX, plevel->bkgd_image);
       texture_load(&img_bkgd, fname, IGNORE_ALPHA);
-      printf("%s",fname);
     }
 }
 
 /* Free graphics data for this level: */
 
-void unloadlevelgfx(void)
+void level_free_gfx(void)
 {
   int i;
 
@@ -233,7 +320,7 @@ void unloadlevelgfx(void)
 
 /* Load a level-specific graphic... */
 
-void load_level_image(texture_type* ptexture, char* theme, char * file, int use_alpha)
+void level_load_image(texture_type* ptexture, char* theme, char * file, int use_alpha)
 {
   char fname[1024];
 
@@ -257,3 +344,35 @@ void level_change(st_level* plevel, float x, float y, unsigned char c)
     plevel->tiles[yy][xx] = c;
 }
 
+/* Free music data for this level: */
+
+void level_free_song(void)
+{
+  free_music(level_song);
+  free_music(level_song_fast);
+}
+
+/* Load music: */
+
+void level_load_song(st_level* plevel)
+{
+
+  char * song_path;
+  char * song_subtitle;
+
+  song_path = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) +
+                              strlen(plevel->song_title) + 8));
+  sprintf(song_path, "%s/music/%s", DATA_PREFIX, plevel->song_title);
+  level_song = load_song(song_path);
+  free(song_path);
+
+
+  song_path = (char *) malloc(sizeof(char) * (strlen(DATA_PREFIX) +
+                              strlen(plevel->song_title) + 8 + 5));
+  song_subtitle = strdup(plevel->song_title);
+  strcpy(strstr(song_subtitle, "."), "\0");
+  sprintf(song_path, "%s/music/%s-fast%s", DATA_PREFIX, song_subtitle, strstr(plevel->song_title, "."));
+  level_song_fast = load_song(song_path);
+  free(song_subtitle);
+  free(song_path);
+}
index a21a0b2..ffadfa5 100644 (file)
 
 #include "texture.h"
 
+/* This type holds meta-information about a level-subset. */
+/* It could be extended to handle manipulation of subsets. */
+typedef struct st_subset
+  {
+    char *name;
+    char *title;
+    char *description;
+    texture_type image;
+    int levels;
+  } st_subset;
+
+void subset_init(st_subset* st_subset);
+void subset_load(st_subset* st_subset, char *subset);
+void subset_free(st_subset* st_subset);
+  
 #define LEVEL_NAME_MAX 20
 
 typedef struct st_level /*It is easier to read the sources IMHO, if we don't write something like int a,b,c; */
@@ -30,15 +45,17 @@ typedef struct st_level /*It is easier to read the sources IMHO, if we don't wri
     int bkgd_blue;
     int width;
   } st_level;
-
-texture_type img_bkgd, img_bkgd_tile[2][4], img_solid[4], img_brick[2];
   
-void loadlevel(st_level* plevel, char * subset, int level);
-void savelevel(st_level* plevel, char * subset, int level);
-void unloadlevel(st_level* plevel);
-void loadlevelgfx(st_level* plevel);
-void unloadlevelgfx();
-void load_level_image(texture_type* ptexture, char* theme, char * file, int use_alpha);
+extern texture_type img_bkgd, img_bkgd_tile[2][4], img_solid[4], img_brick[2];
+  
+int level_load(st_level* plevel, char * subset, int level);
+void level_save(st_level* plevel, char * subset, int level);
+void level_free(st_level* plevel);
+void level_load_gfx(st_level* plevel);
+void level_free_gfx();
+void level_load_image(texture_type* ptexture, char* theme, char * file, int use_alpha);
 void level_change(st_level* plevel, float x, float y, unsigned char c);
+void level_load_song(st_level* plevel);
+void level_free_song(void);
 
 #endif /*SUPERTUX_LEVEL_H*/
index 7f014b1..4a7a382 100644 (file)
@@ -1,4 +1,3 @@
-
 /***************************************************************************
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
@@ -29,8 +28,8 @@
 #include "menu.h"
 #include "level.h"
 #include "badguy.h"
-#include "gameloop.h"
 #include "scene.h"
+#include "button.h"
 
 /* definitions to aid development */
 #define DONE_LEVELEDITOR 1
 /* definitions that affect gameplay */
 #define KEY_CURSOR_SPEED 32
 #define KEY_CURSOR_FASTSPEED 64
-// when pagedown/up pressed speed:
+/* when pagedown/up pressed speed:*/
 #define PAGE_CURSOR_SPEED 13*32
 
 #define CURSOR_LEFT_MARGIN 96
-#define CURSOR_RIGHT_MARGIN 512
+#define CURSOR_RIGHT_MARGIN 600
 /* right_margin should noticed that the cursor is 32 pixels,
    so it should subtract that value */
 
 #define MOUSE_RIGHT_MARGIN 608
 #define MOUSE_POS_SPEED 32
 
-/* Level Intro: */
-/*
-  clearscreen(0, 0, 0);
-  sprintf(str, "Editing Level %s", levelfilename);
-  drawcenteredtext(str, 200, letters_red, NO_UPDATE, 1);
-  sprintf(str, "%s", levelname);
-  drawcenteredtext(str, 224, letters_gold, NO_UPDATE, 1);
-  flipscreen();
-  SDL_Delay(1000);
-*/
-
 /* gameloop funcs declerations */
 
 void loadshared(void);
 void unloadshared(void);
 
 /* own declerations */
-
-void savelevel();
+/* crutial ones (main loop) */
+int le_init();
+void le_quit();
+void le_drawlevel();
+void le_checkevents();
 void le_change(float x, float y, unsigned char c);
-void showhelp();
+void le_showhelp();
 void le_set_defaults(void);
 void le_activate_bad_guys(void);
 
-/* global variables (based on the gameloop ones) */
-
-int level;
-st_level current_level;
-char level_subset[100];
-int show_grid;
-
-int frame;
-texture_type selection;
-int last_time, now_time;
-
-void le_quit(void)
-{
-  unloadlevelgfx();
-  unloadshared();
-  arrays_free();
-  texture_free(&selection);
-}
+/* leveleditor internals */
+static int le_level_changed;  /* if changes, ask for saving, when quiting*/
+static int pos_x, cursor_x, cursor_y, cursor_tile, fire;
+static int le_level;
+static st_level le_current_level;
+static st_subset le_level_subset;
+static int le_show_grid;
+static int le_frame;
+static texture_type le_selection;
+static int done;
+static char le_current_tile;
+static int le_mouse_pressed;
+static button_type le_test_level_bt;
+static button_type le_next_level_bt;
+static button_type le_previous_level_bt;
+static button_type le_rubber_bt;
 
 void le_activate_bad_guys(void)
 {
@@ -109,17 +94,17 @@ void le_activate_bad_guys(void)
   the badguys from tiles                                    */
 
   for (y = 0; y < 15; ++y)
-    for (x = 0; x < current_level.width; ++x)
-      if (current_level.tiles[y][x] >= '0' && current_level.tiles[y][x] <= '9')
-        add_bad_guy(x * 32, y * 32, current_level.tiles[y][x] - '0');
+    for (x = 0; x < le_current_level.width; ++x)
+      if (le_current_level.tiles[y][x] >= '0' && le_current_level.tiles[y][x] <= '9')
+        add_bad_guy(x * 32, y * 32, le_current_level.tiles[y][x] - '0');
 }
 
 void le_set_defaults()
 {
   /* Set defaults: */
 
-  if(current_level.time_left == 0)
-    current_level.time_left = 255;
+  if(le_current_level.time_left == 0)
+    le_current_level.time_left = 255;
 }
 
 /* FIXME: Needs to be implemented. It should ask the user for the level(file)name and then let him create a new level based on this. */
@@ -130,422 +115,516 @@ void newlevel()
 void selectlevel()
 {}
 
-int leveleditor()
+int leveleditor(int levelnb)
 {
-  char str[LEVEL_NAME_MAX];
-  int done;
-  int x, y, i; /* for cicles */
-  int pos_x, cursor_x, cursor_y, cursor_tile, fire;
-  SDL_Event event;
-  SDLKey key;
-  SDLMod keymod;
+  int last_time, now_time;
 
-  strcpy(level_subset,"default");
-  show_grid = NO;
-  
-  level = 1;
+  le_level = levelnb;
+  if(le_init() != 0)
+    return 1;
 
-  initmenu();
-  menumenu = MENU_LEVELEDITOR;
-  show_menu = YES;
+  while(1)
+    {
+      last_time = SDL_GetTicks();
+      le_frame++;
 
-  frame = 0;   /* support for frames in some tiles, like waves and bad guys */
+      le_checkevents();
 
-  arrays_init();
-  
-  loadshared();
-  set_defaults();
+      if(cursor_x < pos_x + CURSOR_LEFT_MARGIN)
+        pos_x = cursor_x - CURSOR_LEFT_MARGIN;
 
-  loadlevel(&current_level,"default",level);
-  loadlevelgfx(&current_level);
+      if(cursor_x > pos_x + CURSOR_RIGHT_MARGIN)
+        pos_x = cursor_x - CURSOR_RIGHT_MARGIN;
 
-  le_activate_bad_guys();
-  le_set_defaults();
+      /* make sure we respect the borders */
+      if(cursor_x < 0)
+        cursor_x = 0;
+      if(cursor_x > (le_current_level.width*32) - 32)
+        cursor_x = (le_current_level.width*32) - 32;
 
-  texture_load(&selection,DATA_PREFIX "/images/leveleditor/select.png", USE_ALPHA);
+      if(pos_x < 0)
+        pos_x = 0;
+      if(pos_x > (le_current_level.width * 32) - screen->w + 32)
+        pos_x = (le_current_level.width * 32) - screen->w + 32;
+
+      /* draw the level */
+      le_drawlevel();
+
+      if(show_menu)
+        {
+          menu_process_current();
+          if(current_menu == &leveleditor_menu)
+            {
+              switch (menu_check(&leveleditor_menu))
+                {
+                case 0:
+                  show_menu = NO;
+                  break;
+                case 4:
+                  done = DONE_LEVELEDITOR;
+                  break;
+                }
+            }
+        }
+
+      if(done)
+        {
+          le_quit();
+          return 0;
+        }
+
+      if(done == DONE_QUIT)
+        {
+          le_quit();
+          return 1;
+        }
+
+      SDL_Delay(25);
+      now_time = SDL_GetTicks();
+      if (now_time < last_time + FPS)
+        SDL_Delay(last_time + FPS - now_time); /* delay some time */
+
+      flipscreen();
+    }
+
+  return done;
+}
+
+int le_init()
+{
+  subset_load(&le_level_subset,"default");
+  le_show_grid = YES;
 
   done = 0;
-  pos_x = 0;
-  cursor_x = 3*32;
-  cursor_y = 2*32;
-  fire = DOWN;
+  menu_reset();
+  menu_set_current(&leveleditor_menu);
+  le_frame = 0;        /* support for frames in some tiles, like waves and bad guys */
 
-  SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
+  arrays_init();
+  loadshared();
+  le_set_defaults();
 
-  while(1)
+  le_level_changed = NO;
+  if(level_load(&le_current_level, le_level_subset.name, le_level) != 0)
     {
-      clearscreen(current_level.bkgd_red, current_level.bkgd_green, current_level.bkgd_blue);
+      le_quit();
+      return 1;
+    }
+  if(le_current_level.time_left == 0)
+    le_current_level.time_left = 255;
 
-      last_time = SDL_GetTicks();
-      frame++;
+  level_load_gfx(&le_current_level);
 
-      keymod = SDL_GetModState();
+  le_current_tile = '.';
+  le_mouse_pressed = NO;
+  le_activate_bad_guys();
 
-      while(SDL_PollEvent(&event))
-        {
-          // testing SDL_KEYDOWN, SDL_KEYUP and SDL_QUIT events
-          switch(event.type)
-            {
-            case SDL_KEYDOWN:  // key pressed
-              key = event.key.keysym.sym;
-              if(show_menu)
-                {
-                  menu_event(&event.key.keysym);
-                  break;
-                }
-              switch(key)
-                {
-                case SDLK_LEFT:
-                  if(fire == DOWN)
-                    cursor_x -= KEY_CURSOR_SPEED;
-                  else
-                    cursor_x -= KEY_CURSOR_FASTSPEED;
-
-                  if(cursor_x < 0)
-                    cursor_x = 0;
-                  break;
-                case SDLK_RIGHT:
-                  if(fire == DOWN)
-                    cursor_x += KEY_CURSOR_SPEED;
-                  else
-                    cursor_x += KEY_CURSOR_FASTSPEED;
-
-                  if(cursor_x > (current_level.width*32) - 32)
-                    cursor_x = (current_level.width*32) - 32;
-                  break;
-                case SDLK_UP:
-                  if(fire == DOWN)
-                    cursor_y -= KEY_CURSOR_SPEED;
-                  else
-                    cursor_y -= KEY_CURSOR_FASTSPEED;
-
-                  if(cursor_y < 0)
-                    cursor_y = 0;
-                  break;
-                case SDLK_DOWN:
-                  if(fire == DOWN)
-                    cursor_y += KEY_CURSOR_SPEED;
-                  else
-                    cursor_y += KEY_CURSOR_FASTSPEED;
-
-                  if(cursor_y > screen->h-32)
-                    cursor_y = screen->h-32;
-                  break;
-                case SDLK_LCTRL:
-                  fire =UP;
-                  break;
-                case SDLK_F1:
-                  showhelp();
-                  break;
-                case SDLK_HOME:
-                  cursor_x = 0;
-                  break;
-                case SDLK_END:
-                  cursor_x = (current_level.width * 32) - 32;
-                  break;
-                case SDLK_PAGEUP:
-                  cursor_x -= PAGE_CURSOR_SPEED;
+  texture_load(&le_selection,DATA_PREFIX "/images/leveleditor/select.png", USE_ALPHA);
+  button_load(&le_test_level_bt,"/images/icons/test-level.png","Test Level","Press this button to test the level that is currently being edited.",150,screen->h - 64);
+  button_load(&le_next_level_bt,"/images/icons/up.png","Test Level","Press this button to test the level that is currently being edited.",screen->w-32,0);
+  button_load(&le_previous_level_bt,"/images/icons/down.png","Test Level","Press this button to test the level that is currently being edited.",screen->w-32,16);
+  button_load(&le_rubber_bt,"/images/icons/rubber.png","Test Level","Press this button to test the level that is currently being edited.",screen->w-32,32);
+  
+  SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
 
-                                                                       if(cursor_x < 0)
-                                                                               cursor_x = 0;
-                  break;
-                case SDLK_PAGEDOWN:
-                  cursor_x += PAGE_CURSOR_SPEED;
+  return 0;
+}
 
-                  if(cursor_x > (current_level.width*32) - 32)
-                    cursor_x = (current_level.width*32) - 32;
-                  break;
-                case SDLK_F9:
-                  if(!show_grid)
-                    show_grid = YES;
-                  else
-                    show_grid = NO;
-                  break;
-                case SDLK_PERIOD:
-                  le_change(cursor_x, cursor_y, '.');
-                  break;
-                case SDLK_a:
-                  if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
-                    le_change(cursor_x, cursor_y, 'A');
-                  else
-                    le_change(cursor_x, cursor_y, 'a');
-                  break;
-                case SDLK_b:
-                  if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
-                    le_change(cursor_x, cursor_y, 'B');
-                  break;
-                case SDLK_c:
-                  if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
-                    le_change(cursor_x, cursor_y, 'C');
-                  else
-                    le_change(cursor_x, cursor_y, 'c');
-                  break;
-                case SDLK_d:
-                  if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
-                    le_change(cursor_x, cursor_y, 'D');
-                  else
-                    le_change(cursor_x, cursor_y, 'd');
-                  break;
-                case SDLK_e:
-                  if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
-                    le_change(cursor_x, cursor_y, 'E');
-                  else
-                    le_change(cursor_x, cursor_y, 'e');
-                  break;
-                case SDLK_f:
-                  if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
-                    le_change(cursor_x, cursor_y, 'F');
-                  else
-                    le_change(cursor_x, cursor_y, 'f');
-                  break;
-                case SDLK_g:
-                  if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
-                    le_change(cursor_x, cursor_y, 'G');
-                  else
-                    le_change(cursor_x, cursor_y, 'g');
-                  break;
-                case SDLK_h:
-                  if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
-                    le_change(cursor_x, cursor_y, 'H');
-                  else
-                    le_change(cursor_x, cursor_y, 'h');
-                  break;
-                case SDLK_i:
-                  if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
-                    le_change(cursor_x, cursor_y, 'I');
-                  else
-                    le_change(cursor_x, cursor_y, 'i');
-                  break;
-                case SDLK_j:
-                  if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
-                    le_change(cursor_x, cursor_y, 'J');
-                  else
-                    le_change(cursor_x, cursor_y, 'j');
-                  break;
-                case SDLK_x:
-                  if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
-                    le_change(cursor_x, cursor_y, 'X');
-                  else
-                    le_change(cursor_x, cursor_y, 'x');
-                  break;
-                case SDLK_y:
-                  if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
-                    le_change(cursor_x, cursor_y, 'Y');
-                  else
-                    le_change(cursor_x, cursor_y, 'y');
-                  break;
-                case SDLK_LEFTBRACKET:
-                  le_change(cursor_x, cursor_y, '[');
-                  break;
-                case SDLK_RIGHTBRACKET:
-                  le_change(cursor_x, cursor_y, ']');
-                  break;
-                case SDLK_HASH:
-                case SDLK_3:
-                  if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
-                    le_change(cursor_x, cursor_y, '#');
-                  break;
-                case SDLK_DOLLAR:
-                case SDLK_4:
-                  if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
-                    le_change(cursor_x, cursor_y, '$');
-                  break;
-                case SDLK_BACKSLASH:
-                  if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
-                    le_change(cursor_x, cursor_y, '|');
-                  else
-                    le_change(cursor_x, cursor_y, '\\');
-                  break;
-                case SDLK_CARET:
-                  le_change(cursor_x, cursor_y, '^');
-                  break;
-                case SDLK_AMPERSAND:
-                case SDLK_6:
-                  if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
-                    le_change(cursor_x, cursor_y, '&');
-                  break;
-                case SDLK_EQUALS:
-                case SDLK_0:
-                  if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
-                    le_change(cursor_x, cursor_y, '=');
-                  else         /* let's add a bad guy */
-                    le_change(cursor_x, cursor_y, '0');
-                
-                 add_bad_guy((((int)cursor_x/32)*32), (((int)cursor_y/32)*32), BAD_BSOD);
-                  break;
-                case SDLK_1:
-                  if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
-                    le_change(cursor_x, cursor_y, '!');
-                  else         /* let's add a bad guy */
-                    le_change(cursor_x, cursor_y, '1');
+void le_quit(void)
+{
+  /*if(level_changed == YES)
+    if(askforsaving() == CANCEL)
+      return;*/ //FIXME
 
-                 add_bad_guy((((int)cursor_x/32)*32), (((int)cursor_y/32)*32), BAD_LAPTOP);
-                  break;
-                case SDLK_2:
-                  le_change(cursor_x, cursor_y, '2');
 
-                 add_bad_guy((((int)cursor_x/32)*32), (((int)cursor_y/32)*32), BAD_MONEY);
-                  break;
-                case SDLK_PLUS:
-                  if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
-                    le_change(cursor_x, cursor_y, '*');
-                  break;
-                default:
-                  break;
-                }
-              break;
-            case SDL_KEYUP:    // key released
-              switch(event.key.keysym.sym)
-                {
-                case SDLK_LCTRL:
-                  fire = DOWN;
-                  break;
-                case SDLK_ESCAPE:
-                  if(!show_menu)
-                    show_menu = YES;
-                  else
-                    show_menu = NO;
-                  break;
-                default:
-                  break;
-                }
-              break;
-              /*            case SDL_MOUSEBUTTONDOWN:
-                            if(event.button.button == SDL_BUTTON_LEFT)
-                              {
-              This will draw current tile in the cursor position, when the interface is done.
-                              }
-                            break;*/
-            case SDL_MOUSEMOTION:
-              if(!show_menu)
-                {
-                  x = event.motion.x;
-                  y = event.motion.y;
+  button_free(&le_test_level_bt);
+  level_free_gfx();
+  level_free(&le_current_level);
+  unloadshared();
+  arrays_free();
+  texture_free(&le_selection);
+}
 
-                  cursor_x = ((int)(pos_x + x) / 32) * 32;
-                  cursor_y = ((int) y / 32) * 32;
-                }
-              break;
-            case SDL_QUIT:     // window closed
-              done = DONE_QUIT;
-              break;
-            default:
-              break;
-            }
-        }
+void le_drawlevel()
+{
+  int y,x,i,s;
+  static char str[LEVEL_NAME_MAX];
 
-      /* mouse movements */
-      /*      x = event.motion.x;
-            if(x < MOUSE_LEFT_MARGIN)
-              pos_x -= MOUSE_POS_SPEED;
-            else if(x > MOUSE_RIGHT_MARGIN)
-              pos_x += MOUSE_POS_SPEED;*/
+  /* Draw the real background */
+  if(le_current_level.bkgd_image[0] != '\0')
+    {
+      s = pos_x / 30;
+      texture_draw_part(&img_bkgd,s,0,0,0,img_bkgd.w - s - 32, img_bkgd.h, NO_UPDATE);
+      texture_draw_part(&img_bkgd,0,0,screen->w - s - 32 ,0,s,img_bkgd.h, NO_UPDATE);
+    }
+  else
+    {
+      clearscreen(le_current_level.bkgd_red, le_current_level.bkgd_green, le_current_level.bkgd_blue);
+    }
 
+  /*       clearscreen(current_level.bkgd_red, current_level.bkgd_green, current_level.bkgd_blue); */
 
-      if(cursor_x < pos_x + CURSOR_LEFT_MARGIN)
-        pos_x = cursor_x - CURSOR_LEFT_MARGIN;
+  for (y = 0; y < 15; ++y)
+    for (x = 0; x < 19; ++x)
+      {
+        drawshape(x * 32, y * 32, le_current_level.tiles[y][x + (pos_x / 32)]);
+      }
+
+  /* draw whats inside stuff when cursor is selecting those */
+  cursor_tile = le_current_level.tiles[cursor_y/32][cursor_x/32];
+  switch(cursor_tile)
+    {
+    case 'B':
+      texture_draw(&img_mints, cursor_x - pos_x, cursor_y, NO_UPDATE);
+      break;
+    case '!':
+      texture_draw(&img_golden_herring, cursor_x - pos_x, cursor_y, NO_UPDATE);
+      break;
+    case 'x':
+    case 'y':
+    case 'A':
+      texture_draw(&img_distro[(le_frame / 5) % 4], cursor_x - pos_x, cursor_y, NO_UPDATE);
+      break;
+    default:
+      break;
+    }
 
-      if(cursor_x > pos_x + CURSOR_RIGHT_MARGIN)
-        pos_x = cursor_x - CURSOR_RIGHT_MARGIN;
+  /* Draw the Bad guys: */
+  for (i = 0; i < num_bad_guys; ++i)
+    {
+      if(bad_guys[i].base.alive == NO)
+        continue;
+      /* to support frames: img_bsod_left[(frame / 5) % 4] */
+      if(bad_guys[i].kind == BAD_BSOD)
+        texture_draw(&img_bsod_left[(le_frame / 5) % 4], ((int)(bad_guys[i].base.x - pos_x)/32)*32, bad_guys[i].base.y, NO_UPDATE);
+      else if(bad_guys[i].kind == BAD_LAPTOP)
+        texture_draw(&img_laptop_left[(le_frame / 5) % 3], ((int)(bad_guys[i].base.x - pos_x)/32)*32, bad_guys[i].base.y, NO_UPDATE);
+      else if (bad_guys[i].kind == BAD_MONEY)
+        texture_draw(&img_money_left[(le_frame / 5) % 2], ((int)(bad_guys[i].base.x - pos_x)/32)*32, bad_guys[i].base.y, NO_UPDATE);
+    }
 
-      if(pos_x < 0)
-        pos_x = 0;
-      if(pos_x > (current_level.width * 32) - screen->w)
-        pos_x = (current_level.width * 32) - screen->w;
-
-      for (y = 0; y < 15; ++y)
-        for (x = 0; x < 21; ++x)
-          drawshape(x * 32, y * 32, current_level.tiles[y][x + (pos_x / 32)]);
-
-/* draw whats inside stuff when cursor is selecting those */
-cursor_tile = current_level.tiles[cursor_y/32][cursor_x/32];
-switch(cursor_tile)
-       {
-       case 'B':
-               texture_draw(&img_mints, cursor_x - pos_x, cursor_y, NO_UPDATE);
-               break;
-       case '!':
-               texture_draw(&img_golden_herring, cursor_x - pos_x, cursor_y, NO_UPDATE);
-               break;
-       case 'x':
-       case 'y':
-       case 'A':
-               texture_draw(&img_distro[(frame / 5) % 4], cursor_x - pos_x, cursor_y, NO_UPDATE);
-               break;
-       default:
-               break;
-       }
-
-      /* Draw the Bad guys: */
-      for (i = 0; i < num_bad_guys; ++i)
-        {
-          if(bad_guys[i].base.alive == NO)
-            continue;
-          /* to support frames: img_bsod_left[(frame / 5) % 4] */
-          if(bad_guys[i].kind == BAD_BSOD)
-            texture_draw(&img_bsod_left[(frame / 5) % 4], ((int)(bad_guys[i].base.x - pos_x)/32)*32, bad_guys[i].base.y, NO_UPDATE);
-          else if(bad_guys[i].kind == BAD_LAPTOP)
-            texture_draw(&img_laptop_left[(frame / 5) % 3], ((int)(bad_guys[i].base.x - pos_x)/32)*32, bad_guys[i].base.y, NO_UPDATE);
-          else if (bad_guys[i].kind == BAD_MONEY)
-            texture_draw(&img_money_left[(frame / 5) % 2], ((int)(bad_guys[i].base.x - pos_x)/32)*32, bad_guys[i].base.y, NO_UPDATE);
-        }
+  /* draw a grid (if selected) */
+  if(le_show_grid)
+    {
+      for(x = 0; x < 19; x++)
+        fillrect(x*32, 0, 1, screen->h, 225, 225, 225,255);
+      for(y = 0; y < 15; y++)
+        fillrect(0, y*32, screen->w - 32, 1, 225, 225, 225,255);
+    }
+
+  fillrect(screen->w - 32, 0, 32, screen->h, 50, 50, 50,255);
+  drawshape(19 * 32, 14 * 32, le_current_tile);
 
-/* draw a grid (if selected) */
-if(show_grid)
-       {
-       for(x = 0; x < 21; x++)
-               fillrect(x*32, 0, 1, 480, 225, 225, 225);
-       for(y = 0; y < 15; y++)
-               fillrect(0, y*32, 640, 1, 225, 225, 225);
-       }
+  button_draw(&le_test_level_bt);
+  button_draw(&le_next_level_bt);
+  button_draw(&le_previous_level_bt);
+  button_draw(&le_rubber_bt);
+  
+  texture_draw(&le_selection, ((int)(cursor_x - pos_x)/32)*32, cursor_y, NO_UPDATE);
 
-      texture_draw(&selection, ((int)(cursor_x - pos_x)/32)*32, cursor_y, NO_UPDATE);
+  sprintf(str, "%d", le_current_level.time_left);
+  text_draw(&white_text, "TIME", 324, 0, 1, NO_UPDATE);
+  text_draw(&gold_text, str, 404, 0, 1, NO_UPDATE);
 
-      sprintf(str, "%d", current_level.time_left);
-      text_draw(&blue_text, "TIME", 324, 0, 1, NO_UPDATE);
-      text_draw(&gold_text, str, 404, 0, 1, NO_UPDATE);
+  text_draw(&white_text, "NAME", 0, 0, 1, NO_UPDATE);
+  text_draw(&gold_text, le_current_level.name, 80, 0, 1, NO_UPDATE);
 
-      sprintf(str, "%s", current_level.name);
-      text_draw(&blue_text, "NAME", 0, 0, 1, NO_UPDATE);
-      text_draw(&gold_text, str, 80, 0, 1, NO_UPDATE);
+  sprintf(str, "%d/%d", le_level,le_level_subset.levels);
+  text_draw(&white_text, "NUMB", 0, 20, 1, NO_UPDATE);
+  text_draw(&gold_text, str, 80, 20, 1, NO_UPDATE);
 
-      text_draw(&blue_text, "F1 for Help", 10, 430, 1, NO_UPDATE);
+  text_draw(&white_small_text, "F1 for Help", 10, 430, 1, NO_UPDATE);
+  text_draw(&white_small_text, "F2 for Testing", 150, 430, 1, NO_UPDATE);
+}
 
-      if(show_menu)
-        {
-          done = drawmenu();
-          if(done)
-         {
-           le_quit();
-            return 0;
-         }
-        }
-      if(done == DONE_QUIT)
+void le_checkevents()
+{
+  SDL_Event event;
+  SDLKey key;
+  SDLMod keymod;
+  int x,y;
+
+  keymod = SDL_GetModState();
+
+  while(SDL_PollEvent(&event))
+    {
+      /* testing SDL_KEYDOWN, SDL_KEYUP and SDL_QUIT events*/
+      switch(event.type)
         {
-       le_quit();
-        return 1;
-       }
+        case SDL_KEYDOWN:      // key pressed
+          key = event.key.keysym.sym;
+          if(show_menu)
+            {
+              menu_event(&event.key.keysym);
+              break;
+            }
+          switch(key)
+            {
+            case SDLK_ESCAPE:
+              if(!show_menu)
+                show_menu = YES;
+              else
+                show_menu = NO;
+              break;
+            case SDLK_LEFT:
+              if(fire == DOWN)
+                cursor_x -= KEY_CURSOR_SPEED;
+              else
+                cursor_x -= KEY_CURSOR_FASTSPEED;
+              break;
+            case SDLK_RIGHT:
+              if(fire == DOWN)
+                cursor_x += KEY_CURSOR_SPEED;
+              else
+                cursor_x += KEY_CURSOR_FASTSPEED;
+              break;
+            case SDLK_UP:
+              if(fire == DOWN)
+                cursor_y -= KEY_CURSOR_SPEED;
+              else
+                cursor_y -= KEY_CURSOR_FASTSPEED;
+
+              if(cursor_y < 0)
+                cursor_y = 0;
+              break;
+            case SDLK_DOWN:
+              if(fire == DOWN)
+                cursor_y += KEY_CURSOR_SPEED;
+              else
+                cursor_y += KEY_CURSOR_FASTSPEED;
+
+              if(cursor_y > screen->h-32)
+                cursor_y = screen->h-32;
+              break;
+            case SDLK_LCTRL:
+              fire =UP;
+              break;
+            case SDLK_F1:
+              le_showhelp();
+              break;
+            case SDLK_F2:
+              level_save(&le_current_level,"test",le_level);
+              gameloop("test",le_level, ST_GL_TEST);
+              menu_set_current(&leveleditor_menu);
+              arrays_init();
+              level_load_gfx(&le_current_level);
+              loadshared();
+              le_activate_bad_guys();
+              break;
+            case SDLK_HOME:
+              cursor_x = 0;
+              break;
+            case SDLK_END:
+              cursor_x = (le_current_level.width * 32) - 32;
+              break;
+            case SDLK_PAGEUP:
+              cursor_x -= PAGE_CURSOR_SPEED;
+              break;
+            case SDLK_PAGEDOWN:
+              cursor_x += PAGE_CURSOR_SPEED;
+              break;
+            case SDLK_F9:
+              le_show_grid = !le_show_grid;
+              break;
+            case SDLK_PERIOD:
+              le_change(cursor_x, cursor_y, '.');
+              break;
+            case SDLK_a:
+              if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
+                le_change(cursor_x, cursor_y, 'A');
+              else
+                le_change(cursor_x, cursor_y, 'a');
+              break;
+            case SDLK_b:
+              if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
+                le_change(cursor_x, cursor_y, 'B');
+              break;
+            case SDLK_c:
+              if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
+                le_change(cursor_x, cursor_y, 'C');
+              else
+                le_change(cursor_x, cursor_y, 'c');
+              break;
+            case SDLK_d:
+              if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
+                le_change(cursor_x, cursor_y, 'D');
+              else
+                le_change(cursor_x, cursor_y, 'd');
+              break;
+            case SDLK_e:
+              if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
+                le_change(cursor_x, cursor_y, 'E');
+              else
+                le_change(cursor_x, cursor_y, 'e');
+              break;
+            case SDLK_f:
+              if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
+                le_change(cursor_x, cursor_y, 'F');
+              else
+                le_change(cursor_x, cursor_y, 'f');
+              break;
+            case SDLK_g:
+              if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
+                le_change(cursor_x, cursor_y, 'G');
+              else
+                le_change(cursor_x, cursor_y, 'g');
+              break;
+            case SDLK_h:
+              if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
+                le_change(cursor_x, cursor_y, 'H');
+              else
+                le_change(cursor_x, cursor_y, 'h');
+              break;
+            case SDLK_i:
+              if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
+                le_change(cursor_x, cursor_y, 'I');
+              else
+                le_change(cursor_x, cursor_y, 'i');
+              break;
+            case SDLK_j:
+              if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
+                le_change(cursor_x, cursor_y, 'J');
+              else
+                le_change(cursor_x, cursor_y, 'j');
+              break;
+            case SDLK_x:
+              if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
+                le_change(cursor_x, cursor_y, 'X');
+              else
+                le_change(cursor_x, cursor_y, 'x');
+              break;
+            case SDLK_y:
+              if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
+                le_change(cursor_x, cursor_y, 'Y');
+              else
+                le_change(cursor_x, cursor_y, 'y');
+              break;
+            case SDLK_LEFTBRACKET:
+              le_change(cursor_x, cursor_y, '[');
+              break;
+            case SDLK_RIGHTBRACKET:
+              le_change(cursor_x, cursor_y, ']');
+              break;
+            case SDLK_HASH:
+            case SDLK_3:
+              if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
+                le_change(cursor_x, cursor_y, '#');
+              break;
+            case SDLK_DOLLAR:
+            case SDLK_4:
+              if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
+                le_change(cursor_x, cursor_y, '$');
+              break;
+            case SDLK_BACKSLASH:
+              if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
+                le_change(cursor_x, cursor_y, '|');
+              else
+                le_change(cursor_x, cursor_y, '\\');
+              break;
+            case SDLK_CARET:
+              le_change(cursor_x, cursor_y, '^');
+              break;
+            case SDLK_AMPERSAND:
+            case SDLK_6:
+              if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
+                le_change(cursor_x, cursor_y, '&');
+              break;
+            case SDLK_EQUALS:
+            case SDLK_0:
+              if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
+                le_change(cursor_x, cursor_y, '=');
+              else             /* let's add a bad guy */
+                le_change(cursor_x, cursor_y, '0');
+
+              add_bad_guy((((int)cursor_x/32)*32), (((int)cursor_y/32)*32), BAD_BSOD);
+              break;
+            case SDLK_1:
+              if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
+                le_change(cursor_x, cursor_y, '!');
+              else             /* let's add a bad guy */
+                le_change(cursor_x, cursor_y, '1');
 
-      SDL_Delay(50);
-      now_time = SDL_GetTicks();
-      if (now_time < last_time + FPS)
-        SDL_Delay(last_time + FPS - now_time); /* delay some time */
+              add_bad_guy((((int)cursor_x/32)*32), (((int)cursor_y/32)*32), BAD_LAPTOP);
+              break;
+            case SDLK_2:
+              le_change(cursor_x, cursor_y, '2');
 
-      flipscreen();
+              add_bad_guy((((int)cursor_x/32)*32), (((int)cursor_y/32)*32), BAD_MONEY);
+              break;
+            case SDLK_PLUS:
+              if(keymod == KMOD_LSHIFT || keymod == KMOD_RSHIFT || keymod == KMOD_CAPS)
+                le_change(cursor_x, cursor_y, '*');
+              break;
+            default:
+              break;
+            }
+          break;
+        case SDL_KEYUP:        // key released
+          switch(event.key.keysym.sym)
+            {
+            case SDLK_LCTRL:
+              fire = DOWN;
+              break;
+            default:
+              break;
+            }
+          break;
+        case SDL_MOUSEBUTTONDOWN:
+          if(event.button.button == SDL_BUTTON_LEFT)
+            {
+              le_mouse_pressed = YES;
+            }
+          break;
+        case SDL_MOUSEBUTTONUP:
+          if(event.button.button == SDL_BUTTON_LEFT)
+            {
+              le_mouse_pressed = NO;
+            }
+          break;
+        case SDL_MOUSEMOTION:
+          if(!show_menu)
+            {
+              x = event.motion.x;
+              y = event.motion.y;
+
+              cursor_x = ((int)(pos_x + x) / 32) * 32;
+              cursor_y = ((int) y / 32) * 32;
+            }
+          break;
+        case SDL_QUIT: // window closed
+          done = DONE_QUIT;
+          break;
+        default:
+          break;
+        }
+    }
+
+  if(le_mouse_pressed)
+    {
+      le_change(cursor_x, cursor_y, le_current_tile);
+      if(button_pressed(&le_test_level_bt,x,y))
+        {
+          level_save(&le_current_level,"test",le_level);
+          gameloop("test",le_level, ST_GL_TEST);
+          menu_set_current(&leveleditor_menu);
+          arrays_init();
+          level_load_gfx(&le_current_level);
+          loadshared();
+          le_activate_bad_guys();
+        }
     }
 
-  return done;
 }
 
 void le_change(float x, float y, unsigned char c)
 {
-int i;
-int xx, yy;
+  int i;
+  int xx, yy;
 
-  level_change(&current_level,x,y,c);
+  level_change(&le_current_level,x,y,c);
 
-  yy = (y / 32);
-  xx = (x / 32);
+  yy = ((int)y / 32);
+  xx = ((int)x / 32);
 
   /* if there is a bad guy over there, remove it */
   for(i = 0; i < num_bad_guys; ++i)
@@ -554,7 +633,7 @@ int xx, yy;
         bad_guys[i].base.alive = NO;
 }
 
-void showhelp()
+void le_showhelp()
 {
   SDL_Event event;
   int i, done;
@@ -583,11 +662,11 @@ void showhelp()
                    "Esc - Menu"};
 
 
-  text_drawf(&red_text, "- Help -", 0, 30, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
+  text_drawf(&blue_text, "- Help -", 0, 30, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
   text_draw(&gold_text, "Keys:", 80, 60, 1, NO_UPDATE);
-  
+
   for(i = 0; i < sizeof(text)/sizeof(char *); i++)
-    text_draw(&blue_text, text[i], 40, 90+(i*16), 1, NO_UPDATE);
+    text_draw(&white_text, text[i], 40, 90+(i*16), 1, NO_UPDATE);
 
   text_drawf(&gold_text, "Press Any Key to Continue", 0, 460, A_HMIDDLE, A_TOP, 1, NO_UPDATE);
 
index a22be9a..e083a64 100644 (file)
@@ -1,5 +1,23 @@
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
 
-int level_editor_started;
-int leveleditor();
+/*  December 28, 2003 - February 1st, 2004 */
+
+/* leveleditor.h - A built-in level editor for SuperTux
+ by Ricardo Cruz <rick2@aeiou.pt>                      */
+
+int leveleditor(int levelnb);
 void newlevel(void);
 void selectlevel(void);
+void le_savelevel();
+void editlevel(void);
+void testlevel(void);
+int le_init(void);
+void le_checkevents(void);
+
index d86a880..e398cfd 100644 (file)
@@ -16,6 +16,8 @@
 #include <ctype.h>
 #endif
 
+#include <stdlib.h>
+#include <stdio.h>
 #include <string.h>
 
 #include "defines.h"
 #include "sound.h"
 #include "scene.h"
 #include "leveleditor.h"
-#include "gameloop.h"
 #include "timer.h"
 #include "high_scores.h"
 
-/* Set defaults */
-void initmenu(void)
-{
-  menu_change = NO;
-  show_menu = NO;
-  menuitem = 0;
-  menumenu = 0;
-  menuaction = -1;
+/* (global) menu variables */
+int menuaction;
+int show_menu;
+int menu_change;
+texture_type checkbox, checkbox_checked;
 
-  delete_character = 0;
-  strcpy(input_string, "");
-}
+menu_type main_menu, game_menu, options_menu, leveleditor_menu, highscore_menu;
+menu_type* current_menu, * last_menu;
+
+/* input implementation variables */
+int delete_character;
+char mn_input_char;
 
-/* ---- Menu Options - Item Sound On/off ----*/
-void menu_option_sound()
+/* Set the current menu */
+void menu_set_current(menu_type* pmenu)
 {
-  if (audio_device == YES)
+  if(pmenu != current_menu)
     {
-      if(menuitem == 1)
-        {
-          if(use_sound == YES)
-            {
-           text_drawf(&red_text, "Sound ON", 0, 224, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-            }
-          else
-            {
-           text_drawf(&red_text, "Sound OFF", 0, 224, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-            }
-
-          if(menuaction == MN_HIT)
-            { /* Disable/Enable sound */
-              if(use_sound == YES)
-                {
-                  use_sound = NO;
-                }
-              else
-                {
-                  use_sound = YES;
-                }
-              menu_change = YES;
-            }
-        }
-      else
-        {
-          if(use_sound == YES)
-           text_drawf(&blue_text, "Sound ON", 0, 224, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-          else
-           text_drawf(&blue_text, "Sound OFF", 0, 224, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-        }
+      menu_change = YES;
+      last_menu = current_menu;
+      current_menu = pmenu;
     }
+}
+
+/* Return a pointer to a new menu item */
+menu_item_type* menu_item_create(int kind, char *text, int init_toggle, void* target_menu)
+{
+  menu_item_type *pnew_item = (menu_item_type*) malloc(sizeof(menu_item_type));
+  pnew_item->kind = kind;
+  pnew_item->text = (char*) malloc(sizeof(char) * (strlen(text) + 1));
+  strcpy(pnew_item->text,text);
+  if(kind == MN_TOGGLE)
+    pnew_item->toggled = init_toggle;
   else
-    { /* if audio_device != YES */
-      /* let the user move over the deactivated option */
-      if (menuitem == 1)
-        {
-         text_drawf(&red_text, "Sound OFF", 0, 224, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-        }
-      else
+    pnew_item->toggled = NO;
+  pnew_item->target_menu = target_menu;
+  pnew_item->input = NULL;
+  return pnew_item;
+}
+
+/* Free a menu and all its items */
+void menu_free(menu_type* pmenu)
+{
+  int i;
+  if(pmenu->num_items != 0 && pmenu->item != NULL)
+    {
+      for(i = 0; i < pmenu->num_items; ++i)
         {
-         text_drawf(&red_text, "Sound OFF", 0, 224, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
+          free(pmenu->item[i].text);
+          free(pmenu->item[i].input);
         }
+      free(pmenu->item);
     }
 }
 
+/* Initialize a menu */
+void menu_init(menu_type* pmenu)
+{
+  pmenu->num_items = 0;
+  pmenu->active_item = 0;
+  pmenu->item = NULL;
+}
+
+/* Add an item to a menu */
+void menu_additem(menu_type* pmenu, menu_item_type* pmenu_item)
+{
+  ++pmenu->num_items;
+  pmenu->item = (menu_item_type*) realloc(pmenu->item, sizeof(menu_item_type) * pmenu->num_items);
+  memcpy(&pmenu->item[pmenu->num_items-1],pmenu_item,sizeof(menu_item_type));
+}
 
-/* ---- Menu Options - Item Music On/off ----*/
-void menu_option_music()
+/* Process actions done on the menu */
+void menu_action(menu_type* pmenu)
 {
-  if (audio_device == YES)
+  int i;
+
+  if(pmenu->num_items != 0 && pmenu->item != NULL)
     {
-      if(menuitem == 2)
+      switch(menuaction)
         {
-          if(use_music == YES)
+        case MN_UP:
+          if(pmenu->active_item > 0)
+            --pmenu->active_item;
+          else
+            pmenu->active_item = pmenu->num_items-1;
+          break;
+        case MN_DOWN:
+          if(pmenu->active_item < pmenu->num_items-1)
+            ++pmenu->active_item;
+          else
+            pmenu->active_item = 0;
+          break;
+        case MN_HIT:
+          if(pmenu->item[pmenu->active_item].kind == MN_GOTO && pmenu->item[pmenu->active_item].target_menu != NULL)
+            menu_set_current((menu_type*)pmenu->item[pmenu->active_item].target_menu);
+          else if(pmenu->item[pmenu->active_item].kind == MN_TOGGLE)
             {
-             text_drawf(&red_text, "Music ON", 0, 256, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
+              pmenu->item[pmenu->active_item].toggled = !pmenu->item[pmenu->active_item].toggled;
+              menu_change = YES;
             }
-          else
+          else if(pmenu->item[pmenu->active_item].kind == MN_ACTION || pmenu->item[pmenu->active_item].kind == MN_TEXTFIELD)
             {
-             text_drawf(&red_text, "Music OFF", 0, 256, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
+              pmenu->item[pmenu->active_item].toggled = YES;
             }
-          if(menuaction == MN_HIT)
-            { /* Disable/Enable music */
-              if(use_music == YES)
-                {  /* In the menu no music is played, so we have to check only use_music */
-                  if(playing_music())
-                    halt_music();
-                  use_music = NO;
-                }
-              else
+          else if(pmenu->item[pmenu->active_item].kind == MN_BACK)
+            {
+              if(last_menu != NULL)
+                menu_set_current(last_menu);
+            }
+          break;
+        case MN_REMOVE:
+          if(pmenu->item[pmenu->active_item].kind == MN_TEXTFIELD)
+            {
+              if(pmenu->item[pmenu->active_item].input != NULL)
                 {
-                  use_music = YES;
-                  if (!playing_music())
+                  i = strlen(pmenu->item[pmenu->active_item].input);
+
+                  while(delete_character > 0)  /* remove charactes */
                     {
-                      play_current_music();
+                      pmenu->item[pmenu->active_item].input[i-1] = '\0';
+                      delete_character--;
                     }
                 }
-              menu_change = YES;
             }
-        } /* if menuitem != 2 : print normal blue font */
-      else
-        {
-          if(use_music == YES)
+          break;
+        case MN_INPUT:
+          if(pmenu->item[pmenu->active_item].kind == MN_TEXTFIELD)
             {
-             text_drawf(&blue_text, "Music ON", 0, 256, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-            }
-          else
-            {
-             text_drawf(&blue_text, "Music OFF", 0, 256, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
+              if(pmenu->item[pmenu->active_item].input != NULL)
+                {      
+                  i = strlen(pmenu->item[pmenu->active_item].input);
+                  pmenu->item[pmenu->active_item].input = (char*) realloc(pmenu->item[pmenu->active_item].input,sizeof(char)*(i + 2));
+                  pmenu->item[pmenu->active_item].input[i] = mn_input_char;
+                  pmenu->item[pmenu->active_item].input[i+1] = '\0';
+                }
+              else
+                {
+                  pmenu->item[pmenu->active_item].input = (char*) malloc(2*sizeof(char));
+                  pmenu->item[pmenu->active_item].input[0] = mn_input_char;
+                  pmenu->item[pmenu->active_item].input[1] = '\0';
+                }
             }
+          break;
         }
     }
-  else
-    { /* if audio_device != YES */
-      /* let the user move over the deactivated option */
-      if (menuitem == 2)
-        {
-         text_drawf(&red_text, "Music OFF", 0, 256, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-        }
-      else
-        {
-         text_drawf(&black_text, "Music OFF", 0, 256, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-        }
-    }
+    
+    menuaction = -1;
+
+  if(pmenu->item[pmenu->active_item].kind == MN_DEACTIVE)
+    menu_action(pmenu);
 }
 
-int menu_main(void)
+/* Check, if the value of the active menu item has changed. */
+int menu_check(menu_type* pmenu)
 {
-  /* Does the menu item exist? If not, we reset to the most down item */
-  if(menuitem > MENU_MAIN_ITEM_MAX)
-    menuitem =0;
-  else if(menuitem < 0)
-    menuitem = MENU_MAIN_ITEM_MAX;
-
-  /*The menu looks different, when the game is started */
-  if(menuitem == 0)
-    {
-      text_drawf(&red_text, "Start Game", 0, 192, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-      if(menuaction == MN_HIT) /* we are ready to start the game, if this item got hit */
-        {
-          game_started = 1;
-          show_menu = 0;
-        }
-    }
-  else
-    text_drawf(&blue_text, "Start Game", 0, 192, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-
-  if(menuitem == 1)
-    {
-          text_drawf(&red_text, "Options", 0, 224, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-      if(menuaction == MN_HIT) /* Switch to the 'Options' menu */
-        {
-          menumenu = MENU_OPTIONS;
-          menu_change = YES;
-        }
-    }
-  else
-        text_drawf(&blue_text, "Options", 0, 224, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-
-  if(menuitem == 2)
+  if(pmenu->num_items != 0 && pmenu->item != NULL)
     {
-          text_drawf(&red_text, "Level editor", 0, 256, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-      if(menuaction == MN_HIT) /* Set variables, so that the level editor is executed */
+      if((pmenu->item[pmenu->active_item].kind == MN_ACTION || pmenu->item[pmenu->active_item].kind == MN_TEXTFIELD) && pmenu->item[pmenu->active_item].toggled == YES)
         {
-          level_editor_started = YES;
+          pmenu->item[pmenu->active_item].toggled = NO;
           show_menu = 0;
+          return pmenu->active_item;
         }
-    }
-  else
-          text_drawf(&blue_text, "Level editor", 0, 256, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-
-  if(menuitem == 3)
-    {
-          text_drawf(&red_text, "Quit", 0, 288, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-      if(menuaction == MN_HIT) /* Quit a running game or the application */
+      else if(pmenu->item[pmenu->active_item].kind == MN_TOGGLE)
         {
-          return 1;
+          return pmenu->active_item;
         }
+      else
+        return -1;
     }
   else
-    {
-              text_drawf(&blue_text, "Quit", 0, 288, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-    }
-
-  return 0;
+    return -1;
 }
 
-int menu_game(void)
+/* Draw the current menu. */
+void menu_draw(menu_type* pmenu)
 {
-  /* Does the menu item exist? If not, we reset to the most down item */
-  if(menuitem > MENU_GAME_ITEM_MAX)
-    menuitem = 0;
-  else if(menuitem < 0)
-    menuitem = MENU_GAME_ITEM_MAX;
-
-  /*The menu looks different, when the game is started */
-  if(menuitem == 0)
-    {
-          text_drawf(&red_text, "Return To Game", 0, 192, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-      if(menuaction == MN_HIT) /* Don't show the menu anymore, if this item got hit */
-        {
-          show_menu = 0;
-          st_pause_ticks_stop();
-        }
-    }
-  else
-          text_drawf(&blue_text, "Return To Game", 0, 192, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-
-  if(menuitem == 1)
-    {
-          text_drawf(&red_text, "Save Game", 0, 224, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-      if(menuaction == MN_HIT) /* Don't show the menu anymore, if this item got hit */
-        {
-          show_menu = 0;
-          savegame();
-        }
-    }
-  else
-  text_drawf(&blue_text, "Save Game", 0, 224, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
+  int i, y, menu_height, menu_width;
 
-  if(menuitem == 2)
+  /* The width of the menu has to be more than the width of the text with the most characters */
+  menu_width = 0;
+  for(i = 0; i < pmenu->num_items; ++i)
     {
-    text_drawf(&red_text, "Load Game", 0, 256, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-      if(menuaction == MN_HIT) /* Don't show the menu anymore, if this item got hit */
+    y = strlen(pmenu->item[i].text) + (pmenu->item[i].input ? strlen(pmenu->item[i].input) : 0);
+      if( y > menu_width )
         {
-          char *x = NULL;  /* In C, you can do this... */
-
-          show_menu = 0;
-          loadgame(x);
+          menu_width = y;
+          if( pmenu->item[i].kind == MN_TOGGLE)
+            menu_width += 2;
         }
     }
-  else
-      text_drawf(&blue_text, "Load Game", 0, 256, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
+  menu_width = menu_width * 16 + 48;
+  menu_height = (pmenu->num_items) * 24;
+  
+  /* Draw a transparent background */
+  fillrect(screen->w/2 - menu_width/2,screen->h/2-(((pmenu->num_items)*24)/2),menu_width,menu_height,150,150,150,100);
 
-  if(menuitem == 3)
+  for(i = 0; i < pmenu->num_items; ++i)
     {
-        text_drawf(&red_text, "Options", 0, 288, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-      if(menuaction == MN_HIT) /* Switch to the 'Options' menu */
+      if(pmenu->item[i].kind == MN_DEACTIVE)
         {
-          menumenu = MENU_OPTIONS;
-          menu_change = YES;
+          text_drawf(&black_text,pmenu->item[i].text,0,(i)*24 - menu_height/2 + 10,A_HMIDDLE, A_VMIDDLE,2,NO_UPDATE);
         }
-    }
-  else
-          text_drawf(&blue_text, "Options", 0, 288, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-
-  if(menuitem == 4)
-    {
-            text_drawf(&red_text, "Quit Game", 0, 320, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-      if(menuaction == MN_HIT) /* Quit a running game */
-        return 1;
-    }
-  else
-    {
-            text_drawf(&blue_text, "Quit Game", 0, 320, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-    }
-
-  return 0;
-}
-
-int menu_options(void)
-{
-  if(menuitem > MENU_OPTIONS_ITEM_MAX )
-    menuitem = 0;
-  else if(menuitem < 0)
-    menuitem = MENU_OPTIONS_ITEM_MAX;
-
-  if(menuitem == 0)
-    {
-      if(use_fullscreen)
-      text_drawf(&red_text, "Fullscreen ON", 0, 192, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-      else
-      text_drawf(&red_text, "Fullscreen OFF", 0, 192, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-      if(menuaction == MN_HIT) /* Disable/Enable fullscreen */
+      else if(pmenu->item[i].kind == MN_TEXTFIELD)
         {
-          if(use_fullscreen)
-            use_fullscreen = 0;
-          else
-            use_fullscreen = 1;
-          st_video_setup();
-          menu_change = YES;
-        }
-    }
-  else
-    {
-      if(use_fullscreen)
-      text_drawf(&blue_text, "Fullscreen ON", 0, 192, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-      else
-      text_drawf(&blue_text, "Fullscreen OFF", 0, 192, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-    }
-
-  /* handle menu sound on/off option */
-  menu_option_sound();
-
-  /* handle menu music on/off option */
-  menu_option_music();
-
-  if(menuitem == 3)
-    {
-    text_drawf(&red_text, "Back", 0, 288, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-      if(menuaction == MN_HIT) /* Go back to main menu. */
-        {
-          if(game_started)
-            menumenu = MENU_GAME;
+          text_drawf(&gold_text,pmenu->item[i].input,(strlen(pmenu->item[i].text) * 16)/2,(i)*24 - menu_height/2 + 10,A_HMIDDLE, A_VMIDDLE,2,NO_UPDATE);
+          if(i == pmenu->active_item)
+            {
+              text_drawf(&blue_text,pmenu->item[i].text,-((strlen(pmenu->item[i].input) * 16)/2),(i)*24 - menu_height/2 + 10,A_HMIDDLE, A_VMIDDLE,3,NO_UPDATE);
+            }
           else
-            menumenu = MENU_MAIN;
-          menu_change = YES;
+            {
+              text_drawf(&white_text,pmenu->item[i].text,-((strlen(pmenu->item[i].input) * 16)/2),(i)*24 - menu_height/2 +10,A_HMIDDLE, A_VMIDDLE,2,NO_UPDATE);
+            }
         }
-    }
-  else
-    text_drawf(&blue_text, "Back", 0, 288, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-
-  return 0;
-}
-
-/* Menu LevelEditor */
-int menu_leveleditor(void)
-{
-  if(menuitem > MENU_LEVELEDITOR_ITEM_MAX )
-    menuitem = 0;
-  else if(menuitem < 0)
-    menuitem = MENU_LEVELEDITOR_ITEM_MAX;
-
-  if(menuitem == 0)
-    {
-        text_drawf(&red_text, "Return To Level Editor", 0, 192, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-      if(menuaction == MN_HIT) /* Don't show the menu anymore, if this item got hit */
-        show_menu = 0;
-    }
-  else
-  text_drawf(&blue_text, "Return To Level Editor", 0, 192, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-
-  if(menuitem == 1)
-    {
-    text_drawf(&red_text, "New Level", 0, 224, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-      if(menuaction == MN_HIT) /* Don't show the menu anymore, if this item got hit */
+      else if(i == pmenu->active_item)
         {
-          show_menu = 0;
-          newlevel();
+          text_drawf(&blue_text,pmenu->item[i].text,0,(i)*24 - menu_height/2 + 10 ,A_HMIDDLE, A_VMIDDLE,3,NO_UPDATE);
         }
-    }
-  else
-  text_drawf(&blue_text, "New Level", 0, 224, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-  
-  if(menuitem == 2)
-    {
-    text_drawf(&red_text, "Load Level", 0, 256, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-      if(menuaction == MN_HIT) /* Create a new Level and load it into the level-editor. */
+      else
         {
-          show_menu = 0;
-          selectlevel();
+          text_drawf(&white_text,pmenu->item[i].text,0,(i)*24 - menu_height/2 + 10,A_HMIDDLE, A_VMIDDLE,2,NO_UPDATE);
         }
-    }
-  else
-  text_drawf(&blue_text, "Load Level", 0, 256, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-
-  if(menuitem == 3)
-    {
-   text_drawf(&red_text, "Save Level", 0, 288, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-      if(menuaction == MN_HIT) /* Save the current level in the level-editor. */
+      if(pmenu->item[i].kind == MN_TOGGLE)
         {
-          show_menu = 0;
-          savelevel(&current_level,"default",level);
-         text_drawf(&gold_text, "SAVED!", 0, 240, A_HMIDDLE, A_TOP, 1, NO_UPDATE);
-          flipscreen();
-          SDL_Delay(1000);
-        }
-    }
-  else
-  text_drawf(&blue_text, "Save Level", 0, 288, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
 
-  if(menuitem == 4)
-    {
-    text_drawf(&red_text, "Quit Level Editor", 0, 320, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-      if(menuaction == MN_HIT) /* Quit the level-editor. (to the main-menu) */
-        {
-          return 1;
+          if(pmenu->item[i].toggled == YES)
+            texture_draw(&checkbox_checked,screen->w / 2 + (strlen(pmenu->item[i].text) * 16)/2  + 16,(i)*24 - menu_height/2 + 10 + screen->h / 2 -8,NO_UPDATE);
+          else
+            texture_draw(&checkbox,screen->w / 2 + (strlen(pmenu->item[i].text) * 16)/2 + 16,(i)*24 - menu_height/2 + 10 + screen->h / 2 - 8,NO_UPDATE);
         }
     }
-  else
-  text_drawf(&blue_text, "Quit Level Editor", 0, 320, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-
-  return 0;
 }
 
-/* Menu HighScore (ask for player's name) */
-int menu_highscore()
+/* Reset/Set global defaults */
+void menu_reset(void)
 {
-char str[60];
-
-while(delete_character > 0)    /* remove charactes */
-       {
-       hs_name[strlen(hs_name)-1] = '\0';
-       delete_character--;
-       }
-
-strcat(hs_name, input_string);
-
-text_drawf(&red_text, "Congratulations", 0, 130, A_HMIDDLE, A_TOP, 2, NO_UPDATE);
-text_draw(&red_text, "Your score:", 30, 250, 1, NO_UPDATE);
-sprintf(str, "%d", hs_score);
-text_draw(&blue_text, str, 350, 250, 1, NO_UPDATE);
-
-text_draw(&red_text, "Enter your name:", 30, 280, 1, NO_UPDATE);
-text_draw(&blue_text, hs_name, 350, 280, 1, NO_UPDATE);
-
-strcpy(input_string, "");
-
-if(menuaction == MN_HIT)    /* name written */
-  show_menu = 0;
+  menu_change = NO;
+  show_menu = NO;
+  menuaction = -1;
+  current_menu = NULL;
+  last_menu = NULL;
 
-return 0;
+  delete_character = 0;
+  mn_input_char = '\0';
 }
 
 /* --- MENU --- */
-/* Draw the menu and execute the (menu)events */
-int drawmenu(void)
+/* Draw the current menu and execute the (menu)events */
+void menu_process_current(void)
 {
-  int quit = 0;
-
   menu_change = NO;
 
-
-  if(menuaction == MN_UP)
-      --menuitem;   /* Go one menu-item up */
-  else if(menuaction == MN_DOWN)
-    ++menuitem;     /* Go one menu-item down */
-
-
-  switch(menumenu)
-  {
-  case MENU_MAIN:
-      quit = menu_main();
-    break;
-  case MENU_GAME:
-      quit = menu_game();
-    break;
-  case MENU_OPTIONS:
-      quit = menu_options();
-    break;
-  case MENU_LEVELEDITOR:
-      quit = menu_leveleditor();
-    break;
-  case MENU_HIGHSCORE:
-      quit = menu_highscore();
-    break;
-  default:
-    break;
-  }
+  if(current_menu != NULL)
+    {
+      menu_action(current_menu);
+      menu_draw(current_menu);
+    }
 
   menuaction = -1;
-
-  return quit;
 }
 
 /* Check for menu event */
 void menu_event(SDL_keysym* keysym)
 {
-SDLKey key = keysym->sym;
-SDLMod keymod;
-char ch[2];
-
-keymod = SDL_GetModState();
-
-/* If the current unicode character is an ASCII character,
-   assign it to ch. */
-if ( (keysym->unicode & 0xFF80) == 0 ) {
-  ch[0] = keysym->unicode & 0x7F;
-  ch[1] = '\0';
-}
-else {
-  /* An International Character. */
-}
+  SDLKey key = keysym->sym;
+  SDLMod keymod;
+  keymod = SDL_GetModState();
+  char ch[2];
+
+  /* If the current unicode character is an ASCII character,
+     assign it to ch. */
+  if ( (keysym->unicode & 0xFF80) == 0 )
+    {
+      ch[0] = keysym->unicode & 0x7F;
+      ch[1] = '\0';
+    }
+  else
+    {
+      /* An International Character. */
+    }
 
-switch(key)
-       {
-       case SDLK_UP:           /* Menu Up */
-               menuaction = MN_UP;
-               menu_change = YES;
-               break;
-       case SDLK_DOWN:         /* Menu Down */
-               menuaction = MN_DOWN;
-               menu_change = YES;
-               break;
-       case SDLK_SPACE:                /* Menu Hit */
-       case SDLK_RETURN:
-               menuaction = MN_HIT;
-               menu_change = YES;
-               break;
-
-       case SDLK_DELETE:
-       case SDLK_BACKSPACE:
-               delete_character++;
-               break;
-       default:
-               if( key >= SDLK_0 && key <= SDLK_9)
-                strcat( input_string, /* (key - SDLK_0) */ ch);
-               else if( key >= SDLK_a && SDLK_z )
-               {
-                strcat( input_string, ch);
-               }
-               break;
+  switch(key)
+    {
+    case SDLK_UP:              /* Menu Up */
+      menuaction = MN_UP;
+      menu_change = YES;
+      break;
+    case SDLK_DOWN:            /* Menu Down */
+      menuaction = MN_DOWN;
+      menu_change = YES;
+      break;
+    case SDLK_SPACE:           /* Menu Hit */
+    case SDLK_RETURN:
+      menuaction = MN_HIT;
+      menu_change = YES;
+      break;
+    case SDLK_DELETE:
+    case SDLK_BACKSPACE:
+      menuaction = MN_REMOVE;
+      menu_change = YES;
+      delete_character++;
+      break;
+    default:
+      if( key >= SDLK_0 && key <= SDLK_9)
+        {
+          menuaction = MN_INPUT;
+          menu_change = YES;
+          mn_input_char = *ch;
+        }
+      else if( key >= SDLK_a && key <= SDLK_z )
+        {
+          menuaction = MN_INPUT;
+          menu_change = YES;
+          mn_input_char = *ch;
+        }
+      else
+        {
+        mn_input_char = '\0';
        }
+      break;
+    }
 
 
   /* FIXME: NO JOYSTICK SUPPORT */
index 92a801a..edccfb8 100644 (file)
 
 #include <SDL.h>
 
-/* (global) menu variables */
-int menuaction;
-int menuitem;
-int menumenu;
-int show_menu;
-int menu_change;
+typedef struct menu_item_type
+{
+ int kind;
+ char *text;
+ char *input;
+ int toggled;
+ void* target_menu;
+}
+menu_item_type;
+
+menu_item_type* menu_item_create(int kind, char *text, int init_toggle, void* target_menu);
+
+typedef struct menu_type
+{
+ int num_items;
+ int active_item;
+ menu_item_type *item;
+}
+menu_type;
 
-#define MENU_MAIN_ITEM_MAX 3
-#define MENU_GAME_ITEM_MAX 4
-#define MENU_OPTIONS_ITEM_MAX 3
-#define MENU_LEVELEDITOR_ITEM_MAX 4
+void menu_init(menu_type* pmenu);
+void menu_free(menu_type* pmenu);
+void menu_additem(menu_type* pmenu, menu_item_type* pmenu_item);
+void menu_action(menu_type* pmenu);
+int menu_check(menu_type* pmenu);
+void menu_draw(menu_type* pmenu);
+void menu_set_current(menu_type* pmenu);
+
+/* Kinds of menu items */
+enum {
+  MN_ACTION,
+  MN_GOTO,
+  MN_TOGGLE,
+  MN_BACK,
+  MN_DEACTIVE,
+  MN_TEXTFIELD
+};
 
 /* Action done on the menu */
 enum {
   MN_UP,
   MN_DOWN,
-  MN_HIT
+  MN_HIT,
+  MN_INPUT,
+  MN_REMOVE
 };
 
-/* Menus */
-enum {
-  MENU_MAIN,
-  MENU_GAME,
-  MENU_OPTIONS,
-  MENU_LEVELEDITOR,
-  MENU_HIGHSCORE
-};
+/* (global) menu variables */
+extern int menuaction;
+extern int show_menu;
+extern int menu_change;
+extern texture_type checkbox, checkbox_checked;
+
+extern menu_type main_menu, game_menu, options_menu, leveleditor_menu, highscore_menu;
+extern menu_type* current_menu, * last_menu;
 
 /* input implementation variables */
-int delete_character;
-char input_string[62];
+extern int delete_character;
+extern char mn_input_char;
 
-/* Initialize the menu variables */
-void initmenu(void);
+/* Reset the global menu variables */
+void menu_reset(void);
 
 /* "Calculate" and draw the menu */
-int drawmenu(void);
+void menu_process_current(void);
 
 /* Check for a menu event */
 void menu_event(SDL_keysym* keysym);
index b10a334..e064bf7 100644 (file)
 #include "scene.h"
 #include "screen.h"
 
+texture_type tux_life,
+tux_right[3],  tux_left[3],
+bigtux_right[3],  bigtux_left[3],
+bigtux_right_jump,  bigtux_left_jump,
+ducktux_right,  ducktux_left,
+skidtux_right,  skidtux_left,
+firetux_right[3],  firetux_left[3],
+bigfiretux_right[3],  bigfiretux_left[3],
+bigfiretux_right_jump,  bigfiretux_left_jump,
+duckfiretux_right,  duckfiretux_left,
+skidfiretux_right,  skidfiretux_left,
+cape_right[2],  cape_left[2],
+bigcape_right[2],  bigcape_left[2];
+
 void player_init(player_type* pplayer)
 {
   pplayer->base.width = 32;
@@ -132,7 +146,10 @@ void player_level_begin(player_type* pplayer)
   pplayer->input.old_fire = UP;
   pplayer->input.right = UP;
   pplayer->input.up = UP;
-
+  
+  timer_init(&pplayer->invincible_timer);
+  timer_init(&pplayer->skidding_timer);
+  timer_init(&pplayer->safe_timer);
 }
 
 void player_action(player_type* pplayer)
@@ -152,338 +169,428 @@ void player_action(player_type* pplayer)
 
   if (!pplayer->dying)
     {
-      if (issolid(pplayer->base.x, pplayer->base.y + 31) &&
-          !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y + 31))
-        {
-          while (issolid(pplayer->base.x, pplayer->base.y + 31))
-            {
-              if (pplayer->base.xm < 0)
-                pplayer->base.x++;
-              else if (pplayer->base.xm > 0)
-                pplayer->base.x--;
-            }
+      /* FIXME: this code is COMPLETLY broken!!! */
+        if (issolid(pplayer->base.x, pplayer->base.y + 31) &&
+            !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y + 31))
+          {
+            while (issolid(pplayer->base.x, pplayer->base.y + 31))
+              {
+                if (pplayer->base.xm < 0)
+                  pplayer->base.x++;
+                else if (pplayer->base.xm > 0)
+                  pplayer->base.x--;
+              }
 
-          pplayer->base.xm = 0;
-        }
+            pplayer->base.xm = 0;
+          }
 
-      if (issolid(pplayer->base.x, pplayer->base.y) &&
-          !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y))
-        {
-          while (issolid(pplayer->base.x, (pplayer->base.y)))
-            {
-              if (pplayer->base.xm < 0)
-                pplayer->base.x++;
-              else if (pplayer->base.xm > 0)
-                pplayer->base.x--;
-            }
+        if (issolid(pplayer->base.x, pplayer->base.y) &&
+            !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y))
+          {
+            while (issolid(pplayer->base.x, (pplayer->base.y)))
+              {
+                if (pplayer->base.xm < 0)
+                  pplayer->base.x++;
+                else if (pplayer->base.xm > 0)
+                  pplayer->base.x--;
+              }
 
-          pplayer->base.xm = 0;
-        }
+            pplayer->base.xm = 0;
+          }
 
-      if (issolid(pplayer->base.x, pplayer->base.y + 31))
-        {
-          /* Set down properly: */
+        if (issolid(pplayer->base.x, pplayer->base.y + 31))
+          {
+            /* Set down properly: */
 
-          int debug_int = 0;
-          while (issolid(pplayer->base.x, pplayer->base.y + 31))
-            {
-              ++debug_int;
-              if(debug_int > 32)
-             {
-                DEBUG_MSG("FIXME - UNDER certain circumstances I'm hanging in a loop here!");
-                             /*the circumstances are:
-               issolid() is true and base.ym == 0
-               use of floating point varibles for base stuff*/
-               break;
-               }
-              if (pplayer->base.ym < 0)
-                pplayer->base.y++;
-              else if (pplayer->base.ym > 0)
-                pplayer->base.y--;
-            }
+            int debug_int = 0;
+            while (issolid(pplayer->base.x, pplayer->base.y + 31))
+              {
+                ++debug_int;
+                if(debug_int > 32)
+                  {
+                    DEBUG_MSG("FIXME - UNDER certain circumstances I'm hanging in a loop here!");
+                    /*the circumstances are:
+                    issolid() is true and base.ym == 0
+                    use of floating point varibles for base stuff*/
+                    break;
+                  }
+                if (pplayer->base.ym < 0)
+                  pplayer->base.y++;
+                else if (pplayer->base.ym > 0)
+                  pplayer->base.y--;
+              }
 
 
-          /* Reset score multiplier (for multi-hits): */
+            /* Reset score multiplier (for multi-hits): */
 
-          if (pplayer->base.ym > 0)
-            score_multiplier = 1;
+            if (pplayer->base.ym > 0)
+              score_multiplier = 1;
 
 
-          /* Stop jumping! */
+            /* Stop jumping! */
 
+      pplayer->base.ym = 0;
+      pplayer->jumping = NO;
+      pplayer->input.up = UP;
+      }
+            /* FIXME: this code is COMPLETLY broken!!! */
+      /*if (issolid(pplayer->base.x, pplayer->base.y) ||
+          (pplayer->size == BIG && !pplayer->duck &&
+           (issolid(pplayer->base.x, pplayer->base.y - 32))))
+        {*/
+      /*if (!issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y) &&
+          (pplayer->size == SMALL || pplayer->duck ||
+           !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y - 32)))*/
+
+      if (((!issolid(pplayer->base.x, pplayer->base.y- pplayer->base.ym * frame_ratio) && (issolid(pplayer->base.x, pplayer->base.y) || issolid(pplayer->base.x, pplayer->base.y+31))))
+      ||((!issolid(pplayer->base.x - pplayer->base.xm * frame_ratio, pplayer->base.y) && (issolid(pplayer->base.x, pplayer->base.y) || issolid(pplayer->base.x+32, pplayer->base.y)))))
+          /*(pplayer->size == SMALL || pplayer->duck ||
+           !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y - 32))*/
+        {
+          pplayer->base.y = pplayer->base.y- pplayer->base.ym * frame_ratio;
           pplayer->base.ym = 0;
-          pplayer->jumping = NO;
-          pplayer->input.up = UP;
+        }
+          
+      if ((!issolid(pplayer->base.x - pplayer->base.xm * frame_ratio, pplayer->base.y) && (issolid(pplayer->base.x, pplayer->base.y) || issolid(pplayer->base.x+32, pplayer->base.y))
+          /*(pplayer->size == SMALL || pplayer->duck ||
+           !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y - 32))*/) || ( pplayer->size == BIG && (
+          (!issolid(pplayer->base.x - pplayer->base.xm * frame_ratio, pplayer->base.y+32) && (issolid(pplayer->base.x, pplayer->base.y+32) || issolid(pplayer->base.x+32, pplayer->base.y+32))
+          /*(pplayer->size == SMALL || pplayer->duck ||
+           !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y - 32))*/))))
+        {
+          pplayer->base.x = pplayer->base.x- pplayer->base.xm * frame_ratio;
+          pplayer->base.xm = 0;
+        }
+       
+          if (pplayer->base.ym <= 0)
+            {
+      if (isbrick(pplayer->base.x, pplayer->base.y) ||
+          isfullbox(pplayer->base.x, pplayer->base.y))
+        {
+          trygrabdistro(pplayer->base.x, pplayer->base.y - 32,BOUNCE);
+          trybumpbadguy(pplayer->base.x, pplayer->base.y - 64);
+          bumpbrick(pplayer->base.x, pplayer->base.y);
+          tryemptybox(pplayer->base.x, pplayer->base.y);
         }
 
+      if (isbrick(pplayer->base.x+ 31, pplayer->base.y) ||
+          isfullbox(pplayer->base.x+ 31, pplayer->base.y))
+        {
+          trygrabdistro(pplayer->base.x+ 31, pplayer->base.y - 32,BOUNCE);
+          trybumpbadguy(pplayer->base.x+ 31, pplayer->base.y - 64);
+          bumpbrick(pplayer->base.x+ 31, pplayer->base.y);
+          tryemptybox(pplayer->base.x+ 31, pplayer->base.y);
+        }
+      /* Get a distro from a brick? */
 
-      /* Bump into things: */
+      if (shape(pplayer->base.x, pplayer->base.y) == 'x' ||
+          shape(pplayer->base.x, pplayer->base.y) == 'y')
+        {
+          add_bouncy_distro(((pplayer->base.x+ 1)
+                             / 32) * 32,
+                            (int)(pplayer->base.y / 32) * 32);
 
-      if (issolid(pplayer->base.x, pplayer->base.y) ||
-          (pplayer->size == BIG && !pplayer->duck &&
-           (issolid(pplayer->base.x, pplayer->base.y - 32))))
+          if (counting_distros == NO)
+            {
+              counting_distros = YES;
+              distro_counter = 100;
+            }
+
+          if (distro_counter <= 0)
+            level_change(&current_level,pplayer->base.x,pplayer->base.y, 'a');
+
+          play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
+          score = score + SCORE_DISTRO;
+          distros++;
+        }
+      else if (shape(pplayer->base.x+ 31, pplayer->base.y) == 'x' ||
+               shape(pplayer->base.x+ 31, pplayer->base.y) == 'y')
         {
-          if (!issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y) &&
-              (pplayer->size == SMALL || pplayer->duck ||
-               !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y - 32)))
+          add_bouncy_distro(((pplayer->base.x+ 1 + 31)
+                             / 32) * 32,
+                            (int)(pplayer->base.y / 32) * 32);
+
+          if (counting_distros == NO)
             {
-              pplayer->base.x = pplayer->base.x- pplayer->base.xm;
-              pplayer->base.xm = 0;
+              counting_distros = YES;
+              distro_counter = 100;
             }
-          else if (!issolid(pplayer->base.x, pplayer->base.y - pplayer->base.ym) &&
-                   (pplayer->size == SMALL || pplayer->duck ||
-                    !issolid(pplayer->base.x, pplayer->base.y - 32 - pplayer->base.ym)))
+
+          if (distro_counter <= 0)
+            level_change(&current_level,pplayer->base.x+ 31, pplayer->base.y, 'a');
+
+          play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
+          score = score + SCORE_DISTRO;
+          distros++;
+        }
+       
+       }
+       else
+{
+  pplayer->base.ym = 0;
+  pplayer->jumping = NO;
+  timer_start(&pplayer->jump_timer,MAX_JUMP_TIME);
+}
+  /*}*/
+  /* Bump into things: * /
+   
+  if (issolid(pplayer->base.x, pplayer->base.y) ||
+      (pplayer->size == BIG && !pplayer->duck &&
+       (issolid(pplayer->base.x, pplayer->base.y - 32))))
+    {
+   
+      if (!issolid(pplayer->base.x, pplayer->base.y - pplayer->base.ym) &&
+          (pplayer->size == SMALL || pplayer->duck ||
+           !issolid(pplayer->base.x, pplayer->base.y - 32 - pplayer->base.ym)))
+        {
+          if (pplayer->base.ym <= 0)
             {
-              if (pplayer->base.ym <= 0)
-                {
-                  /* Jumping up? */
+              /* Jumping up? */
+      /* FIXME: this code is COMPLETLY broken!!! */
+  if (pplayer->size == BIG)
+    {
+      /* Break bricks and empty boxes: * /
 
-                  if (pplayer->size == BIG)
-                    {
-                      /* Break bricks and empty boxes: */
+      if (!pplayer->duck)
+        {
+          if (isbrick(pplayer->base.x, pplayer->base.y - 32) ||
+              isfullbox(pplayer->base.x, pplayer->base.y - 32))
+            {
+              trygrabdistro(pplayer->base.x, pplayer->base.y - 64, BOUNCE);
+              trybumpbadguy(pplayer->base.x, pplayer->base.y - 96);
 
-                      if (!pplayer->duck)
-                        {
-                          if (isbrick(pplayer->base.x, pplayer->base.y - 32) ||
-                              isfullbox(pplayer->base.x, pplayer->base.y - 32))
-                            {
-                              trygrabdistro(pplayer->base.x, pplayer->base.y - 64, BOUNCE);
-                              trybumpbadguy(pplayer->base.x, pplayer->base.y - 96);
+              if (isfullbox(pplayer->base.x, pplayer->base.y - 32))
+                {
+                  bumpbrick(pplayer->base.x, pplayer->base.y - 32);
+                }
 
-                              if (isfullbox(pplayer->base.x, pplayer->base.y - 32))
-                                {
-                                  bumpbrick(pplayer->base.x, pplayer->base.y - 32);
-                                }
+              trybreakbrick(pplayer->base.x, pplayer->base.y - 32);
+              tryemptybox(pplayer->base.x, pplayer->base.y - 32);
+            }
 
-                              trybreakbrick(pplayer->base.x, pplayer->base.y - 32);
-                              tryemptybox(pplayer->base.x, pplayer->base.y - 32);
-                            }
+          if (isbrick(pplayer->base.x+ 31, pplayer->base.y - 32) ||
+              isfullbox(pplayer->base.x+ 31, pplayer->base.y - 32))
+            {
+              trygrabdistro(pplayer->base.x+ 31,
+                            pplayer->base.y - 64,
+                            BOUNCE);
+              trybumpbadguy(pplayer->base.x+ 31,
+                            pplayer->base.y - 96);
 
-                          if (isbrick(pplayer->base.x+ 31, pplayer->base.y - 32) ||
-                              isfullbox(pplayer->base.x+ 31, pplayer->base.y - 32))
-                            {
-                              trygrabdistro(pplayer->base.x+ 31,
-                                            pplayer->base.y - 64,
-                                            BOUNCE);
-                              trybumpbadguy(pplayer->base.x+ 31,
-                                            pplayer->base.y - 96);
-
-                              if (isfullbox(pplayer->base.x+ 31, pplayer->base.y - 32))
-                                {
-                                  bumpbrick(pplayer->base.x+ 31, pplayer->base.y - 32);
-                                }
-
-                              trybreakbrick(pplayer->base.x+ 31,
-                                            pplayer->base.y - 32);
-                              tryemptybox(pplayer->base.x+ 31,
-                                          pplayer->base.y - 32);
-                            }
-                        }
-                      else /* ducking */
-                        {
-                          if (isbrick(pplayer->base.x, pplayer->base.y) ||
-                              isfullbox(pplayer->base.x, pplayer->base.y))
-                            {
-                              trygrabdistro(pplayer->base.x, pplayer->base.y - 32,BOUNCE);
-                              trybumpbadguy(pplayer->base.x, pplayer->base.y - 64);
-                              if (isfullbox(pplayer->base.x, pplayer->base.y))
-                                bumpbrick(pplayer->base.x, pplayer->base.y);
-                              trybreakbrick(pplayer->base.x, pplayer->base.y);
-                              tryemptybox(pplayer->base.x, pplayer->base.y);
-                            }
+              if (isfullbox(pplayer->base.x+ 31, pplayer->base.y - 32))
+                {
+                  bumpbrick(pplayer->base.x+ 31, pplayer->base.y - 32);
+                }
 
-                          if (isbrick(pplayer->base.x+ 31, pplayer->base.y) ||
-                              isfullbox(pplayer->base.x+ 31, pplayer->base.y))
-                            {
-                              trygrabdistro(pplayer->base.x+ 31,
-                                            pplayer->base.y - 32,
-                                            BOUNCE);
-                              trybumpbadguy(pplayer->base.x+ 31,
-                                            pplayer->base.y - 64);
-                              if (isfullbox(pplayer->base.x+ 31, pplayer->base.y))
-                                bumpbrick(pplayer->base.x+ 31, pplayer->base.y);
-                              trybreakbrick(pplayer->base.x+ 31, pplayer->base.y);
-                              tryemptybox(pplayer->base.x+ 31, pplayer->base.y);
-                            }
-                        }
-                    }
-                  else
-                    {
-                      /* It's a brick and we're small, make the brick
-                         bounce, and grab any distros above it: */
+              trybreakbrick(pplayer->base.x+ 31,
+                            pplayer->base.y - 32);
+              tryemptybox(pplayer->base.x+ 31,
+                          pplayer->base.y - 32);
+            }
+        }
+      else /* ducking * /
+        {
+          if (isbrick(pplayer->base.x, pplayer->base.y) ||
+              isfullbox(pplayer->base.x, pplayer->base.y))
+            {
+              trygrabdistro(pplayer->base.x, pplayer->base.y - 32,BOUNCE);
+              trybumpbadguy(pplayer->base.x, pplayer->base.y - 64);
+              if (isfullbox(pplayer->base.x, pplayer->base.y))
+                bumpbrick(pplayer->base.x, pplayer->base.y);
+              trybreakbrick(pplayer->base.x, pplayer->base.y);
+              tryemptybox(pplayer->base.x, pplayer->base.y);
+            }
 
-                      if (isbrick(pplayer->base.x, pplayer->base.y) ||
-                          isfullbox(pplayer->base.x, pplayer->base.y))
-                        {
-                          trygrabdistro(pplayer->base.x, pplayer->base.y - 32,BOUNCE);
-                          trybumpbadguy(pplayer->base.x, pplayer->base.y - 64);
-                          bumpbrick(pplayer->base.x, pplayer->base.y);
-                          tryemptybox(pplayer->base.x, pplayer->base.y);
-                        }
+          if (isbrick(pplayer->base.x+ 31, pplayer->base.y) ||
+              isfullbox(pplayer->base.x+ 31, pplayer->base.y))
+            {
+              trygrabdistro(pplayer->base.x+ 31,
+                            pplayer->base.y - 32,
+                            BOUNCE);
+              trybumpbadguy(pplayer->base.x+ 31,
+                            pplayer->base.y - 64);
+              if (isfullbox(pplayer->base.x+ 31, pplayer->base.y))
+                bumpbrick(pplayer->base.x+ 31, pplayer->base.y);
+              trybreakbrick(pplayer->base.x+ 31, pplayer->base.y);
+              tryemptybox(pplayer->base.x+ 31, pplayer->base.y);
+            }
+        }
+      }
+      else
+      {
+      /* It's a brick and we're small, make the brick
+         bounce, and grab any distros above it: * /
 
-                      if (isbrick(pplayer->base.x+ 31, pplayer->base.y) ||
-                          isfullbox(pplayer->base.x+ 31, pplayer->base.y))
-                        {
-                          trygrabdistro(pplayer->base.x+ 31, pplayer->base.y - 32,BOUNCE);
-                          trybumpbadguy(pplayer->base.x+ 31, pplayer->base.y - 64);
-                          bumpbrick(pplayer->base.x+ 31, pplayer->base.y);
-                          tryemptybox(pplayer->base.x+ 31, pplayer->base.y);
-                        }
+      if (isbrick(pplayer->base.x, pplayer->base.y) ||
+          isfullbox(pplayer->base.x, pplayer->base.y))
+        {
+          trygrabdistro(pplayer->base.x, pplayer->base.y - 32,BOUNCE);
+          trybumpbadguy(pplayer->base.x, pplayer->base.y - 64);
+          bumpbrick(pplayer->base.x, pplayer->base.y);
+          tryemptybox(pplayer->base.x, pplayer->base.y);
+        }
 
+      if (isbrick(pplayer->base.x+ 31, pplayer->base.y) ||
+          isfullbox(pplayer->base.x+ 31, pplayer->base.y))
+        {
+          trygrabdistro(pplayer->base.x+ 31, pplayer->base.y - 32,BOUNCE);
+          trybumpbadguy(pplayer->base.x+ 31, pplayer->base.y - 64);
+          bumpbrick(pplayer->base.x+ 31, pplayer->base.y);
+          tryemptybox(pplayer->base.x+ 31, pplayer->base.y);
+        }
 
-                      /* Get a distro from a brick? */
 
-                      if (shape(pplayer->base.x, pplayer->base.y) == 'x' ||
-                          shape(pplayer->base.x, pplayer->base.y) == 'y')
-                        {
-                          add_bouncy_distro(((pplayer->base.x+ 1)
-                                             / 32) * 32,
-                                            (int)(pplayer->base.y / 32) * 32);
+      /* Get a distro from a brick? * /
 
-                          if (counting_distros == NO)
-                            {
-                              counting_distros = YES;
-                              distro_counter = 100;
-                            }
+      if (shape(pplayer->base.x, pplayer->base.y) == 'x' ||
+          shape(pplayer->base.x, pplayer->base.y) == 'y')
+        {
+          add_bouncy_distro(((pplayer->base.x+ 1)
+                             / 32) * 32,
+                            (int)(pplayer->base.y / 32) * 32);
 
-                          if (distro_counter <= 0)
-                            level_change(&current_level,pplayer->base.x,pplayer->base.y, 'a');
+          if (counting_distros == NO)
+            {
+              counting_distros = YES;
+              distro_counter = 100;
+            }
 
-                          play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
-                          score = score + SCORE_DISTRO;
-                          distros++;
-                        }
-                      else if (shape(pplayer->base.x+ 31, pplayer->base.y) == 'x' ||
-                               shape(pplayer->base.x+ 31, pplayer->base.y) == 'y')
-                        {
-                          add_bouncy_distro(((pplayer->base.x+ 1 + 31)
-                                             / 32) * 32,
-                                            (int)(pplayer->base.y / 32) * 32);
+          if (distro_counter <= 0)
+            level_change(&current_level,pplayer->base.x,pplayer->base.y, 'a');
 
-                          if (counting_distros == NO)
-                            {
-                              counting_distros = YES;
-                              distro_counter = 100;
-                            }
+          play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
+          score = score + SCORE_DISTRO;
+          distros++;
+        }
+      else if (shape(pplayer->base.x+ 31, pplayer->base.y) == 'x' ||
+               shape(pplayer->base.x+ 31, pplayer->base.y) == 'y')
+        {
+          add_bouncy_distro(((pplayer->base.x+ 1 + 31)
+                             / 32) * 32,
+                            (int)(pplayer->base.y / 32) * 32);
+
+          if (counting_distros == NO)
+            {
+              counting_distros = YES;
+              distro_counter = 100;
+            }
 
-                          if (distro_counter <= 0)
-                            level_change(&current_level,pplayer->base.x+ 31, pplayer->base.y, 'a');
+          if (distro_counter <= 0)
+            level_change(&current_level,pplayer->base.x+ 31, pplayer->base.y, 'a');
 
-                          play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
-                          score = score + SCORE_DISTRO;
-                          distros++;
-                        }
-                    }
+          play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
+          score = score + SCORE_DISTRO;
+          distros++;
+        }
+      }
 
 
-                  /* Bump head: */
+      /* Bump head: * /
 
-                  pplayer->base.y = (int)(pplayer->base.y / 32) * 32 + 30;
-                }
-              else
-                {
-                  /* Land on feet: */
+      pplayer->base.y = (int)(pplayer->base.y / 32) * 32 + 30;
+      }
+      else
+      {
+      /* Land on feet: * /
 
-                  pplayer->base.y = (int)(pplayer->base.y / 32) * 32 - 32;
-                }
+      pplayer->base.y = (int)(pplayer->base.y / 32) * 32 - 32;
+      }
 
-              pplayer->base.ym = 0;
-              pplayer->jumping = NO;
-              /*pplayer->jump_counter = MAX_JUMP_COUNT;*/
-              /*timer_init(&pplayer->jump_timer);*/
-              timer_start(&pplayer->jump_timer,MAX_JUMP_TIME);
-            }
-        }
+      pplayer->base.ym = 0;
+      pplayer->jumping = NO;
+      timer_start(&pplayer->jump_timer,MAX_JUMP_TIME);
+      }*/
     }
+}
 
 
 
-  player_grabdistros(pplayer);
+player_grabdistros(pplayer);
 
 
-  /* Slow down horizontally: */
+/* Slow down horizontally: */
 
-  if (!pplayer->dying)
-    {
-      if (pplayer->input.right == UP && pplayer->input.left == UP)
-        {
-          if (isice(pplayer->base.x, pplayer->base.y + 32) ||
-              !issolid(pplayer->base.x, pplayer->base.y + 32))
-            {
-              /* Slowly on ice or in air: */
+if (!pplayer->dying)
+  {
+    if (pplayer->input.right == UP && pplayer->input.left == UP)
+      {
+        if (isice(pplayer->base.x, pplayer->base.y + 32) ||
+            !issolid(pplayer->base.x, pplayer->base.y + 32))
+          {
+            /* Slowly on ice or in air: */
 
-              if (pplayer->base.xm > 0)
-                pplayer->base.xm--;
-              else if (pplayer->base.xm < 0)
-                pplayer->base.xm++;
-            }
-          else
-            {
-              /* Quickly, otherwise: */
+            if (pplayer->base.xm > 0)
+              pplayer->base.xm--;
+            else if (pplayer->base.xm < 0)
+              pplayer->base.xm++;
+          }
+        else
+          {
+            /* Quickly, otherwise: */
 
-              pplayer->base.xm = pplayer->base.xm / 2;
-            }
-        }
+            pplayer->base.xm = pplayer->base.xm / 2;
+          }
+      }
 
 
-      /* Drop vertically: */
+    /* Drop vertically: */
 
-      if (!issolid(pplayer->base.x, pplayer->base.y + 32))
-        {
-          pplayer->base.ym = pplayer->base.ym + GRAVITY;
+    if (!issolid(pplayer->base.x, pplayer->base.y + 32))
+      {
+        pplayer->base.ym = pplayer->base.ym + GRAVITY;
 
-          if (pplayer->base.ym > MAX_YM)
-            pplayer->base.ym = MAX_YM;
-        }
-    }
+        if (pplayer->base.ym > MAX_YM)
+          pplayer->base.ym = MAX_YM;
+      }
+  }
 
 
 
-  timer_check(&pplayer->safe_timer);
+timer_check(&pplayer->safe_timer);
 
 
-  /* ---- DONE HANDLING TUX! --- */
+/* ---- DONE HANDLING TUX! --- */
 
-  /* Handle invincibility timer: */
+/* Handle invincibility timer: */
 
 
-  if (current_music == HERRING_MUSIC && !timer_check(&pplayer->invincible_timer))
-    {
-      /*
-         no, we are no more invincible
-         or we were not in invincible mode
-         but are we in hurry ?
-       */
+if (current_music == HERRING_MUSIC && !timer_check(&pplayer->invincible_timer))
+  {
+    /*
+       no, we are no more invincible
+       or we were not in invincible mode
+       but are we in hurry ?
+     */
 
 
-      if (timer_get_left(&time_left) < TIME_WARNING)
-        {
-          /* yes, we are in hurry
-             stop the herring_song, prepare to play the correct
-             fast level_song !
-           */
-          current_music = HURRYUP_MUSIC;
-        }
-      else
-        {
-          current_music = LEVEL_MUSIC;
-        }
+    if (timer_get_left(&time_left) < TIME_WARNING)
+      {
+        /* yes, we are in hurry
+           stop the herring_song, prepare to play the correct
+           fast level_song !
+         */
+        current_music = HURRYUP_MUSIC;
+      }
+    else
+      {
+        current_music = LEVEL_MUSIC;
+      }
 
-      /* stop the old music if it's being played */
-      if (playing_music())
-        halt_music();
-    }
+    /* stop the old music if it's being played */
+    if (playing_music())
+      halt_music();
+  }
 
-  /* Handle skidding: */
+/* Handle skidding: */
 
-  timer_check(&pplayer->skidding_timer);
+timer_check(&pplayer->skidding_timer);
 
-  /* End of level? */
+/* End of level? */
 
-  if (pplayer->base.x - scroll_x >= endpos && endpos != 0)
-    {
-      next_level = 1;
-    }
+if (pplayer->base.x - scroll_x >= endpos && endpos != 0)
+  {
+    next_level = 1;
+  }
 
 }
 
@@ -569,536 +676,540 @@ void player_handle_horizontal_input(player_type *pplayer, int dir)
 
 void player_handle_vertical_input(player_type *pplayer)
 {
-        if(!timer_started(&pplayer->jump_timer))
-          {
-            timer_start(&pplayer->jump_timer,MAX_JUMP_TIME);
+  if(!timer_started(&pplayer->jump_timer))
+    {
+      timer_start(&pplayer->jump_timer,MAX_JUMP_TIME);
 
 
-            /* Taking off? */
+      /* Taking off? */
 
-            if (!issolid(pplayer->base.x, pplayer->base.y + 32) ||
-                pplayer->base.ym != 0)
-              {
-                /* If they're not on the ground, or are currently moving
-                vertically, don't jump! */
+      if (!issolid(pplayer->base.x, pplayer->base.y + 32) ||
+          pplayer->base.ym != 0)
+        {
+          /* If they're not on the ground, or are currently moving
+          vertically, don't jump! */
 
-                pplayer->jumping = NO;
-                timer_stop(&pplayer->jump_timer);
-              }
-            else
-              {
-                /* Make sure we're not standing back up into a solid! */
+          pplayer->jumping = NO;
+          timer_stop(&pplayer->jump_timer);
+        }
+      else
+        {
+          /* Make sure we're not standing back up into a solid! */
 
-                if (pplayer->size == SMALL || pplayer->duck == NO ||
-                    !issolid(pplayer->base.x, pplayer->base.y))
-                  {
-                    pplayer->jumping = YES;
+          if (pplayer->size == SMALL || pplayer->duck == NO ||
+              !issolid(pplayer->base.x, pplayer->base.y))
+            {
+              pplayer->jumping = YES;
 
-                    if (pplayer->size == SMALL)
-                      play_sound(sounds[SND_JUMP], SOUND_CENTER_SPEAKER);
-                    else
-                      play_sound(sounds[SND_BIGJUMP], SOUND_CENTER_SPEAKER);
-                  }
-              }
-          }
+              if (pplayer->size == SMALL)
+                play_sound(sounds[SND_JUMP], SOUND_CENTER_SPEAKER);
+              else
+                play_sound(sounds[SND_BIGJUMP], SOUND_CENTER_SPEAKER);
+            }
+        }
+    }
 
-        /* Keep jumping for a while: */
+  /* Keep jumping for a while: */
 
-        if (timer_check(&pplayer->jump_timer))
-          {
-            pplayer->base.ym = pplayer->base.ym - JUMP_SPEED * frame_ratio;
-            if (pplayer->base.ym < -YM_FOR_JUMP)
-              pplayer->base.ym = -YM_FOR_JUMP;
-          }
-      }
-   
-  void player_input(player_type *pplayer)
-  {
-    /* Handle key and joystick state: */
+  if (timer_check(&pplayer->jump_timer))
+    {
+      pplayer->base.ym = pplayer->base.ym - JUMP_SPEED * frame_ratio;
+      if (pplayer->base.ym < -YM_FOR_JUMP)
+        pplayer->base.ym = -YM_FOR_JUMP;
+    }
+}
 
+void player_input(player_type *pplayer)
+{
+  /* Handle key and joystick state: */
 
-    if (pplayer->input.right == DOWN && pplayer->input.left == UP)
-      {
-        player_handle_horizontal_input(pplayer,RIGHT);
-      }
-    else if (pplayer->input.left == DOWN && pplayer->input.right == UP)
-      {
-        player_handle_horizontal_input(pplayer,LEFT);
-      }
 
-    /* Jump/jumping? */
+  if (pplayer->input.right == DOWN && pplayer->input.left == UP)
+    {
+      player_handle_horizontal_input(pplayer,RIGHT);
+    }
+  else if (pplayer->input.left == DOWN && pplayer->input.right == UP)
+    {
+      player_handle_horizontal_input(pplayer,LEFT);
+    }
 
-    if ( pplayer->input.up == DOWN)
-      {
-       player_handle_vertical_input(pplayer);
-      }
-    else
-      timer_stop(&pplayer->jump_timer);
-      
-    /* Shoot! */
+  /* Jump/jumping? */
 
-    if (pplayer->input.fire == DOWN && pplayer->input.old_fire == UP && pplayer->got_coffee)
-      {
-        add_bullet(pplayer->base.x, pplayer->base.y, pplayer->base.xm, pplayer->dir);
-      }
+  if ( pplayer->input.up == DOWN)
+    {
+      player_handle_vertical_input(pplayer);
+    }
+  else
+    timer_stop(&pplayer->jump_timer);
 
+  /* Shoot! */
 
-    /* Duck! */
+  if (pplayer->input.fire == DOWN && pplayer->input.old_fire == UP && pplayer->got_coffee)
+    {
+      add_bullet(pplayer->base.x, pplayer->base.y, pplayer->base.xm, pplayer->dir);
+    }
 
-    if (pplayer->input.down == DOWN)
-      {
-        if (pplayer->size == BIG)
-          pplayer->duck = YES;
-      }
-    else
-      {
-        if (pplayer->size == BIG && pplayer->duck == YES)
-          {
-            /* Make sure we're not standing back up into a solid! */
 
-            if (!issolid(pplayer->base.x, pplayer->base.y - 32))
-              pplayer->duck = NO;
-          }
-        else
-          pplayer->duck = NO;
-      }
+  /* Duck! */
 
-    /* (Tux): */
+  if (pplayer->input.down == DOWN)
+    {
+      if (pplayer->size == BIG)
+        pplayer->duck = YES;
+    }
+  else
+    {
+      if (pplayer->size == BIG && pplayer->duck == YES)
+        {
+          /* Make sure we're not standing back up into a solid! */
 
-    if (pplayer->input.right == UP && pplayer->input.left == UP)
-      {
-        pplayer->frame_main = 1;
-        pplayer->frame = 1;
-      }
-    else
-      {
-        if ((pplayer->input.fire == DOWN && (frame % 2) == 0) ||
-            (frame % 4) == 0)
-          pplayer->frame_main = (pplayer->frame_main + 1) % 4;
+          if (!issolid(pplayer->base.x, pplayer->base.y - 32))
+            pplayer->duck = NO;
+        }
+      else
+        pplayer->duck = NO;
+    }
 
-        pplayer->frame = pplayer->frame_main;
+  /* (Tux): */
 
-        if (pplayer->frame == 3)
-          pplayer->frame = 1;
-      }
+  if (pplayer->input.right == UP && pplayer->input.left == UP)
+    {
+      pplayer->frame_main = 1;
+      pplayer->frame = 1;
+    }
+  else
+    {
+      if ((pplayer->input.fire == DOWN && (frame % 2) == 0) ||
+          (frame % 4) == 0)
+        pplayer->frame_main = (pplayer->frame_main + 1) % 4;
 
-  }
+      pplayer->frame = pplayer->frame_main;
 
-  void player_grabdistros(player_type *pplayer)
-  {
-    /* Grab distros: */
-    if (!pplayer->dying)
-      {
-        trygrabdistro(pplayer->base.x, pplayer->base.y, NO_BOUNCE);
-        trygrabdistro(pplayer->base.x+ 31, pplayer->base.y, NO_BOUNCE);
+      if (pplayer->frame == 3)
+        pplayer->frame = 1;
+    }
 
-        if (pplayer->size == BIG && !pplayer->duck)
-          {
-            trygrabdistro(pplayer->base.x, pplayer->base.y - 32, NO_BOUNCE);
-            trygrabdistro(pplayer->base.x+ 31, pplayer->base.y - 32, NO_BOUNCE);
-          }
-      }
+}
 
+void player_grabdistros(player_type *pplayer)
+{
+  /* Grab distros: */
+  if (!pplayer->dying)
+    {
+      trygrabdistro(pplayer->base.x, pplayer->base.y, NO_BOUNCE);
+      trygrabdistro(pplayer->base.x+ 31, pplayer->base.y, NO_BOUNCE);
 
-    /* Enough distros for a One-up? */
+      if (pplayer->size == BIG && !pplayer->duck)
+        {
+          trygrabdistro(pplayer->base.x, pplayer->base.y - 32, NO_BOUNCE);
+          trygrabdistro(pplayer->base.x+ 31, pplayer->base.y - 32, NO_BOUNCE);
+        }
+    }
 
-    if (distros >= DISTROS_LIFEUP)
-      {
-        distros = distros - DISTROS_LIFEUP;
-        if(pplayer->lives < MAX_LIVES)
-          pplayer->lives++;
-        /*We want to hear the sound even, if MAX_LIVES is reached*/
-        play_sound(sounds[SND_LIFEUP], SOUND_CENTER_SPEAKER);
-      }
-  }
 
-  void player_draw(player_type* pplayer)
-  {
-    if (!timer_started(&pplayer->safe_timer) || (frame % 2) == 0)
-      {
-        if (pplayer->size == SMALL)
-          {
-            if (timer_started(&pplayer->invincible_timer))
-              {
-                /* Draw cape: */
+  /* Enough distros for a One-up? */
 
-                if (pplayer->dir == RIGHT)
-                  {
-                    texture_draw(&cape_right[frame % 2],
-                                 pplayer->base.x- scroll_x, pplayer->base.y,
-                                 NO_UPDATE);
-                  }
-                else
-                  {
-                    texture_draw(&cape_left[frame % 2],
-                                 pplayer->base.x- scroll_x, pplayer->base.y,
-                                 NO_UPDATE);
-                  }
-              }
+  if (distros >= DISTROS_LIFEUP)
+    {
+      distros = distros - DISTROS_LIFEUP;
+      if(pplayer->lives < MAX_LIVES)
+        pplayer->lives++;
+      /*We want to hear the sound even, if MAX_LIVES is reached*/
+      play_sound(sounds[SND_LIFEUP], SOUND_CENTER_SPEAKER);
+    }
+}
 
+void player_draw(player_type* pplayer)
+{
+  if (!timer_started(&pplayer->safe_timer) || (frame % 2) == 0)
+    {
+      if (pplayer->size == SMALL)
+        {
+          if (timer_started(&pplayer->invincible_timer))
+            {
+              /* Draw cape: */
 
-            if (!pplayer->got_coffee)
-              {
-                if (pplayer->dir == RIGHT)
-                  {
-                    texture_draw(&tux_right[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE);
-                  }
-                else
-                  {
-                    texture_draw(&tux_left[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE);
-                  }
-              }
-            else
-              {
-                /* Tux got coffee! */
+              if (pplayer->dir == RIGHT)
+                {
+                  texture_draw(&cape_right[frame % 2],
+                               pplayer->base.x- scroll_x, pplayer->base.y,
+                               NO_UPDATE);
+                }
+              else
+                {
+                  texture_draw(&cape_left[frame % 2],
+                               pplayer->base.x- scroll_x, pplayer->base.y,
+                               NO_UPDATE);
+                }
+            }
 
-                if (pplayer->dir == RIGHT)
-                  {
-                    texture_draw(&firetux_right[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE);
-                  }
-                else
-                  {
-                    texture_draw(&firetux_left[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE);
-                  }
-              }
-          }
-        else
-          {
-            if (timer_started(&pplayer->invincible_timer))
-              {
-                /* Draw cape: */
 
-                if (pplayer->dir == RIGHT)
-                  {
-                    texture_draw(&bigcape_right[frame % 2],
-                                 pplayer->base.x- scroll_x - 8 - 16, pplayer->base.y - 32,
-                                 NO_UPDATE);
-                  }
-                else
-                  {
-                    texture_draw(&bigcape_left[frame % 2],
-                                 pplayer->base.x-scroll_x - 8, pplayer->base.y - 32,
-                                 NO_UPDATE);
-                  }
-              }
+          if (!pplayer->got_coffee)
+            {
+              if (pplayer->dir == RIGHT)
+                {
+                  texture_draw(&tux_right[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE);
+                }
+              else
+                {
+                  texture_draw(&tux_left[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE);
+                }
+            }
+          else
+            {
+              /* Tux got coffee! */
 
-            if (!pplayer->got_coffee)
-              {
-                if (!pplayer->duck)
-                  {
-                    if (!timer_started(&pplayer->skidding_timer))
-                      {
-                        if (!pplayer->jumping || pplayer->base.ym > 0)
-                          {
-                            if (pplayer->dir == RIGHT)
-                              {
-                                texture_draw(&bigtux_right[pplayer->frame],
-                                             pplayer->base.x- scroll_x - 8, pplayer->base.y - 32,
-                                             NO_UPDATE);
-                              }
-                            else
-                              {
-                                texture_draw(&bigtux_left[pplayer->frame],
-                                             pplayer->base.x- scroll_x - 8, pplayer->base.y - 32,
-                                             NO_UPDATE);
-                              }
-                          }
-                        else
-                          {
-                            if (pplayer->dir == RIGHT)
-                              {
-                                texture_draw(&bigtux_right_jump,
-                                             pplayer->base.x- scroll_x - 8, pplayer->base.y - 32,
-                                             NO_UPDATE);
-                              }
-                            else
-                              {
-                                texture_draw(&bigtux_left_jump,
-                                             pplayer->base.x- scroll_x - 8, pplayer->base.y - 32,
-                                             NO_UPDATE);
-                              }
-                          }
-                      }
-                    else
-                      {
-                        if (pplayer->dir == RIGHT)
-                          {
-                            texture_draw(&skidtux_right,
-                                         pplayer->base.x- scroll_x - 8, pplayer->base.y - 32,
-                                         NO_UPDATE);
-                          }
-                        else
-                          {
-                            texture_draw(&skidtux_left,
-                                         pplayer->base.x- scroll_x - 8, pplayer->base.y - 32,
-                                         NO_UPDATE);
-                          }
-                      }
-                  }
-                else
-                  {
-                    if (pplayer->dir == RIGHT)
-                      {
-                        texture_draw(&ducktux_right, pplayer->base.x- scroll_x - 8, pplayer->base.y - 16,
-                                     NO_UPDATE);
-                      }
-                    else
-                      {
-                        texture_draw(&ducktux_left, pplayer->base.x- scroll_x - 8, pplayer->base.y - 16,
-                                     NO_UPDATE);
-                      }
-                  }
-              }
-            else
-              {
-                /* Tux has coffee! */
+              if (pplayer->dir == RIGHT)
+                {
+                  texture_draw(&firetux_right[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE);
+                }
+              else
+                {
+                  texture_draw(&firetux_left[pplayer->frame], pplayer->base.x- scroll_x, pplayer->base.y, NO_UPDATE);
+                }
+            }
+        }
+      else
+        {
+          if (timer_started(&pplayer->invincible_timer))
+            {
+              /* Draw cape: */
 
-                if (!pplayer->duck)
-                  {
-                    if (!timer_started(&pplayer->skidding_timer))
-                      {
-                        if (!pplayer->jumping || pplayer->base.ym > 0)
-                          {
-                            if (pplayer->dir == RIGHT)
-                              {
-                                texture_draw(&bigfiretux_right[pplayer->frame],
-                                             pplayer->base.x- scroll_x - 8, pplayer->base.y - 32,
-                                             NO_UPDATE);
-                              }
-                            else
-                              {
-                                texture_draw(&bigfiretux_left[pplayer->frame],
-                                             pplayer->base.x- scroll_x - 8, pplayer->base.y - 32,
-                                             NO_UPDATE);
-                              }
-                          }
-                        else
-                          {
-                            if (pplayer->dir == RIGHT)
-                              {
-                                texture_draw(&bigfiretux_right_jump,
-                                             pplayer->base.x- scroll_x - 8, pplayer->base.y - 32,
-                                             NO_UPDATE);
-                              }
-                            else
-                              {
-                                texture_draw(&bigfiretux_left_jump,
-                                             pplayer->base.x- scroll_x - 8, pplayer->base.y - 32,
-                                             NO_UPDATE);
-                              }
-                          }
-                      }
-                    else
-                      {
-                        if (pplayer->dir == RIGHT)
-                          {
-                            texture_draw(&skidfiretux_right,
-                                         pplayer->base.x- scroll_x - 8, pplayer->base.y - 32,
-                                         NO_UPDATE);
-                          }
-                        else
-                          {
-                            texture_draw(&skidfiretux_left,
-                                         pplayer->base.x- scroll_x - 8, pplayer->base.y - 32,
-                                         NO_UPDATE);
-                          }
-                      }
-                  }
-                else
-                  {
-                    if (pplayer->dir == RIGHT)
-                      {
-                        texture_draw(&duckfiretux_right, pplayer->base.x- scroll_x - 8, pplayer->base.y - 16,
-                                     NO_UPDATE);
-                      }
-                    else
-                      {
-                        texture_draw(&duckfiretux_left, pplayer->base.x- scroll_x - 8, pplayer->base.y - 16,
-                                     NO_UPDATE);
-                      }
-                  }
-              }
-          }
-      }
-  }
+              if (pplayer->dir == RIGHT)
+                {
+                  texture_draw(&bigcape_right[frame % 2],
+                               pplayer->base.x- scroll_x, pplayer->base.y,
+                               NO_UPDATE);
+                }
+              else
+                {
+                  texture_draw(&bigcape_left[frame % 2],
+                               pplayer->base.x-scroll_x, pplayer->base.y,
+                               NO_UPDATE);
+                }
+            }
 
-  void player_collision(player_type* pplayer, void* p_c_object, int c_object)
-  {
-    bad_guy_type* pbad_c = NULL;
+          if (!pplayer->got_coffee)
+            {
+              if (!pplayer->duck)
+                {
+                  if (!timer_started(&pplayer->skidding_timer))
+                    {
+                      if (!pplayer->jumping || pplayer->base.ym > 0)
+                        {
+                          if (pplayer->dir == RIGHT)
+                            {
+                              texture_draw(&bigtux_right[pplayer->frame],
+                                           pplayer->base.x- scroll_x, pplayer->base.y,
+                                           NO_UPDATE);
+                            }
+                          else
+                            {
+                              texture_draw(&bigtux_left[pplayer->frame],
+                                           pplayer->base.x- scroll_x, pplayer->base.y,
+                                           NO_UPDATE);
+                            }
+                        }
+                      else
+                        {
+                          if (pplayer->dir == RIGHT)
+                            {
+                              texture_draw(&bigtux_right_jump,
+                                           pplayer->base.x- scroll_x, pplayer->base.y,
+                                           NO_UPDATE);
+                            }
+                          else
+                            {
+                              texture_draw(&bigtux_left_jump,
+                                           pplayer->base.x- scroll_x, pplayer->base.y,
+                                           NO_UPDATE);
+                            }
+                        }
+                    }
+                  else
+                    {
+                      if (pplayer->dir == RIGHT)
+                        {
+                          texture_draw(&skidtux_right,
+                                       pplayer->base.x- scroll_x, pplayer->base.y,
+                                       NO_UPDATE);
+                        }
+                      else
+                        {
+                          texture_draw(&skidtux_left,
+                                       pplayer->base.x- scroll_x, pplayer->base.y,
+                                       NO_UPDATE);
+                        }
+                    }
+                }
+              else
+                {
+                  if (pplayer->dir == RIGHT)
+                    {
+                      texture_draw(&ducktux_right, pplayer->base.x- scroll_x, pplayer->base.y,
+                                   NO_UPDATE);
+                    }
+                  else
+                    {
+                      texture_draw(&ducktux_left, pplayer->base.x- scroll_x, pplayer->base.y,
+                                   NO_UPDATE);
+                    }
+                }
+            }
+          else
+            {
+              /* Tux has coffee! */
 
-    switch (c_object)
-      {
-      case CO_BADGUY:
-        pbad_c = p_c_object;
-        /* Hurt the player if he just touched it: */
+              if (!pplayer->duck)
+                {
+                  if (!timer_started(&pplayer->skidding_timer))
+                    {
+                      if (!pplayer->jumping || pplayer->base.ym > 0)
+                        {
+                          if (pplayer->dir == RIGHT)
+                            {
+                              texture_draw(&bigfiretux_right[pplayer->frame],
+                                           pplayer->base.x- scroll_x, pplayer->base.y,
+                                           NO_UPDATE);
+                            }
+                          else
+                            {
+                              texture_draw(&bigfiretux_left[pplayer->frame],
+                                           pplayer->base.x- scroll_x, pplayer->base.y,
+                                           NO_UPDATE);
+                            }
+                        }
+                      else
+                        {
+                          if (pplayer->dir == RIGHT)
+                            {
+                              texture_draw(&bigfiretux_right_jump,
+                                           pplayer->base.x- scroll_x, pplayer->base.y,
+                                           NO_UPDATE);
+                            }
+                          else
+                            {
+                              texture_draw(&bigfiretux_left_jump,
+                                           pplayer->base.x- scroll_x, pplayer->base.y,
+                                           NO_UPDATE);
+                            }
+                        }
+                    }
+                  else
+                    {
+                      if (pplayer->dir == RIGHT)
+                        {
+                          texture_draw(&skidfiretux_right,
+                                       pplayer->base.x- scroll_x, pplayer->base.y,
+                                       NO_UPDATE);
+                        }
+                      else
+                        {
+                          texture_draw(&skidfiretux_left,
+                                       pplayer->base.x- scroll_x, pplayer->base.y,
+                                       NO_UPDATE);
+                        }
+                    }
+                }
+              else
+                {
+                  if (pplayer->dir == RIGHT)
+                    {
+                      texture_draw(&duckfiretux_right, pplayer->base.x- scroll_x, pplayer->base.y,
+                                   NO_UPDATE);
+                    }
+                  else
+                    {
+                      texture_draw(&duckfiretux_left, pplayer->base.x- scroll_x, pplayer->base.y,
+                                   NO_UPDATE);
+                    }
+                }
+            }
+        }
+    }
+}
 
-        if (!pbad_c->dying && !pplayer->dying &&
-            !timer_started(&pplayer->safe_timer) &&
-            pbad_c->mode != HELD)
-          {
-            if (pbad_c->mode == FLAT  && pplayer->input.fire != DOWN)
-              {
-                /* Kick: */
+void player_collision(player_type* pplayer, void* p_c_object, int c_object)
+{
+  bad_guy_type* pbad_c = NULL;
+
+  switch (c_object)
+    {
+    case CO_BADGUY:
+      pbad_c = (bad_guy_type*) p_c_object;
+      /* Hurt the player if he just touched it: */
 
-                pbad_c->mode = KICK;
-                play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
+      if (!pbad_c->dying && !pplayer->dying &&
+          !timer_started(&pplayer->safe_timer) &&
+          pbad_c->mode != HELD)
+        {
+          if (pbad_c->mode == FLAT  && pplayer->input.fire != DOWN)
+            {
+              /* Kick: */
 
-                if (pplayer->base.x<= pbad_c->base.x)
-                  {
-                    pbad_c->dir = RIGHT;
-                    pbad_c->base.x = pbad_c->base.x + 16;
-                  }
-                else
-                  {
-                    pbad_c->dir = LEFT;
-                    pbad_c->base.x = pbad_c->base.x - 16;
-                  }
+              pbad_c->mode = KICK;
+              play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
 
-                timer_start(&pbad_c->timer,5000);
-              }
-            else if (pbad_c->mode == FLAT && pplayer->input.fire == DOWN)
-              {
-                pbad_c->mode = HELD;
-                pbad_c->base.y-=8;
-              }
-            else if (pbad_c->mode == KICK)
-              {
-                if (pplayer->base.y < pbad_c->base.y - 16 &&
-                    timer_started(&pbad_c->timer))
-                  {
-                    /* Step on (stop being kicked) */
+              if (pplayer->base.x<= pbad_c->base.x)
+                {
+                  pbad_c->dir = RIGHT;
+                  pbad_c->base.x = pbad_c->base.x + 16;
+                }
+              else
+                {
+                  pbad_c->dir = LEFT;
+                  pbad_c->base.x = pbad_c->base.x - 16;
+                }
 
-                    pbad_c->mode = FLAT;
-                    play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER);
-                    timer_start(&pbad_c->timer, 10000);
-                  }
-                else
-                  {
-                    /* Hurt if you get hit by kicked laptop: */
-
-                    if (timer_started(&pbad_c->timer))
-                      {
-                        if (!timer_started(&pplayer->invincible_timer))
-                          {
-                            player_kill(pplayer,SHRINK);
-                          }
-                        else
-                          {
-                            pbad_c->dying = FALLING;
-                            pbad_c->base.ym = -8;
-                            play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
-                          }
-                      }
-                  }
-              }
-            else
-              {
-                if (!timer_started(&pplayer->invincible_timer ))
-                  {
-                    player_kill(pplayer,SHRINK);
-                  }
-                else
-                  {
-                    pbad_c->dying = FALLING;
-                    pbad_c->base.ym = -8;
-                    play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
-                  }
-              }
-          }
-        score_multiplier++;
-        break;
-      }
+              timer_start(&pbad_c->timer,5000);
+            }
+          else if (pbad_c->mode == FLAT && pplayer->input.fire == DOWN)
+            {
+              pbad_c->mode = HELD;
+              pbad_c->base.y-=8;
+            }
+          else if (pbad_c->mode == KICK)
+            {
+              if (pplayer->base.y < pbad_c->base.y - 16 &&
+                  timer_started(&pbad_c->timer))
+                {
+                  /* Step on (stop being kicked) */
 
-  }
+                  pbad_c->mode = FLAT;
+                  play_sound(sounds[SND_STOMP], SOUND_CENTER_SPEAKER);
+                  timer_start(&pbad_c->timer, 10000);
+                }
+              else
+                {
+                  /* Hurt if you get hit by kicked laptop: */
 
-  /* Kill Player! */
+                  if (timer_started(&pbad_c->timer))
+                    {
+                      if (!timer_started(&pplayer->invincible_timer))
+                        {
+                          player_kill(pplayer,SHRINK);
+                        }
+                      else
+                        {
+                          pbad_c->dying = FALLING;
+                          pbad_c->base.ym = -8;
+                          play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
+                        }
+                    }
+                }
+            }
+          else
+            {
+              if (!timer_started(&pplayer->invincible_timer ))
+                {
+                  player_kill(pplayer,SHRINK);
+                }
+              else
+                {
+                  pbad_c->dying = FALLING;
+                  pbad_c->base.ym = -8;
+                  play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
+                }
+            }
+          score_multiplier++;
+        }
+      break;
+    default:
+      break;
+    }
 
-  void player_kill(player_type* pplayer, int mode)
-  {
-    pplayer->base.ym = -5;
+}
 
-    play_sound(sounds[SND_HURT], SOUND_CENTER_SPEAKER);
+/* Kill Player! */
 
-    if (pplayer->dir == RIGHT)
-      pplayer->base.xm = -8;
-    else if (pplayer->dir == LEFT)
-      pplayer->base.xm = 8;
+void player_kill(player_type* pplayer, int mode)
+{
+  pplayer->base.ym = -5;
 
-    if (mode == SHRINK && pplayer->size == BIG)
-      {
-        if (pplayer->got_coffee)
-          pplayer->got_coffee = NO;
+  play_sound(sounds[SND_HURT], SOUND_CENTER_SPEAKER);
 
-        pplayer->size = SMALL;
+  if (pplayer->dir == RIGHT)
+    pplayer->base.xm = -8;
+  else if (pplayer->dir == LEFT)
+    pplayer->base.xm = 8;
 
-        timer_start(&pplayer->safe_timer,TUX_SAFE_TIME);
-      }
-    else
-      {
-        pplayer->dying = 1;
-      }
-  }
+  if (mode == SHRINK && pplayer->size == BIG)
+    {
+      if (pplayer->got_coffee)
+        pplayer->got_coffee = NO;
 
-  void player_dying(player_type *pplayer)
-  {
-    pplayer->base.ym = pplayer->base.ym + GRAVITY;
+      pplayer->size = SMALL;
+      pplayer->base.height = 32;
+
+      timer_start(&pplayer->safe_timer,TUX_SAFE_TIME);
+    }
+  else
+    {
+      pplayer->dying = 1;
+    }
+}
 
-    /* He died :^( */
+void player_dying(player_type *pplayer)
+{
+  pplayer->base.ym = pplayer->base.ym + GRAVITY;
 
-    --pplayer->lives;
-    player_remove_powerups(pplayer);
-    pplayer->dying = NO;
+  /* He died :^( */
 
-    player_level_begin(pplayer);
+  --pplayer->lives;
+  player_remove_powerups(pplayer);
+  pplayer->dying = NO;
 
-  }
+  player_level_begin(pplayer);
 
-  /* Remove Tux's power ups */
-  void player_remove_powerups(player_type* pplayer)
-  {
-    pplayer->got_coffee = NO;
-    pplayer->size = SMALL;
-  }
+}
 
-  void player_keep_in_bounds(player_type* pplayer)
-  {
-    /* Keep tux in bounds: */
-    if (pplayer->base.x< 0)
-      pplayer->base.x= 0;
-    else if(pplayer->base.x< scroll_x)
-      pplayer->base.x= scroll_x;
-    else if (pplayer->base.x< 160 + scroll_x && scroll_x > 0 && debug_mode == YES)
-      {
-        scroll_x = pplayer->base.x- 160;
-        /*pplayer->base.x+= 160;*/
+/* Remove Tux's power ups */
+void player_remove_powerups(player_type* pplayer)
+{
+  pplayer->got_coffee = NO;
+  pplayer->size = SMALL;
+  pplayer->base.height = 32;
+}
 
-        if(scroll_x < 0)
-          scroll_x = 0;
+void player_keep_in_bounds(player_type* pplayer)
+{
+  /* Keep tux in bounds: */
+  if (pplayer->base.x< 0)
+    pplayer->base.x= 0;
+  else if(pplayer->base.x< scroll_x)
+    pplayer->base.x= scroll_x;
+  else if (pplayer->base.x< 160 + scroll_x && scroll_x > 0 && debug_mode == YES)
+    {
+      scroll_x = pplayer->base.x- 160;
+      /*pplayer->base.x+= 160;*/
 
-      }
-    else if (pplayer->base.x> screen->w / 2 + scroll_x && scroll_x < ((current_level.width * 32) - screen->w))
-      {
-        /* Scroll the screen in past center: */
+      if(scroll_x < 0)
+        scroll_x = 0;
 
-        scroll_x = pplayer->base.x- screen->w / 2;
-        /*pplayer->base.x= 320 + scroll_x;*/
+    }
+  else if (pplayer->base.x> screen->w / 2 + scroll_x && scroll_x < ((current_level.width * 32) - screen->w))
+    {
+      /* Scroll the screen in past center: */
 
-        if (scroll_x > ((current_level.width * 32) - screen->w))
-          scroll_x = ((current_level.width * 32) - screen->w);
-      }
-    else if (pplayer->base.x> 608 + scroll_x)
-      {
-        /* ... unless there's no more to scroll! */
+      scroll_x = pplayer->base.x- screen->w / 2;
+      /*pplayer->base.x= 320 + scroll_x;*/
 
-        /*pplayer->base.x= 608 + scroll_x;*/
-      }
+      if (scroll_x > ((current_level.width * 32) - screen->w))
+        scroll_x = ((current_level.width * 32) - screen->w);
+    }
+  else if (pplayer->base.x> 608 + scroll_x)
+    {
+      /* ... unless there's no more to scroll! */
 
-    /* Keep in-bounds, vertically: */
+      /*pplayer->base.x= 608 + scroll_x;*/
+    }
 
-    if (pplayer->base.y < 0)
-      pplayer->base.y = 0;
-    else if (pplayer->base.y > screen->h)
-      {
-        player_kill(&tux,KILL);
-      }
-  }
+  /* Keep in-bounds, vertically: */
+
+  if (pplayer->base.y < 0)
+    pplayer->base.y = 0;
+  else if (pplayer->base.y > screen->h)
+    {
+      player_kill(&tux,KILL);
+    }
+}
index 1b3dc55..27a9136 100644 (file)
@@ -69,7 +69,7 @@ typedef struct player_type
 }
 player_type;
 
-texture_type tux_life,
+extern texture_type tux_life,
  tux_right[3],  tux_left[3],
  bigtux_right[3],  bigtux_left[3],
  bigtux_right_jump,  bigtux_left_jump,
index 40dedc0..92c8c2d 100644 (file)
 #include <stdlib.h>
 #include "scene.h"
 
+int score, distros, level, next_level, game_pause, quit, score_multiplier, endpos, counting_distros, distro_counter;
+timer_type  super_bkgd_timer;
+float scroll_x;
+int frame;
+bouncy_distro_type *bouncy_distros;
+broken_brick_type *broken_bricks;
+bouncy_brick_type *bouncy_bricks;
+bad_guy_type *bad_guys;
+floating_score_type *floating_scores;
+upgrade_type *upgrades;
+bullet_type *bullets;
+int num_bad_guys;
+int num_bouncy_distros;
+int num_broken_bricks;
+int num_bouncy_bricks;
+int num_floating_scores;
+int num_upgrades;
+int num_bullets;
+player_type tux;
+texture_type img_box_full, img_box_empty, img_mints, img_coffee, img_super_bkgd, img_red_glow;
+timer_type time_left;
+double frame_ratio;
+
 /* Initialize all 'dynamic' arrays */
 void arrays_init(void)
 {
@@ -64,14 +87,14 @@ void set_defaults(void)
 
 /* Add score: */
 
-void add_score(int x, int y, int s)
+void add_score(float x, float y, int s)
 {
   int i, found;
 
 
   /* Add the score: */
 
-  score = score + s;
+  score += s;
 
 
   /* Add a floating score thing to the game: */
@@ -87,7 +110,7 @@ void add_score(int x, int y, int s)
   if (found == -1)
   {
   ++num_floating_scores;
-  floating_scores = realloc(floating_scores,num_floating_scores*sizeof(floating_score_type));
+  floating_scores = (floating_score_type*) realloc(floating_scores,num_floating_scores*sizeof(floating_score_type));
   floating_score_init(&floating_scores[num_floating_scores-1],x,y,s);
   found = -1;
   }
@@ -115,7 +138,7 @@ void add_bouncy_distro(float x, float y)
   if (found == -1)
   {
   ++num_bouncy_distros;
-  bouncy_distros = realloc(bouncy_distros,num_bouncy_distros*sizeof(bouncy_distro_type));
+  bouncy_distros = (bouncy_distro_type*) realloc(bouncy_distros,num_bouncy_distros*sizeof(bouncy_distro_type));
   found = num_bouncy_distros - 1;
   }
     
@@ -155,7 +178,7 @@ void add_broken_brick_piece(float x, float y, float xm, float ym)
   if (found == -1)
   {
   ++num_broken_bricks;
-  broken_bricks = realloc(broken_bricks,num_broken_bricks*sizeof(broken_brick_type));
+  broken_bricks = (broken_brick_type*) realloc(broken_bricks,num_broken_bricks*sizeof(broken_brick_type));
   found = num_broken_bricks - 1;
   }
 
@@ -183,7 +206,7 @@ void add_bouncy_brick(float x, float y)
   if (found == -1)
   {
   ++num_bouncy_bricks;
-  bouncy_bricks = realloc(bouncy_bricks,num_bouncy_bricks*sizeof(bouncy_brick_type));
+  bouncy_bricks = (bouncy_brick_type*) realloc(bouncy_bricks,num_bouncy_bricks*sizeof(bouncy_brick_type));
   found = num_bouncy_bricks - 1;
   }
 
@@ -211,7 +234,7 @@ void add_bad_guy(float x, float y, int kind)
   if (found == -1)
   {
   ++num_bad_guys;
-  bad_guys = realloc(bad_guys,num_bad_guys*sizeof(bad_guy_type));
+  bad_guys = (bad_guy_type*) realloc(bad_guys,num_bad_guys*sizeof(bad_guy_type));
   found = num_bad_guys - 1;
   }
 
@@ -238,7 +261,7 @@ void add_upgrade(float x, float y, int kind)
   if (found == -1)
   {
   ++num_upgrades;
-  upgrades = realloc(upgrades,num_upgrades*sizeof(upgrade_type));
+  upgrades = (upgrade_type*) realloc(upgrades,num_upgrades*sizeof(upgrade_type));
   found = num_upgrades - 1;
   }
 
@@ -265,7 +288,7 @@ void add_bullet(float x, float y, float xm, int dir)
   if (found == -1)
   {
   ++num_bullets;
-  bullets = realloc(bullets,num_bullets*sizeof(bullet_type));
+  bullets = (bullet_type*) realloc(bullets,num_bullets*sizeof(bullet_type));
   found = num_bullets - 1;
   }
 
index 4304007..52e7ce7 100644 (file)
 #include "level.h"
 
 #define FRAME_RATE 10 // 100 Frames per second (10ms)
-int score, distros, level, next_level, game_pause,
-done, quit, score_multiplier, endpos, counting_distros, distro_counter;
-timer_type  super_bkgd_timer;
-float scroll_x;
-int frame;
-bouncy_distro_type *bouncy_distros;
-broken_brick_type *broken_bricks;
-bouncy_brick_type *bouncy_bricks;
-bad_guy_type *bad_guys;
-floating_score_type *floating_scores;
-upgrade_type *upgrades;
-bullet_type *bullets;
-int num_bad_guys;
-int num_bouncy_distros;
-int num_broken_bricks;
-int num_bouncy_bricks;
-int num_floating_scores;
-int num_upgrades;
-int num_bullets;
-player_type tux;
-SDL_Rect src, dest;
-texture_type img_box_full, img_box_empty, img_mints, img_coffee, img_super_bkgd, img_red_glow;
-st_level current_level;
-unsigned int last_update_time;
-unsigned int update_time;
-timer_type time_left;
-double frame_ratio;
+extern int score, distros, level, next_level, game_pause, quit, score_multiplier, endpos, counting_distros, distro_counter;
+extern timer_type  super_bkgd_timer;
+extern float scroll_x;
+extern int frame;
+extern bouncy_distro_type *bouncy_distros;
+extern broken_brick_type *broken_bricks;
+extern bouncy_brick_type *bouncy_bricks;
+extern bad_guy_type *bad_guys;
+extern floating_score_type *floating_scores;
+extern upgrade_type *upgrades;
+extern bullet_type *bullets;
+extern int num_bad_guys;
+extern int num_bouncy_distros;
+extern int num_broken_bricks;
+extern int num_bouncy_bricks;
+extern int num_floating_scores;
+extern int num_upgrades;
+extern int num_bullets;
+extern player_type tux;
+extern texture_type img_box_full, img_box_empty, img_mints, img_coffee, img_super_bkgd, img_red_glow;
+extern timer_type time_left;
+extern double frame_ratio;
 
-void add_score(int x, int y, int s);
+void add_score(float x, float y, int s);
 void set_defaults(void);
 void arrays_init(void);
 void arrays_free(void);
index bbd2c60..349c1ab 100644 (file)
@@ -35,7 +35,7 @@
 void load_and_display_image(char * file)
 {
   SDL_Surface * img;
-  
+
   img = load_image(file, IGNORE_ALPHA);
   SDL_BlitSurface(img, NULL, screen, NULL);
   SDL_FreeSurface(img);
@@ -44,47 +44,79 @@ void load_and_display_image(char * file)
 
 /* --- CLEAR SCREEN --- */
 
-void clearscreen(float r, float g, float b)
+void clearscreen(int r, int g, int b)
 {
 #ifndef NOOPENGL
   if(use_gl)
-  {
-  glClearColor(r/256, g/256, b/256, 1.0);
-  glClear(GL_COLOR_BUFFER_BIT);
-  }
+    {
+      glClearColor(r/256, g/256, b/256, 1.0);
+      glClear(GL_COLOR_BUFFER_BIT);
+    }
   else
 #endif
-  SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, r, g, b));
+
+    SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, r, g, b));
+
 }
 
 /* --- FILL A RECT --- */
 
-void fillrect(float x, float y, float w, float h, float r, float g, float b)
+void fillrect(float x, float y, float w, float h, int r, int g, int b, int a)
 {
 #ifndef NOOPENGL
-if(use_gl)
-       {
-       glBegin(GL_QUADS);
-               glColor3ub(r, g, b);
-               glVertex2i(x, y);
-               glVertex2i(x+w, y);
-               glVertex2i(x+w, y+h);
-               glVertex2i(x, y+h);
-       glEnd();
-       }
-else
-       {
+  if(use_gl)
+    {
+      glEnable(GL_BLEND);
+      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+      glColor4ub(r, g, b,a);
+      
+      glBegin(GL_POLYGON);
+      glVertex2f(x, y);
+      glVertex2f(x+w, y);
+      glVertex2f(x+w, y+h);
+      glVertex2f(x, y+h);
+      glEnd();
+      glDisable(GL_BLEND);
+    }
+  else
+    {
 #endif
-       SDL_Rect rect;
-       rect.x = x;
-       rect.y = y;
-       rect.w = w;
-       rect.h = h;
-
-       SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, r, g, b));
+      SDL_Rect src, rect;
+      SDL_Surface *temp = NULL;
+      
+      rect.x = (int)x;
+      rect.y = (int)y;
+      rect.w = (int)w;
+      rect.h = (int)h;
+      
+      if(a != 255)
+      {
+      temp = SDL_CreateRGBSurface(screen->flags, rect.w, rect.h, screen->format->BitsPerPixel,
+                                  screen->format->Rmask,
+                              screen->format->Gmask,
+                              screen->format->Bmask,
+                              screen->format->Amask);
+
+
+      src.x = 0;
+      src.y = 0;
+      src.w = rect.w;
+      src.h = rect.h;
+
+      SDL_FillRect(temp, &src, SDL_MapRGB(screen->format, r, g, b));
+      
+      SDL_SetAlpha(temp, SDL_SRCALPHA, a);
+      
+      SDL_BlitSurface(temp,0,screen,&rect);
+      
+      SDL_FreeSurface(temp);
+      }
+      else
+      SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, r, g, b));
+      
 #ifndef NOOPENGL
-       }
+
+    }
 #endif
 }
 
@@ -94,44 +126,44 @@ else
 void updatescreen(void)
 {
   if(use_gl)  /*clearscreen(0,0,0);*/
-  SDL_GL_SwapBuffers();
+    SDL_GL_SwapBuffers();
   else
     SDL_UpdateRect(screen, 0, 0, screen->w, screen->h);
 }
 
 void flipscreen(void)
 {
-if(use_gl)
-SDL_GL_SwapBuffers();
-else
-SDL_Flip(screen);
+  if(use_gl)
+    SDL_GL_SwapBuffers();
+  else
+    SDL_Flip(screen);
 }
 
 /* --- LOAD AN IMAGE --- */
 
 SDL_Surface * load_image(char * file, int use_alpha)
 {
-/*
-if(!faccessible(file))
-{
-if(!faccessible(st_dir,
-*/
+  /*
+  if(!faccessible(file))
+  {
+  if(!faccessible(st_dir,
+  */
 
   SDL_Surface * temp, * surf;
-  
+
   temp = IMG_Load(file);
 
   if (temp == NULL)
     st_abort("Can't load", file);
-    
+
   surf = SDL_DisplayFormatAlpha(temp);
 
   if (surf == NULL)
     st_abort("Can't covert to display format", file);
-    
+
   if (use_alpha == IGNORE_ALPHA)
     SDL_SetAlpha(surf, 0, 0);
-  
+
   SDL_FreeSurface(temp);
 
   return(surf);
@@ -139,8 +171,8 @@ if(!faccessible(st_dir,
 
 void update_rect(SDL_Surface *scr, Sint32 x, Sint32 y, Sint32 w, Sint32 h)
 {
-if(!use_gl)
-SDL_UpdateRect(scr, x, y, w, h);
+  if(!use_gl)
+    SDL_UpdateRect(scr, x, y, w, h);
 }
 
 
@@ -149,18 +181,18 @@ SDL_UpdateRect(scr, x, y, w, h);
 void erasetext(char * text, int x, int y, texture_type * ptexture, int update, int shadowsize)
 {
   SDL_Rect dest;
-  
-  
+
+
   dest.x = x;
   dest.y = y;
   dest.w = strlen(text) * 16 + shadowsize;
   dest.h = 17;
-  
+
   if (dest.w > screen->w)
     dest.w = screen->w;
-  
+
   texture_draw_part(ptexture,dest.x,dest.y,dest.x,dest.y,dest.w,dest.h,update);
-  
+
   if (update == UPDATE)
     update_rect(screen, dest.x, dest.y, dest.w, dest.h);
 }
index 7eb8bf8..bab496a 100644 (file)
@@ -25,8 +25,8 @@
 #define IGNORE_ALPHA 1
 
 void load_and_display_image(char * file);
-void clearscreen(float r, float g, float b);
-void fillrect(float x, float y, float w, float h, float r, float g, float b);
+void clearscreen(int r, int g, int b);
+void fillrect(float x, float y, float w, float h, int r, int g, int b, int a);
 void updatescreen(void);
 void flipscreen(void);
 SDL_Surface * load_image(char * file, int use_alpha);
index d7b67f6..91b2189 100644 (file)
@@ -23,8 +23,9 @@
 
 #ifdef LINUX
 #include <pwd.h>
-#include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
 #include <ctype.h>
 #endif
 
@@ -33,6 +34,7 @@
 #include "setup.h"
 #include "screen.h"
 #include "texture.h"
+#include "menu.h"
 
 /* Local function prototypes: */
 
@@ -49,17 +51,126 @@ int faccessible(char *filename)
     return YES;
 }
 
+/* Can we write to this location? */
+int fwriteable(char *filename)
+{
+  FILE* fi;
+  fi = fopen(filename, "wa");
+  if (fi == NULL)
+    {
+      return NO;
+    }
+  return YES;
+}
 
-/* --- SETUP --- */
+/* Makes sure a directory is created in either the SuperTux base directory or the SuperTux base directory.*/
+int fcreatedir(char* relative_dir)
+{
+  char path[1024];
+  snprintf(path, 1024, "%s/%s/", st_dir, relative_dir);
+  if(mkdir(path,0755) != 0)
+    {
+      snprintf(path, 1024, "%s/%s/", DATA_PREFIX, relative_dir);
+      if(mkdir(path,0755) != 0)
+        {
+          return NO;
+        }
+      else
+        {
+          return YES;
+        }
+    }
+  else
+    {
+      return YES;
+    }
+}
 
-void st_directory_setup(void)
+/* Get all names of sub-directories in a certain directory. */
+/* Returns the number of sub-directories found. */
+/* Note: The user has to free the allocated space. */
+char ** dsubdirs(char *rel_path, char* expected_file, int* num)
 {
+  DIR *dirStructP;
+  struct dirent *direntp;
+  int i = 0;
+  char ** sdirs= NULL;
+  char filename[100];
+  char path[1024];
+
+  sprintf(path,"%s/%s",st_dir,rel_path);
+  if((dirStructP = opendir(path)) != NULL)
+    {
+      while((direntp = readdir(dirStructP)) != NULL)
+        {
+          if ( direntp->d_type == DT_DIR )
+            {
+              if(expected_file != NULL)
+                {
+                  sprintf(filename,"%s/%s/%s",path,direntp->d_name,expected_file);
+                  if(!faccessible(filename))
+                    continue;
+                }
 
-  /* Set SuperTux configuration and save directories */
+              sdirs = (char**) realloc(sdirs, sizeof(char*) * (i+1));
+              sdirs[i] = (char*) malloc(sizeof(char) * strlen(direntp->d_name) + 1 );
+              strcpy(sdirs[i],direntp->d_name);
+              ++i;
+            }
+        }
+      closedir(dirStructP);
+    }
 
+  sprintf(path,"%s/%s",DATA_PREFIX,rel_path);
+  if((dirStructP = opendir(path)) != NULL)
+    {
+      while((direntp = readdir(dirStructP)) != NULL)
+        {
+          if ( direntp->d_type == DT_DIR )
+            {
+              if(expected_file != NULL)
+                {
+                  sprintf(filename,"%s/%s/%s",path,direntp->d_name,expected_file);
+                  if(!faccessible(filename))
+                    {
+                      continue;
+                    }
+                  else
+                    {
+                      sprintf(filename,"%s/%s/%s/%s",st_dir,rel_path,direntp->d_name,expected_file);
+                      if(faccessible(filename))
+                        continue;
+                    }
+                }
+
+              sdirs = (char**) realloc(sdirs, sizeof(char*) * (i+1));
+              sdirs[i] = (char*) malloc(sizeof(char) * strlen(direntp->d_name) + 1 );
+              strcpy(sdirs[i],direntp->d_name);
+              ++i;
+            }
+        }
+      closedir(dirStructP);
+    }
+
+  *num = i;
+  return sdirs;
+}
+
+void free_strings(char **strings, int num)
+{
+int i;
+for(i=0; i < num; ++i)
+free(strings[i]);
+}
+
+/* --- SETUP --- */
+/* Set SuperTux configuration and save directories */
+void st_directory_setup(void)
+{
+  char *home;
+  char str[1024];
   /* Get home directory (from $HOME variable)... if we can't determine it,
      use the current directory ("."): */
-  char *home;
   if (getenv("HOME") != NULL)
     home = getenv("HOME");
   else
@@ -75,18 +186,113 @@ void st_directory_setup(void)
   strcpy(st_save_dir,st_dir);
   strcat(st_save_dir,"/save");
 
-  /* Create them. In the case they exist it won't destroy anything. */
+  /* Create them. In the case they exist they won't destroy anything. */
 #ifdef LINUX
 
   mkdir(st_dir, 0755);
   mkdir(st_save_dir, 0755);
+
+  sprintf(str, "%s/levels", st_dir);
+  mkdir(str, 0755);
 #else
   #ifdef WIN32
 
   mkdir(st_dir);
   mkdir(st_save_dir);
+  sprintf(str, "%s/levels", st_dir);
+  mkdir(str);
 #endif
 #endif
+
+}
+
+/* Create and setup menus. */
+void st_menu(void)
+{
+
+  menu_init(&main_menu);
+  menu_additem(&main_menu,menu_item_create(MN_ACTION,"Start Game",0,0));
+  menu_additem(&main_menu,menu_item_create(MN_ACTION,"Load Game",0,0));
+  menu_additem(&main_menu,menu_item_create(MN_GOTO,"Options",0,&options_menu));
+  menu_additem(&main_menu,menu_item_create(MN_ACTION,"Level editor",0,0));
+  menu_additem(&main_menu,menu_item_create(MN_ACTION,"Quit",0,0));
+
+  menu_init(&options_menu);
+  menu_additem(&options_menu,menu_item_create(MN_TOGGLE,"Fullscreen",use_fullscreen,0));
+  if(audio_device == YES)
+    {
+      menu_additem(&options_menu,menu_item_create(MN_TOGGLE,"Sound",use_sound,0));
+      menu_additem(&options_menu,menu_item_create(MN_TOGGLE,"Music",use_music,0));
+    }
+  else
+    {
+      menu_additem(&options_menu,menu_item_create(MN_DEACTIVE,"Sound",use_sound,0));
+      menu_additem(&options_menu,menu_item_create(MN_DEACTIVE,"Music",use_music,0));
+    }
+  menu_additem(&options_menu,menu_item_create(MN_TOGGLE,"Show FPS",show_fps,0));
+  menu_additem(&options_menu,menu_item_create(MN_BACK,"Back",0,0));
+
+  menu_init(&leveleditor_menu);
+  menu_additem(&leveleditor_menu,menu_item_create(MN_ACTION,"Return To Level Editor",0,0));
+  menu_additem(&leveleditor_menu,menu_item_create(MN_ACTION,"New Level",0,0));
+  menu_additem(&leveleditor_menu,menu_item_create(MN_ACTION,"Load Level",0,0));
+  menu_additem(&leveleditor_menu,menu_item_create(MN_ACTION,"Save Level",0,0));
+  menu_additem(&leveleditor_menu,menu_item_create(MN_ACTION,"Quit Level Editor",0,0));
+
+  menu_init(&game_menu);
+  menu_additem(&game_menu,menu_item_create(MN_ACTION,"Return To Game",0,0));
+  menu_additem(&game_menu,menu_item_create(MN_ACTION,"Save Game",0,0));
+  menu_additem(&game_menu,menu_item_create(MN_ACTION,"Load Game",0,0));
+  menu_additem(&game_menu,menu_item_create(MN_GOTO,"Options",0,&options_menu));
+  menu_additem(&game_menu,menu_item_create(MN_ACTION,"Quit Game",0,0));
+
+  menu_init(&highscore_menu);
+  menu_additem(&highscore_menu,menu_item_create(MN_TEXTFIELD,"Enter your name:",0,0));
+
+}
+
+/* Handle changes made to global settings in the options menu. */
+void process_options_menu(void)
+{
+  switch (menu_check(&options_menu))
+    {
+    case 0:
+      if(use_fullscreen != options_menu.item[0].toggled)
+        {
+          use_fullscreen = !use_fullscreen;
+          st_video_setup();
+        }
+      break;
+    case 1:
+      if(use_sound != options_menu.item[1].toggled)
+        use_sound = !use_sound;
+      break;
+    case 2:
+      if(use_music != options_menu.item[2].toggled)
+        {
+          if(use_music == YES)
+            {
+              if(playing_music())
+                {
+                  halt_music();
+                }
+              use_music = NO;
+            }
+          else
+            {
+              use_music = YES;
+              if (!playing_music())
+                {
+                  play_current_music();
+                }
+            }
+        }
+      break;
+    case 3:
+      if(show_fps != options_menu.item[3].toggled)
+        show_fps = !show_fps;
+      break;
+    }
 }
 
 void st_general_setup(void)
@@ -96,12 +302,19 @@ void st_general_setup(void)
   srand(SDL_GetTicks());
 
   /* Load global images: */
-          
- text_load(&black_text,DATA_PREFIX "/images/status/letters-black.png");
- text_load(&gold_text,DATA_PREFIX "/images/status/letters-gold.png");
- text_load(&blue_text,DATA_PREFIX "/images/status/letters-blue.png");
- text_load(&red_text,DATA_PREFIX "/images/status/letters-red.png");
+
+  text_load(&black_text,DATA_PREFIX "/images/status/letters-black.png", TEXT_TEXT, 16,18);
+  text_load(&gold_text,DATA_PREFIX "/images/status/letters-gold.png", TEXT_TEXT, 16,18);
+  text_load(&blue_text,DATA_PREFIX "/images/status/letters-blue.png", TEXT_TEXT, 16,18);
+  text_load(&red_text,DATA_PREFIX "/images/status/letters-red.png", TEXT_TEXT, 16,18);
+  text_load(&white_text,DATA_PREFIX "/images/status/letters-white.png", TEXT_TEXT, 16,18);
+  text_load(&white_small_text,DATA_PREFIX "/images/status/letters-white-small.png", TEXT_TEXT, 8,9);
+  text_load(&yellow_nums,DATA_PREFIX "/images/status/numbers.png", TEXT_NUM, 32,32);
+
+  /* Load GUI/menu images: */
+  texture_load(&checkbox, DATA_PREFIX "/images/status/checkbox.png", USE_ALPHA);
+  texture_load(&checkbox_checked, DATA_PREFIX "/images/status/checkbox-checked.png", USE_ALPHA);
+
   /* Set icon image: */
 
   seticon();
@@ -109,11 +322,37 @@ void st_general_setup(void)
 
 }
 
+void st_general_free(void)
+{
+
+  /* Free global images: */
+
+  text_free(&black_text);
+  text_free(&gold_text);
+  text_free(&white_text);
+  text_free(&blue_text);
+  text_free(&red_text);
+  text_free(&white_small_text); 
+  
+  /* Free GUI/menu images: */
+  texture_free(&checkbox);
+  texture_free(&checkbox_checked);
+
+  /* Free menus */
+
+  menu_free(&main_menu);
+  menu_free(&game_menu);
+  menu_free(&options_menu);
+  menu_free(&leveleditor_menu);
+  menu_free(&highscore_menu);
+
+}
+
 void st_video_setup(void)
 {
 
-if(screen != NULL)
-   SDL_FreeSurface(screen); 
+  if(screen != NULL)
+    SDL_FreeSurface(screen);
 
   /* Init SDL Video: */
 
@@ -129,12 +368,12 @@ if(screen != NULL)
   /* Open display: */
 
   if(use_gl)
-  st_video_setup_gl();
+    st_video_setup_gl();
   else
-  st_video_setup_sdl();
-  
+    st_video_setup_sdl();
+
   texture_setup();
-    
+
   /* Set window manager stuff: */
 
   SDL_WM_SetCaption("Super Tux", "Super Tux");
@@ -143,6 +382,8 @@ if(screen != NULL)
 
 void st_video_setup_sdl(void)
 {
+  SDL_FreeSurface(screen);
+
   if (use_fullscreen == YES)
     {
       screen = SDL_SetVideoMode(640, 480, 16, SDL_FULLSCREEN ) ; /* | SDL_HWSURFACE); */
@@ -156,7 +397,7 @@ void st_video_setup_sdl(void)
           use_fullscreen = NO;
         }
     }
-    else
+  else
     {
       screen = SDL_SetVideoMode(640, 480, 16, SDL_HWSURFACE | SDL_DOUBLEBUF );
 
@@ -175,15 +416,15 @@ void st_video_setup_gl(void)
 {
 #ifndef NOOPENGL
 
-       SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
-       SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
-       SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
-       SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
-       SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+  SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
+  SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
+  SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
+  SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
+  SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
 
   if (use_fullscreen == YES)
     {
-      screen = SDL_SetVideoMode(640, 480, 32, SDL_FULLSCREEN | SDL_OPENGL ) ; /* | SDL_HWSURFACE); */
+      screen = SDL_SetVideoMode(640, 480, 32, SDL_FULLSCREEN | SDL_OPENGL | SDL_OPENGLBLIT ) ; /* | SDL_HWSURFACE); */
       if (screen == NULL)
         {
           fprintf(stderr,
@@ -194,7 +435,7 @@ void st_video_setup_gl(void)
           use_fullscreen = NO;
         }
     }
-    else
+  else
     {
       screen = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE | SDL_OPENGL | SDL_OPENGLBLIT  );
 
@@ -207,23 +448,24 @@ void st_video_setup_gl(void)
           exit(1);
         }
     }
-       
-       /*
-        * Set up OpenGL for 2D rendering.
-        */
-       glDisable(GL_DEPTH_TEST);
-       glDisable(GL_CULL_FACE);
-
-       glViewport(0, 0, screen->w, screen->h);
-       glMatrixMode(GL_PROJECTION);
-       glLoadIdentity();
-       glOrtho(0, screen->w, screen->h, 0, -1.0, 1.0);
-
-       glMatrixMode(GL_MODELVIEW);
-       glLoadIdentity();
-       glTranslatef(0.0f, 0.0f, 0.0f);
-       
+
+  /*
+   * Set up OpenGL for 2D rendering.
+   */
+  glDisable(GL_DEPTH_TEST);
+  glDisable(GL_CULL_FACE);
+
+  glViewport(0, 0, screen->w, screen->h);
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  glOrtho(0, screen->w, screen->h, 0, -1.0, 1.0);
+
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();
+  glTranslatef(0.0f, 0.0f, 0.0f);
+
 #endif
+
 }
 
 void st_joystick_setup(void)
@@ -393,7 +635,7 @@ void seticon(void)
   /* Create mask: */
 
   masklen = (((icon -> w) + 7) / 8) * (icon -> h);
-  mask = malloc(masklen * sizeof(Uint8));
+  mask = (Uint8*) malloc(masklen * sizeof(Uint8));
   memset(mask, 0xFF, masklen);
 
 
@@ -421,7 +663,7 @@ void parseargs(int argc, char * argv[])
   debug_mode = NO;
   use_fullscreen = NO;
   show_fps = NO;
-  use_gl = NO;    
+  use_gl = NO;
 
 #ifndef NOSOUND
 
@@ -453,13 +695,14 @@ void parseargs(int argc, char * argv[])
           show_fps = YES;
         }
       else if (strcmp(argv[i], "--opengl") == 0 ||
-          strcmp(argv[i], "-gl") == 0)
+               strcmp(argv[i], "-gl") == 0)
         {
-       #ifndef NOOPENGL
+#ifndef NOOPENGL
           /* Use OpengGL: */
 
           use_gl = YES;
-       #endif
+#endif
+
         }
       else if (strcmp(argv[i], "--usage") == 0)
         {
@@ -512,7 +755,7 @@ void parseargs(int argc, char * argv[])
           printf("----------  Command-line options  ----------\n\n");
 
           printf("  --opengl            - If opengl support was compiled in, this will enable the EXPERIMENTAL OpenGL mode.\n\n");
-         
+
           printf("  --disable-sound     - If sound support was compiled in,  this will\n                        disable sound for this session of the game.\n\n");
 
           printf("  --disable-music     - Like above, but this will disable music.\n\n");
index db406ad..fdd5c6b 100644 (file)
         #include "sound.h"
 
        int faccessible(char *filename);
-        void st_directory_setup(void);
+       int fcreatedir(char* relative_dir);
+       int fwriteable(char *filename);
+       char ** dsubdirs(char *rel_path, char* expected_file, int* num);
+       void free_strings(char **strings, int num);
+       void st_directory_setup(void);
         void st_general_setup(void);
         void st_video_setup_sdl(void);
         void st_video_setup_gl(void);
@@ -24,7 +28,9 @@
        void st_audio_setup(void);
         void st_joystick_setup(void);
         void st_shutdown(void);
+       void st_menu(void);
         void st_abort(char * reason, char * details);
+       void process_options_menu(void);
         void parseargs(int argc, char * argv[]);
 #endif
 
index 8750dcd..a7b4241 100644 (file)
   April 22, 2000 - December 28, 2003
 */
 
-/* why do we need this ?
-#ifdef LINUX
-#include <pwd.h>
-#include <sys/types.h>
-#include <ctype.h>
-#endif
-*/
-
 #include "defines.h"
 #include "globals.h"
 #include "sound.h"
 #include "setup.h"
 
+/*global variable*/
+int use_sound;           /* handle sound on/off menu and command-line option */
+int use_music;           /* handle music on/off menu and command-line option */
+int audio_device;        /* != 0: available and initialized */
+int current_music;
+
 char * soundfilenames[NUM_SOUNDS] = {
                                       DATA_PREFIX "/sounds/jump.wav",
                                       DATA_PREFIX "/sounds/bigjump.wav",
@@ -49,6 +47,9 @@ char * soundfilenames[NUM_SOUNDS] = {
 
 #include <SDL_mixer.h>
 
+Mix_Chunk * sounds[NUM_SOUNDS];
+Mix_Music * level_song, * level_song_fast, * herring_song;
+
 /* --- OPEN THE AUDIO DEVICE --- */
 
 int open_audio (int frequency, Uint16 format, int channels, int chunksize)
@@ -228,6 +229,9 @@ void play_current_music(void)
 
 #else
 
+void* sounds[NUM_SOUNDS];
+void* level_song, *herring_song;
+
 int open_audio (int frequency, int format, int channels, int chunksize)
 {
   return -1;
index 600d217..6373313 100644 (file)
@@ -22,9 +22,9 @@
 #define SOUND_RESERVED_CHANNELS 2
 
 /*global variable*/
-int use_sound;           /* handle sound on/off menu and command-line option */
-int use_music;           /* handle music on/off menu and command-line option */
-int audio_device;        /* != 0: available and initialized */
+extern int use_sound;           /* handle sound on/off menu and command-line option */
+extern int use_music;           /* handle music on/off menu and command-line option */
+extern int audio_device;        /* != 0: available and initialized */
 
 /* enum of different internal music types */
 enum Music_Type {
@@ -32,7 +32,9 @@ enum Music_Type {
   LEVEL_MUSIC,
   HURRYUP_MUSIC,
   HERRING_MUSIC
-} current_music;
+};
+
+extern int current_music;
 
 /* panning effects: terrible :-) ! */
 enum Sound_Speaker {
@@ -69,8 +71,8 @@ enum {
 #include <SDL_mixer.h>
 
 /* variables for stocking the sound and music */
-Mix_Chunk * sounds[NUM_SOUNDS];
-Mix_Music * level_song, * level_song_fast, * herring_song;
+extern Mix_Chunk * sounds[NUM_SOUNDS];
+extern Mix_Music * level_song, * level_song_fast, * herring_song;
 
 /* functions handling the sound and music */
 int open_audio(int frequency, Uint16 format, int channels, int chunksize);
@@ -91,8 +93,8 @@ void play_current_music(void);
 #else
 
 /* fake variables */
-void* sounds[NUM_SOUNDS];
-void* level_song, *herring_song;
+extern void* sounds[NUM_SOUNDS];
+extern void* level_song, *herring_song;
 
 /* fake sound handlers */
 int open_audio (int frequency, int format, int channels, int chunksize);
index ea6f6fc..181c044 100644 (file)
 #include "globals.h"
 #include "player.h"
 
+texture_type img_bullet;
+texture_type img_golden_herring;
+bitmask* bm_bullet;
+
 void create_special_bitmasks()
 {
   bm_bullet = bitmask_create_SDL(img_bullet.sdl_surface);
@@ -133,8 +137,8 @@ void upgrade_action(upgrade_type *pupgrade)
               pupgrade->base.x = pupgrade->base.x + pupgrade->base.xm * frame_ratio;
               pupgrade->base.y = pupgrade->base.y + pupgrade->base.ym * frame_ratio;
 
-              if (issolid(pupgrade->base.x, pupgrade->base.y + 31) ||
-                  issolid(pupgrade->base.x + 31, pupgrade->base.y + 31))
+              if (issolid(pupgrade->base.x, pupgrade->base.y + 31.) ||
+                  issolid(pupgrade->base.x + 31., pupgrade->base.y + 31.))
                 {
                   if (pupgrade->base.ym > 0)
                     {
@@ -153,10 +157,16 @@ void upgrade_action(upgrade_type *pupgrade)
               else
                 pupgrade->base.ym = pupgrade->base.ym + GRAVITY;
 
-              if (issolid(pupgrade->base.x, pupgrade->base.y))
-                {
-                  pupgrade->base.xm = -pupgrade->base.xm;
-                }
+                 if (issolid(pupgrade->base.x - 1, (int) pupgrade->base.y))
+                    {
+                     if(pupgrade->base.xm < 0)
+                      pupgrade->base.xm = -pupgrade->base.xm;
+                    }
+                   else if (issolid(pupgrade->base.x + pupgrade->base.width-1, (int) pupgrade->base.y))
+                   {
+                     if(pupgrade->base.xm > 0)
+                      pupgrade->base.xm = -pupgrade->base.xm;
+                   }
             }
 
 
@@ -171,16 +181,17 @@ void upgrade_action(upgrade_type *pupgrade)
 
 void upgrade_draw(upgrade_type* pupgrade)
 {
+SDL_Rect dest;
   if (pupgrade->base.alive)
     {
       if (pupgrade->base.height < 32)
         {
           /* Rising up... */
 
-          dest.x = pupgrade->base.x - scroll_x;
-          dest.y = pupgrade->base.y + 32 - pupgrade->base.height;
+          dest.x = (int)(pupgrade->base.x - scroll_x);
+          dest.y = (int)(pupgrade->base.y + 32 - pupgrade->base.height);
           dest.w = 32;
-          dest.h = pupgrade->base.height;
+          dest.h = (int)pupgrade->base.height;
 
           if (pupgrade->kind == UPGRADE_MINTS)
            texture_draw_part(&img_mints,0,0,dest.x,dest.y,dest.w,dest.h,NO_UPDATE);
@@ -223,7 +234,7 @@ void upgrade_collision(upgrade_type* pupgrade, void* p_c_object, int c_object)
       /* Remove the upgrade: */
 
       /* p_c_object is CO_PLAYER, so assign it to pplayer */
-      pplayer = p_c_object;
+      pplayer = (player_type*) p_c_object;
 
       pupgrade->base.alive = NO;
 
@@ -233,6 +244,7 @@ void upgrade_collision(upgrade_type* pupgrade, void* p_c_object, int c_object)
         {
           play_sound(sounds[SND_EXCELLENT], SOUND_CENTER_SPEAKER);
           pplayer->size = BIG;
+         pplayer->base.height = 64;
           timer_start(&super_bkgd_timer, 350);
         }
       else if (pupgrade->kind == UPGRADE_COFFEE)
index dfd9b1d..7190428 100644 (file)
@@ -36,12 +36,12 @@ typedef struct bullet_type
   }
 bullet_type;
 
-texture_type img_bullet;
-bitmask* bm_bullet;
+extern texture_type img_bullet;
+extern bitmask* bm_bullet;
 
 void create_special_bitmasks();
 
-texture_type img_golden_herring;
+extern texture_type img_golden_herring;
 
 void upgrade_init(upgrade_type *pupgrade, float x, float y, int kind);
 void upgrade_action(upgrade_type *pupgrade);
index ad86fd6..9561911 100644 (file)
@@ -31,6 +31,7 @@ int main(int argc, char * argv[])
   st_video_setup();
   st_joystick_setup();
   st_general_setup();
+  st_menu();
     
   done = intro();
   
@@ -39,13 +40,6 @@ int main(int argc, char * argv[])
   while (!done)
     {
       done = title();
-      if (!done)
-      {
-      if(game_started)
-       done = gameloop();
-      else if(level_editor_started)
-        done = leveleditor(1);
-      }
     }
   
   clearscreen(0, 0, 0);
index 44cba5e..e0dc998 100644 (file)
@@ -1,5 +1,5 @@
-#if !defined( SUPERTUX_SUPERTUX_H )
-#define SUPERTUX_SUPERTUX_H 1
+#ifndef SUPERTUX_SUPERTUX_H
+#define SUPERTUX_SUPERTUX_H
         #ifdef LINUX
         #include <pwd.h>
         #include <sys/types.h>
@@ -14,4 +14,4 @@
         #include "gameloop.h"
        #include "leveleditor.h"
         #include "screen.h"
-#endif
+#endif /*SUPERTUX_SUPERTUX_H*/
index 0e2b845..81295cf 100644 (file)
 //
 //
 
+#include <stdlib.h>
 #include <string.h>
 #include "globals.h"
 #include "defines.h"
 #include "screen.h"
 #include "text.h"
 
-void text_load(text_type* ptext, char* file)
+void text_load(text_type* ptext, char* file, int kind, int w, int h)
 {
-  int x, y, c;
+  int x, y;
+  int mx, my;
+  SDL_Surface *conv;
 
-  c = 0;
+  if(kind == TEXT_TEXT)
+    {
+      ptext->chars = (texture_type*) malloc(sizeof(texture_type) * 79);
+      ptext->shadow_chars = (texture_type*) malloc(sizeof(texture_type) * 79);
+      mx = 26;
+      my = 3;
+    }
+  else if(kind == TEXT_NUM)
+    {
+      ptext->chars = (texture_type*) malloc(sizeof(texture_type) * 10);
+      ptext->shadow_chars = (texture_type*) malloc(sizeof(texture_type) * 10);
+      mx = 10;
+      my = 1;
+    }
+  else
+    {
+      ptext->chars = NULL;
+      ptext->shadow_chars = NULL;
+      mx = 0;
+      my = 0;
+    }
+  ptext->kind = kind;
+  ptext->w = w;
+  ptext->h = h;
 
-  for(y = 0; y < 3 ; ++y)
+  for(y = 0; y < my ; ++y)
     {
-      for(x = 0; x < 26 ; ++x)
+      for(x = 0; x < mx ; ++x)
         {
-          texture_load_part(&ptext->chars[c],file,x*16,y*16,16,16, USE_ALPHA);
-          ++c;
+          texture_load_part(&ptext->chars[y*mx+x],file,x*w,y*h,w,h, USE_ALPHA);
         }
     }
+
+  /* Load shadow font. */
+  for(y = 0; y < my ; ++y)
+    {
+      for(x = 0; x < mx ; ++x)
+        {
+         int pixels;
+          int i;
+          conv = SDL_DisplayFormatAlpha(ptext->chars[y*mx+x].sdl_surface);
+         pixels = conv->w * conv->h;
+         SDL_LockSurface(conv);
+          for(i = 0; i < pixels; ++i)
+            {
+              Uint32 *p = (Uint32 *)conv->pixels + i;
+             *p = *p & conv->format->Amask;
+            }
+           SDL_UnlockSurface(conv);
+          SDL_SetAlpha(conv, SDL_SRCALPHA, 128);
+          texture_from_sdl_surface(&ptext->shadow_chars[y*mx+x],conv,USE_ALPHA);
+        }
+    }
+
 }
 
 void text_draw(text_type* ptext, char* text, int x, int y, int shadowsize, int update)
 {
-  int len;
-  int i;
+  if(text != NULL)
+    {
+      if(shadowsize != 0)
+        text_draw_chars(ptext,&ptext->shadow_chars[0], text,x+shadowsize,y+shadowsize, update);
+
+      text_draw_chars(ptext,ptext->chars, text,x,y, update);
+    }
+}
 
-if(shadowsize != 0)
-text_draw(&black_text,text,x+shadowsize,y+shadowsize, 0, update);
+void text_draw_chars(text_type* ptext, texture_type* pchars, char* text, int x, int y, int update)
+{
+  int i,len;
 
   len = strlen(text);
 
-  for( i = 0; i < len; ++i)
+  if(ptext->kind == TEXT_TEXT)
+    {
+      for( i = 0; i < len; ++i)
+        {
+          if( text[i] >= 'A' && text[i] <= 'Z')
+            {
+              texture_draw(&pchars[(int)(text[i] - 'A')],x+i*ptext->w,y,update);
+            }
+          else if( text[i] >= 'a' && text[i] <= 'z')
+            {
+              texture_draw(&pchars[(int)(text[i] - 'a') + 26],x+i*ptext->w,y,update);
+            }
+          else if ( text[i] >= '!' && text[i] <= '9')
+            {
+              texture_draw(&pchars[(int)(text[i] - '!') + 52],x+i*ptext->w,y,update);
+            }
+          else if ( text[i] == '?')
+            {
+              texture_draw(&pchars[77],x+i*ptext->w,y,update);
+            }
+          else if ( text[i] == '\n')
+            {
+              y += ptext->h + 2;
+            }
+        }
+    }
+  else if(ptext->kind == TEXT_NUM)
     {
-      if( text[i] >= 'A' && text[i] <= 'Z')
-      {
-        texture_draw(&ptext->chars[(int)(text[i] - 'A')],x+i*16,y,update);
-       }
-      else if( text[i] >= 'a' && text[i] <= 'z')
-      {
-        texture_draw(&ptext->chars[(int)(text[i] - 'a') + 26],x+i*16,y,update);
-       }
-      else if ( text[i] >= '!' && text[i] <= '9')
-       {
-       texture_draw(&ptext->chars[(int)(text[i] - '!') + 52],x+i*16,y,update);
-       }
-      else if ( text[i] == '?')
-       {
-       texture_draw(&ptext->chars[77],x+i*16,y,update);
-       }
-      else if ( text[i] == '\n')
-       {
-       y += 18;
-       }
+      for( i = 0; i < len; ++i)
+        {
+          if ( text[i] >= '0' && text[i] <= '9')
+            {
+              texture_draw(&pchars[(int)(text[i] - '0')],x+i*ptext->w,y,update);
+            }
+          else if ( text[i] == '\n')
+            {
+              y += ptext->h + 2;
+            }
+        }
     }
 }
 
 void text_drawf(text_type* ptext, char* text, int x, int y, int halign, int valign, int shadowsize, int update)
 {
-if(halign == A_RIGHT)
-x += screen->w;
-else if(halign == A_HMIDDLE)
-x += screen->w/2 - ((strlen(text)*16)/2);
-
-if(valign == A_BOTTOM)
-y += screen->h - 16;
-else if(valign == A_VMIDDLE)
-y += screen->h/2;
+  if(text != NULL)
+    {
+      if(halign == A_RIGHT)
+        x += screen->w;
+      else if(halign == A_HMIDDLE)
+        x += screen->w/2 - ((strlen(text)*ptext->w)/2);
 
-text_draw(ptext,text,x,y,shadowsize,update);
+      if(valign == A_BOTTOM)
+        y += screen->h - ptext->h;
+      else if(valign == A_VMIDDLE)
+        y += screen->h/2 - ptext->h/2;
 
+      text_draw(ptext,text,x,y,shadowsize,update);
+    }
 }
 
 void text_free(text_type* ptext)
 {
   int c;
-  for( c = 0; c < 78; ++c)
-    texture_free(&ptext->chars[c]);
+  if(ptext->kind == TEXT_TEXT)
+    {
+      for( c = 0; c < 78; ++c)
+        texture_free(&ptext->chars[c]);
+    }
+  else if(ptext->kind == TEXT_NUM)
+    {
+      for( c = 0; c < 10; ++c)
+        texture_free(&ptext->chars[c]);
+    }
 }
index a395f11..f04ada2 100644 (file)
 /* Text type */
 typedef struct text_type
   {
-   texture_type chars[78];
+   texture_type* chars;
+   texture_type* shadow_chars;
+   int kind;
+   int w;
+   int h;
   }  
 text_type;
 
+/* Kinds of texts. */
+enum {
+   TEXT_TEXT,
+   TEXT_NUM
+};
+
 enum {
    A_LEFT,
    A_HMIDDLE,
@@ -32,8 +42,9 @@ enum {
    A_NONE
 };
 
-void text_load(text_type* ptext, char* file);
+void text_load(text_type* ptext, char* file, int kind, int w, int h);
 void text_draw(text_type* ptext, char* text, int x, int y, int shadowsize, int update);
+void text_draw_chars(text_type* ptext, texture_type* pchars, char* text, int x, int y, int update);
 void text_drawf(text_type* ptext, char* text, int x, int y, int halign, int valign, int shadowsize, int update);
 void text_free(text_type* ptext);
 
index 303e7d8..803c5b3 100644 (file)
 #include "setup.h"
 #include "texture.h"
 
+void (*texture_load) (texture_type* ptexture, char * file, int use_alpha);
+void (*texture_load_part) (texture_type* ptexture, char * file, int x, int y, int w, int h, int use_alpha);
+void (*texture_free) (texture_type* ptexture);  
+void (*texture_draw) (texture_type* ptexture, float x, float y, int update);  
+void (*texture_draw_bg) (texture_type* ptexture, int update);  
+void (*texture_draw_part) (texture_type* ptexture, float sx, float sy, float x, float y, float w, float h, int update);
+
+
 void texture_setup(void)
 {
 #ifdef NOOPENGL
@@ -73,7 +81,7 @@ static int power_of_two(int input)
        return value;
 }
 
-void texture_create_gl(SDL_Surface * surf, GLint * tex)
+void texture_create_gl(SDL_Surface * surf, GLuint * tex)
 {
   Uint32 saved_flags;
   Uint8  saved_alpha;
@@ -120,6 +128,7 @@ void texture_create_gl(SDL_Surface * surf, GLint * tex)
   glPixelStorei(GL_UNPACK_ROW_LENGTH, conv->pitch / conv->format->BytesPerPixel);
   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB10_A2, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, conv->pixels);
   glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+  glDisable(GL_BLEND);
   SDL_FreeSurface(conv);
 }
 
@@ -131,8 +140,10 @@ void texture_free_gl(texture_type* ptexture)
 
 void texture_draw_gl(texture_type* ptexture, float x, float y, int update)
 {
+float pw = power_of_two(ptexture->w);
+float ph = power_of_two(ptexture->h);
 
-
+  glEnable(GL_TEXTURE_2D);
   glEnable(GL_BLEND);
   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
@@ -143,18 +154,22 @@ void texture_draw_gl(texture_type* ptexture, float x, float y, int update)
   glBegin(GL_QUADS);
   glTexCoord2f(0, 0);
   glVertex2f(x, y);
-  glTexCoord2f((float)ptexture->w / (float)power_of_two(ptexture->w), 0);
+  glTexCoord2f((float)ptexture->w / pw, 0);
   glVertex2f((float)ptexture->w+x, y);
-  glTexCoord2f((float)ptexture->w / (float)power_of_two(ptexture->w), (float)ptexture->h / (float)power_of_two(ptexture->h));  glVertex2f((float)ptexture->w+x, (float)ptexture->h+y);
-  glTexCoord2f(0, (float)ptexture->h / (float)power_of_two(ptexture->h));
+  glTexCoord2f((float)ptexture->w / pw, (float)ptexture->h / ph);  glVertex2f((float)ptexture->w+x, (float)ptexture->h+y);
+  glTexCoord2f(0, (float)ptexture->h / ph);
   glVertex2f(x, (float)ptexture->h+y);
   glEnd();
-
+  
+  glDisable(GL_TEXTURE_2D);
   glDisable(GL_BLEND);
 }
 
 void texture_draw_bg_gl(texture_type* ptexture, int update)
 {
+float pw = power_of_two(ptexture->w);
+float ph = power_of_two(ptexture->h);
+
   glColor3ub(255, 255, 255);
 
   glEnable(GL_TEXTURE_2D);
@@ -163,17 +178,21 @@ void texture_draw_bg_gl(texture_type* ptexture, int update)
   glBegin(GL_QUADS);
   glTexCoord2f(0, 0);
   glVertex2f(0, 0);
-  glTexCoord2f((float)ptexture->w / (float)power_of_two(ptexture->w), 0);
+  glTexCoord2f((float)ptexture->w / pw, 0);
   glVertex2f(screen->w, 0);
-  glTexCoord2f((float)ptexture->w / (float)power_of_two(ptexture->w), (float)ptexture->h / power_of_two(ptexture->h));
+  glTexCoord2f((float)ptexture->w / pw, (float)ptexture->h / ph);
   glVertex2f(screen->w, screen->h);
-  glTexCoord2f(0, (float)ptexture->h / (float)power_of_two(ptexture->h));
+  glTexCoord2f(0, (float)ptexture->h / ph);
   glVertex2f(0, screen->h);
   glEnd();
+  
+  glDisable(GL_TEXTURE_2D);
 }
 
 void texture_draw_part_gl(texture_type* ptexture,float sx, float sy, float x, float y, float w, float h, int update)
 {
+float pw = power_of_two(ptexture->w);
+float ph = power_of_two(ptexture->h);
 
   glBindTexture(GL_TEXTURE_2D, ptexture->gl_texture);
 
@@ -186,16 +205,17 @@ void texture_draw_part_gl(texture_type* ptexture,float sx, float sy, float x, fl
 
 
   glBegin(GL_QUADS);
-  glTexCoord2f(sx / (float)power_of_two(ptexture->w), sy / (float)power_of_two(ptexture->h));
+  glTexCoord2f(sx / pw, sy / ph);
   glVertex2f(x, y);
-  glTexCoord2f((float)(sx + w) / (float)power_of_two(ptexture->w), sy / (float)power_of_two(ptexture->h));
+  glTexCoord2f((float)(sx + w) / pw, sy / ph);
   glVertex2f(w+x, y);
-  glTexCoord2f((sx+w) / (float)power_of_two(ptexture->w), (sy+h) / (float)power_of_two(ptexture->h));
+  glTexCoord2f((sx+w) / pw, (sy+h) / ph);
   glVertex2f(w +x, h+y);
-  glTexCoord2f(sx / (float)power_of_two(ptexture->w), (float)(sy+h) / (float)power_of_two(ptexture->h));
+  glTexCoord2f(sx / pw, (float)(sy+h) / ph);
   glVertex2f(x, h+y);
   glEnd();
 
+  glDisable(GL_TEXTURE_2D);
   glDisable(GL_BLEND);
 
 }
@@ -210,6 +230,9 @@ void texture_load_sdl(texture_type* ptexture, char * file, int use_alpha)
   if (temp == NULL)
     st_abort("Can't load", file);
 
+  if(use_alpha == IGNORE_ALPHA)
+  ptexture->sdl_surface = SDL_DisplayFormat(temp);
+  else
   ptexture->sdl_surface = SDL_DisplayFormatAlpha(temp);
 
   if (ptexture->sdl_surface == NULL)
@@ -260,6 +283,9 @@ void texture_load_part_sdl(texture_type* ptexture, char * file, int x, int y, in
   SDL_SetAlpha(temp,0,0);
 
   SDL_BlitSurface(temp, &src, conv, NULL);
+  if(use_alpha == IGNORE_ALPHA)
+  ptexture->sdl_surface = SDL_DisplayFormat(conv);
+  else
   ptexture->sdl_surface = SDL_DisplayFormatAlpha(conv);
 
   if (ptexture->sdl_surface == NULL)
@@ -277,16 +303,30 @@ void texture_load_part_sdl(texture_type* ptexture, char * file, int x, int y, in
 
 void texture_from_sdl_surface(texture_type* ptexture, SDL_Surface* sdl_surf, int use_alpha)
 {
-
-  /* SDL_Surface * temp;
-
-   temp = IMG_Load(file);
-
-   if (temp == NULL)
-     st_abort("Can't load", file);*/
-
+  Uint32 saved_flags;
+  Uint8  saved_alpha;
+  
+  /* Save the alpha blending attributes */
+  saved_flags = sdl_surf->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
+  saved_alpha = sdl_surf->format->alpha;
+  if ( (saved_flags & SDL_SRCALPHA)
+       == SDL_SRCALPHA )
+    {
+      SDL_SetAlpha(sdl_surf, 0, 0);
+    }
+   
+  if(use_alpha == IGNORE_ALPHA)
+  ptexture->sdl_surface = SDL_DisplayFormat(sdl_surf);
+  else
   ptexture->sdl_surface = SDL_DisplayFormatAlpha(sdl_surf);
 
+  /* Restore the alpha blending attributes */
+  if ( (saved_flags & SDL_SRCALPHA)
+       == SDL_SRCALPHA )
+    {
+      SDL_SetAlpha(ptexture->sdl_surface, saved_flags, saved_alpha);
+    }
+  
   if (ptexture->sdl_surface == NULL)
     st_abort("Can't covert to display format", "SURFACE");
 
@@ -307,15 +347,15 @@ void texture_from_sdl_surface(texture_type* ptexture, SDL_Surface* sdl_surf, int
 
 void texture_draw_sdl(texture_type* ptexture, float x, float y, int update)
 {
+
   SDL_Rect dest;
 
-  dest.x = x;
-  dest.y = y;
+  dest.x = (int)x;
+  dest.y = (int)y;
   dest.w = ptexture->w;
   dest.h = ptexture->h;
-
   SDL_BlitSurface(ptexture->sdl_surface, NULL, screen, &dest);
-
+  
   if (update == UPDATE)
     SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h);
 }
@@ -324,14 +364,14 @@ void texture_draw_sdl(texture_type* ptexture, float x, float y, int update)
 void texture_draw_bg_sdl(texture_type* ptexture, int update)
 {
   SDL_Rect dest;
-
+  
   dest.x = 0;
   dest.y = 0;
   dest.w = screen->w;
   dest.h = screen->h;
-
-  SDL_BlitSurface(ptexture->sdl_surface, NULL, screen, &dest);
-
+  
+  SDL_SoftStretch(ptexture->sdl_surface, NULL, screen, &dest);
+  
   if (update == UPDATE)
     SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h);
 }
@@ -340,15 +380,15 @@ void texture_draw_part_sdl(texture_type* ptexture, float sx, float sy, float x,
 {
   SDL_Rect src, dest;
 
-  src.x = sx;
-  src.y = sy;
-  src.w = w;
-  src.h = h;
+  src.x = (int)sx;
+  src.y = (int)sy;
+  src.w = (int)w;
+  src.h = (int)h;
 
-  dest.x = x;
-  dest.y = y;
-  dest.w = w;
-  dest.h = h;
+  dest.x = (int)x;
+  dest.y = (int)y;
+  dest.w = (int)w;
+  dest.h = (int)h;
 
 
   SDL_BlitSurface(ptexture->sdl_surface, &src, screen, &dest);
index 0448d0e..9904b29 100644 (file)
 typedef struct texture_type
   {
    SDL_Surface* sdl_surface;
-   unsigned gl_texture;
+   GLuint gl_texture;
    int w;
    int h;
   }  
 texture_type;
 
 void texture_setup(void);
-void (*texture_load) (texture_type* ptexture, char * file, int use_alpha);  
-void (*texture_load_part) (texture_type* ptexture, char * file, int x, int y, int w, int h, int use_alpha);
-void (*texture_free) (texture_type* ptexture);  
-void (*texture_draw) (texture_type* ptexture, float x, float y, int update);  
-void (*texture_draw_bg) (texture_type* ptexture, int update);  
-void (*texture_draw_part) (texture_type* ptexture, float sx, float sy, float x, float y, float w, float h, int update);
+extern void (*texture_load) (texture_type* ptexture, char * file, int use_alpha);  
+extern void (*texture_load_part) (texture_type* ptexture, char * file, int x, int y, int w, int h, int use_alpha);
+extern void (*texture_free) (texture_type* ptexture);  
+extern void (*texture_draw) (texture_type* ptexture, float x, float y, int update);  
+extern void (*texture_draw_bg) (texture_type* ptexture, int update);  
+extern void (*texture_draw_part) (texture_type* ptexture, float sx, float sy, float x, float y, float w, float h, int update);
 void texture_load_sdl(texture_type* ptexture, char * file, int use_alpha);
 void texture_load_part_sdl(texture_type* ptexture, char * file, int x, int y, int w, int h, int use_alpha);
 void texture_free_sdl(texture_type* ptexture);
@@ -49,7 +49,7 @@ void texture_free_gl(texture_type* ptexture);
 void texture_draw_gl(texture_type* ptexture, float x, float y, int update);
 void texture_draw_bg_gl(texture_type* ptexture, int update);
 void texture_draw_part_gl(texture_type* ptexture, float sx, float sy, float x, float y, float w, float h, int update);
-void texture_create_gl(SDL_Surface * surf, GLint * tex);
+void texture_create_gl(SDL_Surface * surf, GLuint * tex);
 #endif
 
 #endif /*SUPERTUX_TEXTURE_H*/
index 41b60d1..ffe58cd 100644 (file)
@@ -14,6 +14,8 @@
 #include "defines.h"
 #include "timer.h"
 
+unsigned int st_pause_ticks, st_pause_count;
+
 unsigned int st_get_ticks(void)
 {
 if(st_pause_count != 0)
index e99aa1d..9529242 100644 (file)
@@ -21,8 +21,7 @@ typedef struct timer_type
   }
 timer_type;
 
-unsigned int st_pause_ticks;
-unsigned int st_pause_count;
+extern unsigned int st_pause_ticks, st_pause_count;
 
 unsigned int st_get_ticks(void);
 void st_pause_ticks_init(void);
index 39a99b9..9908fa1 100644 (file)
 #include "menu.h"
 #include "texture.h"
 #include "timer.h"
-
+#include "setup.h"
+#include "level.h"
+#include "gameloop.h"
+#include "leveleditor.h"
 
 /* --- TITLE SCREEN --- */
 
 int title(void)
 {
-  texture_type title, anim1, anim2;
+  texture_type title, img_choose_subset, anim1, anim2;
   SDL_Event event;
   SDLKey key;
-  int done, quit, frame, pict;
+  int done, quit, frame, pict, i;
   char str[80];
+  char **level_subsets;
+  level_subsets = NULL;
+  int subsets_num;
+  level_subsets = dsubdirs("/levels", "info", &subsets_num);
+  st_subset subset;
+  subset_init(&subset);
 
-  game_started = 0;
-  level_editor_started = 0;
-
-  /* Init menu variables */
-  initmenu();
+  /* Rest menu variables */
+  menu_reset();
+  menu_set_current(&main_menu);
 
   clearscreen(0, 0, 0);
   updatescreen();
@@ -58,20 +65,17 @@ int title(void)
   texture_load(&title,DATA_PREFIX "/images/title/title.png", IGNORE_ALPHA);
   texture_load(&anim1,DATA_PREFIX "/images/title/title-anim2.png", IGNORE_ALPHA);
   texture_load(&anim2,DATA_PREFIX "/images/title/title-anim1.png", IGNORE_ALPHA);
-
+  texture_load(&img_choose_subset,DATA_PREFIX "/images/status/choose-level-subset.png", IGNORE_ALPHA);
 
   /* --- Main title loop: --- */
 
   done = 0;
   quit = 0;
   show_menu = 1;
-
   frame = 0;
 
-
   /* Draw the title background: */
-  texture_draw(&title, 0, 0, NO_UPDATE);
-
+  texture_draw_bg(&title, NO_UPDATE);
 
   /* Draw the high score: */
   load_hs();
@@ -82,10 +86,7 @@ int title(void)
 
   while (!done && !quit)
     {
-      
       frame++;
-
-
       /* Handle events: */
 
       while (SDL_PollEvent(&event))
@@ -125,32 +126,102 @@ int title(void)
 
               menuaction = MN_HIT;
             }
-
 #endif
 
         }
 
-      if(use_gl || menu_change)
-        {
-          /* Draw the title background: */
+      /* Draw the title background: */
 
-          texture_draw_bg(&title, NO_UPDATE);
+      texture_draw_bg(&title, NO_UPDATE);
 
-          /* Draw the high score: */
-          sprintf(str, "High score: %d", hs_score);
-           text_drawf(&gold_text, str, 0, -40, A_HMIDDLE, A_BOTTOM, 1, NO_UPDATE);
-  sprintf(str, "by %s", hs_name);
-  text_drawf(&gold_text, str, 0, -20, A_HMIDDLE, A_BOTTOM, 1, NO_UPDATE);
-  
-        }
+      /* Draw the high score: */
+      sprintf(str, "High score: %d", hs_score);
+      text_drawf(&gold_text, str, 0, -40, A_HMIDDLE, A_BOTTOM, 1, NO_UPDATE);
+      sprintf(str, "by %s", hs_name);
+      text_drawf(&gold_text, str, 0, -20, A_HMIDDLE, A_BOTTOM, 1, NO_UPDATE);
 
       /* Don't draw menu, if quit is true */
       if(show_menu && !quit)
-        quit = drawmenu();
-
-      if(game_started || level_editor_started)
-        done = 1;
+        menu_process_current();
 
+      if(current_menu == &main_menu)
+        {
+          switch (menu_check(&main_menu))
+            {
+            case 0:
+              done = 0;
+              i = 0;
+              subset_load(&subset,level_subsets[0]);
+              while(!done)
+                {
+                  texture_draw(&img_choose_subset, 50, 0, NO_UPDATE);
+                  if(subsets_num != 0)
+                    {
+                      texture_draw(&subset.image,135,78,NO_UPDATE);
+                      text_drawf(&gold_text, subset.title, 0, 20, A_HMIDDLE, A_TOP, 1, NO_UPDATE);
+                    }
+                  updatescreen();
+                  SDL_Delay(50);
+                  while(SDL_PollEvent(&event) && !done)
+                    {
+                      switch(event.type)
+                        {
+                        case SDL_QUIT:
+                          done = 1;
+                          quit = 1;
+                        case SDL_KEYDOWN:              // key pressed
+                          /* Keypress... */
+
+                          key = event.key.keysym.sym;
+
+                          if(key == SDLK_LEFT)
+                            {
+                              if(i > 0)
+                                {
+                                  --i;
+                                  subset_free(&subset);
+                                  subset_load(&subset,level_subsets[i]);
+                                }
+                            }
+                          else if(key == SDLK_RIGHT)
+                            {
+                              if(i < subsets_num -1)
+                                {
+                                  ++i;
+                                  subset_free(&subset);
+                                  subset_load(&subset,level_subsets[i]);
+                                }
+                            }
+                          else if(key == SDLK_SPACE || key == SDLK_RETURN)
+                            {
+                              done = YES;
+                              quit = gameloop(subset.name,1,ST_GL_PLAY);
+                             subset_free(&subset);
+                            }
+                          else if(key == SDLK_ESCAPE)
+                            {
+                              done = YES;
+                            }
+                          break;
+                        default:
+                          break;
+                        }
+                    }
+                }
+              break;
+            case 3:
+              done = 1;
+              quit = leveleditor(1);
+              break;
+            case 4:
+              quit = 1;
+              break;
+            }
+        }
+      else if(current_menu == &options_menu)
+        {
+          process_options_menu();
+        }
       /* Animate title screen: */
 
       pict = (frame / 5) % 3;
@@ -161,7 +232,7 @@ int title(void)
         texture_draw(&anim1, 560, 270, NO_UPDATE);
       else if (pict == 2)
         texture_draw(&anim2, 560, 270, NO_UPDATE);
-       
+
       flipscreen();
 
       /* Pause: */
@@ -169,14 +240,12 @@ int title(void)
       SDL_Delay(50);
 
     }
-
-
   /* Free surfaces: */
 
   texture_free(&title);
   texture_free(&anim1);
   texture_free(&anim2);
-
+  free_strings(level_subsets,subsets_num);
 
   /* Return to main! */
 
index f2d472b..0eb6d42 100644 (file)
@@ -29,7 +29,5 @@ typedef struct base_type
   }
 base_type;
 
-//double get_frame_ratio(base_type* pbase);
-
 #endif /*SUPERTUX_TYPE_H*/
 
index 0afcff4..05bac44 100644 (file)
@@ -18,6 +18,7 @@
 #include "defines.h"
 #include "world.h"
 
+texture_type img_distro[4];
 
 void bouncy_distro_init(bouncy_distro_type* pbouncy_distro, float x, float y)
 {
@@ -75,6 +76,7 @@ void broken_brick_action(broken_brick_type* pbroken_brick)
 
 void broken_brick_draw(broken_brick_type* pbroken_brick)
 {
+SDL_Rect src, dest;
   if (pbroken_brick->base.alive)
     {
       src.x = rand() % 16;
@@ -82,8 +84,8 @@ void broken_brick_draw(broken_brick_type* pbroken_brick)
       src.w = 16;
       src.h = 16;
 
-      dest.x = pbroken_brick->base.x - scroll_x;
-      dest.y = pbroken_brick->base.y;
+      dest.x = (int)(pbroken_brick->base.x - scroll_x);
+      dest.y = (int)pbroken_brick->base.y;
       dest.w = 16;
       dest.h = 16;
 
@@ -126,25 +128,26 @@ void bouncy_brick_action(bouncy_brick_type* pbouncy_brick)
 void bouncy_brick_draw(bouncy_brick_type* pbouncy_brick)
 {
   int s;
-
+  SDL_Rect dest;
+  
   if (pbouncy_brick->base.alive)
     {
       if (pbouncy_brick->base.x >= scroll_x - 32 &&
           pbouncy_brick->base.x <= scroll_x + screen->w)
         {
-          dest.x = pbouncy_brick->base.x - scroll_x;
-          dest.y = pbouncy_brick->base.y;
+          dest.x = (int)(pbouncy_brick->base.x - scroll_x);
+          dest.y = (int)pbouncy_brick->base.y;
           dest.w = 32;
           dest.h = 32;
 
           if(current_level.bkgd_image[0] == '\0')
             {
               fillrect(pbouncy_brick->base.x - scroll_x,pbouncy_brick->base.y,32,32,current_level.bkgd_red,current_level.bkgd_green,
-                       current_level.bkgd_blue);
+                       current_level.bkgd_blue,0);
             }
           else
             {
-              s = scroll_x / 30;
+              s = (int)scroll_x / 30;
               texture_draw_part(&img_bkgd,dest.x + s,dest.y,dest.x,dest.y,dest.w,dest.h,NO_UPDATE);
             }
 
@@ -181,7 +184,7 @@ void floating_score_draw(floating_score_type* pfloating_score)
     {
       char str[10];
       sprintf(str, "%d", pfloating_score->value);
-      text_draw(&gold_text, str, pfloating_score->base.x + 16 - strlen(str) * 8, pfloating_score->base.y, 1, NO_UPDATE);
+      text_draw(&gold_text, str, (int)pfloating_score->base.x + 16 - strlen(str) * 8, (int)pfloating_score->base.y, 1, NO_UPDATE);
     }
 }
 
index e85ccda..d1dc7c0 100644 (file)
@@ -22,7 +22,7 @@ typedef struct bouncy_distro_type /*It is easier to read the sources IMHO, if we
   }
 bouncy_distro_type;
 
-texture_type img_distro[4];
+extern texture_type img_distro[4];
 
 void bouncy_distro_init(bouncy_distro_type* pbouncy_distro, float x, float y);
 void bouncy_distro_action(bouncy_distro_type* pbouncy_distro);