} /* push_down() */

/***********************************************************
*
*   Method:
*       push_up
*
*   Description:
*       Determines if character is on ground or air.
*
***********************************************************/

        public void push_up(character_type c)
        {
            int y = ((c.physics.position.y >> 12) + c.physics.hit_box.Height) / Blocks.size.Height;

            c.ground_status      = char_status_enum.GROUND;
            c.physics.position.y = (((y * Blocks.size.Height) - c.physics.hit_box.Height) + 1) << 12;
        } /* push_up() */
        } /* push_right() */

/***********************************************************
*
*   Method:
*       push_left
*
*   Description:
*       Push the character down one block.
*
***********************************************************/

        private void push_left(character_type c)
        {
            int x = ((c.physics.position.x >> 12) + c.physics.hit_box.Width) / Blocks.size.Width;

            c.physics.acceleration.x = 0;
            c.physics.velocity.x     = 0;
            c.physics.position.x     = (((x * Blocks.size.Width) - c.physics.hit_box.Width) << 12) - 1;
        } /* push_left() */
        } /* push_up() */

/***********************************************************
*
*   Method:
*       push_right
*
*   Description:
*       Push the character left one block.
*
***********************************************************/

        private void push_right(character_type c)
        {
            int x = (c.physics.position.x >> 12) / Blocks.size.Width + 1;

            c.physics.acceleration.x = 0;
            c.physics.velocity.x     = 0;
            c.physics.position.x     = (x * Blocks.size.Width) << 12;
        } /* push_right() */
        } /* update_hit_box() */

/***********************************************************
*
*   Method:
*       push_down
*
*   Description:
*       Push the character down one block.
*
***********************************************************/

        private void push_down(character_type c)
        {
            int y = ((c.physics.position.y >> 12) / Blocks.size.Height) + 1;

            c.physics.acceleration.y = 0;
            c.physics.velocity.y     = 0;
            c.physics.position.y     = (y * Blocks.size.Height) << 12;

            c.ground_status = char_status_enum.AIR;
        } /* push_down() */
/***********************************************************
*
*   Method:
*       update_hit_box
*
*   Description:
*       Determines if character is on ground or air.
*
***********************************************************/

        private void update_hit_box(character_type c)
        {
/*----------------------------------------------------------
*  Local variables
*  ----------------------------------------------------------*/
            int[] x = new int[2];
            int[] y = new int[2];
            int   suby;

/*----------------------------------------------------------
*  Update y position and find character boundaries
*  ----------------------------------------------------------*/
            c.physics.position.y += c.physics.velocity.y;

            x[0] = (c.physics.position.x >> 12) / Blocks.size.Width;
            x[1] = ((c.physics.position.x >> 12) + c.physics.hit_box.Width) / Blocks.size.Width;
            y[0] = ((c.physics.position.y >> 12) + c.physics.hit_box.Height) / Blocks.size.Height;
            y[1] = (c.physics.position.y >> 12) / Blocks.size.Height;

            prev_location = c.ground_status;

/*----------------------------------------------------------
*  Check for y collisions
*  ----------------------------------------------------------*/
            if (contains_block(x, y[1]))
            {
                int x_hit;

                push_down(c);

                if (contains_block(x[1], y[1]) && model.level.mario.facing_right())
                {
                    x_hit = x[1];
                }
                else if (contains_block(x[0], y[1]) && !model.level.mario.facing_right())
                {
                    x_hit = x[0];
                }
                else if (contains_block(x[1], y[1]))
                {
                    x_hit = x[1];
                }
                else
                {
                    x_hit = x[0];
                }

                if (model.level.map.blocks[x_hit, y[1]].hit_bottom())
                {
                    c.physics.velocity.y = MarioPhysics.vy_hard_block;
                }
            }
            else if (contains_block(x, y[0]))
            {
                push_up(c);
            }
            else
            {
                c.ground_status = char_status_enum.AIR;
            }

/*----------------------------------------------------------
*  Update x position and find character boundaries
*  ----------------------------------------------------------*/
            c.physics.position.x += c.physics.velocity.x;

            x[0] = (c.physics.position.x >> 12) / Blocks.size.Width;
            x[1] = ((c.physics.position.x >> 12) + c.physics.hit_box.Width) / Blocks.size.Width;
            y[0] = ((c.physics.position.y >> 12) + c.physics.hit_box.Height) / Blocks.size.Height;
            y[1] = (c.physics.position.y >> 12) / Blocks.size.Height;
            suby = (c.physics.position.y >> 12) % Blocks.size.Height;

            if (c.ground_status == char_status_enum.GROUND)
            {
                y[0]--;
            }

/*----------------------------------------------------------
*  Check for x collisions
*  ----------------------------------------------------------*/
            if (contains_block(x[0], y))
            {
                push_right(c);
            }
            else if (contains_block(x[1], y))
            {
                push_left(c);

                /*----------------------------------------------------------
                *  Check for entering a horizontal pipe
                *  ----------------------------------------------------------*/
                if ((c.ground_status == char_status_enum.GROUND) &&
                    (model.game_status == game_status_enum.gameplay) &&
                    (KeyBinding.D_RIGHT_pressed) &&
                    (model.level.map.blocks[x[1], y[0]] != null) &&
                    (model.level.map.blocks[x[1], y[0]].GetType() == typeof(block_pipe_type)))
                {
                    block_pipe_type p = (block_pipe_type)model.level.map.blocks[x[1], y[0]];

                    if (p.pipe.is_linked(c.physics.position.x, y[0] << 16))
                    {
                        model.game_status = game_status_enum.pipe_transition;
                        pipe_entered      = p.pipe;
                        init_frame        = Animations.frame_count;
                        model.pipe_status = pipe_status_enum.ENTER;
                    }
                }
            }
        } /* update_hit_box() */