frodo-wii/Src/Network.h

253 lines
4.8 KiB
C
Raw Normal View History

2009-01-19 07:44:19 +01:00
#ifndef NETWORK_H
#define NETWORK_H
#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
{
STOP = 99,
2009-02-01 11:52:32 +01:00
DISCONNECT = 77,
2009-01-19 07:44:19 +01:00
DISPLAY_UPDATE_RAW = 1,
DISPLAY_UPDATE_RLE = 2,
DISPLAY_UPDATE_DIFF= 3,
SOUND_UPDATE_RAW = 4,
SOUND_UPDATE_RLE = 5,
KEYBOARD_UPDATE = 6,
JOYSTICK_UPDATE = 7,
2009-02-01 11:52:32 +01:00
ENTER_MENU = 8,
GET_PEER_INFO = 9,
2009-01-19 07:44:19 +01:00
};
struct NetworkUpdate
2009-01-19 07:44:19 +01:00
{
Uint16 size;
Uint8 type;
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-19 07:44:19 +01:00
class Network
{
public:
2009-01-24 16:48:43 +01:00
Network();
~Network();
size_t EncodeDisplay(Uint8 *master, Uint8 *remote);
void EncodeJoystickUpdate(Uint8 v);
bool DecodeUpdate(uint8 *screen, uint8 *js = NULL, bool server = false);
void ResetNetworkUpdate(void);
void DrawTransferredBlocks(SDL_Surface *screen);
size_t GetKbps() {
return this->kbps;
}
bool ThrottleTraffic() {
return this->kbps > this->target_kbps;
}
void ResetBytesSent() {
this->traffic = 0;
}
void Tick(int ms);
2009-01-29 21:35:06 +01:00
void CloseSocket(int sock);
bool SendUpdate(int sock);
bool ReceiveUpdate(int sock);
bool ReceiveUpdateBlock(int sock);
protected:
size_t DecodeSoundUpdate(struct NetworkUpdate *src, char *buf);
size_t EncodeSoundRLE(struct NetworkUpdate *dst,
Uint8 *buffer, size_t len);
size_t EncodeSoundRaw(struct NetworkUpdate *dst,
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
*/
size_t EncodeSoundBuffer(struct NetworkUpdate *dst,
2009-01-19 07:44:19 +01:00
Uint8 *buf, size_t len);
/**
* Decode a display update message onto @a screen
*
* @param screen the screen to draw to
* @param src the message to decode
*/
bool DecodeDisplayUpdate(Uint8 *screen, struct NetworkUpdate *src);
2009-01-24 16:48:43 +01:00
void AddNetworkUpdate(struct NetworkUpdate *update);
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);
bool DecodeDisplayDiff(Uint8 *screen, struct NetworkUpdate *src,
int x, int y);
bool DecodeDisplayRLE(Uint8 *screen, struct NetworkUpdate *src,
2009-01-19 07:44:19 +01:00
int x, int y);
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);
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
bool MarshalData(NetworkUpdate *ud);
2009-01-24 16:48:43 +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;
NetworkUpdate *tmp_ud;
NetworkUpdate *cur_ud;
2009-01-28 21:57:48 +01:00
Uint8 *raw_buf;
Uint8 *rle_buf;
Uint8 *diff_buf;
Uint32 *square_updated;
size_t traffic, last_traffic;
int time_since_last_reset;
int target_kbps;
int kbps;
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
bool ReceiveData(void *dst, int sock, size_t sz);
/**
* 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;
Uint8 cur_joystick_data;
2009-01-19 07:44:19 +01:00
private:
void Init();
2009-01-19 07:44:19 +01:00
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;
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 */