mirror of
https://github.com/Oibaf66/frodo-wii.git
synced 2024-11-26 13:34:22 +01:00
Various networking stuff
This commit is contained in:
parent
a6c5b3c6f9
commit
f31320b774
@ -1,3 +1,8 @@
|
|||||||
|
version 7:
|
||||||
|
TODO: Multiple frodo versions, switch between
|
||||||
|
|
||||||
|
-- Simon Kagstrom <simon.kagstrom@gmail.com>,
|
||||||
|
|
||||||
version 6:
|
version 6:
|
||||||
TODO: Multiple frodo versions, switch between
|
TODO: Multiple frodo versions, switch between
|
||||||
* Handle reset button (back to menu)
|
* Handle reset button (back to menu)
|
||||||
@ -14,7 +19,8 @@ version 6:
|
|||||||
is not a PRG to load correctly). Thanks to Dominik Reichardt for pointing
|
is not a PRG to load correctly). Thanks to Dominik Reichardt for pointing
|
||||||
this out
|
this out
|
||||||
|
|
||||||
-- Simon Kagstrom <simon.kagstrom@gmail.com>,
|
-- Simon Kagstrom <simon.kagstrom@gmail.com>, Sat Jan 24 11:48:01 CET 2009
|
||||||
|
|
||||||
|
|
||||||
version 5:
|
version 5:
|
||||||
* Some wiimote sanity checks
|
* Some wiimote sanity checks
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
/* SDL menu */
|
/* SDL menu */
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
#include "VirtualKeyboard.h"
|
#include "VirtualKeyboard.h"
|
||||||
|
#include "Network.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __BEOS__
|
#ifdef __BEOS__
|
||||||
@ -184,6 +185,10 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SDL
|
#ifdef HAVE_SDL
|
||||||
VirtualKeyboard *virtual_keyboard;
|
VirtualKeyboard *virtual_keyboard;
|
||||||
|
NetworkServer *network_server;
|
||||||
|
NetworkClient *network_client;
|
||||||
|
char server_hostname[255];
|
||||||
|
int server_port;
|
||||||
TTF_Font *menu_font;
|
TTF_Font *menu_font;
|
||||||
|
|
||||||
bool fake_key_sequence;
|
bool fake_key_sequence;
|
||||||
@ -201,6 +206,7 @@ public:
|
|||||||
char * bind_one_key(Prefs *np, int which);
|
char * bind_one_key(Prefs *np, int which);
|
||||||
void bind_keys(Prefs *np);
|
void bind_keys(Prefs *np);
|
||||||
void other_options(Prefs *np);
|
void other_options(Prefs *np);
|
||||||
|
void networking_menu(Prefs *np);
|
||||||
void save_load_state(Prefs *np);
|
void save_load_state(Prefs *np);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -39,16 +39,6 @@ static const char *main_menu_messages[] = {
|
|||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *other_options_messages[] = {
|
|
||||||
"Display resolution", /* 0 */
|
|
||||||
"^|double-center|stretched",
|
|
||||||
"Speed (approx)", /* 2 */
|
|
||||||
"^|95|100|110",
|
|
||||||
"Emulate 1541", /* 4 */
|
|
||||||
"^|On|Off",
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char *save_load_state_messages[] = {
|
static const char *save_load_state_messages[] = {
|
||||||
"Load saved state", /* 0 */
|
"Load saved state", /* 0 */
|
||||||
"Save current state", /* 1 */
|
"Save current state", /* 1 */
|
||||||
@ -100,6 +90,12 @@ 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);
|
||||||
|
this->network_server = NULL;
|
||||||
|
this->network_client = NULL;
|
||||||
|
|
||||||
|
strncpy(this->server_hostname, "localhost",
|
||||||
|
sizeof(this->server_hostname));
|
||||||
|
this->server_port = 19760;
|
||||||
}
|
}
|
||||||
|
|
||||||
void C64::c64_ctor2(void)
|
void C64::c64_ctor2(void)
|
||||||
@ -299,10 +295,76 @@ void C64::bind_keys(Prefs *np)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void C64::networking_menu(Prefs *np)
|
||||||
|
{
|
||||||
|
int opt;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
char buf[2][255];
|
||||||
|
const char *network_client_messages[] = {
|
||||||
|
"Start network server", /* 0 */
|
||||||
|
buf[0], /* 1 */
|
||||||
|
buf[1], /* 2 */
|
||||||
|
"Connect to server", /* 3 */
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
snprintf(buf[0], 255, "Server hostname (now %s)",
|
||||||
|
this->server_hostname);
|
||||||
|
snprintf(buf[1], 255, "Server port (now %d)",
|
||||||
|
this->server_port);
|
||||||
|
opt = menu_select(real_screen, this->menu_font,
|
||||||
|
network_client_messages, NULL);
|
||||||
|
|
||||||
|
if (opt == 1 || opt == 2)
|
||||||
|
{
|
||||||
|
const char *m = this->virtual_keyboard->get_string();
|
||||||
|
|
||||||
|
if (m && opt == 1)
|
||||||
|
strncpy(this->server_hostname, m,
|
||||||
|
sizeof(this->server_hostname));
|
||||||
|
if (m && opt == 2)
|
||||||
|
this->server_port = atoi(m);
|
||||||
|
}
|
||||||
|
else if (opt == 0) {
|
||||||
|
/* Cannot be both client and server */
|
||||||
|
if (this->network_client != NULL) {
|
||||||
|
delete this->network_client;
|
||||||
|
this->network_client = NULL;
|
||||||
|
}
|
||||||
|
this->network_server = new NetworkServer(this->server_port);
|
||||||
|
}
|
||||||
|
else if (opt == 3)
|
||||||
|
{
|
||||||
|
if (this->network_server != NULL) {
|
||||||
|
delete this->network_server;
|
||||||
|
this->network_server = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->network_client = new NetworkClient(this->server_hostname,
|
||||||
|
this->server_port);
|
||||||
|
}
|
||||||
|
} while (opt == 1 || opt == 2);
|
||||||
|
|
||||||
|
this->prefs_changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
void C64::other_options(Prefs *np)
|
void C64::other_options(Prefs *np)
|
||||||
{
|
{
|
||||||
|
const char *other_options_messages[] = {
|
||||||
|
"Display resolution", /* 0 */
|
||||||
|
"^|double-center|stretched",
|
||||||
|
"Speed (approx)", /* 2 */
|
||||||
|
"^|95|100|110",
|
||||||
|
"Emulate 1541", /* 4 */
|
||||||
|
"^|On|Off",
|
||||||
|
"Networking", /* 6 */
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
int submenus[3] = { np->DisplayOption, 0, !np->Emul1541Proc };
|
int submenus[3] = { np->DisplayOption, 0, !np->Emul1541Proc };
|
||||||
|
|
||||||
|
|
||||||
#define SPEED_95 33
|
#define SPEED_95 33
|
||||||
#define SPEED_100 28
|
#define SPEED_100 28
|
||||||
#define SPEED_110 25
|
#define SPEED_110 25
|
||||||
@ -334,6 +396,10 @@ void C64::other_options(Prefs *np)
|
|||||||
default:
|
default:
|
||||||
np->MsPerFrame = SPEED_110; break;
|
np->MsPerFrame = SPEED_110; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opt == 6)
|
||||||
|
this->networking_menu(np);
|
||||||
|
|
||||||
this->prefs_changed = true;
|
this->prefs_changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -536,6 +602,19 @@ void C64::VBlank(bool draw_frame)
|
|||||||
TheDisplay->Speedometer((int)speed_index);
|
TheDisplay->Speedometer((int)speed_index);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
if (this->network_server) {
|
||||||
|
/* Perhaps accept a new connection */
|
||||||
|
this->network_server->CheckNewConnection();
|
||||||
|
|
||||||
|
for (int i = 0; i < this->network_server->n_clients; i++) {
|
||||||
|
Uint8 *master = this->TheDisplay->BitmapBase();
|
||||||
|
NetworkClient *remote = this->network_server->clients[i];
|
||||||
|
|
||||||
|
remote->EncodeDisplay(master, remote->screen);
|
||||||
|
remote->SendUpdate();
|
||||||
|
remote->ResetNetworkUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (this->have_a_break) {
|
if (this->have_a_break) {
|
||||||
int submenus[1];
|
int submenus[1];
|
||||||
int opt;
|
int opt;
|
||||||
|
@ -151,6 +151,7 @@ C64_SC.o: C64.cpp sysdeps.h sysconfig.h C64.h CPUC64.h CPU1541.h CIA.h C64_SDL.h
|
|||||||
C64_SC.o: Prefs.h VIC.h SID.h REU.h IEC.h 1541job.h Display.h
|
C64_SC.o: Prefs.h VIC.h SID.h REU.h IEC.h 1541job.h Display.h
|
||||||
CPUC64.o: sysdeps.h sysconfig.h CPUC64.h C64.h VIC.h SID.h CIA.h Prefs.h
|
CPUC64.o: sysdeps.h sysconfig.h CPUC64.h C64.h VIC.h SID.h CIA.h Prefs.h
|
||||||
CPUC64.o: REU.h IEC.h Display.h Version.h CPU_emulline.h
|
CPUC64.o: REU.h IEC.h Display.h Version.h CPU_emulline.h
|
||||||
|
Network.o: Network.h NetworkUnix.h
|
||||||
CPUC64_SC.o: sysdeps.h sysconfig.h CPUC64.h C64.h CPU_common.h VIC.h SID.h
|
CPUC64_SC.o: sysdeps.h sysconfig.h CPUC64.h C64.h CPU_common.h VIC.h SID.h
|
||||||
CPUC64_SC.o: CIA.h Prefs.h REU.h IEC.h Display.h Version.h CPU_emulcycle.h
|
CPUC64_SC.o: CIA.h Prefs.h REU.h IEC.h Display.h Version.h CPU_emulcycle.h
|
||||||
VIC.o: sysdeps.h sysconfig.h VIC.h C64.h CPUC64.h Display.h Prefs.h
|
VIC.o: sysdeps.h sysconfig.h VIC.h C64.h CPUC64.h Display.h Prefs.h
|
||||||
|
109
Src/Network.cpp
109
Src/Network.cpp
@ -22,8 +22,8 @@
|
|||||||
#include "Network.h"
|
#include "Network.h"
|
||||||
#include "Display.h"
|
#include "Display.h"
|
||||||
|
|
||||||
#define N_SQUARES_W 6
|
#define N_SQUARES_W 20
|
||||||
#define N_SQUARES_H 4
|
#define N_SQUARES_H 20
|
||||||
|
|
||||||
#define SQUARE_W (DISPLAY_X / N_SQUARES_W)
|
#define SQUARE_W (DISPLAY_X / N_SQUARES_W)
|
||||||
#define SQUARE_H (DISPLAY_Y / N_SQUARES_H)
|
#define SQUARE_H (DISPLAY_Y / N_SQUARES_H)
|
||||||
@ -33,6 +33,20 @@
|
|||||||
|
|
||||||
#define RAW_SIZE ( (SQUARE_W * SQUARE_H) / 2 )
|
#define RAW_SIZE ( (SQUARE_W * SQUARE_H) / 2 )
|
||||||
|
|
||||||
|
Network::Network()
|
||||||
|
{
|
||||||
|
const size_t size = NETWORK_UPDATE_SIZE;
|
||||||
|
|
||||||
|
/* "big enough" static buffer */
|
||||||
|
this->ud = (NetworkUpdate*)malloc( size );
|
||||||
|
this->ResetNetworkUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
Network::~Network()
|
||||||
|
{
|
||||||
|
free(this->ud);
|
||||||
|
}
|
||||||
|
|
||||||
size_t Network::EncodeDisplayRaw(struct NetworkDisplayUpdate *dst, Uint8 *screen,
|
size_t Network::EncodeDisplayRaw(struct NetworkDisplayUpdate *dst, Uint8 *screen,
|
||||||
int x_start, int y_start)
|
int x_start, int y_start)
|
||||||
{
|
{
|
||||||
@ -193,6 +207,45 @@ size_t Network::EncodeDisplaySquare(struct NetworkDisplayUpdate *dst,
|
|||||||
return dst->size;
|
return dst->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Network::CompareSquare(Uint8 *a, Uint8 *b)
|
||||||
|
{
|
||||||
|
for (int y = 0; y < SQUARE_H; y++)
|
||||||
|
{
|
||||||
|
for (int x = 0; x < SQUARE_W; x++)
|
||||||
|
{
|
||||||
|
Uint8 va = a[ y * DISPLAY_X + x ];
|
||||||
|
Uint8 vb = b[ y * DISPLAY_X + x ];
|
||||||
|
|
||||||
|
if (va == vb)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Network::EncodeDisplay(Uint8 *master, Uint8 *remote)
|
||||||
|
{
|
||||||
|
for ( int sq = 0; sq < N_SQUARES_H * N_SQUARES_W; sq++ )
|
||||||
|
{
|
||||||
|
Uint8 *p_master = &master[ SQUARE_TO_Y(sq) * DISPLAY_X + SQUARE_TO_X(sq) ];
|
||||||
|
Uint8 *p_remote= &remote[ SQUARE_TO_Y(sq) * DISPLAY_X + SQUARE_TO_X(sq) ];
|
||||||
|
|
||||||
|
if (this->CompareSquare(p_master, p_remote) == false)
|
||||||
|
{
|
||||||
|
NetworkDisplayUpdate *dst = (NetworkDisplayUpdate *)this->cur_ud;
|
||||||
|
|
||||||
|
/* Updated, encode this */
|
||||||
|
this->EncodeDisplaySquare(dst, master, sq);
|
||||||
|
this->AddNetworkUpdate((NetworkUpdate*)dst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Everything encoded, store in remote */
|
||||||
|
memcpy(remote, master, DISPLAY_X * DISPLAY_Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Network::DecodeDisplayUpdate(Uint8 *screen,
|
bool Network::DecodeDisplayUpdate(Uint8 *screen,
|
||||||
struct NetworkDisplayUpdate *src)
|
struct NetworkDisplayUpdate *src)
|
||||||
{
|
{
|
||||||
@ -246,37 +299,28 @@ size_t Network::DecodeSoundUpdate(struct NetworkSoundUpdate *src, char *buf)
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkUpdate *Network::GetNetworkUpdate(void)
|
void Network::ResetNetworkUpdate(void)
|
||||||
{
|
{
|
||||||
static NetworkUpdate *out;
|
memset(this->ud, 0, NETWORK_UPDATE_SIZE);
|
||||||
const size_t size = NETWORK_UPDATE_SIZE;
|
|
||||||
|
|
||||||
if (!out)
|
this->ud->type = HEADER;
|
||||||
{
|
this->ud->size = sizeof(NetworkUpdate);
|
||||||
/* "big enough" static buffer */
|
this->cur_ud = (Uint8*)(this->ud + sizeof(NetworkUpdate));
|
||||||
out = (NetworkUpdate*)malloc( size );
|
|
||||||
}
|
|
||||||
memset(out, 0, size);
|
|
||||||
|
|
||||||
out->type = HEADER;
|
|
||||||
out->size = 0;
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Network::ReceiveUpdate(NetworkUpdate *dst, int sock)
|
bool Network::ReceiveUpdate(int sock)
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
|
||||||
memset(&tv, 0, sizeof(tv));
|
memset(&tv, 0, sizeof(tv));
|
||||||
return this->ReceiveUpdate(dst, sock, &tv);
|
return this->ReceiveUpdate(this->ud, sock, &tv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Network::ReceiveUpdateBlock(NetworkUpdate *dst, int sock)
|
bool Network::ReceiveUpdateBlock(int sock)
|
||||||
{
|
{
|
||||||
return this->ReceiveUpdate(dst, sock, NULL);
|
return this->ReceiveUpdate(this->ud, sock, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Network::MarshalData(NetworkUpdate *ud)
|
void Network::MarshalData(NetworkUpdate *ud)
|
||||||
@ -370,5 +414,30 @@ NetworkUpdate *Network::IterateNext(NetworkUpdate *p, unsigned int *cookie)
|
|||||||
return cur;
|
return cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetworkServer::AddClient(int sock)
|
||||||
|
{
|
||||||
|
NetworkClient *cli = new NetworkClient(sock);
|
||||||
|
|
||||||
|
this->clients[this->n_clients] = cli;
|
||||||
|
this->n_clients++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NetworkClient::NetworkClient(int sock)
|
||||||
|
{
|
||||||
|
this->sock = sock;
|
||||||
|
|
||||||
|
this->screen = (Uint8 *)malloc(DISPLAY_X * DISPLAY_Y);
|
||||||
|
assert(this->screen);
|
||||||
|
|
||||||
|
/* Assume black screen */
|
||||||
|
memset(this->screen, 0, DISPLAY_X * DISPLAY_Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkClient::~NetworkClient()
|
||||||
|
{
|
||||||
|
free(this->screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#include "NetworkUnix.h"
|
#include "NetworkUnix.h"
|
||||||
|
@ -36,6 +36,7 @@ struct NetworkJoystickUpdate
|
|||||||
{
|
{
|
||||||
Uint8 type;
|
Uint8 type;
|
||||||
Uint8 which;
|
Uint8 which;
|
||||||
|
Uint16 size;
|
||||||
Uint8 data; /* New value */
|
Uint8 data; /* New value */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -52,6 +53,10 @@ struct NetworkUpdate
|
|||||||
class Network
|
class Network
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Network();
|
||||||
|
|
||||||
|
~Network();
|
||||||
|
|
||||||
/** Encode part of a screen into @a dst
|
/** Encode part of a screen into @a dst
|
||||||
*
|
*
|
||||||
* @param dst the destination update structure
|
* @param dst the destination update structure
|
||||||
@ -63,6 +68,8 @@ public:
|
|||||||
size_t EncodeDisplaySquare(struct NetworkDisplayUpdate *dst,
|
size_t EncodeDisplaySquare(struct NetworkDisplayUpdate *dst,
|
||||||
Uint8 *screen, int square);
|
Uint8 *screen, int square);
|
||||||
|
|
||||||
|
size_t EncodeDisplay(Uint8 *master, Uint8 *remote);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encode the @a buf sound buffer into @a dst
|
* Encode the @a buf sound buffer into @a dst
|
||||||
*
|
*
|
||||||
@ -88,17 +95,13 @@ public:
|
|||||||
|
|
||||||
size_t DecodeSoundUpdate(struct NetworkSoundUpdate *src, char *buf);
|
size_t DecodeSoundUpdate(struct NetworkSoundUpdate *src, char *buf);
|
||||||
|
|
||||||
NetworkUpdate *GetNetworkUpdate(void);
|
void ResetNetworkUpdate(void);
|
||||||
|
|
||||||
bool SendUpdate(NetworkUpdate *src, int sock);
|
bool SendUpdate(int sock);
|
||||||
|
|
||||||
bool ReceiveUpdate(NetworkUpdate *dst, int sock);
|
bool ReceiveUpdate(int sock);
|
||||||
|
|
||||||
bool ReceiveUpdateBlock(NetworkUpdate *dst, int sock);
|
bool ReceiveUpdateBlock(int sock);
|
||||||
|
|
||||||
NetworkUpdate *IterateFirst(NetworkUpdate *p, unsigned int *cookie);
|
|
||||||
|
|
||||||
NetworkUpdate *IterateNext(NetworkUpdate *p, unsigned int *cookie);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
size_t EncodeDisplayRLE(struct NetworkDisplayUpdate *dst, Uint8 *screen,
|
size_t EncodeDisplayRLE(struct NetworkDisplayUpdate *dst, Uint8 *screen,
|
||||||
@ -110,6 +113,25 @@ private:
|
|||||||
size_t EncodeSoundRaw(struct NetworkSoundUpdate *dst,
|
size_t EncodeSoundRaw(struct NetworkSoundUpdate *dst,
|
||||||
Uint8 *buffer, size_t len);
|
Uint8 *buffer, size_t len);
|
||||||
|
|
||||||
|
NetworkUpdate *IterateFirst(NetworkUpdate *p, unsigned int *cookie);
|
||||||
|
|
||||||
|
NetworkUpdate *IterateNext(NetworkUpdate *p, unsigned int *cookie);
|
||||||
|
|
||||||
|
void AddNetworkUpdate(struct NetworkUpdate *update)
|
||||||
|
{
|
||||||
|
this->cur_ud += update->size;
|
||||||
|
this->ud->size += update->size;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Compare two display squares.
|
||||||
|
*
|
||||||
|
* @param a the first square (first byte)
|
||||||
|
* @param b the second square (first byte)
|
||||||
|
*
|
||||||
|
* @return true if they are equal
|
||||||
|
*/
|
||||||
|
bool CompareSquare(Uint8 *a, Uint8 *b);
|
||||||
|
|
||||||
bool DecodeDisplayRLE(Uint8 *screen, struct NetworkDisplayUpdate *src,
|
bool DecodeDisplayRLE(Uint8 *screen, struct NetworkDisplayUpdate *src,
|
||||||
int x, int y);
|
int x, int y);
|
||||||
bool DecodeDisplayRaw(Uint8 *screen, struct NetworkDisplayUpdate *src,
|
bool DecodeDisplayRaw(Uint8 *screen, struct NetworkDisplayUpdate *src,
|
||||||
@ -120,6 +142,9 @@ private:
|
|||||||
void MarshalData(NetworkUpdate *ud);
|
void MarshalData(NetworkUpdate *ud);
|
||||||
|
|
||||||
void DeMarshalData(NetworkUpdate *ud);
|
void DeMarshalData(NetworkUpdate *ud);
|
||||||
|
|
||||||
|
NetworkUpdate *ud;
|
||||||
|
Uint8 *cur_ud;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NetworkClient : public Network
|
class NetworkClient : public Network
|
||||||
@ -127,7 +152,30 @@ class NetworkClient : public Network
|
|||||||
public:
|
public:
|
||||||
NetworkClient(int sock);
|
NetworkClient(int sock);
|
||||||
|
|
||||||
bool ConnectToServer(const char *hostname, int port);
|
~NetworkClient();
|
||||||
|
|
||||||
|
NetworkClient(const char *hostname, int port);
|
||||||
|
|
||||||
|
bool isConnected()
|
||||||
|
{
|
||||||
|
return this->sock >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SendUpdate()
|
||||||
|
{
|
||||||
|
return ((Network*)this)->SendUpdate(this->sock);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReceiveUpdate()
|
||||||
|
{
|
||||||
|
return ((Network*)this)->ReceiveUpdate(this->sock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ReceiveUpdateBlock()
|
||||||
|
{
|
||||||
|
return ((Network*)this)->ReceiveUpdateBlock(this->sock);
|
||||||
|
}
|
||||||
|
|
||||||
Uint8 *screen;
|
Uint8 *screen;
|
||||||
int joystick_port;
|
int joystick_port;
|
||||||
@ -135,19 +183,22 @@ private:
|
|||||||
int sock;
|
int sock;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MAX_NETWORK_CLIENTS 8
|
||||||
|
|
||||||
class NetworkServer : public Network
|
class NetworkServer : public Network
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NetworkServer();
|
NetworkServer(int port);
|
||||||
|
|
||||||
NetworkClient *CheckNewConnection();
|
bool CheckNewConnection();
|
||||||
|
|
||||||
NetworkClient **clients;
|
NetworkClient *clients[MAX_NETWORK_CLIENTS];
|
||||||
int n_clients;
|
int n_clients;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void AddClient(int sock);
|
||||||
|
|
||||||
int listen_sock;
|
int listen_sock;
|
||||||
fd_set listen_fds;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* NETWORK_H */
|
#endif /* NETWORK_H */
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
|
||||||
/* From glibc docs */
|
/* From glibc docs */
|
||||||
static int make_socket (uint16_t port)
|
static int make_socket (uint16_t port)
|
||||||
@ -30,51 +31,101 @@ static int make_socket (uint16_t port)
|
|||||||
return sock;
|
return sock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool init_sockaddr (struct sockaddr_in *name,
|
||||||
|
const char *hostname, uint16_t port)
|
||||||
|
{
|
||||||
|
struct hostent *hostinfo;
|
||||||
|
|
||||||
NetworkServer::NetworkServer()
|
name->sin_family = AF_INET;
|
||||||
|
name->sin_port = htons (port);
|
||||||
|
hostinfo = gethostbyname (hostname);
|
||||||
|
if (hostinfo == NULL)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Unknown host %s.\n", hostname);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
name->sin_addr = *(struct in_addr *) hostinfo->h_addr;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NetworkServer::NetworkServer(int port)
|
||||||
{
|
{
|
||||||
this->n_clients = 0;
|
this->n_clients = 0;
|
||||||
this->listen_sock = make_socket(27697);
|
this->listen_sock = make_socket(port);
|
||||||
|
|
||||||
FD_ZERO(&this->listen_fds);
|
if (listen(this->listen_sock, MAX_NETWORK_CLIENTS) < 0)
|
||||||
FD_SET(this->listen_sock, &this->listen_fds);
|
|
||||||
|
|
||||||
if (listen(this->listen_sock, 4) < 0)
|
|
||||||
{
|
{
|
||||||
perror("listen");
|
perror("listen");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkClient *NetworkServer::CheckNewConnection()
|
bool NetworkServer::CheckNewConnection()
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
struct sockaddr_in client_name;
|
struct sockaddr_in client_name;
|
||||||
size_t size;
|
size_t size;
|
||||||
int client_sock;
|
int client_sock;
|
||||||
|
fd_set listen_fds;
|
||||||
|
|
||||||
|
/* No more than that thanks... */
|
||||||
|
if (this->n_clients >= MAX_NETWORK_CLIENTS)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
FD_ZERO(&listen_fds);
|
||||||
|
FD_SET(this->listen_sock, &listen_fds);
|
||||||
|
|
||||||
/* If something connects, create a new client */
|
/* If something connects, create a new client */
|
||||||
memset(&tv, 0, sizeof(tv));
|
memset(&tv, 0, sizeof(tv));
|
||||||
if (select(1, &this->listen_fds, NULL, NULL, &tv) <= 0)
|
int v = select(this->listen_sock + 1, &listen_fds, NULL, NULL, &tv);
|
||||||
return NULL;
|
|
||||||
|
if ( v < 0)
|
||||||
|
{
|
||||||
|
perror("select");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
else if ( v == 0 )
|
||||||
|
return false;
|
||||||
|
|
||||||
client_sock = accept(this->listen_sock, (struct sockaddr*)&client_name, &size);
|
client_sock = accept(this->listen_sock, (struct sockaddr*)&client_name, &size);
|
||||||
if (client_sock < 0)
|
if (client_sock < 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Accepting client failed\n");
|
fprintf(stderr, "Accepting client failed\n");
|
||||||
return NULL;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new NetworkClient(client_sock);
|
printf("Nej men vobb! En klient har konnektat!\n");
|
||||||
|
/* And add the new one! */
|
||||||
|
this->AddClient(client_sock);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetworkClient::NetworkClient(const char *hostname, int port)
|
||||||
NetworkClient::NetworkClient(int sock)
|
|
||||||
{
|
{
|
||||||
this->sock = sock;
|
/* Again from glibc docs */
|
||||||
|
struct sockaddr_in servername;
|
||||||
|
|
||||||
/* Assume black screen */
|
/* Create the socket. */
|
||||||
memset(this->screen, 0, DISPLAY_X * DISPLAY_Y);
|
this->sock = socket (PF_INET, SOCK_STREAM, 0);
|
||||||
|
if (this->sock < 0)
|
||||||
|
{
|
||||||
|
perror ("socket (client)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Connect to the server. */
|
||||||
|
init_sockaddr (&servername, hostname, port);
|
||||||
|
if (connect(sock, (struct sockaddr *) &servername,
|
||||||
|
sizeof (servername)) != 0)
|
||||||
|
{
|
||||||
|
perror ("connect (client)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkClient::NetworkClient(this->sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Network::ReceiveUpdate(NetworkUpdate *dst, int sock, struct timeval *tv)
|
bool Network::ReceiveUpdate(NetworkUpdate *dst, int sock, struct timeval *tv)
|
||||||
@ -103,13 +154,16 @@ bool Network::ReceiveUpdate(NetworkUpdate *dst, int sock, struct timeval *tv)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Network::SendUpdate(NetworkUpdate *src, int sock)
|
bool Network::SendUpdate(int sock)
|
||||||
{
|
{
|
||||||
|
NetworkUpdate *src = this->ud;
|
||||||
int sz = src->size;
|
int sz = src->size;
|
||||||
|
bool out = true;
|
||||||
|
|
||||||
this->MarshalData(src);
|
this->MarshalData(src);
|
||||||
sz = write(sock, (void*)src, sz);
|
sz = write(sock, (void*)src, sz);
|
||||||
if (sz < src->size)
|
if (sz < src->size)
|
||||||
return false;
|
out = false;
|
||||||
return true;
|
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user