rnd-20040430-1-src
authorHolger Schemel <info@artsoft.org>
Thu, 29 Apr 2004 23:11:24 +0000 (01:11 +0200)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:47:06 +0000 (10:47 +0200)
* added option "handicap" for "levelinfo.conf" (thanks to Niko Böhm)
* added network multiplayer code for Windows (thanks to Niko Böhm)

19 files changed:
ChangeLog
src/Makefile
src/conftime.h
src/events.c
src/game.c
src/init.c
src/libgame/platform.h
src/libgame/sdl.h
src/libgame/setup.c
src/libgame/system.c
src/libgame/system.h
src/main.c
src/main.h
src/netserv.c
src/netserv.h
src/network.c
src/screens.c
src/tape.c
src/tools.c

index c2aed9a63ebeb00641f39e9eb910d864d70e8cb1..bb065a9249dde827786a501d8a65f269c9239822 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2004-04-27
+       * added option "handicap" for "levelinfo.conf" (thanks to Niko Böhm)
+       * added network multiplayer code for Windows (thanks to Niko Böhm)
+
 2004-04-25
        * added option "reachable despite gravity" for gravity movement
        * changed gravity movement of most classic walkable and passable
index f065f0b92cfb9a87ba2326f7db908e702e14b04a..8cc3ee95414b4acece4c2d0f5e97f0f7b3a446ad 100644 (file)
@@ -78,7 +78,7 @@ TARGET = allegro
 endif
 
 ifeq ($(PLATFORM),cross-win32)
-EXTRA_LDFLAGS = -lshfolder
+EXTRA_LDFLAGS = -lshfolder -lwsock32
 PROGNAME = ../$(PROGBASE).exe
 TARGET = sdl
 endif
@@ -93,7 +93,7 @@ SYS_CFLAGS  = -DTARGET_SDL $(shell sdl-config --cflags)
 ifeq ($(PLATFORM),macosx)
 SYS_LDFLAGS = -lSDL_image -lSDL_mixer -lsmpeg $(shell sdl-config --libs)
 else
-SYS_LDFLAGS = -lSDL_image -lSDL_mixer $(shell sdl-config --libs)
+SYS_LDFLAGS = -lSDL_image -lSDL_mixer -lSDL_net $(shell sdl-config --libs)
 endif
 endif
 
index da0260a0b111fd5beaf770959121666bafc6a213..2c0f43fcb441e059b42a47bc8b69aac10d929e56 100644 (file)
@@ -1 +1 @@
-#define COMPILE_DATE_STRING "[2004-04-26 09:36]"
+#define COMPILE_DATE_STRING "[2004-04-30 01:05]"
index 0f11b48a6a7256b9b569509cd5633a96c5bca100..fdb4b6cecdb41334606fdd8669dad338f12372dc 100644 (file)
@@ -646,7 +646,7 @@ void HandleKey(Key key, int key_status)
     if (setup.autorecord)
       TapeStartRecording();
 
-#if defined(PLATFORM_UNIX)
+#if defined(NETWORK_AVALIABLE)
     if (options.network)
       SendToServer_StartPlaying();
     else
@@ -919,7 +919,7 @@ void HandleNoEvent()
     return;
   }
 
-#if defined(PLATFORM_UNIX)
+#if defined(NETWORK_AVALIABLE)
   if (options.network)
     HandleNetworking();
 #endif
index ce4948b85851c59eca8b4a04355079b6597b133c..8dd2407d65a696a82f061696ef495e69c0f190bd 100644 (file)
@@ -1582,7 +1582,7 @@ void InitGame()
 
   network_player_action_received = FALSE;
 
-#if defined(PLATFORM_UNIX)
+#if defined(NETWORK_AVALIABLE)
   /* initial null action */
   if (network_playing)
     SendToServer_MovePlayer(MV_NO_MOVING);
@@ -8198,7 +8198,7 @@ void GameActions()
 #endif
     */
 
-#if defined(PLATFORM_UNIX)
+#if defined(NETWORK_AVALIABLE)
     /* last chance to get network player actions without main loop delay */
     HandleNetworking();
 #endif
@@ -8249,7 +8249,7 @@ void GameActions()
       stored_player[i].effective_action = stored_player[i].action;
   }
 
-#if defined(PLATFORM_UNIX)
+#if defined(NETWORK_AVALIABLE)
   if (network_playing)
     SendToServer_MovePlayer(summarized_player_action);
 #endif
@@ -10559,6 +10559,8 @@ int DigField(struct PlayerInfo *player,
 #if 0
   boolean use_spring_bug = (game.engine_version < VERSION_IDENT(2,2,0,0));
 #endif
+  boolean is_player = (IS_PLAYER(oldx, oldy) || mode != DF_DIG);
+  boolean player_was_pushing = player->is_pushing;
   int jx = oldx, jy = oldy;
   int dx = x - jx, dy = y - jy;
   int nextx = x + dx, nexty = y + dy;
@@ -10571,21 +10573,24 @@ int DigField(struct PlayerInfo *player,
   int old_element = Feld[jx][jy];
   int element;
 
-  if (player->MovPos == 0)
+  if (is_player)               /* function can also be called by EL_PENGUIN */
   {
-    player->is_digging = FALSE;
-    player->is_collecting = FALSE;
-  }
+    if (player->MovPos == 0)
+    {
+      player->is_digging = FALSE;
+      player->is_collecting = FALSE;
+    }
 
-  if (player->MovPos == 0)     /* last pushing move finished */
-    player->is_pushing = FALSE;
+    if (player->MovPos == 0)   /* last pushing move finished */
+      player->is_pushing = FALSE;
 
-  if (mode == DF_NO_PUSH)      /* player just stopped pushing */
-  {
-    player->is_switching = FALSE;
-    player->push_delay = 0;
+    if (mode == DF_NO_PUSH)    /* player just stopped pushing */
+    {
+      player->is_switching = FALSE;
+      player->push_delay = 0;
 
-    return MF_NO_ACTION;
+      return MF_NO_ACTION;
+    }
   }
 
   if (IS_MOVING(x, y) || IS_PLAYER(x, y))
@@ -10644,12 +10649,15 @@ int DigField(struct PlayerInfo *player,
 
   element = Feld[x][y];
 
+  if (!is_player && !IS_COLLECTIBLE(element))  /* penguin cannot collect it */
+    return MF_NO_ACTION;
+
   if (mode == DF_SNAP && !IS_SNAPPABLE(element) &&
       game.engine_version >= VERSION_IDENT(2,2,0,0))
     return MF_NO_ACTION;
 
 #if 1
-  if (game.gravity && !player->is_auto_moving &&
+  if (game.gravity && is_player && !player->is_auto_moving &&
       canFallDown(player) && move_direction != MV_DOWN &&
       !canMoveToValidFieldWithGravity(jx, jy, move_direction))
     return MF_NO_ACTION;       /* player cannot walk here due to gravity */
@@ -10939,7 +10947,7 @@ int DigField(struct PlayerInfo *player,
       {
        RemoveField(x, y);
 
-       if (mode != DF_SNAP)
+       if (is_player && mode != DF_SNAP)
        {
          GfxElement[x][y] = element;
          player->is_collecting = TRUE;
@@ -11025,9 +11033,10 @@ int DigField(struct PlayerInfo *player,
        RaiseScoreElement(element);
        PlayLevelSoundElementAction(x, y, element, ACTION_COLLECTING);
 
-       CheckTriggeredElementChangeByPlayer(x, y, element,
-                                           CE_OTHER_GETS_COLLECTED,
-                                           player->index_bit, dig_side);
+       if (is_player)
+         CheckTriggeredElementChangeByPlayer(x, y, element,
+                                             CE_OTHER_GETS_COLLECTED,
+                                             player->index_bit, dig_side);
 
 #if 1
        if (mode == DF_SNAP)
@@ -11074,11 +11083,25 @@ int DigField(struct PlayerInfo *player,
 #endif
 
 #if 1
-       if (game.engine_version >= VERSION_IDENT(3,0,7,1))
+
+#if 1
+       if (game.engine_version >= VERSION_IDENT(3,1,0,0))
+       {
+         if (player->push_delay_value == -1 || !player_was_pushing)
+           player->push_delay_value = GET_NEW_PUSH_DELAY(element);
+       }
+       else if (game.engine_version >= VERSION_IDENT(3,0,7,1))
        {
          if (player->push_delay_value == -1)
            player->push_delay_value = GET_NEW_PUSH_DELAY(element);
        }
+#else
+       if (game.engine_version >= VERSION_IDENT(3,0,7,1))
+       {
+         if (player->push_delay_value == -1 || !player_was_pushing)
+           player->push_delay_value = GET_NEW_PUSH_DELAY(element);
+       }
+#endif
        else if (game.engine_version >= VERSION_IDENT(2,2,0,7))
        {
          if (!player->is_pushing)
@@ -11098,9 +11121,12 @@ int DigField(struct PlayerInfo *player,
 #endif
 
 #if 0
-       printf("::: push delay: %ld [%d, %d] [%d]\n",
-              player->push_delay_value, FrameCounter, game.engine_version,
-              player->is_pushing);
+       printf("::: push delay: %ld -> %ld [%d, %d] [%d / %d] [%d '%s': %d]\n",
+              player->push_delay, player->push_delay_value,
+              FrameCounter, game.engine_version,
+              player_was_pushing, player->is_pushing,
+              element, element_info[element].token_name,
+              GET_NEW_PUSH_DELAY(element));
 #endif
 
        player->is_pushing = TRUE;
@@ -11851,7 +11877,7 @@ void RequestQuitGame(boolean ask_if_really_quit)
       Request("Do you really want to quit the game ?",
              REQ_ASK | REQ_STAY_CLOSED))
   {
-#if defined(PLATFORM_UNIX)
+#if defined(NETWORK_AVALIABLE)
     if (options.network)
       SendToServer_StopPlaying();
     else
@@ -12042,7 +12068,7 @@ static void HandleGameButtons(struct GadgetInfo *gi)
     case GAME_CTRL_ID_PAUSE:
       if (options.network)
       {
-#if defined(PLATFORM_UNIX)
+#if defined(NETWORK_AVALIABLE)
        if (tape.pausing)
          SendToServer_ContinuePlaying();
        else
@@ -12056,7 +12082,7 @@ static void HandleGameButtons(struct GadgetInfo *gi)
     case GAME_CTRL_ID_PLAY:
       if (tape.pausing)
       {
-#if defined(PLATFORM_UNIX)
+#if defined(NETWORK_AVALIABLE)
        if (options.network)
          SendToServer_ContinuePlaying();
        else
index 61f8ce8e356ce38dfb657682af068db7e86186fa..905aaf70f30a95707acf542768a8d63b881b5c9d 100644 (file)
@@ -4086,14 +4086,14 @@ static void InitMusic(char *identifier)
 
 void InitNetworkServer()
 {
-#if defined(PLATFORM_UNIX)
+#if defined(NETWORK_AVALIABLE)
   int nr_wanted;
 #endif
 
   if (!options.network)
     return;
 
-#if defined(PLATFORM_UNIX)
+#if defined(NETWORK_AVALIABLE)
   nr_wanted = Request("Choose player", REQ_PLAYER | REQ_STAY_CLOSED);
 
   if (!ConnectToServer(options.server_host, options.server_port))
@@ -4368,6 +4368,11 @@ void CloseAllAndExit(int exit_value)
   FreeAllImages();
   FreeTileClipmasks();
 
+#if defined(TARGET_SDL)
+  if (network_server)  /* terminate network server */
+    SDL_KillThread(server_thread);
+#endif
+
   CloseVideoDisplay();
   ClosePlatformDependentStuff();
 
index 61ab27f6a59d9b365b87b7b85eaceb0621524579..5e1683619d8053a003a5273eabf58e15d2c3a165 100644 (file)
@@ -26,6 +26,7 @@
 #define PLATFORM_UNIX
 #endif
 
+
 /* ========================================================================= */
 /* define additional keywords for MS-DOS platform                            */
 /* ========================================================================= */
@@ -42,6 +43,7 @@
 
 #endif
 
+
 /* ========================================================================= */
 /* define additional keywords for several Unix platforms                     */
 /* ========================================================================= */
 #define PLATFORM_MACOSX
 #endif
 
+#if defined(NeXT)
+#define PLATFORM_NEXT
+#endif
+
 /* detecting HP-UX by the following compiler keyword definitions:
    - in K&R mode (the default), the HP C compiler defines "hpux"
    - in ANSI mode (-Aa or -Ae), the HP C compiler defines "__hpux"
 #define PLATFORM_HPUX
 #endif
 
+
+/* ========================================================================= */
+/* this should better go into "system.h" or "features.h" (yet to be created) */
+/* ========================================================================= */
+
+#if defined(PLATFORM_UNIX) || defined(TARGET_SDL)
+#define NETWORK_AVALIABLE
+#endif
+
+
 #endif /* PLATFORM_H */
index 8ad6308bc823dc1d368246615685852facd22689..fc05cb7063ad22ebbe4d8c88c66ab51b8a7d62d9 100644 (file)
@@ -17,6 +17,8 @@
 #include "SDL.h"
 #include "SDL_image.h"
 #include "SDL_mixer.h"
+#include "SDL_net.h"
+#include "SDL_thread.h"
 
 
 /* definitions needed for "system.c" */
index 8fa4317c3beab9502bfa62ad100d629b6a42469d..1d5a35919715dc5d48f4341aeb182e7e89b047b9 100644 (file)
@@ -1584,8 +1584,9 @@ void checkSetupFileHashIdentifier(SetupFileHash *setup_file_hash,
 #define LEVELINFO_TOKEN_MUSIC_SET      13
 #define LEVELINFO_TOKEN_FILENAME       14
 #define LEVELINFO_TOKEN_FILETYPE       15
+#define LEVELINFO_TOKEN_HANDICAP       16
 
-#define NUM_LEVELINFO_TOKENS           16
+#define NUM_LEVELINFO_TOKENS           17
 
 static LevelDirTree ldi;
 
@@ -1607,7 +1608,8 @@ static struct TokenInfo levelinfo_tokens[] =
   { TYPE_STRING,  &ldi.sounds_set,     "sounds_set"    },
   { TYPE_STRING,  &ldi.music_set,      "music_set"     },
   { TYPE_STRING,  &ldi.level_filename, "filename"      },
-  { TYPE_STRING,  &ldi.level_filetype, "filetype"      }
+  { TYPE_STRING,  &ldi.level_filetype, "filetype"      },
+  { TYPE_STRING,  &ldi.handicap,       "handicap"      }
 };
 
 static void setTreeInfoToDefaults(TreeInfo *ldi, int type)
@@ -1662,6 +1664,7 @@ static void setTreeInfoToDefaults(TreeInfo *ldi, int type)
     ldi->level_group = FALSE;
     ldi->handicap_level = 0;
     ldi->readonly = TRUE;
+    ldi->handicap = TRUE;
   }
 }
 
@@ -1724,9 +1727,9 @@ static void setTreeInfoToDefaultsFromParent(TreeInfo *ldi, TreeInfo *parent)
     ldi->level_group = FALSE;
     ldi->handicap_level = 0;
     ldi->readonly = TRUE;
+    ldi->handicap = TRUE;
   }
 
-
 #else
 
   /* first copy all values from the parent structure ... */
@@ -2006,9 +2009,8 @@ static boolean LoadLevelInfoFromLevelConf(TreeInfo **node_first,
 #endif
 
   leveldir_new->handicap_level =       /* set handicap to default value */
-    (leveldir_new->user_defined ?
-     leveldir_new->last_level :
-     leveldir_new->first_level);
+    (leveldir_new->user_defined || !leveldir_new->handicap ?
+     leveldir_new->last_level : leveldir_new->first_level);
 
   pushTreeInfo(node_first, leveldir_new);
 
@@ -2880,7 +2882,7 @@ void LoadLevelSetup_SeriesInfo()
       if (level_nr > leveldir_current->last_level + 1)
        level_nr = leveldir_current->last_level;
 
-      if (leveldir_current->user_defined)
+      if (leveldir_current->user_defined || !leveldir_current->handicap)
        level_nr = leveldir_current->last_level;
 
       leveldir_current->handicap_level = level_nr;
index 656d97f90d732e5e988b65e7d1fe838786072b93..8f26dc77fb97e7933f5ed2f24c71d453b0dfd5d9 100644 (file)
@@ -117,6 +117,8 @@ void InitPlatformDependentStuff(void)
 #if defined(TARGET_SDL)
   if (SDL_Init(SDL_INIT_EVENTTHREAD | SDL_INIT_NOPARACHUTE) < 0)
     Error(ERR_EXIT, "SDL_Init() failed: %s", SDL_GetError());
+
+  SDLNet_Init();
 #endif
 }
 
index 7f26f635386c435c95548595290e79dfeec15f84..74a74a67e150ce4cd9baaaa8c709f675d730e4a6 100644 (file)
@@ -656,6 +656,7 @@ struct TreeInfo
   boolean parent_link; /* entry links back to parent directory */
   boolean user_defined;        /* user defined levels are stored in home directory */
   boolean readonly;    /* readonly levels can not be changed with editor */
+  boolean handicap;    /* level set has no handicap when set to "false" */
 
   int color;           /* color to use on selection screen for this level */
   char *class_desc;    /* description of level series class */
index 7f74f6aea73069fd23255934436a4b200748edf3..e2182ecd2c22a400d8c397228895ea9be00ffd1d 100644 (file)
@@ -34,6 +34,11 @@ int                  game_status = -1;
 boolean                        level_editor_test_game = FALSE;
 boolean                        network_playing = FALSE;
 
+#if defined(TARGET_SDL)
+boolean                        network_server = FALSE;
+SDL_Thread            *server_thread;
+#endif
+
 int                    key_joystick_mapping = 0;
 
 boolean                        redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
index c6ae5644403c38615d4a43583339964a36e3de87..b1c8303ee0eebafe09db794dc4028a5a8ffd3148 100644 (file)
@@ -1863,6 +1863,11 @@ extern int                       game_status;
 extern boolean                 level_editor_test_game;
 extern boolean                 network_playing;
 
+#if defined(TARGET_SDL)
+extern boolean                 network_server;
+extern SDL_Thread             *server_thread;
+#endif
+
 extern int                     key_joystick_mapping;
 
 extern boolean                 redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
index 08d161023dbf20312319899a9161b853bac9a1fd..692265338b597df45b8b62510eb2bb736da08919 100644 (file)
@@ -8,23 +8,28 @@
 *               Germany                                    *
 *               e-mail: info@artsoft.org                   *
 *----------------------------------------------------------*
-* network.c                                                *
+* netserv.c                                                *
 ***********************************************************/
 
 #include "libgame/platform.h"
 
-#if defined(PLATFORM_UNIX)
+#if defined(NETWORK_AVALIABLE)
 
 #include <fcntl.h>
 #include <sys/time.h>
 #include <signal.h>
-#include <sys/socket.h>
 #include <errno.h>
+
+#if defined(TARGET_SDL)
+#include "main.h"
+#else
+#include <sys/socket.h>
 #include <netinet/in.h>
 #include <netinet/tcp.h>
 #include <arpa/inet.h>
 #include <netdb.h>
 #include <sys/select.h>                        /* apparently needed for OS/2 port */
+#endif
 
 #include "libgame/libgame.h"
 
@@ -35,7 +40,12 @@ static int onceonly = 0;
 
 struct NetworkServerPlayerInfo
 {
+#if defined(TARGET_SDL)
+  TCPsocket fd;
+#else
   int fd;
+#endif
+
   char player_name[16];
   unsigned char number;
   struct NetworkServerPlayerInfo *next;
@@ -52,17 +62,23 @@ static struct NetworkServerPlayerInfo *first_player = NULL;
 
 #define NEXT(player) ((player)->next ? (player)->next : first_player)
 
+#if defined(TARGET_SDL)
+/* TODO: peer address */
+static TCPsocket lfd;          /* listening socket */
+static SDLNet_SocketSet fds;   /* socket set */
+#else
 static struct sockaddr_in saddr;
-static int lfd;
+static int lfd;                        /* listening socket */
+static fd_set fds;             /* socket set */
+static int tcp = -1;
+#endif
+
 static unsigned char realbuffer[512], *buffer = realbuffer + 4;
 
 static int interrupt;
-static int tcp = -1;
 
 static unsigned long ServerFrameCounter = 0;
 
-static fd_set fds;
-
 static void addtobuffer(struct NetworkServerPlayerInfo *player,
                        unsigned char *b, int len)
 {
@@ -78,7 +94,11 @@ static void flushuser(struct NetworkServerPlayerInfo *player)
 {
   if (player->nwrite)
   {
+#if defined(TARGET_SDL)
+    SDLNet_TCP_Send(player->fd, player->writbuffer, player->nwrite);
+#else
     write(player->fd, player->writbuffer, player->nwrite);
+#endif
     player->nwrite = 0;
   }
 }
@@ -124,7 +144,13 @@ static void RemovePlayer(struct NetworkServerPlayerInfo *player)
       }
     }
   }
+
+#if defined(TARGET_SDL)
+  SDLNet_TCP_DelSocket(fds, player->fd);
+  SDLNet_TCP_Close(player->fd);
+#else
   close(player->fd);
+#endif
 
   if (player->introduced)
   {
@@ -147,7 +173,11 @@ static void RemovePlayer(struct NetworkServerPlayerInfo *player)
   }
 }
 
+#if defined(TARGET_SDL)
+static void AddPlayer(TCPsocket fd)
+#else
 static void AddPlayer(int fd)
+#endif
 {
   struct NetworkServerPlayerInfo *player, *v;
   unsigned char nxn;
@@ -165,6 +195,10 @@ static void AddPlayer(int fd)
   player->action = 0;
   player->action_received = FALSE;
 
+#if defined(TARGET_SDL)
+  SDLNet_TCP_AddSocket(fds, fd);
+#endif
+
   first_player = player;
 
   nxn = 1;
@@ -202,9 +236,11 @@ static void AddPlayer(int fd)
 #endif
 
   player->number = nxn;
+#if !defined(TARGET_SDL)
   if (options.verbose)
     Error(ERR_NETWORK_SERVER, "client %d connecting from %s",
          nxn, inet_ntoa(saddr.sin_addr));
+#endif
   clients++;
 
   buffer[0] = 0;
@@ -448,18 +484,35 @@ static void Handle_OP_MOVE_PLAYER(struct NetworkServerPlayerInfo *player)
   ServerFrameCounter++;
 }
 
+#if defined(TARGET_SDL)
+/* the following is not used for a standalone server;
+   the pointer points to an integer containing the port-number */
+int NetworkServerThread(void *ptr)
+{
+  NetworkServer(*((int *) ptr), 0);
+
+  /* should never be reached */
+  return 0;
+}
+#endif
+
 void NetworkServer(int port, int serveronly)
 {
-  int i, sl, on;
+  int sl;
   struct NetworkServerPlayerInfo *player;
-  int mfd;
   int r; 
   unsigned int len;
+#if defined(TARGET_SDL)
+  IPaddress ip;
+#else
+  int i, on;
+  int is_daemon = 0;
   struct protoent *tcpproto;
   struct timeval tv;
-  int is_daemon = 0;
+  int mfd;
+#endif
 
-#ifndef NeXT
+#if defined(PLATFORM_UNIX) && !defined(PLATFORM_NEXT)
   struct sigaction sact;
 #endif
 
@@ -469,10 +522,13 @@ void NetworkServer(int port, int serveronly)
   if (!serveronly)
     onceonly = 1;
 
+#if !defined(TARGET_SDL)
   if ((tcpproto = getprotobyname("tcp")) != NULL)
     tcp = tcpproto->p_proto;
+#endif
 
-#ifdef NeXT
+#if defined(PLATFORM_UNIX)
+#if defined(PLATFORM_NEXT)
   signal(SIGPIPE, SIG_IGN);
 #else
   sact.sa_handler = SIG_IGN;
@@ -480,7 +536,28 @@ void NetworkServer(int port, int serveronly)
   sact.sa_flags = 0;
   sigaction(SIGPIPE, &sact, NULL);
 #endif
+#endif
+
+#if defined(TARGET_SDL)
+
+  /* assume that SDL is already initialized */
+#if 0
+  if (SDLNet_Init() == -1)
+    Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_Init() failed");
+  atexit(SDLNet_Quit);
+#endif
+
+  if (SDLNet_ResolveHost(&ip, NULL, port) == -1)
+    Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_ResolveHost() failed");
 
+  lfd = SDLNet_TCP_Open(&ip);
+  if (!lfd)
+    Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_TCP_Open() failed");
+
+  fds = SDLNet_AllocSocketSet(MAX_PLAYERS+1);
+  SDLNet_TCP_AddSocket(fds, lfd);
+
+#else
 
   if ((lfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
     Error(ERR_EXIT_NETWORK_SERVER, "socket() failed");
@@ -496,7 +573,9 @@ void NetworkServer(int port, int serveronly)
     Error(ERR_EXIT_NETWORK_SERVER, "bind() failed");
 
   listen(lfd, 5);
+#endif
 
+#if !defined(TARGET_SDL)
   if (is_daemon)
   {
     /* become a daemon, breaking all ties with the controlling terminal */
@@ -519,6 +598,7 @@ void NetworkServer(int port, int serveronly)
     open("/dev/null", O_WRONLY);
     open("/dev/null", O_WRONLY);
   }
+#endif
 
   if (options.verbose)
   {
@@ -534,6 +614,15 @@ void NetworkServer(int port, int serveronly)
     for (player = first_player; player; player = player->next)
       flushuser(player);
 
+#if defined(TARGET_SDL)
+    if ((sl = SDLNet_CheckSockets(fds, 500000)) < 1)
+    {
+      Error(ERR_NETWORK_SERVER, SDLNet_GetError());
+      perror("SDLNet_CheckSockets");
+    }
+
+#else
+
     FD_ZERO(&fds);
     mfd = lfd;
     player = first_player;
@@ -554,6 +643,7 @@ void NetworkServer(int port, int serveronly)
       else
        continue;
     }
+#endif
 
     if (sl < 0)
       continue;
@@ -561,6 +651,20 @@ void NetworkServer(int port, int serveronly)
     if (sl == 0)
       continue;
 
+    /* accept incoming connections */
+#if defined(TARGET_SDL)
+    if (SDLNet_SocketReady(lfd))
+    {
+      TCPsocket newsock;
+
+      newsock = SDLNet_TCP_Accept(lfd);
+
+      if (newsock)
+       AddPlayer(newsock);
+    }
+
+#else
+
     if (FD_ISSET(lfd, &fds))
     {
       int newfd, slen;
@@ -583,14 +687,27 @@ void NetworkServer(int port, int serveronly)
       }
       continue;
     }
+#endif
 
     player = first_player;
 
     do
     {
+#if defined(TARGET_SDL)
+      if (SDLNet_SocketReady(player->fd))
+#else
       if (FD_ISSET(player->fd, &fds))
+#endif
       {
-       r = read(player->fd, player->readbuffer + player->nread, MAX_BUFFER_SIZE - player->nread);
+#if defined(TARGET_SDL)
+       /* read only 1 byte, because SDLNet blocks when we want more than is
+          in the buffer */
+       r = SDLNet_TCP_Recv(player->fd, player->readbuffer + player->nread, 1);
+#else
+       r = read(player->fd, player->readbuffer + player->nread,
+                MAX_BUFFER_SIZE - player->nread);
+#endif
+
        if (r <= 0)
        {
          if (options.verbose)
@@ -686,4 +803,4 @@ void NetworkServer(int port, int serveronly)
   }
 }
 
-#endif /* PLATFORM_UNIX */
+#endif /* NETWORK_AVALIABLE */
index 5805fa24aabbef50ac5f3458b3fe57bd7d22468c..5efcb80339f8055386c60f4257d0ee3efbc7ea06 100644 (file)
 
 #define MAX_BUFFER_SIZE                4096
 
+#if defined(TARGET_SDL)
+int NetworkServerThread(void *);
+#endif
+
 void NetworkServer(int, int);
 
 #endif
index 914f4971b2fdf9686d572d0aafb31bb1ebc2deaf..575e846b38fe3c49fc001528be157055738da28b 100644 (file)
 
 #include "libgame/platform.h"
 
-#if defined(PLATFORM_UNIX)
+#if defined(NETWORK_AVALIABLE)
 
 #include <signal.h>
 #include <sys/time.h>
+
+#if defined(TARGET_SDL)
+#include "main.h"
+#else
 #include <sys/wait.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <netinet/tcp.h>
 #include <arpa/inet.h>
 #include <netdb.h>
+#endif
 
 #include "libgame/libgame.h"
 
@@ -50,7 +55,13 @@ static struct NetworkClientPlayerInfo first_player =
 
 /* server stuff */
 
-static int sfd;
+#if defined(TARGET_SDL)
+static TCPsocket sfd;          /* server socket */
+static SDLNet_SocketSet rfds;  /* socket set */
+#else
+static int sfd;                        /* server socket */
+#endif
+
 static byte realbuffer[512];
 static byte readbuffer[MAX_BUFFER_SIZE], writbuffer[MAX_BUFFER_SIZE];
 static byte *buffer = realbuffer + 4;
@@ -72,7 +83,11 @@ static void SendBufferToServer(int size)
   nwrite += 4 + size;
 
   /* directly send the buffer to the network server */
+#if defined(TARGET_SDL)
+  SDLNet_TCP_Send(sfd, writbuffer, nwrite);
+#else
   write(sfd, writbuffer, nwrite);
+#endif
   nwrite = 0;
 }
 
@@ -109,6 +124,15 @@ char *getNetworkPlayerName(int player_nr)
 
 static void StartNetworkServer(int port)
 {
+#if defined(TARGET_SDL)
+  static int p;
+
+  p = port;
+  server_thread = SDL_CreateThread(NetworkServerThread, &p);
+  network_server = TRUE;
+
+#else
+
   switch (fork())
   {
     case 0:
@@ -127,8 +151,68 @@ static void StartNetworkServer(int port)
       /* we are parent process -- resume normal operation */
       return;
   }
+#endif
 }
 
+#if defined(TARGET_SDL)
+boolean ConnectToServer(char *hostname, int port)
+{
+  IPaddress ip;
+  int i;
+
+  if (port == 0)
+    port = DEFAULT_SERVER_PORT;
+
+  rfds = SDLNet_AllocSocketSet(1);
+
+  if (hostname)
+  {
+    SDLNet_ResolveHost(&ip, hostname, port);
+    if (ip.host == INADDR_NONE)
+      Error(ERR_EXIT, "cannot locate host '%s'", hostname);
+  }
+  else
+  {
+    SDLNet_Write32(0x7f000001, &ip.host);      /* 127.0.0.1 */
+    SDLNet_Write16(port, &ip.port);
+  }
+
+  sfd = SDLNet_TCP_Open(&ip);
+
+  if (sfd)
+  {
+    SDLNet_TCP_AddSocket(rfds, sfd);
+    return TRUE;
+  }
+  else
+  {
+    printf("SDLNet_TCP_Open(): %s\n", SDLNet_GetError());
+  }
+
+  if (hostname)                        /* connect to specified server failed */
+    return FALSE;
+
+  printf("No rocksndiamonds server on localhost -- starting up one ...\n");
+  StartNetworkServer(port);
+
+  /* wait for server to start up and try connecting several times */
+  for (i = 0; i < 6; i++)
+  {
+    Delay(500);                        /* wait 500 ms == 0.5 seconds */
+
+    if ((sfd = SDLNet_TCP_Open(&ip)))          /* connected */
+    {
+      SDLNet_TCP_AddSocket(rfds, sfd);
+      return TRUE;
+    }
+  }
+
+  /* when reaching this point, connect to newly started server has failed */
+  return FALSE;
+}
+
+#else
+
 boolean ConnectToServer(char *hostname, int port)
 {
   struct sockaddr_in s;
@@ -169,7 +253,7 @@ boolean ConnectToServer(char *hostname, int port)
   if (hostname)        /* connect to specified server failed */
     return FALSE;
 
-  printf("No rocksndiamonds server on localhost - starting up one ...\n");
+  printf("No rocksndiamonds server on localhost -- starting up one ...\n");
   StartNetworkServer(port);
 
   /* wait for server to start up and try connecting several times */
@@ -191,6 +275,7 @@ boolean ConnectToServer(char *hostname, int port)
   /* when reaching this point, connect to newly started server has failed */
   return FALSE;
 }
+#endif /* defined(TARGET_SDL) */
 
 void SendToServer_PlayerName(char *player_name)
 {
@@ -583,39 +668,60 @@ static void HandleNetworkingMessages()
   fflush(stdout);
 }
 
+/* TODO */
+
 void HandleNetworking()
 {
+#if !defined(TARGET_SDL)
   static struct timeval tv = { 0, 0 };
   fd_set rfds;
+#endif
   int r = 0;
 
-  FD_ZERO(&rfds);
-  FD_SET(sfd, &rfds);
-
-  r = select(sfd + 1, &rfds, NULL, NULL, &tv);
+  do
+  {
+#if defined(TARGET_SDL)
+    if ((r = SDLNet_CheckSockets(rfds, 1)) < 0)
+      Error(ERR_EXIT, "HandleNetworking(): SDLNet_CheckSockets() failed");
 
-  if (r < 0 && errno != EINTR)
-    Error(ERR_EXIT, "HandleNetworking(): select() failed");
+#else
 
-  if (r < 0)
     FD_ZERO(&rfds);
+    FD_SET(sfd, &rfds);
 
-  if (FD_ISSET(sfd, &rfds))
-  {
-    int r;
+    r = select(sfd + 1, &rfds, NULL, NULL, &tv);
 
-    r = read(sfd, readbuffer + nread, MAX_BUFFER_SIZE - nread);
+    if (r < 0 && errno != EINTR)
+      Error(ERR_EXIT, "HandleNetworking(): select() failed");
 
     if (r < 0)
-      Error(ERR_EXIT, "error reading from network server");
+      FD_ZERO(&rfds);
+#endif
+
+#if defined(TARGET_SDL)
+    if (r > 0)
+#else
+    if (FD_ISSET(sfd, &rfds))
+#endif
+    {
+#if defined(TARGET_SDL)
+      r = SDLNet_TCP_Recv(sfd, readbuffer + nread, 1);
+#else
+      r = read(sfd, readbuffer + nread, MAX_BUFFER_SIZE - nread);
+#endif
+
+      if (r < 0)
+       Error(ERR_EXIT, "error reading from network server");
 
-    if (r == 0)
-      Error(ERR_EXIT, "connection to network server lost");
+      if (r == 0)
+       Error(ERR_EXIT, "connection to network server lost");
 
-    nread += r;
+      nread += r;
 
-    HandleNetworkingMessages();
+      HandleNetworkingMessages();
+    }
   }
+  while (r > 0);
 }
 
 #endif /* PLATFORM_UNIX */
index 50c8685ab59f7116c9ba68ec9612545b50d0430c..2196c6e49c7a2b1830ad19eb63854b5f4cb4d772 100644 (file)
@@ -495,7 +495,7 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button)
        if (setup.autorecord)
          TapeStartRecording();
 
-#if defined(PLATFORM_UNIX)
+#if defined(NETWORK_AVALIABLE)
        if (options.network)
          SendToServer_StartPlaying();
        else
index 479adfbfc0f2cb4767f73cdc8d76f5f5b2f381b2..d3fdd45729a3bbd03f34a80020b7b281ffe965d2 100644 (file)
@@ -734,7 +734,7 @@ static void TapeStartGameRecording()
 {
   TapeStartRecording();
 
-#if defined(PLATFORM_UNIX)
+#if defined(NETWORK_AVALIABLE)
   if (options.network)
     SendToServer_StartPlaying();
   else
index 0159d9bbba1b2313e9de6e0ea135ec029d4409c6..7e8b6921a4769e86e197e2f6fc37e1265ff2147f 100644 (file)
@@ -2072,7 +2072,7 @@ boolean Request(char *text, unsigned int req_state)
   SetMouseCursor(CURSOR_DEFAULT);
 #endif
 
-#if defined(PLATFORM_UNIX)
+#if defined(NETWORK_AVALIABLE)
   /* pause network game while waiting for request to answer */
   if (options.network &&
       game_status == GAME_MODE_PLAYING &&
@@ -2323,7 +2323,7 @@ boolean Request(char *text, unsigned int req_state)
 
   SetDrawBackgroundMask(REDRAW_FIELD);
 
-#if defined(PLATFORM_UNIX)
+#if defined(NETWORK_AVALIABLE)
   /* continue network game after request */
   if (options.network &&
       game_status == GAME_MODE_PLAYING &&