new collision detection. cleanups. bug fixes. music approach patch from Ricardo.
authorTobias Gläßer <tobi.web@gmx.de>
Sat, 13 Mar 2004 02:20:57 +0000 (02:20 +0000)
committerTobias Gläßer <tobi.web@gmx.de>
Sat, 13 Mar 2004 02:20:57 +0000 (02:20 +0000)
SVN-Revision: 200

14 files changed:
src/badguy.c
src/badguy.h
src/collision.c
src/collision.h
src/gameloop.c
src/leveleditor.c
src/player.c
src/player.h
src/scene.c
src/sound.c
src/sound.h
src/special.c
src/special.h
src/title.c

index 27530cd..5cc1f16 100644 (file)
@@ -42,6 +42,7 @@ void badguy_init(bad_guy_type* pbad, float x, float y, int kind)
   pbad->base.y = y;
   pbad->base.xm = 1.3;
   pbad->base.ym = 4.8;
+  pbad->old_base = pbad->base;
   pbad->dir = LEFT;
   pbad->seen = NO;
   timer_init(&pbad->timer,YES);
@@ -75,16 +76,20 @@ void badguy_action(bad_guy_type* pbad)
 
               pbad->base.y = pbad->base.y + pbad->base.ym * frame_ratio;
 
+              if (pbad->dying != FALLING)
+              collision_swept_object_map(&pbad->old_base,&pbad->base);
+              if (pbad->base.y > screen->h)
+                pbad->base.alive = NO;
 
               /* Bump into things horizontally: */
 
               if (!pbad->dying)
                 {
-                  if (issolid( pbad->base.x - 1, (int) pbad->base.y + 16))
+                  if (issolid( pbad->base.x, (int) pbad->base.y + 16))
                     {
                       pbad->dir = RIGHT;
                     }
-                  else if (issolid( pbad->base.x + pbad->base.width-1, (int) pbad->base.y + 16))
+                  else if (issolid( pbad->base.x + pbad->base.width, (int) pbad->base.y + 16))
                     {
                       pbad->dir = LEFT;
                     }
@@ -135,7 +140,7 @@ void badguy_action(bad_guy_type* pbad)
 
               /* Move left/right: */
 
-              if (pbad->mode != KICK && pbad->mode != HELD)
+              if (pbad->mode != HELD)
                 {
                   if (pbad->dying == NO ||
                       pbad->dying == FALLING)
@@ -146,31 +151,33 @@ void badguy_action(bad_guy_type* pbad)
                         pbad->base.x = pbad->base.x - pbad->base.xm * frame_ratio;
                     }
                 }
-              else if (pbad->mode == KICK)
-                {
-                  /* Obsolete
-                                  if (pbad->dir == RIGHT)
-                                    pbad->base.x = pbad->base.x + 16;
-                                  else if (pbad->dir == LEFT)
-                                    pbad->base.x = pbad->base.x - 16;*/
-                }
               else if (pbad->mode == HELD)
                 { /* FIXME: The pbad object shouldn't know about pplayer objects. */
                   /* If we're holding the laptop */
-                  if(tux.dir==RIGHT)
+                 pbad->dir=tux.dir;
+                  if(pbad->dir==RIGHT)
                     {
-                      pbad->base.x = tux.base.x - 16;
-                      pbad->base.y = tux.base.y - 8 - (tux.size*16);
+                      pbad->base.x = tux.base.x + 16;
+                      pbad->base.y = tux.base.y + tux.base.height/1.5 - pbad->base.height;
                     }
                   else /* facing left */
                     {
                       pbad->base.x = tux.base.x - 16;
-                      pbad->base.y = tux.base.y - 8 - (tux.size*16);
+                      pbad->base.y = tux.base.y + tux.base.height/1.5 - pbad->base.height;
                     }
+                   if(collision_object_map(&pbad->base))
+                   {
+                     pbad->base.x = tux.base.x;
+                     pbad->base.y = tux.base.y + tux.base.height/1.5 - pbad->base.height;
+                   }
 
                   if(tux.input.fire != DOWN) /* SHOOT! */
                     {
-                      pbad->dir=tux.dir;
+                     if(pbad->dir = LEFT)
+                     pbad->base.x -= 24;
+                     else
+                     pbad->base.x += 24;
+                     
                       pbad->mode=KICK;
                       pbad->base.ym-=8;
                       play_sound(sounds[SND_KICK],SOUND_CENTER_SPEAKER);
@@ -182,7 +189,11 @@ void badguy_action(bad_guy_type* pbad)
 
               if(pbad->mode != HELD)
                 pbad->base.y = pbad->base.y + pbad->base.ym * frame_ratio;
-
+               
+              if (pbad->dying != FALLING)
+              collision_swept_object_map(&pbad->old_base,&pbad->base);
+              if (pbad->base.y > screen->h)
+                pbad->base.alive = NO;
               /* Bump into things horizontally: */
 
               /* Bump into things horizontally: */
@@ -190,11 +201,11 @@ void badguy_action(bad_guy_type* pbad)
               if (!pbad->dying)
                 {
                   int changed = pbad->dir;
-                  if (issolid( pbad->base.x - 1, (int) pbad->base.y + 16))
+                  if (issolid( pbad->base.x, (int) pbad->base.y + 16))
                     {
                       pbad->dir = RIGHT;
                     }
-                  else if (issolid( pbad->base.x + pbad->base.width-1, (int) pbad->base.y + 16))
+                  else if (issolid( pbad->base.x + pbad->base.width, (int) pbad->base.y + 16))
                     {
                       pbad->dir = LEFT;
                     }
@@ -252,8 +263,7 @@ void badguy_action(bad_guy_type* pbad)
                   pbad->base.ym = physic_get_velocity(&pbad->physic);
                 }
 
-              if (pbad->base.y > screen->h)
-                pbad->base.alive = NO;
+
             }
           else if (pbad->kind == BAD_MONEY)
             {
@@ -263,6 +273,12 @@ void badguy_action(bad_guy_type* pbad)
               /* Move vertically: */
 
               pbad->base.y = pbad->base.y + pbad->base.ym * frame_ratio;
+             
+              if (pbad->dying != FALLING)
+              collision_swept_object_map(&pbad->old_base,&pbad->base);
+
+              if (pbad->base.y > screen->h)
+                pbad->base.alive = NO;
 
               if(physic_get_state(&pbad->physic) == -1)
                 {
@@ -278,11 +294,12 @@ void badguy_action(bad_guy_type* pbad)
                       physic_set_start_vy(&pbad->physic,6.);
                       pbad->base.ym = physic_get_velocity(&pbad->physic);
                     }
-                  else if(issolid(pbad->base.x, pbad->base.y - 1))
+                  else if(issolid(pbad->base.x, pbad->base.y))
                     { /* This works, but isn't the best solution imagineable */
                       physic_set_state(&pbad->physic,PH_VT);
                       physic_set_start_vy(&pbad->physic,0.);
                       pbad->base.ym = physic_get_velocity(&pbad->physic);
+                     ++pbad->base.y;
                     }
                   else
                     {
@@ -298,9 +315,6 @@ void badguy_action(bad_guy_type* pbad)
                     }
                   pbad->base.ym = physic_get_velocity(&pbad->physic);
                 }
-
-              if (pbad->base.y > screen->h)
-                pbad->base.alive = NO;
             }
           else if (pbad->kind == -1)
           {}
@@ -585,6 +599,7 @@ void badguy_collision(bad_guy_type* pbad, void *p_c_object, int c_object)
         }
       else if (pbad->kind == BAD_LAPTOP)
         {
+
           if (pbad->mode != KICK)
             {
               /* Flatten! */
@@ -602,7 +617,6 @@ void badguy_collision(bad_guy_type* pbad, void *p_c_object, int c_object)
             {
               /* Kick! */
 
-              pbad->mode = KICK;
               play_sound(sounds[SND_KICK], SOUND_CENTER_SPEAKER);
 
               if (pplayer_c->base.x <= pbad->base.x)
@@ -623,7 +637,7 @@ void badguy_collision(bad_guy_type* pbad, void *p_c_object, int c_object)
                     25 * score_multiplier);
 
           /* play_sound(sounds[SND_SQUISH]); */
-        }
+         }
       break;
     }
 
index 258e12a..0acdcea 100644 (file)
@@ -39,6 +39,7 @@ typedef struct bad_guy_type
     int dir;
     int frame;
     base_type base;
+    base_type old_base;
     timer_type timer;
     physic_type physic;
   }
index 98892bc..78cbc3e 100644 (file)
 int rectcollision(base_type* one, base_type* two)
 {
 
-  if (one->x >= two->x - one->width &&
-      one->x <= two->x + two->width  &&
-      one->y >= two->y - one->height &&
-      one->y <= two->y + two->height )
+  if (one->x >= two->x - one->width + 1 &&
+      one->x <= two->x + two->width - 1  &&
+      one->y >= two->y - one->height + 1&&
+      one->y <= two->y + two->height - 1)
     {
       return YES;
     }
@@ -33,11 +33,10 @@ int rectcollision(base_type* one, base_type* two)
 
 int rectcollision_offset(base_type* one, base_type* two, float off_x, float off_y)
 {
-
-  if (one->x >= two->x - one->width +off_x &&
-      one->x <= two->x + two->width + off_x &&
-      one->y >= two->y - one->height + off_y &&
-      one->y <= two->y + two->height + off_y )
+  if (one->x >= two->x - one->width +off_x + 1 &&
+      one->x <= two->x + two->width + off_x - 1 &&
+      one->y >= two->y - one->height + off_y + 1 &&
+      one->y <= two->y + two->height + off_y - 1)
     {
       return YES;
     }
@@ -47,6 +46,175 @@ int rectcollision_offset(base_type* one, base_type* two, float off_x, float off_
     }
 }
 
+int collision_object_map(base_type* pbase)
+{
+  int v,h,i;
+
+  v = (int)pbase->height / 16;
+  h = (int)pbase->width / 16;
+
+  if(issolid(pbase->x + 1, pbase->y + 1) ||
+      issolid(pbase->x + pbase->width -1, pbase->y + 1) ||
+      issolid(pbase->x +1, pbase->y + pbase->height -1) ||
+      issolid(pbase->x + pbase->width -1, pbase->y + pbase->height - 1))
+    return YES;
+
+  for(i = 1; i < h; ++i)
+    {
+      if(issolid(pbase->x + i*16,pbase->y + 1))
+        return YES;
+    }
+
+  for(i = 1; i < h; ++i)
+    {
+      if(  issolid(pbase->x + i*16,pbase->y + pbase->height - 1))
+        return YES;
+    }
+
+  for(i = 1; i < v; ++i)
+    {
+      if(  issolid(pbase->x + 1, pbase->y + i*16))
+        return YES;
+    }
+  for(i = 1; i < v; ++i)
+    {
+      if(  issolid(pbase->x + pbase->width - 1, pbase->y + i*16))
+        return YES;
+    }
+
+  return NO;
+}
+
+
+int collision_swept_object_map(base_type* old, base_type* current)
+{
+  int steps; /* Used to speed up the collision tests, by stepping every 16pixels in the path. */
+  int h; 
+  float i;
+  float lpath; /* Holds the longest path, which is either in X or Y direction. */
+  float xd,yd; /* Hold the smallest steps in X and Y directions. */
+  float temp, xt, yt; /* Temporary variable. */
+
+  lpath = 0;
+  xd = 0;
+  yd = 0;
+
+  if(old->x == current->x && old->y == current->y)
+    {
+      return 0;
+    }
+  else if(old->x == current->x && old->y != current->y)
+    {
+      lpath = current->y - old->y;
+      if(lpath < 0)
+        {
+          yd = -1;
+          lpath = -lpath;
+        }
+      else
+        {
+          yd = 1;
+        }
+
+      h = 1;
+      xd = 0;
+
+    }
+  else if(old->x != current->x && old->y == current->y)
+    {
+      lpath = current->x - old->x;
+      if(lpath < 0)
+        {
+          xd = -1;
+          lpath = -lpath;
+        }
+      else
+        {
+          xd = 1;
+        }
+      h = 2;
+      yd = 0;
+    }
+  else
+    {
+      lpath = current->x - old->x;
+      if(lpath < 0)
+        lpath = -lpath;
+      if(current->y - old->y > lpath || old->y - current->y > lpath)
+        lpath = current->y - old->y;
+      if(lpath < 0)
+        lpath = -lpath;
+      h = 3;
+      xd = (current->x - old->x) / lpath;
+      yd = (current->y - old->y) / lpath;
+    }
+
+  steps = (int)(lpath / (float)16);
+
+  old->x += xd;
+  old->y += yd;
+
+  for(i = 0; i <= lpath; old->x += xd, old->y += yd, ++i)
+    {
+      if(steps > 0)
+        {
+          old->y += yd*16.;
+          old->x += xd*16.;
+          steps--;
+        }
+
+      if(collision_object_map(old))
+        {
+
+          switch(h)
+            {
+            case 1:
+              current->y = old->y - yd;
+              while(collision_object_map(current))
+                current->y -= yd;
+              break;
+            case 2:
+              current->x = old->x - xd;
+              while(collision_object_map(current))
+                current->x -= xd;
+              break;
+            case 3:
+              xt = current->x;
+              yt = current->y;
+              current->x = old->x - xd;
+              current->y = old->y - yd;
+              while(collision_object_map(current))
+                {
+                  current->x -= xd;
+                  current->y -= yd;
+                }
+
+              temp = current->x;
+              current->x = xt;
+              if(!collision_object_map(current))
+                break;
+
+              current->x = temp;
+              temp = current->y;
+              current->y = yt;
+
+              if(!collision_object_map(current))
+                break;
+
+              current->y = temp;
+
+              break;
+            default:
+              break;
+            }
+          break;
+        }
+    }
+
+  *old = *current;
+
+}
+
 void collision_handler()
 {
   int i,j;
@@ -99,7 +267,7 @@ void collision_handler()
           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 && bad_guys[i].kind != BAD_MONEY)
+              if (tux.base.y + tux.base.height < bad_guys[i].base.y + 8 > 0 && bad_guys[i].kind != BAD_MONEY && bad_guys[i].mode != HELD)
                 {
                   badguy_collision(&bad_guys[i], &tux, CO_PLAYER);
                 }
index 8f48123..8f18904 100644 (file)
@@ -25,6 +25,8 @@ enum
 
 int rectcollision(base_type* one, base_type* two);
 int rectcollision_offset(base_type* one, base_type* two, float off_x, float off_y);
+int collision_swept_object_map(base_type* old, base_type* current);
+int collision_object_map(base_type* object);
 
 /* Checks for all possible collisions.
    And calls the collision_handlers, which the collision_objects provide for this case (or not). */
index 64b9c16..b580f00 100644 (file)
@@ -57,6 +57,7 @@ static int st_gl_mode;
 static unsigned int last_update_time;
 static unsigned int update_time;
 static int pause_menu_frame;
+static int debug_fps;
 
 /* Local function prototypes: */
 
@@ -219,7 +220,12 @@ void game_event(void)
             case SDLK_s:
               if(debug_mode == YES)
                 score += 1000;
-              break;
+            case SDLK_f:
+              if(debug_fps == YES)
+             debug_fps = NO;
+             else
+             debug_fps = YES;
+              break;         
             default:
               break;
             }
@@ -296,8 +302,7 @@ int game_action(void)
     {
       /* Tux either died, or reached the end of a level! */
 
-      if (playing_music())
-        halt_music();
+      halt_music();
 
 
       if (next_level)
@@ -362,6 +367,8 @@ int game_action(void)
       if(st_gl_mode != ST_GL_TEST)
         levelintro();
       start_timers();
+      /* Play music: */
+      play_current_music();
     }
 
   player_action(&tux);
@@ -616,6 +623,10 @@ int gameloop(char * subset, int levelnb, int mode)
   clearscreen(0, 0, 0);
   updatescreen();
 
+  /* Play music: */
+  play_current_music();
+
+
   while (SDL_PollEvent(&event))
   {}
 
@@ -626,7 +637,7 @@ int gameloop(char * subset, int levelnb, int mode)
 
       /* Calculate the movement-factor */
       frame_ratio = ((double)(update_time-last_update_time))/((double)FRAME_RATE);
-
+      
       if(!timer_check(&frame_timer))
         {
           timer_start(&frame_timer,25);
@@ -680,12 +691,18 @@ int gameloop(char * subset, int levelnb, int mode)
 
       if(!game_pause && !show_menu)
         {
+       /*float z = frame_ratio;
+       frame_ratio = 1;
+       while(z >= 1)
+       {*/
           if (game_action() == 0)
             {
               /* == 0: no more lives */
               /* == -1: continues */
               return 0;
             }
+         /*  --z;
+           }*/
         }
       else
         {
@@ -693,8 +710,8 @@ int gameloop(char * subset, int levelnb, int mode)
           SDL_Delay(50);
         }
 
-      if(debug_mode && tux.input.down == DOWN)
-        SDL_Delay(45);
+      if(debug_mode && debug_fps == YES)
+        SDL_Delay(160);
 
       /*Draw the current scene to the screen */
       /*If the machine running the game is too slow
@@ -733,28 +750,17 @@ int gameloop(char * subset, int levelnb, int mode)
         {
           /* are we low on time ? */
           if ((timer_get_left(&time_left) < TIME_WARNING)
-              && (current_music != HURRYUP_MUSIC))
-            {
-              current_music = HURRYUP_MUSIC;
-              /* stop the others music, prepare to play the fast music */
-              if (playing_music())
-                {
-                  halt_music();
-                }
-            }
+              && (get_current_music() != HURRYUP_MUSIC))     /* play the fast music */
+             {
+              set_current_music(HURRYUP_MUSIC);
+              play_current_music();
+             }
 
         }
       else
         player_kill(&tux,KILL);
 
 
-      /* Keep playing the correct music: */
-
-      if (!playing_music())
-        {
-          play_current_music();
-        }
-
       /* Calculate frames per second */
       if(show_fps)
         {
@@ -771,8 +777,7 @@ int gameloop(char * subset, int levelnb, int mode)
     }
   while (!done && !quit);
 
-  if (playing_music())
-    halt_music();
+  halt_music();
 
   level_free_gfx();
   level_free(&current_level);
@@ -1513,6 +1518,7 @@ void bumpbrick(float x, float y)
                    (int)(y / 32) * 32);
 
   play_sound(sounds[SND_BRICK], SOUND_CENTER_SPEAKER);
+
 }
 
 
index c8cd348..e6caec1 100644 (file)
@@ -77,6 +77,7 @@ void le_highlight_selection();
 void apply_level_settings_menu();
 void update_subset_settings_menu();
 void save_subset_settings_menu();
+void le_update_buttons(char*);
 
 /* leveleditor internals */
 static string_list_type level_subsets;
@@ -355,7 +356,7 @@ void le_new_subset(char *subset_name)
   level_save(&new_lev,subset_name,1);
 }
 
-le_update_buttons(char *theme)
+void le_update_buttons(char *theme)
 {
   int i;
   char filename[1024];
index 4615cbe..5e65023 100644 (file)
@@ -31,6 +31,16 @@ skidfiretux_right,  skidfiretux_left,
 cape_right[2],  cape_left[2],
 bigcape_right[2],  bigcape_left[2];
 
+void player_input_init(player_input_type* pplayer_input)
+{
+  pplayer_input->down = UP;
+  pplayer_input->fire = UP;
+  pplayer_input->left = UP;
+  pplayer_input->old_fire = UP;
+  pplayer_input->right = UP;
+  pplayer_input->up = UP;
+}
+
 void player_init(player_type* pplayer)
 {
   pplayer->base.width = 32;
@@ -43,6 +53,7 @@ void player_init(player_type* pplayer)
   pplayer->base.y = 240;
   pplayer->base.xm = 0;
   pplayer->base.ym = 0;
+  pplayer->old_base = pplayer->base;
   pplayer->dir = RIGHT;
   pplayer->duck = NO;
 
@@ -55,12 +66,7 @@ void player_init(player_type* pplayer)
   pplayer->score = 0;
   pplayer->distros = 0;
 
-  pplayer->input.down = UP;
-  pplayer->input.fire = UP;
-  pplayer->input.left = UP;
-  pplayer->input.old_fire = UP;
-  pplayer->input.right = UP;
-  pplayer->input.up = UP;
+  player_input_init(&pplayer->input);
 
   pplayer->keymap.jump = SDLK_UP;
   pplayer->keymap.duck = SDLK_DOWN;
@@ -113,13 +119,9 @@ void player_level_begin(player_type* pplayer)
   pplayer->base.y = 240;
   pplayer->base.xm = 0;
   pplayer->base.ym = 0;
+  pplayer->old_base = pplayer->base;
 
-  pplayer->input.down = UP;
-  pplayer->input.fire = UP;
-  pplayer->input.left = UP;
-  pplayer->input.old_fire = UP;
-  pplayer->input.right = UP;
-  pplayer->input.up = UP;
+  player_input_init(&pplayer->input);
 
   timer_init(&pplayer->invincible_timer,YES);
   timer_init(&pplayer->skidding_timer,YES);
@@ -131,6 +133,9 @@ void player_level_begin(player_type* pplayer)
 
 void player_action(player_type* pplayer)
 {
+  int i, jumped_in_solid;
+  jumped_in_solid = NO;
+
   /* --- HANDLE TUX! --- */
 
   player_input(pplayer);
@@ -140,6 +145,8 @@ void player_action(player_type* pplayer)
   pplayer->base.x += pplayer->base.xm * frame_ratio;
   pplayer->base.y += pplayer->base.ym * frame_ratio;
 
+  collision_swept_object_map(&pplayer->old_base,&pplayer->base);
+
   player_keep_in_bounds(pplayer);
 
   /* Land: */
@@ -147,51 +154,42 @@ void player_action(player_type* pplayer)
   if (!pplayer->dying)
     {
 
-       while(issolid( pplayer->base.x + 16,  pplayer->base.y + pplayer->base.height) && !issolid( pplayer->base.x + 16,  pplayer->base.y + 1))
-        {
-          --pplayer->base.y;
-        }
-      while(issolid( pplayer->base.x + 16,  pplayer->base.y + 1) && !issolid( pplayer->base.x + 16,  pplayer->base.y + pplayer->base.height))
-        {
-          ++pplayer->base.y;
-        }
-      while(issolid( pplayer->base.x - 1,  pplayer->base.y + 1) || issolid( pplayer->base.x - 1,  pplayer->base.y+pplayer->base.height))
-        {
-          ++pplayer->base.x;
-        }
-      while(issolid( pplayer->base.x + 32,  pplayer->base.y + 1) || issolid( pplayer->base.x + 32,  pplayer->base.y+pplayer->base.height))
-        {
-          --pplayer->base.x;
-        }
-    
-      /*if(physic_is_set(&pplayer->vphysic))
-        {
-          pplayer->base.ym = physic_get_velocity(&pplayer->vphysic);
-        }
-      else
-        {*/
-      if( /*!issolid( pplayer->base.x + 16,  pplayer->base.y + pplayer->base.height )*/ !player_on_ground(pplayer))
+
+      if( !player_on_ground(pplayer))
         {
-          if(!physic_is_set(&pplayer->vphysic))
+          if(player_under_solid(pplayer))
             {
               physic_set_state(&pplayer->vphysic,PH_VT);
-              physic_set_start_vy(&pplayer->vphysic,0.);
+              physic_set_start_vy(&pplayer->vphysic,0);
+              jumped_in_solid = YES;
+            }
+          else
+            {
+              if(!physic_is_set(&pplayer->vphysic))
+                {
+                  physic_set_state(&pplayer->vphysic,PH_VT);
+                  physic_set_start_vy(&pplayer->vphysic,0);
+                }
             }
           pplayer->base.ym = physic_get_velocity(&pplayer->vphysic);
+
         }
       else
         {
+
           /* Land: */
 
           if (pplayer->base.ym > 0)
             {
-              pplayer->base.y = (int)(((int)(pplayer->base.y +1) / 32) * 32);
+              pplayer->base.y = (int)(((int)pplayer->base.y / 32) * 32);
               pplayer->base.ym = 0;
             }
+
           physic_init(&pplayer->vphysic);
         }
 
-      if(pplayer->base.ym < 0)
+
+      if(jumped_in_solid == YES)
         {
 
           if (isbrick(pplayer->base.x, pplayer->base.y) ||
@@ -267,382 +265,24 @@ void player_action(player_type* pplayer)
         }
 
       player_grabdistros(pplayer);
-
-      /* 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;
-         }*/
-
-      /*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;
-        }*/
-
-      /*if (issolid(pplayer->base.x, pplayer->base.y + 31))
+      if(jumped_in_solid == YES)
         {
-          /* Set down properly: * /
-
-          int debug_int = 0;
-          while (issolid(pplayer->base.x, pplayer->base.y + 31))
+          ++pplayer->base.y;
+          ++pplayer->old_base.y;
+          if(player_on_ground(pplayer))
             {
-              ++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--;
+              /* Make sure jumping is off. */
+              pplayer->jumping = NO;
             }
+        }
 
-
-          /* Reset score multiplier (for multi-hits): */
+      /* Reset score multiplier (for multi-hits): */
 
       if (pplayer->base.ym > 2)
         score_multiplier = 1;
 
-
-      /* 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;
-        }
-
-      if (((issolid(pplayer->base.x, pplayer->base.y) || issolid(pplayer->base.x+32, pplayer->base.y)) &&  (!issolid(pplayer->base.x - pplayer->base.xm * frame_ratio, pplayer->base.y))
-          /*(pplayer->size == SMALL || pplayer->duck ||
-           !issolid(pplayer->base.x- pplayer->base.xm, pplayer->base.y - 32))* /) || 
-      (!issolid(pplayer->base.x - pplayer->base.xm * frame_ratio, pplayer->base.y+pplayer->base.height) && (issolid(pplayer->base.x, pplayer->base.y+pplayer->base.height) || issolid(pplayer->base.x +32, pplayer->base.y+pplayer->base.height))))
-        {
-      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? * /
-
-      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 (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')
-        {
-          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');
-
-          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)
-                {
-                  /* Jumping up? */
-      /* FIXME: this code is COMPLETLY broken!!! */
-      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 (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);
-                }
-
-              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 (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, 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);
-
-              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')
-            {
-              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');
-
-              play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
-              score = score + SCORE_DISTRO;
-              distros++;
-            }
-          }
-
-
-          /* 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 - 32;
-          }
-
-          pplayer->base.ym = 0;
-          pplayer->jumping = NO;
-          timer_start(&pplayer->jump_timer,MAX_JUMP_TIME);
-          }*/
-        }
     }
 
-
-  /*
-    player_grabdistros(pplayer);
-  */
-
-  /* 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->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;
-  }
-  }
-
-
-  /* Drop vertically: * /
-
-  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;
-  }
-  }
-
-
-  */
   timer_check(&pplayer->safe_timer);
 
 
@@ -651,7 +291,7 @@ void player_action(player_type* pplayer)
   /* Handle invincibility timer: */
 
 
-  if (current_music == HERRING_MUSIC && !timer_check(&pplayer->invincible_timer))
+  if (get_current_music() == HERRING_MUSIC && !timer_check(&pplayer->invincible_timer))
     {
       /*
          no, we are no more invincible
@@ -666,16 +306,15 @@ void player_action(player_type* pplayer)
              stop the herring_song, prepare to play the correct
              fast level_song !
            */
-          current_music = HURRYUP_MUSIC;
+          set_current_music(HURRYUP_MUSIC);
         }
       else
         {
-          current_music = LEVEL_MUSIC;
+          set_current_music(LEVEL_MUSIC);
         }
 
-      /* stop the old music if it's being played */
-      if (playing_music())
-        halt_music();
+      /* start playing it */
+      play_current_music();
     }
 
   /* Handle skidding: */
@@ -693,9 +332,23 @@ void player_action(player_type* pplayer)
 
 int player_on_ground(player_type *pplayer)
 {
-  if( issolid(pplayer->base.x + pplayer->base.width / 2, pplayer->base.y + pplayer->base.height + 1) ||
-      issolid(pplayer->base.x + 1, pplayer->base.y + pplayer->base.height + 1) ||
-      issolid(pplayer->base.x + pplayer->base.width - 1, pplayer->base.y + pplayer->base.height + 1)  )
+  if( issolid(pplayer->base.x + pplayer->base.width / 2, pplayer->base.y + pplayer->base.height) ||
+      issolid(pplayer->base.x + 1, pplayer->base.y + pplayer->base.height) ||
+      issolid(pplayer->base.x + pplayer->base.width - 1, pplayer->base.y + pplayer->base.height)  )
+    {
+      return YES;
+    }
+  else
+    {
+      return NO;
+    }
+}
+
+int player_under_solid(player_type *pplayer)
+{
+  if( issolid(pplayer->base.x + pplayer->base.width / 2, pplayer->base.y) ||
+      issolid(pplayer->base.x + 1, pplayer->base.y) ||
+      issolid(pplayer->base.x + pplayer->base.width - 1, pplayer->base.y)  )
     {
       return YES;
     }
@@ -720,7 +373,7 @@ void player_handle_horizontal_input(player_type *pplayer, int dir)
       pplayer->dir = dir;
     }
 
-  if ((dir ? (pplayer->base.xm < 0) : (pplayer->base.xm > 0)) && !isice(pplayer->base.x, pplayer->base.y + 32) &&
+  if ((dir ? (pplayer->base.xm < 0) : (pplayer->base.xm > 0)) && !isice(pplayer->base.x, pplayer->base.y + pplayer->base.height) &&
       !timer_started(&pplayer->skidding_timer))
     {
       pplayer->base.xm = 0;
@@ -806,7 +459,7 @@ void player_handle_vertical_input(player_type *pplayer)
     }
   else if(pplayer->input.up == UP && pplayer->jumping == YES)
     {
-      if (issolid(pplayer->base.x + 16, pplayer->base.y + pplayer->base.height + 1))
+      if (player_on_ground(pplayer))
         {
           physic_init(&pplayer->vphysic);
           pplayer->jumping == NO;
@@ -831,42 +484,6 @@ void player_handle_vertical_input(player_type *pplayer)
             }
         }
     }
-
-  /* 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! * /
-
-      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)
-            play_sound(sounds[SND_JUMP], SOUND_CENTER_SPEAKER);
-          else
-            play_sound(sounds[SND_BIGJUMP], SOUND_CENTER_SPEAKER);
-        }
-    }*/
-
-  /* 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 = pplayer->base.ym/*-YM_FOR_JUMP* /;
-    }*/
 }
 
 void player_input(player_type *pplayer)
@@ -917,28 +534,38 @@ void player_input(player_type *pplayer)
 
   if (pplayer->input.down == DOWN)
     {
-      if (pplayer->size == BIG)
-      {
-        pplayer->duck = YES;
-       pplayer->base.height = 32;
-       }
+      if (pplayer->size == BIG && pplayer->duck != YES)
+        {
+          pplayer->duck = YES;
+          pplayer->base.height = 32;
+          pplayer->base.y += 32;
+        }
     }
   else
     {
       if (pplayer->size == BIG && pplayer->duck == YES)
         {
           /* Make sure we're not standing back up into a solid! */
+          pplayer->base.height = 64;
+          pplayer->base.y -= 32;
 
-          if (!issolid(pplayer->base.x + 16, pplayer->base.y - 16))
-         {
-            pplayer->duck = NO;
-           pplayer->base.height = 64;
-           }
+          if (!collision_object_map(&pplayer->base) /*issolid(pplayer->base.x + 16, pplayer->base.y - 16)*/)
+            {
+              pplayer->duck = NO;
+              pplayer->base.height = 64;
+              pplayer->old_base.y -= 32;
+              pplayer->old_base.height = 64;
+            }
+          else
+            {
+              pplayer->base.height = 32;
+              pplayer->base.y += 32;
+            }
         }
       else
-      {
-        pplayer->duck = NO;
-       }
+        {
+          pplayer->duck = NO;
+        }
     }
 
   /* (Tux): */
@@ -1237,10 +864,10 @@ void player_collision(player_type* pplayer, void* p_c_object, int c_object)
               else
                 {
                   pbad_c->dir = LEFT;
-                  pbad_c->base.x = pbad_c->base.x - 16;
+                  pbad_c->base.x = pbad_c->base.x - 32;          
                 }
-
-              timer_start(&pbad_c->timer,5000);
+             
+            timer_start(&pbad_c->timer,5000);
             }
           else if (pbad_c->mode == FLAT && pplayer->input.fire == DOWN)
             {
index 31b0c5d..80fc737 100644 (file)
@@ -58,6 +58,8 @@ typedef struct player_input_type
 }
 player_input_type;
 
+void player_input_init(player_input_type* pplayer_input);
+
 typedef struct player_type 
 {
  player_input_type input;
@@ -74,6 +76,7 @@ typedef struct player_type
  int frame;
  int lives;
  base_type base;
+ base_type old_base;
  timer_type invincible_timer;
  timer_type skidding_timer;
  timer_type safe_timer;
@@ -110,5 +113,6 @@ void player_dying(player_type *pplayer);
 void player_remove_powerups(player_type *pplayer);
 void player_keep_in_bounds(player_type *pplayer);
 int player_on_ground(player_type *pplayer);
+int player_under_solid(player_type *pplayer);
 
 #endif /*SUPERTUX_PLAYER_H*/
index f151d86..88daf20 100644 (file)
@@ -82,7 +82,7 @@ void set_defaults(void)
   endpos = 0;
 
   /* set current song/music */
-  current_music = LEVEL_MUSIC;
+  set_current_music(LEVEL_MUSIC);
 }
 
 /* Add score: */
index a7b4241..d81db72 100644 (file)
@@ -207,24 +207,37 @@ void free_music(Mix_Music *music)
       music = NULL;
     }
 }
-
-void play_current_music(void)
-{
-          switch (current_music)
-            {
-            case LEVEL_MUSIC:
-              play_music(level_song, 1);
-              break;
-            case HERRING_MUSIC:
-              play_music(herring_song, 1);
-              break;
-            case HURRYUP_MUSIC: // keep the compiler happy
-              play_music(level_song_fast, 1);
-              break;
-            case NO_MUSIC:      // keep the compiler happy for the moment :-)
-            {}
-              /*default:*/
-            }
+ int get_current_music()
+  {
+ return current_music;
+ }
+ void set_current_music(int music)
+ {
+ current_music = music;
+ }
+ void play_current_music()
+ {
+ if(playing_music())
+   halt_music();
+ switch(current_music)
+   {
+   case LEVEL_MUSIC:
+     play_music(level_song, -1);  // -1 to play forever
+     break;
+   case HERRING_MUSIC:
+     play_music(herring_song, -1);
+     break;
+   case HURRYUP_MUSIC:
+     play_music(level_song_fast, -1);
+     break;
+   case NO_MUSIC:      // keep the compiler happy for the moment :-)
+     {}
+ /*default:*/
+ }
+ /* use halt_music whenever you want to stop it */
 }
 
 #else
@@ -281,6 +294,14 @@ void free_music(void *music)
 void free_chunk(void *chunk)
 {}
 
+int get_current_music()
+{
+}
+
+void set_current_music(int music)
+{
+}
+
 void play_current_music(void)
 {}
 
index eb862ed..3a1d30a 100644 (file)
@@ -34,7 +34,6 @@ enum Music_Type {
   HERRING_MUSIC
 };
 
-extern int current_music;
 
 /* panning effects: terrible :-) ! */
 enum Sound_Speaker {
@@ -90,7 +89,9 @@ int play_music(Mix_Music*music, int loops);
 void free_music(Mix_Music*music);
 void free_chunk(Mix_Chunk*chunk);
 
-void play_current_music(void);
+int get_current_music();
+void set_current_music(int music);
+void play_current_music();
 
 #else
 
@@ -112,6 +113,8 @@ int play_music(void *music, int loops);
 void free_music(void *music);
 void free_chunk(void *chunk);
 
+int get_current_music();
+void set_current_music(int music);
 void play_current_music(void);
 
 #endif
index 181c044..639edc5 100644 (file)
@@ -112,6 +112,7 @@ void upgrade_init(upgrade_type *pupgrade, float x, float y, int kind)
   pupgrade->base.xm = 2;
   pupgrade->base.ym = -2;
   pupgrade->base.height = 0;
+  pupgrade->old_base = pupgrade->base;
 }
 
 void upgrade_action(upgrade_type *pupgrade)
@@ -124,8 +125,8 @@ void upgrade_action(upgrade_type *pupgrade)
           /* Rise up! */
 
           pupgrade->base.height = pupgrade->base.height + 0.7 * frame_ratio;
-         if(pupgrade->base.height > 32)
-         pupgrade->base.height = 32;
+          if(pupgrade->base.height > 32)
+            pupgrade->base.height = 32;
         }
       else
         {
@@ -137,8 +138,17 @@ 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.))
+              collision_swept_object_map(&pupgrade->old_base,&pupgrade->base);
+
+              /* Off the screen?  Kill it! */
+
+              if (pupgrade->base.x < scroll_x - pupgrade->base.width)
+                pupgrade->base.alive = NO;
+              if (pupgrade->base.y > screen->h)
+                pupgrade->base.alive = NO;
+
+              if (issolid(pupgrade->base.x + 1, pupgrade->base.y + 32.) ||
+                  issolid(pupgrade->base.x + 31., pupgrade->base.y + 32.))
                 {
                   if (pupgrade->base.ym > 0)
                     {
@@ -155,33 +165,27 @@ void upgrade_action(upgrade_type *pupgrade)
                     }
                 }
               else
-                pupgrade->base.ym = pupgrade->base.ym + GRAVITY;
+                pupgrade->base.ym = pupgrade->base.ym + GRAVITY * frame_ratio;
 
-                 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;
-                   }
+              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, (int) pupgrade->base.y))
+                {
+                  if(pupgrade->base.xm > 0)
+                    pupgrade->base.xm = -pupgrade->base.xm;
+                }
             }
 
-
-          /* Off the screen?  Kill it! */
-
-          if (pupgrade->base.x < scroll_x - pupgrade->base.width)
-            pupgrade->base.alive = NO;
-
         }
     }
 }
 
 void upgrade_draw(upgrade_type* pupgrade)
 {
-SDL_Rect dest;
+  SDL_Rect dest;
   if (pupgrade->base.alive)
     {
       if (pupgrade->base.height < 32)
@@ -194,11 +198,11 @@ SDL_Rect dest;
           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);
+            texture_draw_part(&img_mints,0,0,dest.x,dest.y,dest.w,dest.h,NO_UPDATE);
           else if (pupgrade->kind == UPGRADE_COFFEE)
-           texture_draw_part(&img_coffee,0,0,dest.x,dest.y,dest.w,dest.h,NO_UPDATE);
+            texture_draw_part(&img_coffee,0,0,dest.x,dest.y,dest.w,dest.h,NO_UPDATE);
           else if (pupgrade->kind == UPGRADE_HERRING)
-           texture_draw_part(&img_golden_herring,0,0,dest.x,dest.y,dest.w,dest.h,NO_UPDATE);
+            texture_draw_part(&img_golden_herring,0,0,dest.x,dest.y,dest.w,dest.h,NO_UPDATE);
         }
       else
         {
@@ -244,7 +248,14 @@ 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;
+          pplayer->base.height = 64;
+         pplayer->base.y -= 32;
+         if(collision_object_map(&pplayer->base))
+         {
+         pplayer->base.height = 32;
+         pplayer->base.y += 32;
+         pplayer->duck = YES;
+         }
           timer_start(&super_bkgd_timer, 350);
         }
       else if (pupgrade->kind == UPGRADE_COFFEE)
@@ -259,11 +270,10 @@ void upgrade_collision(upgrade_type* pupgrade, void* p_c_object, int c_object)
           timer_start(&pplayer->invincible_timer,TUX_INVINCIBLE_TIME);
           timer_start(&super_bkgd_timer, 250);
           /* play the herring song ^^ */
-          if (current_music != HURRYUP_MUSIC)
+          if (get_current_music() != HURRYUP_MUSIC)
             {
-              current_music = HERRING_MUSIC;
-              if (playing_music())
-                halt_music();
+              set_current_music(HERRING_MUSIC);
+              play_current_music();
             }
         }
       break;
index e7b9eb5..cf5d21e 100644 (file)
@@ -35,6 +35,7 @@ typedef struct upgrade_type
   {
     int kind;
     base_type base;
+    base_type old_base;
   }
 upgrade_type;
 
index 8d34f46..f687a89 100644 (file)
 #include "gameloop.h"
 #include "leveleditor.h"
 
-texture_type bkg_title, img_choose_subset, anim1, anim2;
-SDL_Event event;
-SDLKey key;
-int quit, frame, pict, i;
+static texture_type bkg_title, img_choose_subset, anim1, anim2;
+static SDL_Event event;
+static SDLKey key;
+static int quit, frame, pict, i;
 
 void display_credits();