From 98cdb3fce945485772ccc49741fa29051338ce0d Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Fri, 30 Apr 2004 01:11:24 +0200 Subject: [PATCH] =?utf8?q?rnd-20040430-1-src=20*=20added=20option=20"handi?= =?utf8?q?cap"=20for=20"levelinfo.conf"=20(thanks=20to=20Niko=20B=F6hm)=20?= =?utf8?q?*=20added=20network=20multiplayer=20code=20for=20Windows=20(than?= =?utf8?q?ks=20to=20Niko=20B=F6hm)?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- ChangeLog | 4 ++ src/Makefile | 4 +- src/conftime.h | 2 +- src/events.c | 4 +- src/game.c | 78 ++++++++++++++-------- src/init.c | 9 ++- src/libgame/platform.h | 16 +++++ src/libgame/sdl.h | 2 + src/libgame/setup.c | 16 +++-- src/libgame/system.c | 2 + src/libgame/system.h | 1 + src/main.c | 5 ++ src/main.h | 5 ++ src/netserv.c | 145 +++++++++++++++++++++++++++++++++++++---- src/netserv.h | 4 ++ src/network.c | 144 ++++++++++++++++++++++++++++++++++------ src/screens.c | 2 +- src/tape.c | 2 +- src/tools.c | 4 +- 19 files changed, 372 insertions(+), 77 deletions(-) diff --git a/ChangeLog b/ChangeLog index c2aed9a6..bb065a92 100644 --- 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 diff --git a/src/Makefile b/src/Makefile index f065f0b9..8cc3ee95 100644 --- a/src/Makefile +++ b/src/Makefile @@ -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 diff --git a/src/conftime.h b/src/conftime.h index da0260a0..2c0f43fc 100644 --- a/src/conftime.h +++ b/src/conftime.h @@ -1 +1 @@ -#define COMPILE_DATE_STRING "[2004-04-26 09:36]" +#define COMPILE_DATE_STRING "[2004-04-30 01:05]" diff --git a/src/events.c b/src/events.c index 0f11b48a..fdb4b6ce 100644 --- a/src/events.c +++ b/src/events.c @@ -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 diff --git a/src/game.c b/src/game.c index ce4948b8..8dd2407d 100644 --- a/src/game.c +++ b/src/game.c @@ -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 diff --git a/src/init.c b/src/init.c index 61f8ce8e..905aaf70 100644 --- a/src/init.c +++ b/src/init.c @@ -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(); diff --git a/src/libgame/platform.h b/src/libgame/platform.h index 61ab27f6..5e168361 100644 --- a/src/libgame/platform.h +++ b/src/libgame/platform.h @@ -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 */ /* ========================================================================= */ @@ -74,6 +76,10 @@ #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" @@ -84,4 +90,14 @@ #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 */ diff --git a/src/libgame/sdl.h b/src/libgame/sdl.h index 8ad6308b..fc05cb70 100644 --- a/src/libgame/sdl.h +++ b/src/libgame/sdl.h @@ -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" */ diff --git a/src/libgame/setup.c b/src/libgame/setup.c index 8fa4317c..1d5a3591 100644 --- a/src/libgame/setup.c +++ b/src/libgame/setup.c @@ -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; diff --git a/src/libgame/system.c b/src/libgame/system.c index 656d97f9..8f26dc77 100644 --- a/src/libgame/system.c +++ b/src/libgame/system.c @@ -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 } diff --git a/src/libgame/system.h b/src/libgame/system.h index 7f26f635..74a74a67 100644 --- a/src/libgame/system.h +++ b/src/libgame/system.h @@ -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 */ diff --git a/src/main.c b/src/main.c index 7f74f6ae..e2182ecd 100644 --- a/src/main.c +++ b/src/main.c @@ -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]; diff --git a/src/main.h b/src/main.h index c6ae5644..b1c8303e 100644 --- a/src/main.h +++ b/src/main.h @@ -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]; diff --git a/src/netserv.c b/src/netserv.c index 08d16102..69226533 100644 --- a/src/netserv.c +++ b/src/netserv.c @@ -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 #include #include -#include #include + +#if defined(TARGET_SDL) +#include "main.h" +#else +#include #include #include #include #include #include /* 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 */ diff --git a/src/netserv.h b/src/netserv.h index 5805fa24..5efcb803 100644 --- a/src/netserv.h +++ b/src/netserv.h @@ -38,6 +38,10 @@ #define MAX_BUFFER_SIZE 4096 +#if defined(TARGET_SDL) +int NetworkServerThread(void *); +#endif + void NetworkServer(int, int); #endif diff --git a/src/network.c b/src/network.c index 914f4971..575e846b 100644 --- a/src/network.c +++ b/src/network.c @@ -13,16 +13,21 @@ #include "libgame/platform.h" -#if defined(PLATFORM_UNIX) +#if defined(NETWORK_AVALIABLE) #include #include + +#if defined(TARGET_SDL) +#include "main.h" +#else #include #include #include #include #include #include +#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 */ diff --git a/src/screens.c b/src/screens.c index 50c8685a..2196c6e4 100644 --- a/src/screens.c +++ b/src/screens.c @@ -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 diff --git a/src/tape.c b/src/tape.c index 479adfbf..d3fdd457 100644 --- a/src/tape.c +++ b/src/tape.c @@ -734,7 +734,7 @@ static void TapeStartGameRecording() { TapeStartRecording(); -#if defined(PLATFORM_UNIX) +#if defined(NETWORK_AVALIABLE) if (options.network) SendToServer_StartPlaying(); else diff --git a/src/tools.c b/src/tools.c index 0159d9bb..7e8b6921 100644 --- a/src/tools.c +++ b/src/tools.c @@ -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 && -- 2.34.1