diff --git a/Src/C64.h b/Src/C64.h index a9d1354..27434be 100644 --- a/Src/C64.h +++ b/Src/C64.h @@ -195,6 +195,7 @@ public: char server_hostname[255]; int server_port; int network_connection_type; + Network *peer; TTF_Font *menu_font; bool fake_key_sequence; diff --git a/Src/C64_SDL.h b/Src/C64_SDL.h index 448bf9a..04ae369 100644 --- a/Src/C64_SDL.h +++ b/Src/C64_SDL.h @@ -100,16 +100,16 @@ void C64::c64_ctor1(void) sizeof(this->server_hostname)); this->server_port = 19760; this->network_connection_type = NONE; + this->peer = NULL; if (fixme_tmp_network_server) { - Network::StartNetworkServer(this->server_port); + this->peer = new Network("localhost", this->server_port, true); this->network_connection_type = MASTER; } if (fixme_tmp_network_client) { - printf("Klajent\n"); strcpy(this->server_hostname, fixme_tmp_network_client); - Network::ConnectTo(this->server_hostname, this->server_port); + this->peer = new Network(this->server_hostname, this->server_port, false); this->network_connection_type = CLIENT; } } @@ -344,11 +344,13 @@ void C64::networking_menu(Prefs *np) this->server_port = atoi(m); } else if (opt == 0) { - Network::StartNetworkServer(this->server_port); + this->peer = new Network(this->server_hostname, + this->server_port, true); this->network_connection_type = MASTER; } else if (opt == 3) { - Network::ConnectTo(this->server_hostname, this->server_port); + this->peer = new Network(this->server_hostname, + this->server_port, false); this->network_connection_type = CLIENT; } } while (opt == 1 || opt == 2); @@ -558,19 +560,18 @@ void C64::network_vblank() Uint32 now = SDL_GetTicks(); #endif - /* Perhaps accept a new connection */ - Network::CheckNewConnection(); - - for (int i = 0; i < Network::n_peers; i++) { + if (this->peer) { Uint8 *master = this->TheDisplay->BitmapBase(); - Network *remote = Network::peers[i]; + Network *remote = this->peer; uint8 *js; static bool has_throttled; if (this->quit_thyself) { remote->Disconnect(); - continue; + delete remote; + this->peer = NULL; + return; } remote->Tick( now - last_time_update ); @@ -592,8 +593,9 @@ void C64::network_vblank() if (remote->DecodeUpdate(remote->GetScreen(), js) == false) { /* Disconnect or sending crap, remove this guy! */ - Network::RemovePeer(remote); - continue; + delete remote; + this->peer = NULL; + return; } if (this->network_connection_type == CLIENT) this->TheDisplay->Update(remote->GetScreen()); @@ -604,7 +606,7 @@ void C64::network_vblank() remote->ThrottleTraffic()) { /* Skip this frame if the data rate is too high */ has_throttled = true; - continue; + return; } /* Perhaps send updates to the other side (what is determined by @@ -616,7 +618,6 @@ void C64::network_vblank() { /* Disconnect or broken data */ printf("Could not send update\n"); - Network::RemovePeer(remote); } else remote->ResetNetworkUpdate(); diff --git a/Src/Display_SDL.h b/Src/Display_SDL.h index 9bbf5d3..f3aaf49 100644 --- a/Src/Display_SDL.h +++ b/Src/Display_SDL.h @@ -226,12 +226,9 @@ void C64Display::Update(uint8 *src_pixels) } draw_string(real_screen, 0, 0, networktraffic_string, black, fill_gray); - for (int i = 0; i < Network::n_peers; i++) - { - Network *peer = Network::peers[i]; - peer->DrawTransferredBlocks(real_screen); - } + if (TheC64->peer) + TheC64->peer->DrawTransferredBlocks(real_screen); SDL_Flip(real_screen); } diff --git a/Src/Network.cpp b/Src/Network.cpp index 597778d..844e3d4 100644 --- a/Src/Network.cpp +++ b/Src/Network.cpp @@ -36,12 +36,12 @@ #define RLE_SIZE ( RAW_SIZE * 4 + 8) #define DIFF_SIZE ( RAW_SIZE * 4 + 8) -Network::Network(int sock, struct sockaddr_in *peer_addr, bool is_master) +Network::Network(const char *remote_host, int port, bool is_master) { const size_t size = NETWORK_UPDATE_SIZE; - this->sock = sock; this->is_master = is_master; + this->connected = false; /* "big enough" buffer */ this->ud = (NetworkUpdate*)malloc( size ); @@ -69,19 +69,11 @@ Network::Network(int sock, struct sockaddr_in *peer_addr, bool is_master) /* Assume black screen */ memset(this->screen, 0, DISPLAY_X * DISPLAY_Y); - /* Peer addresses */ - memset(&this->private_addr, 0, sizeof(struct sockaddr_in)); - memcpy(&this->public_addr, peer_addr, sizeof(struct sockaddr_in)); - this->connection_addr = &this->public_addr; - - /* If we are not the master, connect to the other side */ - if (!this->is_master) + /* Peer addresses, if it fails we are out of luck */ + if (this->InitSocket(remote_host, port) == false) { - InitNetworkUpdate(this->cur_ud, PEER_CONNECT, - sizeof(NetworkUpdate)); - this->AddNetworkUpdate(this->cur_ud); - this->SendUpdate(); - this->ResetNetworkUpdate(); + fprintf(stderr, "Could not init the socket\n"); + exit(1); } } @@ -499,12 +491,14 @@ void Network::DrawTransferredBlocks(SDL_Surface *screen) bool Network::ReceiveUpdate() { struct timeval tv; - bool out; memset(&tv, 0, sizeof(tv)); - out = this->ReceiveUpdate(this->ud, NETWORK_UPDATE_SIZE, &tv); + return this->ReceiveUpdate(this->ud, NETWORK_UPDATE_SIZE, &tv); +} - return out; +bool Network::ReceiveUpdateBlocking() +{ + return this->ReceiveUpdate(this->ud, NETWORK_UPDATE_SIZE, NULL); } bool Network::ReceiveUpdate(NetworkUpdate *dst, size_t total_sz, @@ -524,7 +518,7 @@ bool Network::ReceiveUpdate(NetworkUpdate *dst, size_t total_sz, /* Receive the header */ actual_sz = this->ReceiveFrom(pp, this->sock, - sz_left, this->connection_addr); + sz_left, &this->connection_addr); if (actual_sz < 0) return false; @@ -555,7 +549,8 @@ bool Network::SendUpdate() sz = this->GetNetworkUpdateSize(); if (sz <= 0) return false; - if (this->SendTo((void*)src, this->sock, sz, this->connection_addr) < 0) + if (this->SendTo((void*)src, this->sock, + sz, &this->connection_addr) < 0) return false; this->traffic += sz; @@ -752,29 +747,14 @@ bool Network::DecodeUpdate(uint8 *screen, uint8 *js) return out; } -void Network::AddPeer(Network *peer) +bool Network::WaitForConnection() { - Network::peers[Network::n_peers] = peer; - Network::n_peers++; + return this->ReceiveUpdateBlocking(); } -void Network::RemovePeer(Network *peer) +bool Network::ConnectToPeer() { - for (int i = 0; i < Network::n_peers; i++) - { - if (Network::peers[i] == peer) - { - if (i < Network::n_peers - 1) - { - /* Swap with last */ - Network::peers[i] = Network::peers[Network::n_peers - 1]; - } - delete peer; - Network::n_peers--; - return; - } - } - /* Not found */ + return this->SendUpdate(); } void Network::Disconnect() @@ -785,14 +765,8 @@ void Network::Disconnect() /* Add a stop at the end of the update */ this->AddNetworkUpdate(disconnect); this->SendUpdate(); - - Network::RemovePeer(this); } -int Network::n_peers; -int Network::listen_sock; -Network *Network::peers[1]; - uint8 Network::sample_buf[NETWORK_SOUND_BUF_SIZE]; int Network::sample_head; int Network::sample_tail; diff --git a/Src/Network.h b/Src/Network.h index 0d35e48..8cc3179 100644 --- a/Src/Network.h +++ b/Src/Network.h @@ -103,7 +103,7 @@ static inline NetworkUpdate *InitNetworkUpdate(NetworkUpdate *ud, uint16 type, u class Network { public: - Network(int sock, struct sockaddr_in *peer_addr, bool is_master); + Network(const char *remote_host, int port, bool is_master); ~Network(); @@ -140,11 +140,15 @@ public: bool ReceiveUpdate(); + bool ReceiveUpdateBlocking(); + static bool StartNetworkServer(int port); static bool CheckNewConnection(); - static bool ConnectTo(const char *hostname, int port); + bool WaitForConnection(); + + bool ConnectToPeer(); Uint8 *GetScreen() { @@ -157,16 +161,8 @@ public: */ void Disconnect(); - static void AddPeer(Network *who); - - static void RemovePeer(Network *peer); - static void PushSound(uint8 vol); - /* Listener-related */ - static Network *peers[1]; - static int n_peers; - protected: size_t DecodeSoundUpdate(struct NetworkUpdate *src, char *buf); @@ -235,6 +231,8 @@ protected: bool ReceiveData(void *dst, int sock, size_t sz); + bool InitSocket(const char *remote_host, int port); + /* Simple wrapper around our friend recvfrom */ ssize_t ReceiveFrom(void *dst, int sock, size_t sz, struct sockaddr_in *from); @@ -278,17 +276,12 @@ protected: Uint8 *screen; int joystick_port; bool is_master; /* Some peers are more equal than others */ + bool connected; Uint8 cur_joystick_data; /* Connection to the peer */ int sock; - - struct sockaddr_in private_addr; - struct sockaddr_in public_addr; - struct sockaddr_in *connection_addr; /* Points to either of the above */ - - /* Listener-related */ - static int listen_sock; + struct sockaddr_in connection_addr; /* Points to either of the above */ /* Sound */ static uint8 sample_buf[NETWORK_SOUND_BUF_SIZE]; diff --git a/Src/NetworkUnix.h b/Src/NetworkUnix.h index 8a4ba3b..fd6e696 100644 --- a/Src/NetworkUnix.h +++ b/Src/NetworkUnix.h @@ -65,7 +65,35 @@ bool init_sockaddr (struct sockaddr_in *name, return true; } +bool Network::InitSocket(const char *remote_host, int port) +{ + /* Create the socket. */ + this->sock = socket (PF_INET, SOCK_DGRAM, 0); + if (this->sock < 0) + { + perror ("socket (client)"); + return false; + } + set_sock_opts(this->sock); + + /* Connect to the server. */ + init_sockaddr(&this->connection_addr, remote_host, port); + + if (this->is_master) + { + if (bind(this->sock, (struct sockaddr *)&this->connection_addr, + sizeof (this->connection_addr)) < 0) + { + perror ("bind"); + return false; + } + } + + return true; +} + +#if 0 bool Network::StartNetworkServer(int port) { Network::listen_sock = make_socket(port); @@ -141,6 +169,7 @@ bool Network::ConnectTo(const char *hostname, int port) return true; } +#endif bool Network::ReceiveData(void *dst, int sock, size_t sz) {