2009-01-19 07:44:19 +01:00
|
|
|
#ifndef NETWORK_H
|
|
|
|
#define NETWORK_H
|
|
|
|
|
2009-01-29 21:26:40 +01:00
|
|
|
#if defined(GEKKO)
|
|
|
|
# include <network.h>
|
|
|
|
#else
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
#endif
|
2009-01-19 07:44:19 +01:00
|
|
|
#include <SDL.h>
|
|
|
|
|
|
|
|
#define NETWORK_UPDATE_SIZE (256 * 1024)
|
|
|
|
enum
|
|
|
|
{
|
2009-01-26 22:00:23 +01:00
|
|
|
STOP = 99,
|
2009-01-19 07:44:19 +01:00
|
|
|
DISPLAY_UPDATE_RAW = 1,
|
|
|
|
DISPLAY_UPDATE_RLE = 2,
|
2009-01-25 11:07:51 +01:00
|
|
|
DISPLAY_UPDATE_DIFF= 3,
|
|
|
|
SOUND_UPDATE_RAW = 4,
|
|
|
|
SOUND_UPDATE_RLE = 5,
|
|
|
|
KEYBOARD_UPDATE = 6,
|
|
|
|
JOYSTICK_UPDATE = 7,
|
2009-01-29 19:04:31 +01:00
|
|
|
DISCONNECT = 8,
|
2009-01-19 07:44:19 +01:00
|
|
|
};
|
|
|
|
|
2009-01-26 22:00:23 +01:00
|
|
|
struct NetworkUpdate
|
2009-01-19 07:44:19 +01:00
|
|
|
{
|
|
|
|
Uint16 size;
|
|
|
|
Uint8 type;
|
|
|
|
|
2009-01-26 22:00:23 +01:00
|
|
|
union {
|
|
|
|
struct {
|
|
|
|
Uint8 square;
|
|
|
|
} display;
|
|
|
|
struct {
|
|
|
|
Uint8 val;
|
|
|
|
} joystick;
|
|
|
|
struct {
|
|
|
|
Uint8 val; /* Should be STOP */
|
|
|
|
} stop;
|
|
|
|
} u;
|
2009-01-19 07:44:19 +01:00
|
|
|
|
|
|
|
/* The rest is just data of some type */
|
|
|
|
Uint8 data[];
|
|
|
|
};
|
|
|
|
|
2009-01-26 22:00:23 +01:00
|
|
|
|
2009-01-19 07:44:19 +01:00
|
|
|
class Network
|
|
|
|
{
|
|
|
|
public:
|
2009-01-24 16:48:43 +01:00
|
|
|
Network();
|
|
|
|
|
|
|
|
~Network();
|
|
|
|
|
2009-01-25 11:07:51 +01:00
|
|
|
size_t EncodeDisplay(Uint8 *master, Uint8 *remote);
|
|
|
|
|
2009-01-29 21:48:58 +01:00
|
|
|
bool DecodeUpdate(uint8 *screen, bool server = false);
|
2009-01-25 11:07:51 +01:00
|
|
|
|
|
|
|
void ResetNetworkUpdate(void);
|
|
|
|
|
|
|
|
void DrawTransferredBlocks(SDL_Surface *screen);
|
|
|
|
|
|
|
|
size_t GetBytesSent() {
|
|
|
|
return this->bytes_sent;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ResetBytesSent() {
|
|
|
|
this->bytes_sent = 0;
|
|
|
|
}
|
|
|
|
|
2009-01-29 21:35:06 +01:00
|
|
|
void CloseSocket(int sock);
|
|
|
|
|
2009-01-25 11:07:51 +01:00
|
|
|
bool SendUpdate(int sock);
|
|
|
|
|
|
|
|
bool ReceiveUpdate(int sock);
|
|
|
|
|
|
|
|
bool ReceiveUpdateBlock(int sock);
|
|
|
|
|
|
|
|
protected:
|
2009-01-26 22:00:23 +01:00
|
|
|
size_t DecodeSoundUpdate(struct NetworkUpdate *src, char *buf);
|
2009-01-25 11:07:51 +01:00
|
|
|
|
2009-01-26 22:00:23 +01:00
|
|
|
size_t EncodeSoundRLE(struct NetworkUpdate *dst,
|
2009-01-25 11:07:51 +01:00
|
|
|
Uint8 *buffer, size_t len);
|
2009-01-26 22:00:23 +01:00
|
|
|
size_t EncodeSoundRaw(struct NetworkUpdate *dst,
|
2009-01-25 11:07:51 +01:00
|
|
|
Uint8 *buffer, size_t len);
|
2009-01-24 16:48:43 +01:00
|
|
|
|
2009-01-28 21:57:48 +01:00
|
|
|
/** Encode part of a screen into @a dst in a single sweep
|
|
|
|
*
|
|
|
|
* @param dst the destination update structure
|
|
|
|
* @param screen the screen to encode
|
|
|
|
* @param remote the current remote screen
|
|
|
|
* @param square the square index of the screen to encode
|
|
|
|
*
|
|
|
|
* @return the size of the encoded message
|
|
|
|
*/
|
|
|
|
size_t EncodeDisplaySquare(struct NetworkUpdate *dst,
|
|
|
|
Uint8 *screen, Uint8 *remote, int square);
|
|
|
|
|
2009-01-19 07:44:19 +01:00
|
|
|
/**
|
|
|
|
* Encode the @a buf sound buffer into @a dst
|
|
|
|
*
|
|
|
|
* @param dst the destination update structure
|
|
|
|
* @param buf the buffer to encode
|
|
|
|
* @param len the length of the in-buffer
|
|
|
|
*
|
|
|
|
* @return the size of the encoded message
|
|
|
|
*/
|
2009-01-26 22:00:23 +01:00
|
|
|
size_t EncodeSoundBuffer(struct NetworkUpdate *dst,
|
2009-01-19 07:44:19 +01:00
|
|
|
Uint8 *buf, size_t len);
|
|
|
|
|
2009-01-26 22:00:23 +01:00
|
|
|
void EncodeJoystickUpdate(struct NetworkUpdate *dst,
|
2009-01-19 07:44:19 +01:00
|
|
|
Uint8 which, Uint8 v);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Decode a display update message onto @a screen
|
|
|
|
*
|
|
|
|
* @param screen the screen to draw to
|
|
|
|
* @param src the message to decode
|
|
|
|
*/
|
2009-01-26 22:00:23 +01:00
|
|
|
bool DecodeDisplayUpdate(Uint8 *screen, struct NetworkUpdate *src);
|
2009-01-24 16:48:43 +01:00
|
|
|
|
2009-01-24 21:57:23 +01:00
|
|
|
void AddNetworkUpdate(struct NetworkUpdate *update);
|
|
|
|
|
2009-01-26 22:00:23 +01:00
|
|
|
size_t GetNetworkUpdateSize(void)
|
|
|
|
{
|
|
|
|
return (Uint8*)this->cur_ud - (Uint8*)this->ud;
|
|
|
|
}
|
|
|
|
|
2009-01-24 16:48:43 +01:00
|
|
|
/**
|
|
|
|
* 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);
|
|
|
|
|
2009-01-26 22:00:23 +01:00
|
|
|
bool DecodeDisplayDiff(Uint8 *screen, struct NetworkUpdate *src,
|
2009-01-25 11:07:51 +01:00
|
|
|
int x, int y);
|
2009-01-26 22:00:23 +01:00
|
|
|
bool DecodeDisplayRLE(Uint8 *screen, struct NetworkUpdate *src,
|
2009-01-19 07:44:19 +01:00
|
|
|
int x, int y);
|
2009-01-26 22:00:23 +01:00
|
|
|
bool DecodeDisplayRaw(Uint8 *screen, struct NetworkUpdate *src,
|
2009-01-19 07:44:19 +01:00
|
|
|
int x, int y);
|
|
|
|
|
|
|
|
bool ReceiveUpdate(NetworkUpdate *dst, int sock, struct timeval *tv);
|
|
|
|
|
2009-01-26 22:00:23 +01:00
|
|
|
bool ReceiveData(void *dst, int sock, size_t sz);
|
|
|
|
|
|
|
|
bool SendData(void *src, int sock, size_t sz);
|
|
|
|
|
|
|
|
virtual bool Select(int sock, struct timeval *tv);
|
2009-01-19 07:44:19 +01:00
|
|
|
|
2009-01-26 22:00:23 +01:00
|
|
|
bool MarshalData(NetworkUpdate *ud);
|
2009-01-24 16:48:43 +01:00
|
|
|
|
2009-01-26 22:00:23 +01:00
|
|
|
bool MarshalAllData(NetworkUpdate *p);
|
|
|
|
|
|
|
|
bool DeMarshalData(NetworkUpdate *ud);
|
|
|
|
|
|
|
|
NetworkUpdate *GetNext(NetworkUpdate *p)
|
|
|
|
{
|
|
|
|
return (NetworkUpdate*)((Uint8*)p + p->size);
|
|
|
|
}
|
|
|
|
|
2009-01-24 16:48:43 +01:00
|
|
|
NetworkUpdate *ud;
|
2009-01-25 11:07:51 +01:00
|
|
|
NetworkUpdate *tmp_ud;
|
2009-01-26 22:00:23 +01:00
|
|
|
NetworkUpdate *cur_ud;
|
2009-01-28 21:57:48 +01:00
|
|
|
Uint8 *raw_buf;
|
|
|
|
Uint8 *rle_buf;
|
|
|
|
Uint8 *diff_buf;
|
2009-01-24 21:57:23 +01:00
|
|
|
size_t bytes_sent;
|
2009-01-25 11:07:51 +01:00
|
|
|
Uint32 *square_updated;
|
2009-01-19 07:44:19 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
class NetworkClient : public Network
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
NetworkClient(int sock);
|
|
|
|
|
2009-01-24 16:48:43 +01:00
|
|
|
~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);
|
|
|
|
}
|
2009-01-19 07:44:19 +01:00
|
|
|
|
2009-01-26 22:00:23 +01:00
|
|
|
bool ReceiveData(void *dst, int sock, size_t sz);
|
|
|
|
|
2009-01-29 19:04:31 +01:00
|
|
|
/**
|
|
|
|
* Disconnect from the other end. You should delete the object
|
|
|
|
* after having done this.
|
|
|
|
*/
|
|
|
|
void Disconnect();
|
|
|
|
|
2009-01-19 07:44:19 +01:00
|
|
|
Uint8 *screen;
|
|
|
|
int joystick_port;
|
|
|
|
private:
|
|
|
|
int sock;
|
|
|
|
};
|
|
|
|
|
2009-01-24 16:48:43 +01:00
|
|
|
#define MAX_NETWORK_CLIENTS 8
|
|
|
|
|
2009-01-19 07:44:19 +01:00
|
|
|
class NetworkServer : public Network
|
|
|
|
{
|
|
|
|
public:
|
2009-01-24 16:48:43 +01:00
|
|
|
NetworkServer(int port);
|
2009-01-19 07:44:19 +01:00
|
|
|
|
2009-01-24 16:48:43 +01:00
|
|
|
bool CheckNewConnection();
|
2009-01-19 07:44:19 +01:00
|
|
|
|
2009-01-24 16:48:43 +01:00
|
|
|
NetworkClient *clients[MAX_NETWORK_CLIENTS];
|
2009-01-19 07:44:19 +01:00
|
|
|
int n_clients;
|
|
|
|
|
2009-01-29 19:04:31 +01:00
|
|
|
void RemoveClient(NetworkClient *client);
|
|
|
|
|
2009-01-19 07:44:19 +01:00
|
|
|
private:
|
2009-01-24 16:48:43 +01:00
|
|
|
void AddClient(int sock);
|
|
|
|
|
2009-01-19 07:44:19 +01:00
|
|
|
int listen_sock;
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif /* NETWORK_H */
|