Make the network server be non-blocking, i.e., allow continuing to play

while waiting for someone to connect. Also fix a buffer overflow in the
network transfer string...
This commit is contained in:
simon.kagstrom 2009-04-04 08:23:51 +00:00
parent 5ab6b38e6c
commit 0c563eb137
6 changed files with 63 additions and 13 deletions

View File

@ -9,6 +9,16 @@
TODO: Handle Run/Stop in virtual keyboard (?)
version 9:
* Fix a buffer overflow in the network status string...
* Add network version field and display an error message if
an un-matching network version is connected
* Select with zero timeout when waiting for peer addresses
* Don't block the server when connecting and instead draw a status
string to indicate that we're waiting for a connection
* Networking support now works (but without sound being transferred). A
broker is installed on c64-network.game-host.org.

View File

@ -45,6 +45,7 @@
enum
{
NONE,
MASTER_CONNECT,
MASTER,
CLIENT
};

View File

@ -72,7 +72,7 @@ void C64::c64_ctor1(void)
this->virtual_keyboard = new VirtualKeyboard(real_screen, this->menu_font);
strncpy(this->server_hostname, "c64-network.game-host.org",
strncpy(this->server_hostname, "192.168.10.139",
sizeof(this->server_hostname));
this->server_port = 46214;
this->network_connection_type = NONE;
@ -350,11 +350,13 @@ void C64::networking_menu(Prefs *np)
this->peer = new Network(this->server_hostname,
this->server_port, master);
this->network_connection_type = master ? MASTER : CLIENT;
if (this->peer->Connect() == false)
this->network_connection_type = master ? MASTER_CONNECT : CLIENT;
if (this->network_connection_type == CLIENT &&
this->peer->Connect() == false)
{
delete this->peer;
this->peer = NULL;
this->network_connection_type = NONE;
}
}
} while (opt == 1 || opt == 2);
@ -568,7 +570,8 @@ void C64::network_vblank()
if (this->quit_thyself)
{
remote->Disconnect();
if (this->network_connection_type != MASTER_CONNECT)
remote->Disconnect();
delete remote;
this->peer = NULL;
return;
@ -580,6 +583,21 @@ void C64::network_vblank()
js = &TheCIA1->Joystick1;
else
js = &TheCIA1->Joystick2;
} else if (this->network_connection_type == MASTER_CONNECT) {
network_connection_error_t err = this->peer->ConnectFSM();
TheDisplay->display_status_string("WAITING FOR CONNECTION...", 1);
if (err == OK) {
this->network_connection_type = MASTER;
TheDisplay->display_status_string("CLIENT CONNECTED!", 1);
}
else if (err != AGAIN_ERROR)
{
delete remote;
this->peer = NULL;
}
return;
} else {
if (ThePrefs.JoystickSwap)
js = &TheCIA1->Joystick2;

View File

@ -109,6 +109,7 @@ public:
#if defined(__unix) || defined(GEKKO)
bool quit_requested;
#endif
void display_status_string(char *str, int seconds);
private:
int led_state[4];
@ -143,8 +144,11 @@ private:
#ifdef HAVE_SDL
char speedometer_string[16]; // Speedometer text
char networktraffic_string[16]; // Speedometer text
char networktraffic_string[80]; // Speedometer text
void draw_string(SDL_Surface *s, int x, int y, const char *str, uint8 front_color, uint8 back_color);
char *on_screen_message;
int on_screen_message_start_time;
int on_screen_message_time;
#endif
#ifdef __unix

View File

@ -130,8 +130,10 @@ C64Display::C64Display(C64 *the_c64) : TheC64(the_c64)
quit_requested = false;
speedometer_string[0] = 0;
networktraffic_string[0] = 0;
this->on_screen_message = NULL;
this->on_screen_message_start_time = 0;
this->on_screen_message_time = 0;
printf("ssof2 %d:%d\n", sizeof(C64Display), sizeof(C64));
// Open window
SDL_WM_SetCaption(VERSION_STRING, "Frodo");
// LEDs off
@ -226,6 +228,15 @@ void C64Display::Update(uint8 *src_pixels)
}
draw_string(real_screen, 0, 0, networktraffic_string, black, fill_gray);
if (this->on_screen_message) {
struct timeval tv;
gettimeofday(&tv, NULL);
draw_string(real_screen, 60, 30,
this->on_screen_message, black, fill_gray);
if (tv.tv_sec - this->on_screen_message_start_time > this->on_screen_message_time)
this->on_screen_message = NULL;
}
SDL_Flip(real_screen);
}
@ -235,6 +246,16 @@ void C64Display::Update()
this->Update((Uint8*)screen);
}
void C64Display::display_status_string(char *str, int seconds)
{
struct timeval tv;
gettimeofday(&tv, NULL);
this->on_screen_message = str;
this->on_screen_message_start_time = tv.tv_sec;
this->on_screen_message_time = seconds;
}
/*
* Draw string into surface using the C64 ROM font
*/
@ -300,8 +321,8 @@ void C64Display::Speedometer(int speed)
void C64Display::NetworkTrafficMeter(float kb_per_s, bool is_throttled)
{
sprintf(this->networktraffic_string, "%6.2f KB/S%s",
kb_per_s, is_throttled ? " THROTTLED" : "");
snprintf(this->networktraffic_string, sizeof(this->networktraffic_string),
"%6.2f KB/S%s", kb_per_s, is_throttled ? " THROTTLED" : "");
}
/*

View File

@ -892,13 +892,9 @@ void Network::SendPingAck(int seq)
network_connection_error_t Network::WaitForPeerAddress()
{
NetworkUpdateListPeers *pi;
struct timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 0;
this->ResetNetworkUpdate();
if (this->ReceiveUpdate(&tv) == false)
if (this->ReceiveUpdate() == false)
return AGAIN_ERROR;
if (this->ud->type == PING)
{