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 (?) TODO: Handle Run/Stop in virtual keyboard (?)
version 9: 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 * Networking support now works (but without sound being transferred). A
broker is installed on c64-network.game-host.org. broker is installed on c64-network.game-host.org.

View File

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

View File

@ -72,7 +72,7 @@ void C64::c64_ctor1(void)
this->virtual_keyboard = new VirtualKeyboard(real_screen, this->menu_font); 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)); sizeof(this->server_hostname));
this->server_port = 46214; this->server_port = 46214;
this->network_connection_type = NONE; this->network_connection_type = NONE;
@ -350,11 +350,13 @@ void C64::networking_menu(Prefs *np)
this->peer = new Network(this->server_hostname, this->peer = new Network(this->server_hostname,
this->server_port, master); this->server_port, master);
this->network_connection_type = master ? MASTER : CLIENT; this->network_connection_type = master ? MASTER_CONNECT : CLIENT;
if (this->peer->Connect() == false) if (this->network_connection_type == CLIENT &&
this->peer->Connect() == false)
{ {
delete this->peer; delete this->peer;
this->peer = NULL; this->peer = NULL;
this->network_connection_type = NONE;
} }
} }
} while (opt == 1 || opt == 2); } while (opt == 1 || opt == 2);
@ -568,6 +570,7 @@ void C64::network_vblank()
if (this->quit_thyself) if (this->quit_thyself)
{ {
if (this->network_connection_type != MASTER_CONNECT)
remote->Disconnect(); remote->Disconnect();
delete remote; delete remote;
this->peer = NULL; this->peer = NULL;
@ -580,6 +583,21 @@ void C64::network_vblank()
js = &TheCIA1->Joystick1; js = &TheCIA1->Joystick1;
else else
js = &TheCIA1->Joystick2; 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 { } else {
if (ThePrefs.JoystickSwap) if (ThePrefs.JoystickSwap)
js = &TheCIA1->Joystick2; js = &TheCIA1->Joystick2;

View File

@ -109,6 +109,7 @@ public:
#if defined(__unix) || defined(GEKKO) #if defined(__unix) || defined(GEKKO)
bool quit_requested; bool quit_requested;
#endif #endif
void display_status_string(char *str, int seconds);
private: private:
int led_state[4]; int led_state[4];
@ -143,8 +144,11 @@ private:
#ifdef HAVE_SDL #ifdef HAVE_SDL
char speedometer_string[16]; // Speedometer text 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); 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 #endif
#ifdef __unix #ifdef __unix

View File

@ -130,8 +130,10 @@ C64Display::C64Display(C64 *the_c64) : TheC64(the_c64)
quit_requested = false; quit_requested = false;
speedometer_string[0] = 0; speedometer_string[0] = 0;
networktraffic_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 // Open window
SDL_WM_SetCaption(VERSION_STRING, "Frodo"); SDL_WM_SetCaption(VERSION_STRING, "Frodo");
// LEDs off // LEDs off
@ -226,6 +228,15 @@ void C64Display::Update(uint8 *src_pixels)
} }
draw_string(real_screen, 0, 0, networktraffic_string, black, fill_gray); 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); SDL_Flip(real_screen);
} }
@ -235,6 +246,16 @@ void C64Display::Update()
this->Update((Uint8*)screen); 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 * 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) void C64Display::NetworkTrafficMeter(float kb_per_s, bool is_throttled)
{ {
sprintf(this->networktraffic_string, "%6.2f KB/S%s", snprintf(this->networktraffic_string, sizeof(this->networktraffic_string),
kb_per_s, is_throttled ? " THROTTLED" : ""); "%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() network_connection_error_t Network::WaitForPeerAddress()
{ {
NetworkUpdateListPeers *pi; NetworkUpdateListPeers *pi;
struct timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 0;
this->ResetNetworkUpdate(); this->ResetNetworkUpdate();
if (this->ReceiveUpdate(&tv) == false) if (this->ReceiveUpdate() == false)
return AGAIN_ERROR; return AGAIN_ERROR;
if (this->ud->type == PING) if (this->ud->type == PING)
{ {