Ejemplo n.º 1
0
// something has gone wrong :(
void network_tyrian_halt( unsigned int err, bool attempt_sync )
{
#ifdef __BLACKBERRY__
	quit = true;
#else
	const char *err_msg[] = {
		"Quitting...",
		"Other player quit the game.",
		"Network connection was lost.",
		"Network connection failed.",
		"Network version mismatch.",
		"Network delay mismatch.",
		"Network player number conflict.",
	};

	quit = true;

	if (err >= COUNTOF(err_msg))
		err = 0;

	fade_black(10);

	VGAScreen = VGAScreenSeg;

	JE_loadPic(VGAScreen, 2, false);
	JE_dString(VGAScreen, JE_fontCenter(err_msg[err], SMALL_FONT_SHAPES), 140, err_msg[err], SMALL_FONT_SHAPES);

	JE_showVGA();
	fade_palette(colors, 10, 0, 255);

	if (attempt_sync)
	{
		while (!network_is_sync() && network_is_alive())
		{
			service_SDL_events(false);

			network_check();
			SDL_Delay(16);
		}
	}

	if (err)
	{
		while (!JE_anyButton())
			SDL_Delay(16);
	}

	fade_black(10);

	SDLNet_Quit();

	JE_tyrianHalt(5);
#endif
}
Ejemplo n.º 2
0
void wait_noinput( JE_boolean keyboard, JE_boolean mouse, JE_boolean joystick )
{
	service_SDL_events(false);
	while ((keyboard && keydown) || (mouse && mousedown) || (joystick && joydown))
	{
		SDL_Delay(SDL_POLL_INTERVAL);
		poll_joysticks();
		service_SDL_events(false);

		if (isNetworkGame)
			network_check();
	}
}
Ejemplo n.º 3
0
void wait_noinput( JE_boolean keyboard, JE_boolean mouse, JE_boolean joystick )
{
	service_SDL_events(false);
	while ((keyboard && keydown) || (mouse && mousedown) || (joystick && joydown))
	{
		JE_showVGA(); // Must update screen on Android to get new mouse events
		SDL_Delay(SDL_POLL_INTERVAL);
		poll_joysticks();
		service_SDL_events(false);
		
#ifdef WITH_NETWORK
		if (isNetworkGame)
			network_check();
#endif
	}
}
Ejemplo n.º 4
0
// attempt to punch through firewall by firing off UDP packets at the opponent
// exchange game information
int network_connect( void )
{
#ifdef __BLACKBERRY__
#else
	SDLNet_ResolveHost(&ip, network_opponent_host, network_opponent_port);

	SDLNet_UDP_Bind(socket, 0, &ip);

	Uint16 episodes = 0, episodes_local = 0;
	assert(EPISODE_MAX <= 16);
	for (int i = EPISODE_MAX - 1; i >= 0; i--)
	{
		episodes <<= 1;
		episodes |= (episodeAvail[i] != 0);
	}
	episodes_local = episodes;

	assert(NET_PACKET_SIZE - 12 >= 20 + 1);
	if (strlen(network_player_name) > 20)
		network_player_name[20] = '\0';

connect_reset:
	network_prepare(PACKET_CONNECT);
	SDLNet_Write16(NET_VERSION, &packet_out_temp->data[4]);
	SDLNet_Write16(network_delay,   &packet_out_temp->data[6]);
	SDLNet_Write16(episodes_local,  &packet_out_temp->data[8]);
	SDLNet_Write16(thisPlayerNum,   &packet_out_temp->data[10]);
	strcpy((char *)&packet_out_temp->data[12], network_player_name);
	network_send(12 + strlen(network_player_name) + 1); // PACKET_CONNECT

	// until opponent sends connect packet
	while (true)
	{
		push_joysticks_as_keyboard();
		service_SDL_events(false);

		if (newkey && lastkey_sym == SDLK_ESCAPE)
			network_tyrian_halt(0, false);

		// never timeout
		last_in_tick = SDL_GetTicks();

		if (packet_in[0] && SDLNet_Read16(&packet_in[0]->data[0]) == PACKET_CONNECT)
			break;

		network_update();
		network_check();

		SDL_Delay(16);
	}

connect_again:
	if (SDLNet_Read16(&packet_in[0]->data[4]) != NET_VERSION)
	{
		fprintf(stderr, "error: network version did not match opponent's\n");
		network_tyrian_halt(4, true);
	}
	if (SDLNet_Read16(&packet_in[0]->data[6]) != network_delay)
	{
		fprintf(stderr, "error: network delay did not match opponent's\n");
		network_tyrian_halt(5, true);
	}
	if (SDLNet_Read16(&packet_in[0]->data[10]) == thisPlayerNum)
	{
		fprintf(stderr, "error: player number conflicts with opponent's\n");
		network_tyrian_halt(6, true);
	}

	episodes = SDLNet_Read16(&packet_in[0]->data[8]);
	for (int i = 0; i < EPISODE_MAX; i++) {
		episodeAvail[i] &= (episodes & 1);
		episodes >>= 1;
	}

	network_opponent_name = malloc(packet_in[0]->len - 12 + 1);
	strcpy(network_opponent_name, (char *)&packet_in[0]->data[12]);

	network_update();

	// until opponent has acknowledged
	while (!network_is_sync())
	{
		service_SDL_events(false);

		// got a duplicate packet; process it again (but why?)
		if (packet_in[0] && SDLNet_Read16(&packet_in[0]->data[0]) == PACKET_CONNECT)
			goto connect_again;

		network_check();

		// maybe opponent didn't get our packet
		if (SDL_GetTicks() - last_out_tick > NET_RETRY)
			goto connect_reset;

		SDL_Delay(16);
	}

	// send another packet since sometimes the network syncs without both connect packets exchanged
	// there should be a better way to handle this
	network_prepare(PACKET_CONNECT);
	SDLNet_Write16(NET_VERSION, &packet_out_temp->data[4]);
	SDLNet_Write16(network_delay,   &packet_out_temp->data[6]);
	SDLNet_Write16(episodes_local,  &packet_out_temp->data[8]);
	SDLNet_Write16(thisPlayerNum,   &packet_out_temp->data[10]);
	strcpy((char *)&packet_out_temp->data[12], network_player_name);
	network_send(12 + strlen(network_player_name) + 1); // PACKET_CONNECT

	connected = true;
#endif

	return 0;
}
Ejemplo n.º 5
0
// receive state packet, wait until received
bool network_state_update( void )
{
#ifdef __BLACKBERRY__
	return false;
#else
	if (network_state_is_reset())
	{
		return 0;
	} else {
		packets_shift_up(packet_state_in, NET_PACKET_QUEUE);

		packets_shift_up(packet_state_in_xor, NET_PACKET_QUEUE);

		last_state_in_sync++;

		// current xor packet index
		int x = network_delay - (last_state_in_sync - 1) % network_delay - 1;

		// loop until needed packet is available
		while (!packet_state_in[0])
		{
			// xor the packet from thin air, if possible
			if (packet_state_in_xor[x] && SDLNet_Read16(&packet_state_in_xor[x]->data[0]) == PACKET_STATE_XOR)
			{
				// check for all other required packets
				bool okay = true;
				for (int i = 1; i <= x; i++)
				{
					if (packet_state_in[i] == NULL)
					{
						okay = false;
						break;
					}
				}
				if (okay)
				{
					packet_state_in[0] = SDLNet_AllocPacket(NET_PACKET_SIZE);
					packet_copy(packet_state_in[0], packet_state_in_xor[x]);
					for (int i = 1; i <= x; i++)
						for (int j = 4; j < packet_state_in[0]->len; j++)
							packet_state_in[0]->data[j] ^= packet_state_in[i]->data[j];
					break;
				}
			}

			static Uint32 resend_tick = 0;
			if (SDL_GetTicks() - last_state_in_tick > NET_RESEND && SDL_GetTicks() - resend_tick > NET_RESEND)
			{
				SDLNet_Write16(PACKET_STATE_RESEND,    &packet_out_temp->data[0]);
				SDLNet_Write16(last_state_in_sync - 1, &packet_out_temp->data[2]);
				network_send_no_ack(4);  // PACKET_RESEND

				resend_tick = SDL_GetTicks();
			}

			if (network_check() == 0)
				SDL_Delay(1);
		}

		if (network_delay > 1)
		{
			// process the current in packet against the xor queue
			if (packet_state_in_xor[x] == NULL)
			{
				packet_state_in_xor[x] = SDLNet_AllocPacket(NET_PACKET_SIZE);
				packet_copy(packet_state_in_xor[x], packet_state_in[0]);
				packet_state_in_xor[x]->status = 0;
			} else {
				for (int j = 4; j < packet_state_in_xor[x]->len; j++)
					packet_state_in_xor[x]->data[j] ^= packet_state_in[0]->data[j];
			}
		}

		last_state_in_tick = SDL_GetTicks();
	}

	return 1;
#endif
}
Ejemplo n.º 6
0
int main(void){

    /*
     * Initializations
     */
    cli();

    // Make sure interrupts belong to us
    MCUCR = (1<<IVCE);
    MCUCR = 0;

    // Initialize global variables
    g_ext_ref_present = false;
    g_gps_present = false;
    g_switch_pos = PREFER_INTERNAL;
    g_ref = NO_REF;

    // Atmega128
    setup_atmel_io_ports();

    // Reset ClkDist chip
    reset_TI_CDCE18005();

    // GPSDO communication
    usart_init();

    // Ethernet stack
    network_init();
    register_udp_listener(OCTOCLOCK_UDP_CTRL_PORT,  handle_udp_ctrl_packet);
    register_udp_listener(OCTOCLOCK_UDP_GPSDO_PORT, handle_udp_gpsdo_packet);

    // Timers
    TIMER1_INIT(); // Network
    TIMER3_INIT(); // External reference check

    // Debug (does nothing when not in debug mode)
    DEBUG_INIT();
    DEBUG_LOG(" "); // Force a newline between runs

    leds_off();

    sei();

    // Check if GPS present (should only need to happen once)
    g_gps_present = (PIND & (1<<DDD4));

    // State of previous iteration
    prev_ref           = NO_REF;
    prev_switch_pos    = PREFER_EXTERNAL;
    cli();
    prev_ICR3          = ICR3;
    sei();
    prev_num_overflows = 0;

    /*
     * Main loop
     */
    while(true){
        // Check switch position
        g_switch_pos = (PINC & (1<<DDC1)) ? PREFER_EXTERNAL : PREFER_INTERNAL;

        /*
         * Check input capture pin for external reference detection.
         *
         * 16-bit reads could be corrupted during an interrupt, so
         * disable interrupts for safety.
         */
        cli();
        current_ICR3          = ICR3;
        current_num_overflows = num_overflows;
        sei();

        // Signal detected, reset timer
        if(current_ICR3 != prev_ICR3){
            cli();
            TCNT3 = 0;
            num_overflows = 0;
            sei();
            g_ext_ref_present = true;
        }

        // Timeout, no external reference detected
        if(current_num_overflows >= EXT_REF_TIMEOUT){
            g_ext_ref_present = false;
        }

        // Determine and set reference based on state
        if(!g_gps_present && !g_ext_ref_present)     g_ref = NO_REF;
        else if(g_gps_present && !g_ext_ref_present) g_ref = INTERNAL;
        else if(!g_gps_present && g_ext_ref_present) g_ref = EXTERNAL;
        else g_ref = (g_switch_pos == PREFER_INTERNAL) ? INTERNAL : EXTERNAL;

        if((g_ref != prev_ref) || (g_switch_pos != prev_switch_pos)){
            if(g_switch_pos == PREFER_INTERNAL) prefer_internal();
            else prefer_external();
        }

        // Record this iteration's state
        prev_ref           = g_ref;
        prev_switch_pos    = g_switch_pos;
        prev_ICR3          = current_ICR3;
        prev_num_overflows = current_num_overflows;

        // Handle incoming Ethernet packets
        network_check();
    }
}