Example #1
0
/* 
 * move_left
 *   DESCRIPTION: Move the player right one pixel (assumed to be a legal move)
 *   INPUTS: xpos -- pointer to player's x position (pixel) in the maze
 *   OUTPUTS: *xpos -- decreased by one from initial value
 *   RETURN VALUE: none
 *   SIDE EFFECTS: pans display by one pixel when appropriate
 */
static void
move_left (int* xpos)
{
    /*
     * Move player by one pixel and check whether display should be panned.
     * Panning is necessary when the player moves past the left pan border
     * while the leftmost pixels of the maze are not on-screen.
     */
    if (--(*xpos) < game_info.map_x + BLOCK_X_DIM * PAN_BORDER && 
	game_info.map_x > SHOW_MIN) {
	/*
	 * Shift the logical view to the left by one pixel and draw the
	 * new line.
	 */
	set_view_window (--game_info.map_x, game_info.map_y);
	(void)draw_vert_line (0);
    }
}
Example #2
0
/* 
 * move_up
 *   DESCRIPTION: Move the player up one pixel (assumed to be a legal move)
 *   INPUTS: ypos -- pointer to player's y position (pixel) in the maze
 *   OUTPUTS: *ypos -- reduced by one from initial value
 *   RETURN VALUE: none
 *   SIDE EFFECTS: pans display by one pixel when appropriate
 */
static void
move_up (int* ypos)
{
    /*
     * Move player by one pixel and check whether display should be panned.
     * Panning is necessary when the player moves past the upper pan border
     * while the top pixels of the maze are not on-screen.
     */
    if (--(*ypos) < game_info.map_y + BLOCK_Y_DIM * PAN_BORDER && 
	game_info.map_y > SHOW_MIN) {
	/*
	 * Shift the logical view upwards by one pixel and draw the
	 * new line.
	 */
	set_view_window (game_info.map_x, --game_info.map_y);
	(void)draw_horiz_line (0);
    }
}
Example #3
0
/* 
 * move_photo_right
 *   DESCRIPTION: Move background photo right one or more pixels.  Amount of
 *                motion depends on game_info.x_speed.  Movement stops at
 *                left edge of photo.
 *   INPUTS: none
 *   OUTPUTS: none
 *   RETURN VALUE: none
 *   SIDE EFFECTS: shifts view window
 */
static void
move_photo_right ()
{
    int32_t delta; /* Number of pixels by which to move. */
    int32_t idx;   /* Index over columns to redraw.      */

    /* Calculate the number of pixels by which to move. */
    delta = (game_info.x_speed > game_info.map_x ?
	     game_info.map_x : game_info.x_speed);

    /* Shift the logical view to the left. */
    game_info.map_x -= delta;
    set_view_window (game_info.map_x, game_info.map_y);

    /* Draw the newly exposed lines. */
    for (idx = 0; delta > idx; idx++) {
	(void)draw_vert_line (idx);
    }
}
Example #4
0
/* 
 * move_photo_down
 *   DESCRIPTION: Move background photo down one or more pixels.  Amount of
 *                motion depends on game_info.y_speed.  Movement stops at
 *                upper edge of photo.
 *   INPUTS: none
 *   OUTPUTS: none
 *   RETURN VALUE: none
 *   SIDE EFFECTS: shifts view window
 */
static void
move_photo_down ()
{
    int32_t delta; /* Number of pixels by which to move. */
    int32_t idx;   /* Index over rows to redraw.         */

    /* Calculate the number of pixels by which to move. */
    delta = (game_info.y_speed > game_info.map_y ?
	     game_info.map_y : game_info.y_speed);

    /* Shift the logical view upward. */
    game_info.map_y -= delta;
    set_view_window (game_info.map_x, game_info.map_y);

    /* Draw the newly exposed lines. */
    for (idx = 0; delta > idx; idx++) {
	(void)draw_horiz_line (idx);
    }
}
Example #5
0
/* 
 * prepare_maze_level
 *   DESCRIPTION: Prepare for a maze of a given level.  Fills the game_info
 *		  structure, creates a maze, and initializes the display.
 *   INPUTS: level -- level to be used for selecting parameter values
 *   OUTPUTS: none
 *   RETURN VALUE: 0 on success, -1 on failure
 *   SIDE EFFECTS: writes entire game_info structure; changes maze;
 *                 initializes display
 */
static int
prepare_maze_level (int level)
{
    int i; /* loop index for drawing display */
    
    /*
     * Record level in game_info; other calculations use offset from
     * level 1.
     */
    game_info.number = level--;

    /* Set per-level parameter values. */
    if ((game_info.maze_x_dim = MAZE_MIN_X_DIM + 2 * level) >
	MAZE_MAX_X_DIM)
	game_info.maze_x_dim = MAZE_MAX_X_DIM;
    if ((game_info.maze_y_dim = MAZE_MIN_Y_DIM + 2 * level) >
	MAZE_MAX_Y_DIM)
	game_info.maze_y_dim = MAZE_MAX_Y_DIM;
    if ((game_info.initial_fruit_count = 1 + level / 2) > 6)
	game_info.initial_fruit_count = 6;
    if ((game_info.time_to_first_fruit = 300 - 30 * level) < 120)
	game_info.time_to_first_fruit = 120;
    if ((game_info.time_between_fruits = 300 - 60 * level) < 60)
	game_info.time_between_fruits = 60;
    if ((game_info.tick_usec = 20000 - 1750 * level) < 5000)
	game_info.tick_usec = 5000;

    /* Initialize dynamic values. */
    game_info.map_x = game_info.map_y = SHOW_MIN;

    /* Create a maze. */
    if (make_maze (game_info.maze_x_dim, game_info.maze_y_dim,
		   game_info.initial_fruit_count) != 0)
	return -1;
    
    /* Set logical view and draw initial screen. */
    set_view_window (game_info.map_x, game_info.map_y);
    for (i = 0; i < SCROLL_Y_DIM; i++)
	(void)draw_horiz_line (i);

    /* Return success. */
    return 0;
}
Example #6
0
/* 
 * move_photo_up
 *   DESCRIPTION: Move background photo up one or more pixels.  Amount of
 *                motion depends on game_info.y_speed.  Movement stops at
 *                lower edge of photo.
 *   INPUTS: none
 *   OUTPUTS: none
 *   RETURN VALUE: none
 *   SIDE EFFECTS: shifts view window
 */
static void
move_photo_up ()
{
    int32_t delta; /* Number of pixels by which to move. */
    int32_t idx;   /* Index over rows to redraw.         */

    /* Calculate the number of pixels by which to move. */
    delta = room_photo_height (game_info.where) - SCROLL_Y_DIM - 
    	    game_info.map_y;
    delta = (game_info.y_speed > delta ? delta : game_info.y_speed);

    /* Shift the logical view upward. */
    game_info.map_y += delta;
    set_view_window (game_info.map_x, game_info.map_y);

    /* Draw the newly exposed lines. */
    for (idx = 1; delta >= idx; idx++) {
	(void)draw_horiz_line (SCROLL_Y_DIM - idx);
    }
}
Example #7
0
/* 
 * move_photo_left
 *   DESCRIPTION: Move background photo left one or more pixels.  Amount of
 *                motion depends on game_info.x_speed.  Movement stops at
 *                right edge of photo.
 *   INPUTS: none
 *   OUTPUTS: none
 *   RETURN VALUE: none
 *   SIDE EFFECTS: shifts view window
 */
static void
move_photo_left ()
{
    int32_t delta; /* Number of pixels by which to move. */
    int32_t idx;   /* Index over columns to redraw.      */

    /* Calculate the number of pixels by which to move. */
    delta = room_photo_width (game_info.where) - SCROLL_X_DIM -
    	    game_info.map_x;
    delta = (game_info.x_speed > delta ? delta : game_info.x_speed);

    /* Shift the logical view to the right. */
    game_info.map_x += delta;
    set_view_window (game_info.map_x, game_info.map_y);

    /* Draw the newly exposed lines. */
    for (idx = 1; delta >= idx; idx++) {
	(void)draw_vert_line (SCROLL_X_DIM - idx);
    }
}
Example #8
0
/* 
 * move_down
 *   DESCRIPTION: Move the player right one pixel (assumed to be a legal move)
 *   INPUTS: ypos -- pointer to player's y position (pixel) in the maze
 *   OUTPUTS: *ypos -- increased by one from initial value
 *   RETURN VALUE: none
 *   SIDE EFFECTS: pans display by one pixel when appropriate
 */
static void
move_down (int* ypos)
{
    /*
     * Move player by one pixel and check whether display should be panned.
     * Panning is necessary when the player moves past the right pan border
     * while the bottom pixels of the maze are not on-screen.
     */
    if (++(*ypos) > game_info.map_y + SCROLL_Y_DIM -
	    BLOCK_Y_DIM * (PAN_BORDER + 1) && 
	game_info.map_y + SCROLL_Y_DIM < 
	    (2 * game_info.maze_y_dim + 1) * BLOCK_Y_DIM - SHOW_MIN) {
	/*
	 * Shift the logical view downwards by one pixel and draw the
	 * new line.
	 */
	set_view_window (game_info.map_x, ++game_info.map_y);
	(void)draw_horiz_line (SCROLL_Y_DIM - 1);
    }
}
Example #9
0
/* 
 * move_right
 *   DESCRIPTION: Move the player right one pixel (assumed to be a legal move)
 *   INPUTS: xpos -- pointer to player's x position (pixel) in the maze
 *   OUTPUTS: *xpos -- increased by one from initial value
 *   RETURN VALUE: none
 *   SIDE EFFECTS: pans display by one pixel when appropriate
 */
static void
move_right (int* xpos)
{
    /*
     * Move player by one pixel and check whether display should be panned.
     * Panning is necessary when the player moves past the right pan border
     * while the rightmost pixels of the maze are not on-screen.
     */
    if (++(*xpos) > game_info.map_x + SCROLL_X_DIM -
	    BLOCK_X_DIM * (PAN_BORDER + 1) &&
	game_info.map_x + SCROLL_X_DIM < 
	    (2 * game_info.maze_x_dim + 1) * BLOCK_X_DIM - SHOW_MIN) {
	/*
	 * Shift the logical view to the right by one pixel and draw the
	 * new line.
	 */
	set_view_window (++game_info.map_x, game_info.map_y);
	(void)draw_vert_line (SCROLL_X_DIM - 1);
    }
}
Example #10
0
/* 
 * game_loop
 *   DESCRIPTION: Main event loop for the adventure game.
 *   INPUTS: none
 *   OUTPUTS: none
 *   RETURN VALUE: GAME_QUIT if the player quits, or GAME_WON if they have won
 *   SIDE EFFECTS: drives the display, etc.
 */
static game_condition_t
game_loop ()
{
    /* 
     * Variables used to carry information between event loop ticks; see
     * initialization below for explanations of purpose.
     */
    struct timeval start_time, tick_time;

    struct timeval cur_time; /* current time (during tick)      */
    cmd_t cmd;               /* command issued by input control */
    int32_t enter_room;      /* player has changed rooms        */

    /* Record the starting time--assume success. */
    (void)gettimeofday (&start_time, NULL);

    /* Calculate the time at which the first event loop tick should occur. */
    tick_time = start_time;
    if ((tick_time.tv_usec += TICK_USEC) > 1000000) {
	tick_time.tv_sec++;
	tick_time.tv_usec -= 1000000;
    }

    /* The player has just entered the first room. */
    enter_room = 1;

    /* The main event loop. */
    while (1) {
	/* 
	 * Update the screen, preparing the VGA palette and photo-drawing
	 * routines and drawing a new room photo first if the player has
	 * entered a new room, then showing the screen (and status bar,
	 * once you have it working).
	 */
	if (enter_room) {
	    /* Reset the view window to (0,0). */
	    game_info.map_x = game_info.map_y = 0;
	    set_view_window (game_info.map_x, game_info.map_y);

	    /* Discard any partially-typed command. */
	    reset_typed_command ();
	    
	    /* Adjust colors and photo drawing for the current room photo. */
	    prep_room (game_info.where);

	    /* Draw the room (calls show. */
	    redraw_room ();

	    /* Only draw once on entry. */
	    enter_room = 0;
	}

	show_screen ();
	//lock status_msg to prevent changes
	(void)pthread_mutex_lock (&msg_lock);
	room_t* curr_room = game_info.where; // This is the current room pointer
	// Now call fill_status_bar with all the possible strings as params
	fill_status_bar(room_name(curr_room), get_typed_command(), status_msg);
	(void)pthread_mutex_unlock (&msg_lock); //unlock
	// Calculate game time
	display_time_on_tux (cur_time.tv_sec - start_time.tv_sec);
	/*
	 * Wait for tick.  The tick defines the basic timing of our
	 * event loop, and is the minimum amount of time between events.
	 */
	do {
	    if (gettimeofday (&cur_time, NULL) != 0) {
		/* Panic!  (should never happen) */
		clear_mode_X ();
		shutdown_input ();
		perror ("gettimeofday");
		exit (3);
	    }
	} while (!time_is_after (&cur_time, &tick_time));

	/*
	 * Advance the tick time.  If we missed one or more ticks completely, 
	 * i.e., if the current time is already after the time for the next 
	 * tick, just skip the extra ticks and advance the clock to the one
	 * that we haven't missed.
	 */
	do {
	    if ((tick_time.tv_usec += TICK_USEC) > 1000000) {
		tick_time.tv_sec++;
		tick_time.tv_usec -= 1000000;
	    }
	} while (time_is_after (&cur_time, &tick_time));

	/*
	 * Handle asynchronous events.  These events use real time rather
	 * than tick counts for timing, although the real time is rounded
	 * off to the nearest tick by definition.
	 */
	/* (none right now...) */

	/* 
	 * Handle synchronous events--in this case, only player commands. 
	 * Note that typed commands that move objects may cause the room
	 * to be redrawn.
	 */
	
	cmd = get_command ();
	switch (cmd) {
	    case CMD_UP:    move_photo_down ();  break;
	    case CMD_RIGHT: move_photo_left ();  break;
	    case CMD_DOWN:  move_photo_up ();    break;
	    case CMD_LEFT:  move_photo_right (); break;
	    case CMD_MOVE_LEFT:   
		enter_room = (TC_CHANGE_ROOM == 
			      try_to_move_left (&game_info.where));
		break;
	    case CMD_ENTER:
		enter_room = (TC_CHANGE_ROOM ==
			      try_to_enter (&game_info.where));
		break;
	    case CMD_MOVE_RIGHT:
		enter_room = (TC_CHANGE_ROOM == 
			      try_to_move_right (&game_info.where));
		break;
	    case CMD_TYPED:
		if (handle_typing ()) {
		    enter_room = 1;
		}
		break;
	    case CMD_QUIT: return GAME_QUIT;
	    default: break;
	}
	// Repeat the same thing for the tux
	cmd = get_tux_command();
	switch (cmd) {
	    case CMD_UP:    move_photo_down ();  break;
	    case CMD_RIGHT: move_photo_left ();  break;
	    case CMD_DOWN:  move_photo_up ();    break;
	    case CMD_LEFT:  move_photo_right (); break;
	    case CMD_MOVE_LEFT:   
		enter_room = (TC_CHANGE_ROOM == 
			      try_to_move_left (&game_info.where));
		break;
	    case CMD_ENTER:
		enter_room = (TC_CHANGE_ROOM ==
			      try_to_enter (&game_info.where));
		break;
	    case CMD_MOVE_RIGHT:
		enter_room = (TC_CHANGE_ROOM == 
			      try_to_move_right (&game_info.where));
		break;
	    case CMD_QUIT: return GAME_QUIT;
	    default: break;
	}
	/* If player wins the game, their room becomes NULL. */
	if (NULL == game_info.where) {
	    return GAME_WON;
	}
    } /* end of the main event loop */
}