Somewhat working networking (hey - hardcoding!)

This commit is contained in:
simon.kagstrom 2009-01-24 20:57:23 +00:00
parent f31320b774
commit 83d797ede3
8 changed files with 150 additions and 63 deletions

View File

@ -24,6 +24,11 @@
#define TMP_PATH "tmp"
#endif
/* TODO: */
extern int fixme_tmp_network_client;
extern int fixme_tmp_network_server;
static struct timeval tv_start;
static const char *main_menu_messages[] = {
"Invoke key sequence", /* 0 */
@ -96,6 +101,12 @@ void C64::c64_ctor1(void)
strncpy(this->server_hostname, "localhost",
sizeof(this->server_hostname));
this->server_port = 19760;
if (fixme_tmp_network_server)
this->network_server = new NetworkServer(this->server_port);
if (fixme_tmp_network_client)
this->network_client = new NetworkClient(this->server_hostname,
this->server_port);
}
void C64::c64_ctor2(void)
@ -549,6 +560,10 @@ void C64::Run(void)
void C64::VBlank(bool draw_frame)
{
/* From Acorn port */
static uint64_t lastFrame;
static uint32_t now;
#if defined(GEKKO)
WPAD_ScanPads();
#endif
@ -577,32 +592,16 @@ void C64::VBlank(bool draw_frame)
TheCIA2->CountTOD();
// Update window if needed
if (draw_frame) {
if (draw_frame && this->network_client == NULL) {
TheDisplay->Update();
#if 0
// Calculate time between VBlanks, display speedometer
struct timeval tv;
gettimeofday(&tv, NULL);
if ((tv.tv_usec -= tv_start.tv_usec) < 0) {
tv.tv_usec += 1000000;
tv.tv_sec -= 1;
}
tv.tv_sec -= tv_start.tv_sec;
double elapsed_time = (double)tv.tv_sec * 1000000 + tv.tv_usec;
speed_index = 20000 / (elapsed_time + 1) * 100;
static int frms = 1;
frms--;
if (this->network_server && frms == 0) {
static uint32_t last_time_update;
static size_t bytes_sent;
// Limit speed to 100% if desired
if ((speed_index > 100)) {
usleep((unsigned long)(20000 - elapsed_time));
speed_index = 100;
}
gettimeofday(&tv_start, NULL);
TheDisplay->Speedometer((int)speed_index);
#endif
}
if (this->network_server) {
frms = 6;
/* Perhaps accept a new connection */
this->network_server->CheckNewConnection();
@ -613,6 +612,27 @@ void C64::VBlank(bool draw_frame)
remote->EncodeDisplay(master, remote->screen);
remote->SendUpdate();
remote->ResetNetworkUpdate();
bytes_sent += remote->GetBytesSent();
}
if (now - last_time_update > 1000)
{
printf("%.2f kbytes / second\n",
((bytes_sent * 1000.0) / ((float)now - last_time_update)) / 1024.0);
for (int i = 0; i < this->network_server->n_clients; i++)
this->network_server->clients[i]->ResetBytesSent();
bytes_sent = 0;
last_time_update = now;
}
}
else if (this->network_client) {
/* Got something? */
if (this->network_client->ReceiveUpdateBlock())
{
this->network_client->DecodeUpdate(
this->network_client->screen);
TheDisplay->Update(this->network_client->screen);
this->network_client->ResetNetworkUpdate();
}
}
if (this->have_a_break) {
@ -676,12 +696,10 @@ void C64::VBlank(bool draw_frame)
if (this->quit_thyself)
ThePrefs.Save(PREFS_PATH);
}
/* From Acorn port */
static uint64_t lastFrame;
#if defined(GEKKO)
uint32_t now = ticks_to_millisecs(gettime());
now = ticks_to_millisecs(gettime());
#else
uint32_t now = SDL_GetTicks();
now = SDL_GetTicks();
#endif
if ( (now - lastFrame) < ThePrefs.MsPerFrame) {

View File

@ -82,6 +82,7 @@ public:
void FakeKeyPress(int kc, uint8 *CIA_key_matrix, uint8 *CIA_rev_matrix);
void TranslateKey(SDLKey key, bool key_up, uint8 *key_matrix, uint8 *rev_matrix, uint8 *joystick);
void UpdateKeyMatrix(int c64_key, bool key_up, uint8 *key_matrix, uint8 *rev_matrix);
void Update(uint8 *src_pixels);
#endif
bool NumLock(void);
void InitColors(uint8 *colors);

View File

@ -176,9 +176,8 @@ void C64Display::NewPrefs(Prefs *prefs)
* Redraw bitmap
*/
void C64Display::Update(void)
void C64Display::Update(uint8 *src_pixels)
{
Uint8 *src_pixels = (Uint8*)screen;
const Uint16 src_pitch = DISPLAY_X;
if (ThePrefs.DisplayOption == 0) {
@ -228,6 +227,10 @@ void C64Display::Update(void)
SDL_Flip(real_screen);
}
void C64Display::Update()
{
this->Update((Uint8*)screen);
}
/*
* Draw string into surface using the C64 ROM font

View File

@ -17,7 +17,7 @@ DESTDIR =
CXX = g++
CC = gcc
CFLAGS =-DFRODO_SC -g -O2 -I/usr/include/SDL -I$(DEVKITPRO)/libogc/include -D_GNU_SOURCE=1 -D_REENTRANT -DHAVE_SDL -DORBIT2=1 -pthread -I/usr/include/libglade-2.0 -I/usr/include/gtk-2.0 -I/usr/include/libxml2 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/pixman-1 -I/usr/include/libgnomeui-2.0 -I/usr/include/libart-2.0 -I/usr/include/gconf/2 -I/usr/include/gnome-keyring-1 -I/usr/include/libgnome-2.0 -I/usr/include/libbonoboui-2.0 -I/usr/include/libgnomecanvas-2.0 -I/usr/include/gnome-vfs-2.0 -I/usr/lib/gnome-vfs-2.0/include -I/usr/include/orbit-2.0 -I/usr/include/libbonobo-2.0 -I/usr/include/bonobo-activation-2.0 -I/usr/include/gail-1.0 -I./ -DKBD_LANG=0
CFLAGS =-DFRODO_SC -g -I/usr/include/SDL -I$(DEVKITPRO)/libogc/include -D_GNU_SOURCE=1 -D_REENTRANT -DHAVE_SDL -DORBIT2=1 -pthread -I/usr/include/libglade-2.0 -I/usr/include/gtk-2.0 -I/usr/include/libxml2 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/pixman-1 -I/usr/include/libgnomeui-2.0 -I/usr/include/libart-2.0 -I/usr/include/gconf/2 -I/usr/include/gnome-keyring-1 -I/usr/include/libgnome-2.0 -I/usr/include/libbonoboui-2.0 -I/usr/include/libgnomecanvas-2.0 -I/usr/include/gnome-vfs-2.0 -I/usr/lib/gnome-vfs-2.0/include -I/usr/include/orbit-2.0 -I/usr/include/libbonobo-2.0 -I/usr/include/bonobo-activation-2.0 -I/usr/include/gail-1.0 -I./ -DKBD_LANG=0
DEFS = -DHAVE_CONFIG_H -DDATADIR=\"$(datadir)/frodo/\" -DBINDIR=\"$(bindir)/\" -DHAVE_SDL
LDFLAGS = -Wl,-E
LIBS = -L/usr/lib -lSDL -lSDL_ttf -pthread -lglade-2.0 -lxml2 -lgnomeui-2 -lSM -lICE -lbonoboui-2 -lgnomevfs-2 -lgnomecanvas-2 -lgnome-2 -lpopt -lbonobo-2 -lbonobo-activation -lORBit-2 -lart_lgpl_2 -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lpangocairo-1.0 -lpango-1.0 -lcairo -lgconf-2 -lgthread-2.0 -lrt -lgmodule-2.0 -ldl -lgobject-2.0 -lglib-2.0

View File

@ -22,8 +22,8 @@
#include "Network.h"
#include "Display.h"
#define N_SQUARES_W 20
#define N_SQUARES_H 20
#define N_SQUARES_W 16
#define N_SQUARES_H 8
#define SQUARE_W (DISPLAY_X / N_SQUARES_W)
#define SQUARE_H (DISPLAY_Y / N_SQUARES_H)
@ -40,6 +40,7 @@ Network::Network()
/* "big enough" static buffer */
this->ud = (NetworkUpdate*)malloc( size );
this->ResetNetworkUpdate();
this->bytes_sent = 0;
}
Network::~Network()
@ -53,9 +54,9 @@ size_t Network::EncodeDisplayRaw(struct NetworkDisplayUpdate *dst, Uint8 *screen
const int raw_w = SQUARE_W / 2;
dst->type = DISPLAY_UPDATE_RAW;
for (int y = y_start; y < y_start + SQUARE_W; y++)
for (int y = y_start; y < y_start + SQUARE_H; y++)
{
for (int x = x_start; x < x_start + SQUARE_H; x += 2)
for (int x = x_start; x < x_start + SQUARE_W; x += 2)
{
Uint8 a = screen[ y * DISPLAY_X + x ];
Uint8 b = screen[ y * DISPLAY_X + (x + 1) ];
@ -77,9 +78,9 @@ size_t Network::EncodeDisplayRLE(struct NetworkDisplayUpdate *dst, Uint8 *screen
dst->type = DISPLAY_UPDATE_RLE;
for (int y = y_start; y < y_start + SQUARE_W; y++)
for (int y = y_start; y < y_start + SQUARE_H; y++)
{
for (int x = x_start; x < x_start + SQUARE_H; x++)
for (int x = x_start; x < x_start + SQUARE_W; x++)
{
if (color != screen[ y * DISPLAY_X + x ] ||
len >= 255)
@ -94,6 +95,13 @@ size_t Network::EncodeDisplayRLE(struct NetworkDisplayUpdate *dst, Uint8 *screen
len++;
}
}
if (len != 0)
{
dst->data[out] = len;
dst->data[out + 1] = color;
out += 2;
}
return out;
}
@ -141,12 +149,13 @@ bool Network::DecodeDisplayRLE(Uint8 *screen, struct NetworkDisplayUpdate *src,
int p = 0;
int x = x_start;
int y = y_start;
int sz = src->size - sizeof(NetworkDisplayUpdate);
/* Something is wrong if this is true... */
if (src->size % 2 != 0)
if (sz % 2 != 0)
return false;
while (p < src->size)
while (p < sz)
{
Uint8 len = src->data[p];
Uint8 color = src->data[p+1];
@ -173,9 +182,9 @@ bool Network::DecodeDisplayRaw(Uint8 *screen, struct NetworkDisplayUpdate *src,
{
const int raw_w = SQUARE_W / 2;
for (int y = y_start; y < y_start + SQUARE_W; y++)
for (int y = y_start; y < y_start + SQUARE_H; y++)
{
for (int x = x_start; x < x_start + SQUARE_H; x += 2)
for (int x = x_start; x < x_start + SQUARE_W; x += 2)
{
Uint8 v = src->data[(y - y_start) * raw_w + (x - x_start) / 2];
Uint8 a = v >> 4;
@ -216,7 +225,7 @@ bool Network::CompareSquare(Uint8 *a, Uint8 *b)
Uint8 va = a[ y * DISPLAY_X + x ];
Uint8 vb = b[ y * DISPLAY_X + x ];
if (va == vb)
if (va != vb)
return false;
}
}
@ -305,7 +314,7 @@ void Network::ResetNetworkUpdate(void)
this->ud->type = HEADER;
this->ud->size = sizeof(NetworkUpdate);
this->cur_ud = (Uint8*)(this->ud + sizeof(NetworkUpdate));
this->cur_ud = (Uint8*)(this->ud->data);
}
@ -323,6 +332,15 @@ bool Network::ReceiveUpdateBlock(int sock)
return this->ReceiveUpdate(this->ud, sock, NULL);
}
void Network::AddNetworkUpdate(NetworkUpdate *update)
{
size_t sz = update->size;
this->cur_ud += sz;
this->ud->size += sz;
}
void Network::MarshalData(NetworkUpdate *ud)
{
Uint8 *p = ud->data;
@ -330,7 +348,7 @@ void Network::MarshalData(NetworkUpdate *ud)
int sz = ud->size;
ud->size = htons(ud->size);
while (len < ud->size)
while (len < sz)
{
p = p + len;
@ -343,7 +361,7 @@ void Network::MarshalData(NetworkUpdate *ud)
{
NetworkDisplayUpdate *tmp = (NetworkDisplayUpdate *)p;
len = tmp->size;
len += tmp->size;
tmp->size = htons(tmp->size);
} break;
case JOYSTICK_UPDATE:
@ -375,8 +393,8 @@ void Network::DeMarshalData(NetworkUpdate *ud)
{
NetworkDisplayUpdate *tmp = (NetworkDisplayUpdate *)p;
len = tmp->size;
tmp->size = ntohl(tmp->size);
tmp->size = ntohs(tmp->size);
len += tmp->size;
} break;
case JOYSTICK_UPDATE:
len = sizeof(NetworkJoystickUpdate);
@ -388,6 +406,28 @@ void Network::DeMarshalData(NetworkUpdate *ud)
}
}
bool Network::DecodeUpdate(uint8 *screen)
{
unsigned int cookie;
NetworkUpdate *p;
int i = 0;
for (p = this->IterateFirst(this->ud, &cookie); p;
p = this->IterateNext(this->ud, &cookie))
{
switch(p->type)
{
case DISPLAY_UPDATE_RAW:
case DISPLAY_UPDATE_RLE:
this->DecodeDisplayUpdate(screen, (NetworkDisplayUpdate*)p);
break;
default:
break;
}
i++;
}
}
NetworkUpdate *Network::IterateFirst(NetworkUpdate *p, unsigned int *cookie)
{
Uint8 *p8 = (Uint8*)p;
@ -398,15 +438,15 @@ NetworkUpdate *Network::IterateFirst(NetworkUpdate *p, unsigned int *cookie)
return NULL;
*cookie = *cookie + cur->size;
return (NetworkUpdate *)p->data;
return cur;
}
NetworkUpdate *Network::IterateNext(NetworkUpdate *p, unsigned int *cookie)
{
NetworkUpdate *cur = (NetworkUpdate *)(p->data + *cookie);
NetworkUpdate *cur = (NetworkUpdate *)(((Uint8*)p) + *cookie);
/* End of iteration */
if ( *cookie >= p->size )
if ( *cookie >= p->size || cur->size == 0)
return NULL;
*cookie = *cookie + cur->size;
@ -439,5 +479,4 @@ NetworkClient::~NetworkClient()
free(this->screen);
}
#include "NetworkUnix.h"

View File

@ -95,6 +95,8 @@ public:
size_t DecodeSoundUpdate(struct NetworkSoundUpdate *src, char *buf);
bool DecodeUpdate(uint8 *screen);
void ResetNetworkUpdate(void);
bool SendUpdate(int sock);
@ -103,6 +105,14 @@ public:
bool ReceiveUpdateBlock(int sock);
size_t GetBytesSent() {
return this->bytes_sent;
}
void ResetBytesSent() {
this->bytes_sent = 0;
}
private:
size_t EncodeDisplayRLE(struct NetworkDisplayUpdate *dst, Uint8 *screen,
int x, int y);
@ -117,11 +127,8 @@ private:
NetworkUpdate *IterateNext(NetworkUpdate *p, unsigned int *cookie);
void AddNetworkUpdate(struct NetworkUpdate *update)
{
this->cur_ud += update->size;
this->ud->size += update->size;
}
void AddNetworkUpdate(struct NetworkUpdate *update);
/**
* Compare two display squares.
*
@ -145,6 +152,7 @@ private:
NetworkUpdate *ud;
Uint8 *cur_ud;
size_t bytes_sent;
};
class NetworkClient : public Network

View File

@ -7,8 +7,9 @@
/* From glibc docs */
static int make_socket (uint16_t port)
{
int sock;
struct sockaddr_in name;
int sock;
int d = 1;
/* Create the socket. */
sock = socket (PF_INET, SOCK_STREAM, 0);
@ -18,6 +19,11 @@ static int make_socket (uint16_t port)
exit (EXIT_FAILURE);
}
if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR, &d, sizeof(int)) < 0) {
perror("setsockopt");
exit(1);
}
/* Give the socket a name. */
name.sin_family = AF_INET;
name.sin_port = htons (port);
@ -89,6 +95,7 @@ bool NetworkServer::CheckNewConnection()
else if ( v == 0 )
return false;
size = sizeof(client_name);
client_sock = accept(this->listen_sock, (struct sockaddr*)&client_name, &size);
if (client_sock < 0)
{
@ -96,7 +103,6 @@ bool NetworkServer::CheckNewConnection()
return false;
}
printf("Nej men vobb! En klient har konnektat!\n");
/* And add the new one! */
this->AddClient(client_sock);
@ -125,7 +131,11 @@ NetworkClient::NetworkClient(const char *hostname, int port)
return;
}
NetworkClient::NetworkClient(this->sock);
this->screen = (Uint8 *)malloc(DISPLAY_X * DISPLAY_Y);
assert(this->screen);
/* Assume black screen */
memset(this->screen, 0, DISPLAY_X * DISPLAY_Y);
}
bool Network::ReceiveUpdate(NetworkUpdate *dst, int sock, struct timeval *tv)
@ -137,7 +147,7 @@ bool Network::ReceiveUpdate(NetworkUpdate *dst, int sock, struct timeval *tv)
FD_ZERO(&fds);
FD_SET(sock, &fds);
v = select(1, &fds, NULL, NULL, tv);
v = select(sock + 1, &fds, NULL, NULL, tv);
if (v < 0)
{
fprintf(stderr, "Select failed\n");
@ -160,6 +170,8 @@ bool Network::SendUpdate(int sock)
int sz = src->size;
bool out = true;
this->bytes_sent += sz;
this->MarshalData(src);
sz = write(sock, (void*)src, sz);
if (sz < src->size)

View File

@ -100,11 +100,17 @@ Frodo::Frodo()
/*
* Process command line arguments
*/
int fixme_tmp_network_client = 0;
int fixme_tmp_network_server = 0;
void Frodo::ArgvReceived(int argc, char **argv)
{
if (argc == 2)
strncpy(prefs_path, argv[1], 255);
if (argc == 2 &&
strcmp(argv[1], "-s") == 0)
fixme_tmp_network_server = 1;
if (argc == 2 &&
strcmp(argv[1], "-c") == 0)
fixme_tmp_network_client = 1;
}