Ejemplo n.º 1
0
/* 
 *tux_thread
 *   DESCRIPTION: Function executed by tux helper thread.
 *             
 *   INPUTS: none (ignored)
 *   OUTPUTS: none
 *   RETURN VALUE: NULL
 *   SIDE EFFECTS: get the command from the tux and do the corrosponding operations.
 */
static void*
tux_thread (void* ignore)
{
	cmd_t cmd;
	struct timeval start_time, tick_time;

    struct timeval cur_time; /* current time (during tick)      */


    /* 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;
    }

	while(1)
	{
		(void)pthread_mutex_lock (&cmd_lock);
    
    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: 
			game = GAME_QUIT; break;
	    default: break;
	}

    (void)pthread_mutex_unlock (&cmd_lock);
	/* If player wins the game, their room becomes NULL. */
	if (NULL == game_info.where) {
	    game = GAME_WON;
	}


	/*
	 * 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));
	}
	
	
	return NULL;
}
Ejemplo n.º 2
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 */
}
Ejemplo n.º 3
0
/*
 * main
 *   DESCRIPTION: Initializes and runs the two threads
 *   INPUTS: none
 *   OUTPUTS: none
 *   RETURN VALUE: 0 on success, -1 on failure
 *   SIDE EFFECTS: none
 */
int main()
{
	int ret;
   	struct termios tio_new;
	unsigned long update_rate = 32; /* in Hz */

	pthread_t tid1;
	pthread_t tid2;
	pthread_t tid3;

	// Initialize RTC
	fd = open("/dev/rtc", O_RDONLY, 0);
	// Enable RTC periodic interrupts at update_rate Hz
	// Default max is 64...must change in /proc/sys/dev/rtc/max-user-freq
	ret = ioctl(fd, RTC_IRQP_SET, update_rate);	
	ret = ioctl(fd, RTC_PIE_ON, 0);
	
	//Initialize Tux control
	tux_fd=open("/dev/ttyS0", O_RDWR | O_NOCTTY);
	int ldsic_num = N_MOUSE;
	ioctl(tux_fd, TIOCSETD, &ldsic_num);
	ioctl(tux_fd, TUX_INIT);
	

	// Initialize Keyboard
	// Turn on non-blocking mode
    	if (fcntl (fileno (stdin), F_SETFL, O_NONBLOCK) != 0) 
	{
        	perror ("fcntl to make stdin non-blocking");
		return -1;
    	}
	
	// Save current terminal attributes for stdin.
    	if (tcgetattr (fileno (stdin), &tio_orig) != 0) 
	{
		perror ("tcgetattr to read stdin terminal settings");
		return -1;
	}
	
	// Turn off canonical (line-buffered) mode and echoing of keystrokes
 	// Set minimal character and timing parameters so as
        tio_new = tio_orig;
    	tio_new.c_lflag &= ~(ICANON | ECHO);
    	tio_new.c_cc[VMIN] = 1;
    	tio_new.c_cc[VTIME] = 0;
    	if (tcsetattr (fileno (stdin), TCSANOW, &tio_new) != 0) 
	{
		perror ("tcsetattr to set stdin terminal settings");
		return -1;
	}


	// Perform Sanity Checks and then initialize input and display
	if ((sanity_check () != 0) || (set_mode_X (fill_horiz_buffer, fill_vert_buffer) != 0))
	{
		return 3;
	}

	// Create the threads
	pthread_create(&tid1, NULL, rtc_thread, NULL);
	pthread_create(&tid2, NULL, keyboard_thread, NULL);
	pthread_create(&tid3, NULL, tux_thread, NULL);
	
	// Wait for all the threads to end
	pthread_join(tid1, NULL);
	pthread_join(tid2, NULL);
	pthread_join(tid3, NULL);

	// Shutdown Display
	clear_mode_X();
	
	// Close Keyboard
	(void)tcsetattr (fileno (stdin), TCSANOW, &tio_orig);
		
	// Close RTC
	close(fd);
	
	//Close Tux Control
	close(tux_fd);

	// Print outcome of the game
	if (winner == 1)
	{	
		printf ("You win the game!  CONGRATULATIONS!\n");
	}
	else if (quit_flag == 1)
	{
		printf ("Quitter!\n");
	}
	else
	{
		printf ("Sorry, you lose...\n");
	}

	// Return success
	return 0;
}