/*
====================================================================
Clear all client data.
====================================================================
*/
void client_data_clear( void )
{
    list_clear( client_users );
    client_user = 0;
    list_clear( client_channels );
    list_clear( client_levelsets );
    client_levelset = 0;
    gui_list_update( list_users, 0 );
    gui_list_update( list_channels, 0 );
    gui_list_update( list_levels, 0 );
}
static void client_add_pause_chatter_intern( 
    GuiWidget *list, char *string, int info )
{
    int i, j;
    static Text *text;
    /* build new text */
    text = create_text( string, 52 );
    /* move old lines up */
    for ( i = 0; i < CHAT_LINE_COUNT - text->count; i++ )
        strcpy( pause_chatter[i], pause_chatter[i + text->count] );
    /* copy new lines */
    for ( j = 0, i = CHAT_LINE_COUNT - text->count; 
          i < CHAT_LINE_COUNT; i++, j++ ) {
        if ( info ) {
            strcpy( pause_chatter[i] + 1, text->lines[j] );
            pause_chatter[i][0] = '!';
        }
        else if ( j > 0 ) {
            strcpy( pause_chatter[i] + 3 + info, text->lines[j] );
            pause_chatter[i][0] = ' '; 
            pause_chatter[i][1] = ' '; 
            pause_chatter[i][2] = ' ';
        }
        else
            strcpy( pause_chatter[i], text->lines[j] );
    }
    /* free memory */
    delete_text( text );
    /* update gui */
    gui_list_update( list, CHAT_LINE_COUNT );
}
예제 #3
0
/*
====================================================================
Select topic and display help text.
====================================================================
*/
void client_handle_topic_list( GuiWidget *widget, GuiEvent *event )
{
	if ( event->type != GUI_ITEM_SELECTED ) return;
	if ( event->item.y >= client_topic_count ) return;
	gui_list_goto( list_help, 0 );
	if ( client_help_text ) delete_text( client_help_text );
	client_help_text = create_text( client_helps[event->item.y], 41 );
	gui_list_update( list_help, client_help_text->count );
}
예제 #4
0
/*
====================================================================
Open channel selector
====================================================================
*/
void client_select_channel( GuiWidget *widget, GuiEvent *event )
{
    if ( event->type != GUI_CLICKED ) return;
    /* select first channel (we always have MAIN) */
    gui_list_update( list_channels, client_channels->count );
    if ( client_channels->count > 0 ) {
        gui_edit_set_text( edit_channel, list_first( client_channels ) );
        gui_list_select( list_channels, 0,0, 1 );
    }
    gui_widget_show( dlg_channels );
    client_state = CLIENT_SELECT_CHANNEL;
}
예제 #5
0
/*
====================================================================
Build the GUI and everything nescessary for the client chatroom.
client_create() installs client_delete() as exit function.
====================================================================
*/
void client_create( void )
{
#ifdef NETWORK_ENABLED
    GuiWidget *parent;
    SDL_Surface *surface;
    /* users, channels, games */
    client_data_create();
    /* CONNECT WINDOW */
    dlg_connect = gui_box_create( 0, -1,-1, 400, 224, 0, 0 );
    parent = dlg_connect;
    /* hint label */
    gui_label_create( 
        parent, 10, 10, parent->width - 20, 100, 1, 
        0, 4, 0, STK_FONT_ALIGN_LEFT, HINT_CONNECT );
    /* server edit */
    gui_label_create( 
        parent, 10, 120, 180, 20, 0, 
        0, 2, 0, STK_FONT_ALIGN_RIGHT, _("Server:") );
    edit_server = gui_edit_create(
        parent, parent->width - 190, 120, 180, 20,
        0, 2, 0, 22, config.server );
    /* user name */
    gui_label_create( 
        parent, 10, 150, 180, 20, 0, 
        0, 2, 0, STK_FONT_ALIGN_RIGHT, _("Username:"******"Connect") );
    gui_button_create(
        parent, parent->width/2 +20, 180, 
        140, 24, client_close_connect_window, 0,0,0,0,0, _("Cancel") );
    /* INFO */
    dlg_info = gui_box_create( 0, -1,-1, 300, 114, 0, 1 );
    label_info = gui_label_create( dlg_info, -1,10,276,60,0, 0,
        2, 0, STK_FONT_ALIGN_LEFT, _("no info") );
    gui_button_create( dlg_info, 
        -1, dlg_info->height - 34,
        100, 24, client_close_info, 0,0,0,0,0,
        _("Close") );
    /* CONFIRM */
    dlg_confirm = gui_box_create( 0, -1,-1, 300, 160, 0, 1 );
    label_confirm = gui_label_create( dlg_confirm, -1,10,276,110,0, 0,
        2, 0, STK_FONT_ALIGN_LEFT, _("no info") );
    gui_button_create( dlg_confirm, 
        dlg_confirm->width/2-110, dlg_confirm->height - 30,
        100, 20, client_confirm, 0,0,0,0,0,
        _("OK") );
    gui_button_create( dlg_confirm, 
        dlg_confirm->width/2+10, dlg_confirm->height - 30,
        100, 20, client_cancel, 0,0,0,0,0,
        _("Cancel") );
    /* CHATROOM */
    dlg_chatroom = gui_box_create( 0, 0,0,640,480, 
        client_recv_packet, 1 );
    gui_widget_enable_event( dlg_chatroom, GUI_TIME_PASSED );
    surface = gui_widget_get_surface( dlg_chatroom );
    stk_surface_apply_wallpaper( 
        surface, 0,0,-1,-1, cr_wallpaper, STK_OPAQUE );
    /* chat window */
    list_chatter = gui_list_create( dlg_chatroom, 0,0,470,444, NULL,
        0, 1, 14, 20, client_render_chatter, GUI_LIST_NO_SELECT );
    /* edit + send/whisper buttons */
    gui_button_create( dlg_chatroom, 330,448,60,24, 
        client_send_chatter, 0,0,0,0,0, _("Send") );
    gui_button_create( dlg_chatroom, 390,448,80,24, 
        client_whisper_chatter, 0,0,0,0,0, _("Whisper") );
    edit_chatter = gui_edit_create( dlg_chatroom, 0,448,327,24,
        client_send_chatter, 2, 0, MAX_CHATTER_SIZE, "" );
    gui_widget_enable_event( edit_chatter, GUI_KEY_RELEASED );
    gui_widget_set_default_key_widget( dlg_chatroom, edit_chatter );
    /* channel button + users in channel */
    label_channel = gui_label_create( dlg_chatroom, 
        474,0,142,18,1, NULL,
        2, 0, STK_FONT_ALIGN_CENTER_X, _("MAIN") );
    gui_button_create( dlg_chatroom, 616,0,18,18, 
        client_select_channel,
        0,0,0,0,0, _("C") );
    list_users = gui_list_create( dlg_chatroom, 
        474,20,160,142, client_handle_user_list,
        1, 1, 14, 20, client_render_user, 
        GUI_LIST_SINGLE_SELECT );
    /* levels label, levels, transfer button */
    gui_label_create( dlg_chatroom, 474,164,160,18,1, NULL,
        2, 0, STK_FONT_ALIGN_CENTER_X, _("Levelsets") );
    list_levels = gui_list_create( dlg_chatroom, 
        474,184,160,120, client_handle_levelset_list,
        1, 1, 14, 20, client_render_levelset, 
        GUI_LIST_SINGLE_SELECT );
    /* box with level settings */
    parent = gui_box_create( dlg_chatroom,
        474,306,160,94, NULL, 0 );
    gui_label_create( parent, 2,2,102,20,0, NULL,
        2, NULL, STK_FONT_ALIGN_LEFT, _("Difficulty:") );
    gui_spinbutton_create( parent, 102,2,50,20, 
        client_update_difficulty,
        1, 3, 1, config.mp_diff+1 );
    gui_label_create( parent, 2,2+22,102,20,0, NULL,
        2, NULL, STK_FONT_ALIGN_LEFT, _("Rounds:") );
    gui_spinbutton_create( parent, 102,2+22,50,20,
        client_update_rounds,
        1, 3, 1, config.mp_rounds );
    gui_label_create( parent, 2,2+44,102,20,0, NULL,
        2, NULL, STK_FONT_ALIGN_LEFT, _("Frags:") );
    gui_spinbutton_create( parent, 102,2+44,50,20, 
        client_update_frags,
        5, 30, 5, config.mp_frags );
    gui_label_create( parent, 2,2+66,102,20,0, NULL,
        2, NULL, STK_FONT_ALIGN_LEFT, _("Balls:") );
    gui_spinbutton_create( parent, 102,2+66,50,20,
        client_update_balls,
        1, 6, 1, config.mp_balls );
    /* challenge & disconnect */
    gui_button_create( dlg_chatroom, 
        474,402,160,20, client_challenge,
        0,0,0,0,0, _("Challenge") );
    gui_button_create( dlg_chatroom,
	474,dlg_chatroom->height-44,160,20,
	client_open_connect_window,
	0,0,0,0,0, _("Connect") );
    gui_button_create( dlg_chatroom, 
        534,dlg_chatroom->height-20,100,20, 
        client_quit,
        0,0,0,0,0, _("Quit") );
    gui_button_create( dlg_chatroom, 
        474,dlg_chatroom->height-20,50,20, 
        client_popup_help,
        0,0,0,0,0, _("Help") );
    /* CHANNELS selector */
    dlg_channels = gui_box_create( 0, -1,-1, 200, 244, NULL, 1 );
    list_channels = gui_list_create( dlg_channels, -1,10, 176,150, 
        client_handle_channel_list, 0, 1, 14, 20, 
        client_render_channel, GUI_LIST_SINGLE_SELECT );
    gui_label_create( dlg_channels, -1,160, 176,20,0, NULL,
        2, 0, STK_FONT_ALIGN_LEFT, _("Channel:") );
    edit_channel = gui_edit_create( dlg_channels, 
        -1,180, 176,20, NULL,
        2, 0, 12, "" );
    gui_widget_set_default_key_widget( dlg_channels, edit_channel );
    gui_edit_set_filter( edit_channel, GUI_EDIT_ALPHANUMERICAL2 );
    gui_button_create( dlg_channels, 
        dlg_channels->width/2-90,210,80,20, 
        client_enter_channel, 0,0,0,0,0, _("Enter") );
    gui_button_create( dlg_channels, 
        dlg_channels->width/2+10,210,80,20, 
        client_cancel_channel, 0,0,0,0,0, _("Cancel") );
    /* STATISTICS */
    dlg_stats = gui_box_create( 0, -1,-1,386,260, NULL, 1 );
    gui_label_create( dlg_stats, -1,10,360,20,1, NULL,
        0, 0, STK_FONT_ALIGN_CENTER_X, _("Statistics") );
    label_winner = gui_label_create( dlg_stats, 
        -1,40,360,16,0, NULL,
        0, 0, STK_FONT_ALIGN_CENTER_X, "..." );
    label_stats = gui_label_create( dlg_stats, 
        -1,62,360,150,0, NULL,
        0, 0, STK_FONT_ALIGN_LEFT, _("Awaiting stats...") );
    gui_button_create( dlg_stats, -1,220,160,20,
        client_close_stats, 0,0,0,0,0, _("Close") );
    /* PAUSEROOM */
    dlg_pauseroom = gui_box_create( 0, -1,-1,480,366, NULL, 1 );
    list_pausechatter = gui_list_create( 
        dlg_pauseroom, 0,0,470,300, NULL,
        0, 1, 14, 20, client_render_pause_chatter, 
        GUI_LIST_NO_SELECT );
    edit_pausechatter = gui_edit_create( 
        dlg_pauseroom, 0,303,470,24,
        client_send_pausechatter, 2, 0, MAX_CHATTER_SIZE, "" );
    gui_widget_enable_event( edit_pausechatter, GUI_KEY_RELEASED );
    gui_widget_set_default_key_widget( dlg_pauseroom, edit_pausechatter );
    gui_button_create( dlg_pauseroom, -1,334,100,20,
        client_close_pauseroom, 0,0,0,0,0, _("Close") );
    /* HELP */
    dlg_help = gui_box_create( 0, -1,-1,548,358, NULL, 1 );
    gui_label_create( dlg_help, -1,10,470,20,1, NULL,
        0, 0, STK_FONT_ALIGN_CENTER_X, _("Network Quick Help") );
    list_topic = gui_list_create( 
        dlg_help, 10,40,160,270, client_handle_topic_list,
        0, 1, 14, 20, client_render_topic,
        GUI_LIST_SINGLE_SELECT );
    list_help = gui_list_create( 
        dlg_help, 180,40,350,300, NULL,
        0, 1, 14, 20, client_render_help, 
        GUI_LIST_NO_SELECT );
    gui_button_create( dlg_help, 10,320,160,20, client_close_help,
        0,0,0,0,0, _("Close") );
    /* INITS */
    /* empty chatter */
    memset( chatter, 0, sizeof( chatter ) );
    /* update chatboxes */
    gui_list_update( list_chatter, CHAT_LINE_COUNT );
    gui_list_update( list_pausechatter, CHAT_LINE_COUNT );
    gui_list_goto( list_chatter, -1 );
    gui_list_goto( list_pausechatter, -1 );
    /* set help topics */
    gui_list_update( list_topic, client_topic_count );
    /* call client_delete at exit */
    atexit( client_delete );
#endif
}
예제 #6
0
/* run the state driven loop until game is broken up or finished */
void client_game_run( void )
{
	int ms, frame_delay = config.fps?10:1;
	int button_clicked, key_pressed;
	SDL_Event event;
	int abort = 0, i, j, penalty;
	/* frame rate */
	int frames = 0;
	int frame_time = SDL_GetTicks();

	event_clear_sdl_queue();
	
	stk_display_fade( STK_FADE_IN, STK_FADE_DEFAULT_TIME );
	
	stats_received = 0;
	stk_timer_reset(); ms = 1;
	while ( !abort && !stk_quit_request ) {
		/* check wether an event occured */
		button_clicked = key_pressed = 0;
		if ( SDL_PollEvent( &event ) ) {
			if ( client_state == CS_PAUSE && game->game_type == GT_NETWORK )
				gui_dispatch_event( &event, ms );
			else
			if ( event.type == SDL_MOUSEBUTTONDOWN )
				button_clicked = event.button.button;
			else
			if ( event.type == SDL_KEYDOWN ) {
				key_pressed = event.key.keysym.sym;
				if ( handle_default_key( key_pressed, &abort ) )
					key_pressed = 0;
			}
			else
			if (event.type == SDL_ACTIVEEVENT)
		          {
			    if (event.active.state == SDL_APPINPUTFOCUS ||
				event.active.state == SDL_APPACTIVE )
                            if (event.active.gain == 0 )
			      client_set_pause(1);
			  }
		}
		else if ( client_state == CS_PAUSE && game->game_type == GT_NETWORK )
			gui_dispatch_event( 0, ms );

		/* check whether Shift is pressed to switch between own and highest score */
		if (game->game_type == GT_LOCAL)
		  handle_display_switch();

		/* let server know we're still alive except
		 * in CS_PLAY as we send paddle updates there */
		if ( game->game_type == GT_NETWORK )
			comm_send_heartbeat();

		/* handle client */
		switch ( client_state ) {

		case CS_FINAL_STATS:
			if ( key_pressed==SDLK_SPACE ) abort = 1;
			break;
			
		case CS_FATAL_ERROR:
			/* after game was violently broken up the server
			 * may still send the stats of the game so far */
			if ( button_clicked || key_pressed ) {
				SDL_Delay(250); /* give time to release button */
				set_state( CS_RECV_STATS );
				display_text( font, "Receiving final stats..." );
			}
			break;
			
		case CS_FINAL_TABLE:
			if ( button_clicked || key_pressed ) {
				check_highscores();
				select_chart( game_set->name, 0 );
                                /* remove saved game */
                                slot_delete( 0 );
                                slot_update_hint( 0, item_resume_0->hint );
				/* quit local game */
				abort = 1;
			}
			break;

		case CS_SCORE_TABLE:
			/* show who's next player and scores in local game */
			display_score_table( "Next Player: %s", cur_player->name );
			set_state( CS_GET_READY );
			break;
        
        case CS_BONUS_LEVEL_SCORE:
            /* display total score from this level for player */
            display_bonus_level_score();
			set_state( CS_GET_READY_FOR_NEXT_LEVEL );
            break;
			
		case CS_FINAL_PLAYER_INFO:
			if ( button_clicked || key_pressed ) {
				SDL_Delay(250); /* give time to release button */
				set_state( CS_NEXT_PLAYER );
			}
			break;

		case CS_RECV_LEVEL:
			comm_recv();
			if ( cur_player->next_level_received ) {
				cur_player->next_level_received = 0;
				cur_player->paddle_id = cur_player->next_paddle_id;
				init_next_round();
			}
			break;

		case CS_RECV_STATS:
			comm_recv();
			if ( stats_received ) {
				set_state( CS_FINAL_STATS );
				display_final_stats();
			}
			break;
			
		case CS_ROUND_RESULT:
			if ( button_clicked || key_pressed ) {
				SDL_Delay(250); /* give time to release button */
				if ( game_over ) {
					set_state( CS_RECV_STATS );
					display_text( font, "Receiving final stats..." );
				} else {
					set_state( CS_RECV_LEVEL );
					display_text( font, "Receiving level data..." );
 				}
			}
			break;
			
		case CS_GET_READY:
			if ( button_clicked || key_pressed ) {
				SDL_Delay(250); /* give time to release button */
				comm_send_short( MSG_READY );
				set_state( CS_PLAY );
			}
			break;

		case CS_GET_READY_FOR_NEXT_LEVEL:
			if ( button_clicked || key_pressed ) {
				SDL_Delay(250); /* give time to release button */
				set_state( CS_NEXT_LEVEL );
			}
			break;

		case CS_PAUSE:
			if ( game->game_type == GT_LOCAL ) break;

			/* check wether pause chatroom has been closed
			 * either by client or remote */
			comm_recv();
			break;
			
		case CS_PLAY:
			/* hide objects */
			begin_frame();
			
			/* apply events to local paddle */
			paddle_handle_events( l_paddle, ms );

			/* update local objects and communicate if
			 * comm_delay ms have passed */
			update_game( ms );
			
			/* show objects */
			end_frame();

			/* handle local level over */
			if ( game->level_over ) {
				if ( game->game_type == GT_LOCAL ) {
					if ( game_set == 0 ) {
						abort = 1; /* was a test level */
						grab_input(0);
						break;
					}
					if ( game->winner == PADDLE_BOTTOM )
                    {
                        if (local_game->isBonusLevel)
                            set_state( CS_BONUS_LEVEL_SCORE );
                        else
                            set_state( CS_NEXT_LEVEL );
                    }
					else
						set_state( CS_LOOSE_LIFE );
				} else {
					finalize_round();
				}
			}
			break;

		case CS_NEXT_LEVEL:
			/* apply paddle stats to player */
			game_set_current( local_game );
			game_update_stats( PADDLE_BOTTOM, &cur_player->stats );
			game_set_current( game );
			/* init next level for player in local game */
			cur_player->level_id++;
			if ( cur_player->level_id >= game_set->count ) {
				/* deactivate player */
				cur_player->lives = 0;
				display_text( font, 
					"You've cleared all levels...#Congratulations!!!" );
				set_state( CS_FINAL_PLAYER_INFO );
				break;
			}
			/* get snapshot for next init */
			cur_player->snapshot = *game_set->levels[cur_player->level_id];
			/* cycle players */
			set_state( CS_NEXT_PLAYER );
			break;

		case CS_RESTART_LEVEL:
			/* apply paddle stats to player */
			game_set_current( local_game );
			game_update_stats( PADDLE_BOTTOM, &cur_player->stats );
			game_set_current( game );
			/* reset level for next turn */
			cur_player->snapshot = *game_set->levels[cur_player->level_id];
			/* decrease lives (is checked that this wasn't the last one) */
			cur_player->lives--;
			/* cycle players */
			set_state( CS_NEXT_PLAYER );
			break;
			
		case CS_LOOSE_LIFE:
			/* apply paddle stats to player */
			game_set_current( local_game );
			game_update_stats( PADDLE_BOTTOM, &cur_player->stats );
			game_set_current( game );

			/* remember level for next turn */
			game_get_level_snapshot( &cur_player->snapshot );

			/* decrease lives */
			cur_player->lives--;
			if ( cur_player->lives == 0 ) {
				display_text( font, 
					"You've lost all lives...#Do you want to buy a continue#for 100%% of your score? y/n" );
                                set_state( CS_CONFIRM_CONTINUE );
				//set_state( CS_FINAL_PLAYER_INFO );
				break;
			}
			set_state( CS_NEXT_PLAYER );
			break;

		case CS_NEXT_PLAYER:
			/* game over? */
			if ( players_count() == 0 ) {
				display_score_table( "Game Over!" );
				set_state( CS_FINAL_TABLE );
				break;
			}
			/* speak and fade */
			play_speech();
			fade_anims();
			/* finalize current game context */
			finalize_level();
			/* set next player */
			cur_player = players_get_next();
			init_level( cur_player, PADDLE_BOTTOM );
			if ( player_count > 1 )
				set_state( CS_SCORE_TABLE );
			else {
				set_state( CS_PLAY ); /* one player starts immediately */
				stk_display_update( STK_UPDATE_ALL );
			}
			break;
		
                case CS_CONFIRM_CONTINUE:
		case CS_CONFIRM_QUIT:
		case CS_CONFIRM_WARP:
		case CS_CONFIRM_RESTART:
			if ( key_pressed == 0 ) break;
			if ( key_pressed==SDLK_n||key_pressed==SDLK_ESCAPE ) {
                            /* if denying continue... DIE!!! */
                            if ( client_state == CS_CONFIRM_CONTINUE )
                            {
				SDL_Delay(250); /* give time to release button */
				set_state( CS_NEXT_PLAYER );
                                //set_state( CS_FINAL_PLAYER_INFO );
                            }
                            else
				set_state( CS_PLAY );
			    break;
			}
			if ( key_pressed != SDLK_y && key_pressed != SDLK_z ) break;
			/* handle confirmed action */
			SDL_Delay(250); /* give time to release button */
			switch( client_state ) {
                                case CS_CONFIRM_CONTINUE:
                                    /* clear score and give full lives again */
                                    cur_player->lives = game->diff->lives;
                                    cur_player->stats.total_score = 0;
                                    set_state( CS_NEXT_PLAYER );
                                    break;
				case CS_CONFIRM_QUIT:
					comm_send_short( MSG_QUIT_GAME );
					if ( game->game_type == GT_LOCAL ) {
						/* apply paddle stats to player */
						game_set_current( local_game );
						game_update_stats( PADDLE_BOTTOM, &cur_player->stats );
						game_set_current( game );
                                                /* no higscore check anymore as game is supposed to
                                                 * be resumed until normal game over */
						/* testing levels don't got for
						 * high scores ***
						if ( game_set ) {
							check_highscores();
							select_chart( game_set->name, 0 );
						}*/
                                                /* save local game */
                                                if ( game_set != 0 /*not testing a level*/ )
                                                    save_local_game( 0 );
						
                                                abort = 1;
					}
					else {
						/* await game stats */
						set_state( CS_RECV_STATS );
						display_text( font, "Receiving final stats..." );
					}
					break;
				case CS_CONFIRM_WARP:
					game->winner = -1; /* no speech */
					local_game->winner = -1; /* not counted as win */
                                        /* substract doubled score of remaining bricks */
                                        penalty = 0;
                                        for ( i = 0; i < MAP_WIDTH; i++ )
                                            for ( j = 0; j < MAP_HEIGHT; j++ )
                                                if ( local_game->bricks[i][j].dur != -1 )
                                                    penalty += local_game->bricks[i][j].score;
                                        printf( "warp penalty: -%d\n", penalty );
                                        local_game->paddles[0]->score -= penalty;
					set_state( CS_NEXT_LEVEL );
					break;
				case CS_CONFIRM_RESTART:
					game->winner = -1; /* no speech */
					local_game->winner = -1; /* not counted as win */
					local_game->level_over = 1;
					set_state( CS_RESTART_LEVEL );
					break;
			}
			break;

		}

		/* update anything that was changed */
		stk_display_update( STK_UPDATE_RECTS );

		/* get time since last call and delay if below frame_delay */
		ms = stk_timer_get_time();
		if ( ms < frame_delay ) {
			SDL_Delay( frame_delay - ms );
			ms += stk_timer_get_time();
		}
		frames++;
	}
	finalize_level();
	client_state = CLIENT_NONE;

	stk_display_fade( STK_FADE_OUT, STK_FADE_DEFAULT_TIME );
	if ( stk_quit_request )
		comm_send_short( MSG_DISCONNECT );
	else
		comm_send_short( MSG_UNHIDE );

	/* frame rate */
	frame_time = SDL_GetTicks() - frame_time;
	printf( "Time: %.2f, Frames: %i -> FPS: %.2f\n", 
		(double)frame_time / 1000, frames, 1000.0*frames/frame_time );

	event_clear_sdl_queue();

	/* update the selected user and the user list in network as 
	 * we received ADD/REMOVE_USER messages */
	gui_list_update( list_users, client_users->count );
	/* re-select current entry */
	if ( client_user ) {
		i = list_check( client_users, client_user );
		if ( i != -1 )
			gui_list_select( list_users, 0, i, 1 );
	}
}
예제 #7
0
static void client_parse_packet()
{
	int i, num;
	char name[16];
	unsigned char type;
	int handled;
	
	while ( 1 ) {
		type = (unsigned)msg_read_int8(); handled = 0;
		
		if ( msg_read_failed() ) break; /* no more messages */

		switch ( type ) {
		    	case MSG_PREPARE_FULL_UPDATE:
				/* do only clear users as channels and
				 * levelsets are fixed */
				list_clear( client_users ); client_user = 0;
				handled = 1;
				break;
			case MSG_ERROR:
				client_printf_chatter( 1, _("ERROR: %s"), msg_read_string() );
				handled = 1;
				break;
			case MSG_BUSY:
				if ( client_state == CLIENT_AWAIT_ANSWER ||
				     client_state == CLIENT_AWAIT_TRANSFER_CONFIRMATION )
					client_popup_info( 
						_("%s is busy at the moment."), 
						mp_peer_name );
				handled = 1;
				break;
			case MSG_DISCONNECT:
				client_disconnect();
				handled = 1;
				break;
			case MSG_SET_COMM_DELAY:
				client_comm_delay = msg_read_int16();
				printf( _("comm_delay set to %i\n"), client_comm_delay );
				handled = 1;
				break;
			/* chatter */
			case MSG_SERVER_INFO:
				client_add_chatter( msg_read_string(), 1 );
				handled = 1;
				break;
			case MSG_CHATTER:
				client_add_chatter( msg_read_string(), 0 );
				handled = 1;
				break;
			/* users */
			case MSG_ADD_USER:
				num = msg_read_int32();
				snprintf( name, 16, "%s", msg_read_string() ); name[15] = 0;
				if ( msg_read_failed() ) break;
				client_add_user( num, name );
				gui_list_update( 
						list_users, 
						client_users->count );
				/* re-select current entry */
				if ( client_user ) {
					num = list_check( client_users, client_user );
					if ( num != -1 )
						gui_list_select( list_users, 0, num, 1 );
				}
				handled = 1;
				break;
			case MSG_REMOVE_USER:
				num = msg_read_int32();
				if ( msg_read_failed() ) break;
				client_remove_user( num );
				gui_list_update( 
					list_users, 
					client_users->count );
				/* re-select current entry */
				if ( client_user ) {
					num = list_check( client_users, client_user );
					if ( num != -1 )
						gui_list_select( list_users, 0, num, 1 );
				}
				handled = 1;
				break;
			case MSG_CHANNEL_LIST:
				list_clear( client_channels );
				num = msg_read_int8();
				for ( i = 0; i < num; i++ )
					list_add( client_channels, strdup(msg_read_string()) );
				handled = 1;
				break;
			case MSG_LEVELSET_LIST:
				list_clear( client_levelsets );
				num = msg_read_int8();
				for ( i = 0; i < num; i++ )
					list_add( client_levelsets, strdup(msg_read_string()) );
    				gui_list_update( list_levels, client_levelsets->count );
				handled = 1;
				break;
			case MSG_ADD_LEVELSET:
				list_add( client_levelsets, strdup(msg_read_string()) );
    				gui_list_update( list_levels, client_levelsets->count );
				handled = 1;
				break;
			case MSG_SET_CHANNEL:
				/* we only need to update the name */
				gui_label_set_text( label_channel, msg_read_string() );
				handled = 1;
				break;
			/* challenge */
			case MSG_CHALLENGE:
				/* the user may only be challenged if client state is NONE
				   because otherwise he is doing something that shouldn't be
				   interrupted */
				if ( client_state != CLIENT_NONE ) {
					msg_begin_writing( msgbuf, &msglen, 128 );
					msg_write_int8( MSG_BUSY );
					msg_write_int32( msg_read_int32() );
					client_transmit( CODE_BLUE, msglen, msgbuf );
					break;
				}
				snprintf( mp_peer_name, 15, "%s", msg_read_string() );
				snprintf( mp_levelset, 16, "%s", msg_read_string() );
				mp_diff = msg_read_int8();
				mp_rounds = msg_read_int8();
				mp_frags = msg_read_int8();
				mp_balls = msg_read_int8();
				if ( msg_read_failed() ) break;
				client_popup_confirm( _("    You have been challenged!##"\
						"    Challenger: %13s#"\
						"    Levelset:   %13s#"\
						"    Difficulty: %13s#"\
						"    Rounds:     %13i#"\
						"    Frag Limit: %13i#"\
						"    Balls:      %13i"),
						mp_peer_name, mp_levelset, mp_diff_names[mp_diff],
						mp_rounds, mp_frags, mp_balls );
				client_state = CLIENT_ANSWER;
				handled = 1;
				break;
			case MSG_REJECT_CHALLENGE:
				handled = 1;
				if ( client_state != CLIENT_AWAIT_ANSWER ) break;
				client_popup_info( 
					_("%s is too scared to accept your challenge."), 
					mp_peer_name );
				break;
			case MSG_CANCEL_GAME:
				handled = 1;
				if ( client_state != CLIENT_ANSWER ) break;
				gui_widget_hide( dlg_confirm );
				client_popup_info( _("%s got cold feet."), mp_peer_name );
				break;
			case MSG_ACCEPT_CHALLENGE:
				handled = 1;
				if ( client_state != CLIENT_AWAIT_ANSWER ) break;
				gui_widget_hide( dlg_info );

				/* play */
				gui_disable_event_filter();
				if ( client_game_init_network( mp_peer_name, mp_diff ) )
					client_game_run();
				client_game_finalize();
				gui_enable_event_filter();

				gui_widget_draw( dlg_chatroom );
				stk_display_fade( STK_FADE_IN, STK_FADE_DEFAULT_TIME );
				break;

			/* dummy parse game packets that may arrive after the QUIT_GAME
			 * message was sent because ADD_USER commands may be in the
			 * package and these we should get. */
			case MSG_PADDLE_STATE:
				comm_unpack_paddle_dummy( net_buffer, &msg_read_pos );
				handled = 1;
				break;
			case MSG_SHOT_POSITIONS:
				comm_unpack_shots_dummy( net_buffer, &msg_read_pos );
				handled = 1;
				break;
			case MSG_BALL_POSITIONS:
				comm_unpack_balls_dummy( net_buffer, &msg_read_pos );
				handled = 1;
				break;
			case MSG_SCORES:
				comm_unpack_scores_dummy( net_buffer, &msg_read_pos );
				handled = 1;
				break;
			case MSG_BRICK_HITS:
				comm_unpack_brick_hits_dummy( net_buffer, &msg_read_pos );
				handled = 1;
				break;
			case MSG_NEW_EXTRAS:
				comm_unpack_collected_extras_dummy( net_buffer, &msg_read_pos );
				handled = 1;
				break;
			case MSG_ROUND_OVER:
				i = msg_read_int8();
				handled = 1;
				break;
			case MSG_LAST_ROUND_OVER:
				i = msg_read_int8();
				handled = 1;
				break;

		}

		if ( !handled ) {
			printf( _("chat: state %i: invalid message %x: skipping %i bytes\n"),
				client_state, type, net_buffer_cur_size - msg_read_pos );
			msg_read_pos = net_buffer_cur_size;
		}
	}
}