no message
[crow/jumpnbump.git] / main.c
diff --git a/main.c b/main.c
index 845e9e3..91b1b00 100644 (file)
--- a/main.c
+++ b/main.c
 #include "globals.h"
 #include <fcntl.h>
 
+#ifdef USE_NET
+#include "SDL_net.h"
+#endif /* USE_NET */
+
 #ifndef M_PI
 #define M_PI           3.14159265358979323846
 #endif
@@ -239,19 +243,20 @@ int filelength(int handle)
 int client_player_num = -1;
 int is_server = 1;
 int is_net = 0;
-int sock = -1;
+
+#ifdef USE_NET
+TCPsocket sock = NULL;
+SDLNet_SocketSet socketset = NULL;
 
 typedef struct
 {
-    int sock;
-#ifdef USE_SDL_NET
-    /*struct timeval last_timestamp;*/
-    struct sockaddr *addr;
-    int addrlen;
-#endif
+       TCPsocket sock;
+       IPaddress addr;
+       SDLNet_SocketSet socketset;
 } NetInfo;
 
 NetInfo net_info[JNB_MAX_PLAYERS];
+#endif
 
 typedef struct
 {
@@ -275,54 +280,62 @@ typedef struct
 #define NETCMD_KILL         (0xF00DF00D + 8)
 
 
-#if USE_SDL_NET
+#ifdef USE_NET
 void bufToPacket(const char *buf, NetPacket *pkt)
 {
-       SDLNet_Write32(*((unsigned long *) (buf +  0)), pkt->cmd);
-       SDLNet_Write32(*((unsigned long *) (buf +  4)), pkt->arg);
-       SDLNet_Write32(*((unsigned long *) (buf +  8)), pkt->arg2);
-       SDLNet_Write32(*((unsigned long *) (buf + 12)), pkt->arg3);
-       SDLNet_Write32(*((unsigned long *) (buf + 16)), pkt->arg4);
+       SDLNet_Write32(*((unsigned long *) (buf +  0)), &pkt->cmd);
+       SDLNet_Write32(*((unsigned long *) (buf +  4)), &pkt->arg);
+       SDLNet_Write32(*((unsigned long *) (buf +  8)), &pkt->arg2);
+       SDLNet_Write32(*((unsigned long *) (buf + 12)), &pkt->arg3);
+       SDLNet_Write32(*((unsigned long *) (buf + 16)), &pkt->arg4);
+/*
+       pkt->cmd               =        ntohl(*((unsigned long *) (buf +  0)));
+       pkt->arg               = (long) ntohl(*((unsigned long *) (buf +  4)));
+       pkt->arg2              = (long) ntohl(*((unsigned long *) (buf +  8)));
+       pkt->arg3              = (long) ntohl(*((unsigned long *) (buf + 12)));
+       pkt->arg4              = (long) ntohl(*((unsigned long *) (buf + 16)));
+*/
 }
 
 
 void packetToBuf(const NetPacket *pkt, char *buf)
 {
-       *((unsigned long *) (buf +  0)) = SDLNet_Read32(pkt->cmd);
-       *((unsigned long *) (buf +  4)) = SDLNet_Read32((unsigned long) pkt->arg);
-       *((unsigned long *) (buf +  8)) = SDLNet_Read32((unsigned long) pkt->arg2);
-       *((unsigned long *) (buf + 12)) = SDLNet_Read32((unsigned long) pkt->arg3);
-       *((unsigned long *) (buf + 16)) = SDLNet_Read32((unsigned long) pkt->arg4);
+       *((unsigned long *) (buf +  0)) = SDLNet_Read32(&pkt->cmd);
+       *((unsigned long *) (buf +  4)) = SDLNet_Read32(&pkt->arg);
+       *((unsigned long *) (buf +  8)) = SDLNet_Read32(&pkt->arg2);
+       *((unsigned long *) (buf + 12)) = SDLNet_Read32(&pkt->arg3);
+       *((unsigned long *) (buf + 16)) = SDLNet_Read32(&pkt->arg4);
+/*
+       *((unsigned long *) (buf +  0)) = htonl(pkt->cmd);
+       *((unsigned long *) (buf +  4)) = htonl((unsigned long) pkt->arg);
+       *((unsigned long *) (buf +  8)) = htonl((unsigned long) pkt->arg2);
+       *((unsigned long *) (buf + 12)) = htonl((unsigned long) pkt->arg3);
+       *((unsigned long *) (buf + 16)) = htonl((unsigned long) pkt->arg4);
+*/
 }
-#endif
 
-void sendPacketToSock(int s, NetPacket *pkt)
+
+void sendPacketToSock(TCPsocket s, NetPacket *pkt)
 {
-#if USE_SDL_NET
-    int bytes_left = NETPKTBUFSIZE;
-    int bw;
-    char buf[NETPKTBUFSIZE];
-    char *ptr = buf;
-
-    return;
-    
-    packetToBuf(pkt, buf);
-    while (bytes_left > 0) {
-        bw = write(s, ptr, bytes_left);  /* this might block. For now, we'll deal. */
-        if (bw < 0) {
-            if (errno != EAGAIN) {
-                perror("SERVER: write()");
-                close(s);
-                exit(42);
-            }
-        } else if (bw == 0) {
-            SDL_Delay(1);
-        } else {
-            bytes_left -= bw;
-            ptr += bw;
-        }
-    }
-#endif
+       int bytes_left = NETPKTBUFSIZE;
+       int bw;
+       char buf[NETPKTBUFSIZE];
+       char *ptr = buf;
+
+       packetToBuf(pkt, buf);
+       while (bytes_left > 0) {
+               bw = SDLNet_TCP_Send(s, ptr, bytes_left);
+               if (bw < 0) {
+                       fprintf(stderr, "SERVER: SDLNet_TCP_Send(): %s\n", SDLNet_GetError());
+                       SDLNet_TCP_Close(s);
+                       exit(42);
+               } else if (bw == 0) {
+                       SDL_Delay(1);
+               } else {
+                       bytes_left -= bw;
+                       ptr += bw;
+               }
+       }
 }
 
 
@@ -346,35 +359,27 @@ void sendPacketToAll(NetPacket *pkt)
 }
 
 
-int grabPacket(int s, NetPacket *pkt)
+int grabPacket(TCPsocket s, SDLNet_SocketSet ss, NetPacket *pkt)
 {
-#if USE_SDL_NET
-    char buf[NETPKTBUFSIZE];
-    struct timeval tv;
-    fd_set rfds;
-    int rc;
-    int retval = 0;
-
-    FD_ZERO(&rfds);
-    FD_SET(s, &rfds);
-    tv.tv_sec = tv.tv_usec = 0;    /* don't block. */
-    if (select(s + 1, &rfds, NULL, NULL, &tv)) {
-        rc = read(s, buf, NETPKTBUFSIZE);
-        if (rc <= 0) {  /* closed connection? */
-            retval = -1;
-        } else if (rc != NETPKTBUFSIZE) { // !!! FIXME: buffer these?
-            printf("NETWORK: -BUG- ... dropped a packet! (had %d of %d bytes).\b",
-                    rc, NETPKTBUFSIZE);
-        } else {
-            bufToPacket(buf, pkt);
-            retval = 1;
-        }
-    }
-
-    return(retval);
-#endif
+       static char buf[NETPKTBUFSIZE];
+       static int buf_count = 0;
+       int rc;
+       int retval = 0;
+
+       if (SDLNet_CheckSockets(ss, 0) > 0) {
+               rc = SDLNet_TCP_Recv(s, &buf[buf_count], NETPKTBUFSIZE - buf_count);
+               if (rc <= 0) {  /* closed connection? */
+                       retval = -1;
+               } else if (rc != NETPKTBUFSIZE) {
+                       buf_count = rc;
+               } else {
+                       buf_count = 0;
+                       bufToPacket(buf, pkt);
+                       retval = 1;
+               }
+       }
 
-    return 0;
+       return(retval);
 }
 
 
@@ -386,17 +391,17 @@ int serverRecvPacket(NetPacket *pkt)
        assert(is_server);
 
        for (i = 0; i < JNB_MAX_PLAYERS; i++) {
-               int s = net_info[i].sock;
+               TCPsocket s = net_info[i].sock;
 
                if ((i == client_player_num) || (!player[i].enabled))
                        continue;
 
-               rc = grabPacket(s, pkt);
+               rc = grabPacket(s, net_info[i].socketset, pkt);
                if (rc < 0) {
                        NetPacket pkt;
 
                        player[i].enabled = 0;
-                       close(s);
+                       SDLNet_TCP_Close(s);
                        pkt.cmd = NETCMD_BYE;
                        pkt.arg = i;
                        pkt.arg2 = 0;
@@ -421,13 +426,13 @@ void wait_for_greenlight(void)
 
        do {
                int rc;
-               while ((rc = grabPacket(sock, &pkt)) == 0) {
+               while ((rc = grabPacket(sock, socketset, &pkt)) == 0) {
                        SDL_Delay(100);  /* nap and then try again. */
                }
 
                if (rc < 0) {
                        printf("CLIENT: Lost connection.\n");
-                       close(sock);
+                       SDLNet_TCP_Close(sock);
                        exit(42);
                }
        } while (pkt.cmd != NETCMD_GREENLIGHT);
@@ -460,6 +465,7 @@ void tellServerGoodbye(void)
                sendPacketToSock(sock, &pkt);
        }
 }
+#endif /* USE_NET */
 
 
 void processMovePacket(NetPacket *pkt)
@@ -495,13 +501,17 @@ void tellServerPlayerMoved(int playerid, int movement_type, int newval)
 
        if (is_server) {
                processMovePacket(&pkt);
-               sendPacketToAll(&pkt);
+#ifdef USE_NET
+               if (is_net)
+                       sendPacketToAll(&pkt);
        } else {
                sendPacketToSock(sock, &pkt);
+#endif
        }
 }
 
 
+#ifdef USE_NET
 void tellServerNewPosition(void)
 {
        NetPacket pkt;
@@ -516,6 +526,7 @@ void tellServerNewPosition(void)
                sendPacketToSock(sock, &pkt);
        }
 }
+#endif /* USE_NET */
 
 
 void processKillPacket(NetPacket *pkt)
@@ -561,6 +572,7 @@ void processKillPacket(NetPacket *pkt)
 }
 
 
+#ifdef USE_NET
 void processPositionPacket(NetPacket *pkt)
 {
        int playerid = pkt->arg;
@@ -612,7 +624,7 @@ int update_players_from_server(void)
 
        assert(!is_server);
 
-       while ((rc = grabPacket(sock, &pkt)) != 0) {
+       while ((rc = grabPacket(sock, socketset, &pkt)) != 0) {
                if (rc < 0) {
                        printf("CLIENT: Lost connection.\n");
                        pkt.cmd = NETCMD_BYE;
@@ -621,8 +633,9 @@ int update_players_from_server(void)
 
                if (pkt.cmd == NETCMD_BYE) {
                        if (pkt.arg == client_player_num) {
-                               close(sock);
-                               sock = -1;
+                               SDLNet_FreeSocketSet(socketset);
+                               SDLNet_TCP_Close(sock);
+                               sock = NULL;
                                server_said_bye = 1;
                                return(0);
                        } else {
@@ -656,6 +669,7 @@ void serverSendAlive(int playerid)
        pkt.arg3 = player[playerid].y;
        sendPacketToAll(&pkt);
 }
+#endif /* USE_NET */
 
 
 void serverSendKillPacket(int killer, int victim)
@@ -669,294 +683,272 @@ void serverSendKillPacket(int killer, int victim)
        pkt.arg3 = player[victim].x;
        pkt.arg4 = player[victim].y;
        processKillPacket(&pkt);
-       sendPacketToAll(&pkt);
+#ifdef USE_NET
+       if (is_net)
+               sendPacketToAll(&pkt);
+#endif
 }
 
 
+#ifdef USE_NET
 void update_players_from_clients(void)
 {
-#if USE_SDL_NET
-    int i;
-    NetPacket pkt;
-    int playerid;
-
-    return;
-
-    assert(is_server);
-
-    while ((playerid = serverRecvPacket(&pkt)) >= 0) {
-        if (pkt.cmd == NETCMD_BYE) {
-            pkt.arg = playerid;  /* just in case. */
-            sendPacketToAll(&pkt);
-            player[playerid].enabled = 0;
-            close(net_info[playerid].sock);
-        } else if (pkt.cmd == NETCMD_POSITION) {
-            pkt.arg = playerid;  /* just in case. */
-            processPositionPacket(&pkt);
-            for (i = 0; i < (sizeof (net_info) / sizeof (net_info[0])); i++) {
-                if (i != playerid) {
-                    sendPacket(i, &pkt);
-                }
-            }
-        } else if (pkt.cmd == NETCMD_MOVE) {
-            pkt.arg = playerid;  /* just in case. */
-            //pkt.arg3 = player[playerid].x;
-            //pkt.arg4 = player[playerid].y;
-            processMovePacket(&pkt);
-            sendPacketToAll(&pkt);
-        } else {
-            printf("SERVER: Got unknown packet (0x%lX).\n", pkt.cmd);
-        }
-    }
-#endif
+       int i;
+       NetPacket pkt;
+       int playerid;
+
+       assert(is_server);
+
+       while ((playerid = serverRecvPacket(&pkt)) >= 0) {
+               if (pkt.cmd == NETCMD_BYE) {
+                       pkt.arg = playerid;  /* just in case. */
+                       sendPacketToAll(&pkt);
+                       player[playerid].enabled = 0;
+                       SDLNet_FreeSocketSet(net_info[playerid].socketset);
+                       SDLNet_TCP_Close(net_info[playerid].sock);
+               } else if (pkt.cmd == NETCMD_POSITION) {
+                       pkt.arg = playerid;  /* just in case. */
+                       processPositionPacket(&pkt);
+                       for (i = 0; i < JNB_MAX_PLAYERS; i++) {
+                               if (i != playerid) {
+                                       sendPacket(i, &pkt);
+                               }
+                       }
+               } else if (pkt.cmd == NETCMD_MOVE) {
+                       pkt.arg = playerid;  /* just in case. */
+                       /*
+                       pkt.arg3 = player[playerid].x;
+                       pkt.arg4 = player[playerid].y;
+                       */
+                       processMovePacket(&pkt);
+                       sendPacketToAll(&pkt);
+               } else {
+                       printf("SERVER: Got unknown packet (0x%lX).\n", pkt.cmd);
+               }
+       }
 }
 
 
 void init_server(const char *netarg)
 {
-#if USE_SDL_NET
-    NetPacket pkt;
-    char ipstr[128];
-    struct hostent *hent;
-    struct sockaddr_in addr;
-    struct in_addr inaddr;
-    int i;
-    int wait_for_clients = ((netarg == NULL) ? 0 : atoi(netarg));
-
-    if ((wait_for_clients > 3) || (wait_for_clients < 0)) {
-        printf("SERVER: Waiting for bogus client count (%d).\n", wait_for_clients);
-        exit(42);
-    }
+       NetPacket pkt;
+       IPaddress addr;
+       int i;
+       int wait_for_clients = ((netarg == NULL) ? 0 : atoi(netarg));
+       char *ipstr;
 
-    sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
-    if (sock < 0) {
-        perror("SERVER: socket()");
-        exit(42);
-    }
+       if ((wait_for_clients > (JNB_MAX_PLAYERS - 1)) || (wait_for_clients < 0)) {
+               printf("SERVER: Waiting for bogus client count (%d).\n", wait_for_clients);
+               exit(42);
+       }
 
-    memset(&addr, '\0', sizeof (addr));
-    addr.sin_family = AF_INET;
-    addr.sin_port = htons(JNB_INETPORT);
-    addr.sin_addr.s_addr = INADDR_ANY;
-    if (bind(sock, (struct sockaddr *) &addr,
-            (socklen_t) sizeof (addr)) == -1) {
-        perror("SERVER: bind()");
-        close(sock);
-        exit(42);
-    }
+       if (SDLNet_Init() < 0) {
+               exit(42);
+       }
+       atexit(SDLNet_Quit);
+       
+       SDLNet_ResolveHost(&addr, NULL, JNB_INETPORT);
+       ipstr = SDLNet_ResolveIP(&addr);
+       SDLNet_ResolveHost(&addr, ipstr, JNB_INETPORT);
+       printf("SERVER: we are %s (%i.%i.%i.%i:%i).\n", ipstr, (addr.host >> 0) & 0xff, (addr.host >> 8) & 0xff, (addr.host >> 16) & 0xff, (addr.host >> 24) & 0xff, addr.port);
+       net_info[client_player_num].addr = addr;
+
+       addr.host = INADDR_ANY;
+       sock = SDLNet_TCP_Open(&addr);
+       if (sock == NULL) {
+               fprintf(stderr, "SERVER: SDLNet_TCP_Open(): %s\n", SDLNet_GetError());
+               exit(42);
+       }
 
-    if (listen(sock, wait_for_clients) == -1) {
-        perror("SERVER: listen()");
-        close(sock);
-        exit(42);
-    }
+       player[client_player_num].enabled = 1;
 
-    player[client_player_num].enabled = 1;
+       printf("SERVER: waiting for (%d) clients...\n", wait_for_clients);
 
-    gethostname(ipstr, sizeof (ipstr));
-    hent = gethostbyname(ipstr);
-    if (hent != NULL) {
-        memcpy(&inaddr, hent->h_addr, hent->h_length);
-        strncpy(ipstr, inet_ntoa(inaddr), sizeof (ipstr));
-    }
+       socketset = SDLNet_AllocSocketSet(JNB_MAX_PLAYERS + 1);
+       SDLNet_TCP_AddSocket(socketset, sock);
 
-    printf("SERVER: we are [%s].\n", ipstr);
-
-    addr.sin_addr.s_addr = inaddr.s_addr;
-    addr.sin_family = AF_INET;
-    addr.sin_port = htons(JNB_INETPORT);
-    net_info[client_player_num].addr = malloc(sizeof (addr));
-    memcpy(net_info[client_player_num].addr, &addr, sizeof (addr));
-    net_info[client_player_num].addrlen = sizeof (addr);
-    /*gettimeofday(&net_info[client_player_num].last_timestamp, NULL);*/
-
-    printf("SERVER: waiting for (%d) clients...\n", wait_for_clients);
-
-    while (wait_for_clients > 0)
-    {
-        char buf[NETPKTBUFSIZE];
-        struct sockaddr_in from;
-        socklen_t fromlen = sizeof (from);
-        int negatory = 1;
-        int br;
-        int s;
-
-        s = accept(sock, (struct sockaddr *) &from, &fromlen);
-        if (s < 0)
-        {
-            perror("SERVER: accept()");
-            close(sock);
-            exit(42);
-        } /* if */
-
-        br = read(s, buf, NETPKTBUFSIZE);
-        if (br < 0) {
-            perror("SERVER: read()");
-            close(s);
-            close(sock);
-            exit(42);
-        }
-
-        strncpy(ipstr, inet_ntoa(from.sin_addr), sizeof (ipstr));
-        printf("SERVER: Got data from [%s].\n", ipstr);
-
-        if (br != NETPKTBUFSIZE) {
-            printf("SERVER: Bogus packet.\n");
-            continue;
-        }
-
-        bufToPacket(buf, &pkt);
-        if (pkt.cmd != NETCMD_HELLO) {
-            printf("SERVER: Bogus packet.\n");
-            continue;
-        }
-
-        printf("SERVER: Client claims to be player #%ld.\n", pkt.arg);
-
-        if (pkt.arg > (sizeof (player) / sizeof (player[0]))) {
-            printf("SERVER:  (that's an invalid player number.)\n");
-        } else {
-            if (player[pkt.arg].enabled) {
-                printf("SERVER:  (that player number is already taken.)\n");
-            } else {
-                negatory = 0;
-            }
-        }
-
-        if (negatory) {
-            printf("SERVER: Forbidding connection.\n");
-            pkt.cmd = NETCMD_NACK;
-            sendPacketToSock(s, &pkt);
-            close(s);
-        } else {
-            player[pkt.arg].enabled = 1;
-            net_info[pkt.arg].sock = s;
-            net_info[pkt.arg].addr = malloc(fromlen);
-            memcpy(net_info[pkt.arg].addr, &from, fromlen);
-            net_info[pkt.arg].addrlen = fromlen;
-            /*memcpy(&net_info[pkt.arg].last_timestamp, &pkt.timestamp, sizeof (pkt.timestamp));*/
-            wait_for_clients--;
-            printf("SERVER: Granting connection. (%d) to go.\n", wait_for_clients);
-            pkt.cmd = NETCMD_ACK;
-            sendPacket(pkt.arg, &pkt);
-        }
-    }
+       while (wait_for_clients > 0)
+       {
+               char buf[NETPKTBUFSIZE];
+               IPaddress *from;
+               int negatory = 1;
+               int br;
+               TCPsocket s;
+
+               /* Wait for events */
+               SDLNet_CheckSockets(socketset, ~0);
+               if ( SDLNet_SocketReady(sock) ) {
+                       s = SDLNet_TCP_Accept(sock);
+
+                       if (s == NULL)
+                       {
+                               fprintf(stderr, "SERVER: SDLNet_TCP_Accept(): %s", SDLNet_GetError());
+                               SDLNet_TCP_Close(sock);
+                               exit(42);
+                       }
+               } else
+                       continue;
+
+               br = SDLNet_TCP_Recv(s, buf, NETPKTBUFSIZE);
+               if (br < 0) {
+                       fprintf(stderr, "SERVER: SDLNet_TCP_Recv(): %s\n", SDLNet_GetError());
+                       SDLNet_TCP_Close(s);
+                       SDLNet_TCP_Close(sock);
+                       exit(42);
+               }
 
-    close(sock);  /* done with the listen socket. */
-    sock = -1;
+               from = SDLNet_TCP_GetPeerAddress(s);
+               ipstr = SDLNet_ResolveIP(from);
+               printf("SERVER: Got data from %s (%i.%i.%i.%i:%i).\n", ipstr, (from->host >> 0) & 0xff, (from->host >> 8) & 0xff, (from->host >> 16) & 0xff, (from->host >> 24) & 0xff, from->port);
 
-    printf("SERVER: Got all our connections. Greenlighting clients...\n");
+               if (br != NETPKTBUFSIZE) {
+                       printf("SERVER: Bogus packet.\n");
+                       continue;
+               }
 
-    pkt.cmd = NETCMD_GREENLIGHT;
-    pkt.arg = 0;
-    for (i = 0; i < (sizeof (net_info) / sizeof (net_info[0])); i++) {
-        if (player[i].enabled) {
-            pkt.arg |= (1 << i);
-        }
-    }
-    sendPacketToAll(&pkt);
-#endif
+               bufToPacket(buf, &pkt);
+               if (pkt.cmd != NETCMD_HELLO) {
+                       printf("SERVER: Bogus packet.\n");
+                       continue;
+               }
+
+               printf("SERVER: Client claims to be player #%ld.\n", pkt.arg);
+
+               if (pkt.arg > JNB_MAX_PLAYERS) {
+                       printf("SERVER:  (that's an invalid player number.)\n");
+               } else {
+                       if (player[pkt.arg].enabled) {
+                               printf("SERVER:  (that player number is already taken.)\n");
+                       } else {
+                               negatory = 0;
+                       }
+               }
+
+               if (negatory) {
+                       printf("SERVER: Forbidding connection.\n");
+                       pkt.cmd = NETCMD_NACK;
+                       sendPacketToSock(s, &pkt);
+                       SDLNet_TCP_Close(s);
+               } else {
+                       player[pkt.arg].enabled = 1;
+                       net_info[pkt.arg].sock = s;
+                       net_info[pkt.arg].addr = *from;
+                       net_info[pkt.arg].socketset = SDLNet_AllocSocketSet(1);
+                       SDLNet_TCP_AddSocket(net_info[pkt.arg].socketset, net_info[pkt.arg].sock);
+                       wait_for_clients--;
+                       printf("SERVER: Granting connection. (%d) to go.\n", wait_for_clients);
+                       pkt.cmd = NETCMD_ACK;
+                       sendPacket(pkt.arg, &pkt);
+               }
+       }
+
+       SDLNet_TCP_Close(sock);  /* done with the listen socket. */
+       SDLNet_FreeSocketSet(socketset);
+       sock = NULL;
+       socketset = NULL;
+
+       printf("SERVER: Got all our connections. Greenlighting clients...\n");
+
+       pkt.cmd = NETCMD_GREENLIGHT;
+       pkt.arg = 0;
+       for (i = 0; i < JNB_MAX_PLAYERS; i++) {
+               if (player[i].enabled) {
+                       pkt.arg |= (1 << i);
+               }
+       }
+       sendPacketToAll(&pkt);
 }
 
 
 void connect_to_server(char *netarg)
 {
-#if USE_SDL_NET
-    NetPacket pkt;
-    char buf[NETPKTBUFSIZE];
-    char ipstr[128];
-    struct hostent *hent;
-    struct sockaddr_in addr;
-    struct in_addr inaddr;
-    socklen_t addrlen;
-    int br;
-
-    if (netarg == NULL) {
-        printf("CLIENT: Need to specify host to connect to.\n");
-        exit(42);
-    }
+       NetPacket pkt;
+       char buf[NETPKTBUFSIZE];
+       char *ipstr;
+       IPaddress hent;
+       IPaddress addr;
+       int br;
+
+       if (netarg == NULL) {
+               printf("CLIENT: Need to specify host to connect to.\n");
+               exit(42);
+       }
 
-    player[client_player_num].enabled = 1;
-    gethostname(ipstr, sizeof (ipstr));
-    hent = gethostbyname(ipstr);
-    if (hent != NULL) {
-        net_info[client_player_num].addr = malloc(hent->h_length);
-        memcpy(&net_info[client_player_num].addr, &hent->h_addr, hent->h_length);
-        net_info[client_player_num].addrlen = hent->h_length;
-        memcpy(&inaddr, hent->h_addr, hent->h_length);
-        strncpy(ipstr, inet_ntoa(inaddr), sizeof (ipstr));
-    }
-    printf("CLIENT: we are [%s].\n", ipstr);
+       if (SDLNet_Init() < 0) {
+               exit(42);
+       }
+       atexit(SDLNet_Quit);
+       
+       player[client_player_num].enabled = 1;
 
-    /*gettimeofday(&net_info[client_player_num].last_timestamp, NULL);*/
+       SDLNet_ResolveHost(&addr, NULL, JNB_INETPORT);
+       ipstr = SDLNet_ResolveIP(&addr);
+       SDLNet_ResolveHost(&addr, ipstr, JNB_INETPORT);
+       printf("CLIENT: we are %s (%i.%i.%i.%i:%i).\n", ipstr, (addr.host >> 0) & 0xff, (addr.host >> 8) & 0xff, (addr.host >> 16) & 0xff, (addr.host >> 24) & 0xff, addr.port);
+       net_info[client_player_num].addr = addr;
 
-    hent = gethostbyname(netarg);
-    if (hent == NULL) {
-        herror("CLIENT: couldn't find host");
-        exit(42);
-    }
+       if (SDLNet_ResolveHost(&hent, netarg, JNB_INETPORT) < 0) {
+               fprintf(stderr, "CLIENT: couldn't find host: %s\n", SDLNet_GetError());
+               exit(42);
+       }
 
-    sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
-    if (sock < 0) {
-        perror("CLIENT: socket()");
-        exit(42);
-    }
+       sock = SDLNet_TCP_Open(&hent);
+       if (sock == NULL) {
+               fprintf(stderr, "CLIENT: SDLNet_TCP_Open(): %s\n", SDLNet_GetError());
+               exit(42);
+       }
 
-    memcpy(&inaddr, hent->h_addr, hent->h_length);
-    printf("CLIENT: connecting to [%s]...\n", inet_ntoa(inaddr));
+       socketset = SDLNet_AllocSocketSet(1);
+       SDLNet_TCP_AddSocket(socketset, sock);
 
-    addr.sin_family = AF_INET;
-    addr.sin_port = htons(JNB_INETPORT);
-    memcpy(&addr.sin_addr.s_addr, hent->h_addr, hent->h_length);
-    if (connect(sock, (struct sockaddr *) &addr, sizeof (addr)) == -1) {
-        perror("CLIENT: connect()");
-        exit(42);
-    }
+       printf("CLIENT: connected to %s...\n", SDLNet_ResolveIP(&hent));
 
-    printf("CLIENT: Got socket. Sending HELLO packet...\n");
-    pkt.cmd = NETCMD_HELLO;
-    pkt.arg = client_player_num;
-    sendPacketToSock(sock, &pkt);
-
-    printf("CLIENT: Waiting for ACK from server...\n");
-    
-    addrlen = sizeof (addr);
-    br = read(sock, buf, NETPKTBUFSIZE);
-    if (br < 0) {
-        perror("CLIENT: read()");
-        close(sock);
-        exit(42);
-    }
+       printf("CLIENT: Sending HELLO packet...\n");
+       pkt.cmd = NETCMD_HELLO;
+       pkt.arg = client_player_num;
+       sendPacketToSock(sock, &pkt);
 
-    if (br != NETPKTBUFSIZE) {
-        printf("CLIENT: Bogus packet size (%d of %d). FIXME.\n",
-                br, NETPKTBUFSIZE);
-        close(sock);
-        exit(42);
-    }
+       printf("CLIENT: Waiting for ACK from server...\n");
 
-    bufToPacket(buf, &pkt);
+       br = SDLNet_TCP_Recv(sock, buf, NETPKTBUFSIZE);
+       if (br < 0) {
+               fprintf(stderr, "CLIENT: recv(): %s\n", SDLNet_GetError());
+               SDLNet_FreeSocketSet(socketset);
+               SDLNet_TCP_Close(sock);
+               exit(42);
+       }
 
-    if (pkt.cmd == NETCMD_NACK) {
-        printf("CLIENT: Server forbid us from playing.\n");
-        close(sock);
-        exit(42);
-    }
+       if (br != NETPKTBUFSIZE) {
+               printf("CLIENT: Bogus packet size (%d of %d). FIXME.\n", br, NETPKTBUFSIZE);
+               SDLNet_FreeSocketSet(socketset);
+               SDLNet_TCP_Close(sock);
+               exit(42);
+       }
 
-    if (pkt.cmd != NETCMD_ACK) {
-        printf("CLIENT: Unexpected packet (cmd=0x%lX).\n", pkt.cmd);
-        close(sock);
-        exit(42);
-    }
+       bufToPacket(buf, &pkt);
 
-    printf("CLIENT: Server accepted our connection.\n");
+       if (pkt.cmd == NETCMD_NACK) {
+               printf("CLIENT: Server forbid us from playing.\n");
+               SDLNet_FreeSocketSet(socketset);
+               SDLNet_TCP_Close(sock);
+               exit(42);
+       }
 
-    wait_for_greenlight();
-#endif
+       if (pkt.cmd != NETCMD_ACK) {
+               printf("CLIENT: Unexpected packet (cmd=0x%lX).\n", pkt.cmd);
+               SDLNet_FreeSocketSet(socketset);
+               SDLNet_TCP_Close(sock);
+               exit(42);
+       }
+
+       printf("CLIENT: Server accepted our connection.\n");
+
+       wait_for_greenlight();
 }
+#endif /* USE_NET */
 
 
-static flip_pixels(unsigned char *pixels)
+static void flip_pixels(unsigned char *pixels)
 {
        int x,y;
        unsigned char temp;
@@ -979,7 +971,7 @@ int main(int argc, char *argv[])
        int l1;
        int s1, s2, s3, s4;
        int closest_player = 0, dist, cur_dist = 0;
-       int end_loop_flag = 0, fade_flag;
+       int end_loop_flag = 0, fade_flag = 0;
        int mod_vol, sfx_vol, mod_fade_direction;
        char str1[100];
        char pal[768];
@@ -1012,7 +1004,6 @@ int main(int argc, char *argv[])
                setpalette(0, 256, cur_pal);
 
                recalculate_gob(&rabbit_gobs, pal);
-               //recalculate_gob(&font_gobs, pal);
                recalculate_gob(&object_gobs, pal);
                recalculate_gob(&number_gobs, pal);
 
@@ -1060,11 +1051,15 @@ int main(int argc, char *argv[])
                        while (update_count) {
 
                                if (key_pressed(1) == 1) {
-                                       if (is_server) {
-                                               serverTellEveryoneGoodbye();
-                                       } else {
-                                               tellServerGoodbye();
+#ifdef USE_NET
+                                       if (is_net) {
+                                               if (is_server) {
+                                                       serverTellEveryoneGoodbye();
+                                               } else {
+                                                       tellServerGoodbye();
+                                               }
                                        }
+#endif
                                        end_loop_flag = 1;
                                        memset(pal, 0, 768);
                                        mod_fade_direction = 0;
@@ -1144,13 +1139,17 @@ int main(int argc, char *argv[])
                                        last_keys[0] = 0;
                                }
 
-                               if (is_server) {
-                                       update_players_from_clients();
-                               } else {
-                                       if (!update_players_from_server()) {
-                                               break;  /* got a BYE packet */
+#ifdef USE_NET
+                               if (is_net) {
+                                       if (is_server) {
+                                               update_players_from_clients();
+                                       } else {
+                                               if (!update_players_from_server()) {
+                                                       break;  /* got a BYE packet */
+                                               }
                                        }
                                }
+#endif
 
                                steer_players();
 
@@ -1436,36 +1435,50 @@ int main(int argc, char *argv[])
                                update_count--;
                        }
 
-                       if ( (player[client_player_num].dead_flag == 0) &&
-                               (
-                                (player[client_player_num].action_left) ||
-                                (player[client_player_num].action_right) ||
-                                (player[client_player_num].action_up) ||
-                                (player[client_player_num].jump_ready == 0)
-                               )
-                          ) {
-                               tellServerNewPosition();
+#ifdef USE_NET
+                       if (is_net) {
+                               if ( (player[client_player_num].dead_flag == 0) &&
+                                       (
+                                        (player[client_player_num].action_left) ||
+                                        (player[client_player_num].action_right) ||
+                                        (player[client_player_num].action_up) ||
+                                        (player[client_player_num].jump_ready == 0)
+                                       )
+                                  ) {
+                                       tellServerNewPosition();
+                               }
                        }
+#endif
 
                        update_count = intr_sysupdate();
 
-                       if ((server_said_bye) || ((fade_flag == 0) && (end_loop_flag == 1)))
+#ifdef USE_NET
+                       if (is_net) {
+                               if ((server_said_bye) || ((fade_flag == 0) && (end_loop_flag == 1)))
+                                       break;
+                       } else
+#endif
+                       if ((fade_flag == 0) && (end_loop_flag == 1))
                                break;
                }
 
-               if (is_server) {
-                       serverTellEveryoneGoodbye();
-                       close(sock);
-                       sock = -1;
-               } else {
-                       if (!server_said_bye) {
-                               tellServerGoodbye();
-                       }
+#ifdef USE_NET
+               if (is_net) {
+                       if (is_server) {
+                               serverTellEveryoneGoodbye();
+                               SDLNet_TCP_Close(sock);
+                               sock = NULL;
+                       } else {
+                               if (!server_said_bye) {
+                                       tellServerGoodbye();
+                               }
 
-                       close(sock);
-                       sock = -1;
+                               SDLNet_TCP_Close(sock);
+                               sock = NULL;
+                       }
                }
-
+#endif
+               
                main_info.view_page = 0;
                main_info.draw_page = 1;
 
@@ -1476,7 +1489,6 @@ int main(int argc, char *argv[])
                memset(mask_pic, 0, JNB_WIDTH*JNB_HEIGHT);
                register_mask(mask_pic);
 
-               //recalculate_gob(&font_gobs, pal);
                register_background(NULL, NULL);
 
                draw_begin();
@@ -1517,7 +1529,8 @@ int main(int argc, char *argv[])
                        return 1;
                }
 
-               for (c1 = 0; c1 < 16; c1++) { // fix dark font
+               /* fix dark font */
+               for (c1 = 0; c1 < 16; c1++) {
                        pal[(240 + c1) * 3 + 0] = c1 << 2;
                        pal[(240 + c1) * 3 + 1] = c1 << 2;
                        pal[(240 + c1) * 3 + 2] = c1 << 2;
@@ -2013,7 +2026,10 @@ void position_player(int player_num)
                        player[player_num].image = player_anims[player[player_num].anim].frame[player[player_num].frame].image;
 
                        if (is_server) {
-                               serverSendAlive(player_num);
+#ifdef USE_NET
+                               if (is_net)
+                                       serverSendAlive(player_num);
+#endif
                                player[player_num].dead_flag = 0;
                        }
 
@@ -2579,6 +2595,9 @@ void deinit_level(void)
 #ifndef PATH_MAX
 #define PATH_MAX 1024
 #endif
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
 
 unsigned char *datafile_buffer = NULL;
 
@@ -2633,7 +2652,8 @@ static void preread_datafile(const char *fname)
 
     fd = open(fname, O_RDONLY | O_BINARY);
     if (fd == -1) {
-        fprintf(stderr, "can't open %s: %s\n", fname, strerror(errno));
+        fprintf(stderr, "can't open %s:", fname);
+       perror("");
         exit(42);
     }
 
@@ -2673,7 +2693,9 @@ int init_program(int argc, char *argv[], char *pal)
                1, 0, 8, 5, 0, 0, 0, 0, 0, 0
        };
 
+#ifdef USE_NET
        memset(&net_info, 0, sizeof(net_info));
+#endif
 
 #ifdef DOS
        if (__djgpp_nearptr_enable() == 0)
@@ -2727,6 +2749,7 @@ int init_program(int argc, char *argv[], char *pal)
                                        if (client_player_num < 0)
                                                client_player_num = atoi(argv[c1 + 1]);
                                }
+#ifdef USE_NET
                        } else if (stricmp(argv[c1], "-server") == 0) {
                                if (c1 < (argc - 1)) {
                                        is_server = 1;
@@ -2739,6 +2762,7 @@ int init_program(int argc, char *argv[], char *pal)
                                        is_net = 1;
                                        netarg = argv[c1 + 1];
                                }
+#endif
                        } else if (stricmp(argv[c1], "-mouse") == 0) {
                                if (c1 < (argc - 1)) {
                                        if (stricmp(argv[c1 + 1], "2") == 0)
@@ -2749,7 +2773,7 @@ int init_program(int argc, char *argv[], char *pal)
                        }
                        else if (strstr(argv[1],"-v")) {
                                printf("jumpnbump %s compiled %s at %s with",JNB_VERSION,__DATE__,__TIME__);
-#ifndef _SDLnet_h
+#ifndef USE_NET
                                printf("out");
 #endif
                                printf(" network support.\n");
@@ -2761,8 +2785,11 @@ int init_program(int argc, char *argv[], char *pal)
                                printf("  -h                       this help\n");
                                printf("  -v                       print version\n");
                                printf("  -dat level.dat           play a different level\n");
-                               printf("  -port port               define listen port\n");
-                               printf("  -net player host rport   define network players\n");
+#ifdef USE_NET
+                               printf("  -server playercount      start as server waiting for players\n");
+                               printf("  -connect host            connect to server\n");
+#endif
+                               printf("  -player num              set main player to num (0-3). Needed for networking\n");
                                printf("  -fireworks               screensaver mode\n");
                                printf("  -fullscreen              run in fullscreen mode\n");
                                printf("  -nosound                 play without sound\n");
@@ -2948,7 +2975,8 @@ int init_program(int argc, char *argv[], char *pal)
        memset(mask_pic, 0, JNB_WIDTH*JNB_HEIGHT);
        register_mask(mask_pic);
 
-       for (c1 = 0; c1 < 16; c1++) { // fix dark font
+       /* fix dark font */
+       for (c1 = 0; c1 < 16; c1++) {
                pal[(240 + c1) * 3 + 0] = c1 << 2;
                pal[(240 + c1) * 3 + 1] = c1 << 2;
                pal[(240 + c1) * 3 + 2] = c1 << 2;
@@ -3027,11 +3055,15 @@ int init_program(int argc, char *argv[], char *pal)
                }
        }
 
-       if (is_server) {
-               init_server(netarg);
-       } else {
-               connect_to_server(netarg);
+#ifdef USE_NET
+       if (is_net) {
+               if (is_server) {
+                       init_server(netarg);
+               } else {
+                       connect_to_server(netarg);
+               }
        }
+#endif
 
        return 0;
 
@@ -3077,7 +3109,13 @@ void deinit_program(void)
 
 unsigned short rnd(unsigned short max)
 {
-       return (rand() % max);
+#if (RAND_MAX < 0x7fff)
+#error "rand returns too small values"
+#elif (RAND_MAX == 0x7fff)
+       return (unsigned short)((rand()*2) % (int)max);
+#else
+       return (unsigned short)(rand() % (int)max);
+#endif
 }