From 523f786f2011e2592a21f47d33de7f570c8eb613 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 11 Sep 2010 20:29:22 +0000 Subject: Fix docgen error with key_multi_msgplayer8 config file variable. Subversion-branch: /branches/raven-branch Subversion-revision: 2064 --- src/m_config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/m_config.c b/src/m_config.c index 8b93cfd3..a277fc38 100644 --- a/src/m_config.c +++ b/src/m_config.c @@ -1108,7 +1108,7 @@ static default_t extra_defaults_list[] = // Key to send a message to player 8 during multiplayer games. // - CONFIG_VARIABLE_KEY(key_multi_msgplayer8) + CONFIG_VARIABLE_KEY(key_multi_msgplayer8), }; static default_collection_t extra_defaults = -- cgit v1.2.3 From ea810eeed93cbc7e988f47841d26fc10f8c44c7c Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Tue, 14 Sep 2010 17:47:12 +0000 Subject: Re-enable multiplayer support for Doom only, in preparation for network code refactoring. Subversion-branch: /branches/raven-branch Subversion-revision: 2087 --- src/Makefile.am | 6 ++++-- src/doomfeatures.h | 2 +- src/net_client.c | 5 +++-- src/net_gui.c | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 54450e78..55901885 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -141,9 +141,11 @@ EXTRA_LIBS = \ @SDLNET_LIBS@ if HAVE_WINDRES -@PROGRAM_PREFIX@doom_SOURCES=$(SOURCE_FILES_WITH_DEH) resource.rc +@PROGRAM_PREFIX@doom_SOURCES=$(SOURCE_FILES_WITH_DEH) resource.rc \ + $(FEATURE_MULTIPLAYER_SOURCE_FILES) else -@PROGRAM_PREFIX@doom_SOURCES=$(SOURCE_FILES_WITH_DEH) +@PROGRAM_PREFIX@doom_SOURCES=$(SOURCE_FILES_WITH_DEH) \ + $(FEATURE_MULTIPLAYER_SOURCE_FILES) endif @PROGRAM_PREFIX@doom_LDADD = doom/libdoom.a $(EXTRA_LIBS) diff --git a/src/doomfeatures.h b/src/doomfeatures.h index c5e6067a..46e26e52 100644 --- a/src/doomfeatures.h +++ b/src/doomfeatures.h @@ -37,7 +37,7 @@ // Enables multiplayer support (network games) -//#define FEATURE_MULTIPLAYER 1 +#define FEATURE_MULTIPLAYER 1 // Enables sound output diff --git a/src/net_client.c b/src/net_client.c index a1697944..bf2e4e56 100644 --- a/src/net_client.c +++ b/src/net_client.c @@ -28,10 +28,8 @@ #include "config.h" #include "doomtype.h" -#include "doomstat.h" #include "deh_main.h" #include "deh_str.h" -#include "g_game.h" #include "i_system.h" #include "i_timer.h" #include "m_argv.h" @@ -47,6 +45,9 @@ #include "w_checksum.h" #include "w_wad.h" +#include "doom/doomstat.h" +#include "doom/g_game.h" + typedef enum { // waiting for the game to start diff --git a/src/net_gui.c b/src/net_gui.c index 8c848d1c..913b083d 100644 --- a/src/net_gui.c +++ b/src/net_gui.c @@ -268,7 +268,7 @@ void NET_WaitForStart(void) } I_SetWindowTitle("Waiting for game start"); - I_SetWindowIcon(); + //I_SetWindowIcon(); BuildGUI(); -- cgit v1.2.3 From 63712ec1880bf0df7df6c215b01da9bafb9b6976 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 18 Sep 2010 16:58:29 +0000 Subject: Move Doom-specific code from net_client.c into d_net.c. Subversion-branch: /branches/raven-branch Subversion-revision: 2109 --- src/doom/d_net.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/net_client.c | 75 ++++++++------------------------------------- 2 files changed, 105 insertions(+), 62 deletions(-) (limited to 'src') diff --git a/src/doom/d_net.c b/src/doom/d_net.c index 464922d4..a081b72a 100644 --- a/src/doom/d_net.c +++ b/src/doom/d_net.c @@ -64,6 +64,7 @@ ticcmd_t netcmds[MAXPLAYERS][BACKUPTICS]; int nettics[MAXPLAYERS]; int maketic; +int recvtic; // Used for original sync code. @@ -214,6 +215,97 @@ void NetUpdate (void) } } +// Called when a player leaves the game + +static void D_PlayerQuitGame(player_t *player) +{ + static char exitmsg[80]; + unsigned int player_num; + + player_num = player - players; + + // Do this the same way as Vanilla Doom does, to allow dehacked + // replacements of this message + + strncpy(exitmsg, DEH_String("Player 1 left the game"), sizeof(exitmsg)); + exitmsg[sizeof(exitmsg) - 1] = '\0'; + + exitmsg[7] += player_num; + + playeringame[player_num] = false; + players[consoleplayer].message = exitmsg; + + // TODO: check if it is sensible to do this: + + if (demorecording) + { + G_CheckDemoStatus (); + } +} + +static void D_Disconnected(void) +{ + int i; + + // In drone mode, the game cannot continue once disconnected. + + if (drone) + { + I_Error("Disconnected from server in drone mode."); + } + + // disconnected from server + + printf("Disconnected from server.\n"); + + for (i=0; icmds as @@ -242,7 +201,8 @@ static void NET_CL_Disconnected(void) // the d_net.c structures (netcmds/nettics) and save the new ticcmd // back into recvwindow_cmd_base. -static void NET_CL_ExpandFullTiccmd(net_full_ticcmd_t *cmd, unsigned int seq) +static void NET_CL_ExpandFullTiccmd(net_full_ticcmd_t *cmd, unsigned int seq, + ticcmd_t *ticcmds) { int latency; fixed_t adjustment; @@ -309,33 +269,20 @@ static void NET_CL_ExpandFullTiccmd(net_full_ticcmd_t *cmd, unsigned int seq) continue; } - if (playeringame[i] && !cmd->playeringame[i]) - { - NET_CL_PlayerQuitGame(&players[i]); - } - - playeringame[i] = cmd->playeringame[i]; - - if (playeringame[i]) + if (cmd->playeringame[i]) { net_ticdiff_t *diff; - ticcmd_t ticcmd; diff = &cmd->cmds[i]; // Use the ticcmd diff to patch the previous ticcmd to // the new ticcmd - NET_TiccmdPatch(&recvwindow_cmd_base[i], diff, &ticcmd); - - // Save in d_net.c structures - - netcmds[i][nettics[i] % BACKUPTICS] = ticcmd; - ++nettics[i]; + NET_TiccmdPatch(&recvwindow_cmd_base[i], diff, &ticcmds[i]); // Store a copy for next time - recvwindow_cmd_base[i] = ticcmd; + recvwindow_cmd_base[i] = ticcmds[i]; } } } @@ -344,11 +291,15 @@ static void NET_CL_ExpandFullTiccmd(net_full_ticcmd_t *cmd, unsigned int seq) static void NET_CL_AdvanceWindow(void) { + ticcmd_t ticcmds[MAXPLAYERS]; + while (recvwindow[0].active) { // Expand tic diff data into d_net.c structures - NET_CL_ExpandFullTiccmd(&recvwindow[0].cmd, recvwindow_start); + NET_CL_ExpandFullTiccmd(&recvwindow[0].cmd, recvwindow_start, + ticcmds); + D_ReceiveTic(ticcmds, recvwindow[0].cmd.playeringame); // Advance the window -- cgit v1.2.3 From 253731b66d4a70d5040d11e4b1acf8aa58230a46 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 19 Sep 2010 20:09:36 +0000 Subject: Read response file in binary mode, to fix incomplete response file bug. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2122 --- src/m_argv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/m_argv.c b/src/m_argv.c index 7fc15863..99295c6d 100644 --- a/src/m_argv.c +++ b/src/m_argv.c @@ -74,9 +74,9 @@ static void LoadResponseFile(int argv_index) int i, k; response_filename = myargv[argv_index] + 1; - + // Read the response file into memory - handle = fopen(response_filename, "r"); + handle = fopen(response_filename, "rb"); if (handle == NULL) { -- cgit v1.2.3 From 4dac08c8694f9b347b2b5c0ca12a0d26b1ae6589 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 26 Sep 2010 01:21:02 +0000 Subject: Restructure player quit code to take place on the first tic after the player quit, to avoid possible desyncs. Further refactoring to split game-specific code from generic code. Subversion-branch: /branches/raven-branch Subversion-revision: 2141 --- src/doom/d_main.c | 5 +- src/doom/d_net.c | 316 ++++++++++++++++++++++++++++++---------------------- src/doom/doomstat.h | 2 +- src/doom/g_game.c | 6 +- 4 files changed, 192 insertions(+), 137 deletions(-) (limited to 'src') diff --git a/src/doom/d_main.c b/src/doom/d_main.c index f3a4b037..fed6a1b4 100644 --- a/src/doom/d_main.c +++ b/src/doom/d_main.c @@ -457,9 +457,12 @@ void D_DoomLoop (void) // process one or more tics if (singletics) { + static ticcmd_t cmds[MAXPLAYERS]; + I_StartTic (); D_ProcessEvents (); - G_BuildTiccmd (&netcmds[consoleplayer][maketic%BACKUPTICS]); + netcmds = cmds; + G_BuildTiccmd(&cmds[consoleplayer]); if (advancedemo) D_DoAdvanceDemo (); M_Ticker (); diff --git a/src/doom/d_net.c b/src/doom/d_net.c index a081b72a..a15d3b1a 100644 --- a/src/doom/d_net.c +++ b/src/doom/d_net.c @@ -49,19 +49,27 @@ #include "net_sdl.h" #include "net_loop.h" +// The complete set of data for a particular tic. + +typedef struct +{ + ticcmd_t cmds[MAXPLAYERS]; + boolean ingame[MAXPLAYERS]; +} ticcmd_set_t; // // NETWORKING // // gametic is the tic about to (or currently being) run -// maketic is the tick that hasn't had control made for it yet -// nettics[] has the maketics for all players +// maketic is the tic that hasn't had control made for it yet +// recvtic is the latest tic received from the server. // -// a gametic cannot be run until nettics[] > gametic for all players +// a gametic cannot be run until ticcmds are received for it +// from all players. // -ticcmd_t netcmds[MAXPLAYERS][BACKUPTICS]; -int nettics[MAXPLAYERS]; +ticcmd_set_t ticdata[BACKUPTICS]; +ticcmd_t *netcmds; int maketic; int recvtic; @@ -208,10 +216,10 @@ void NetUpdate (void) } #endif - netcmds[consoleplayer][maketic % BACKUPTICS] = cmd; + ticdata[maketic % BACKUPTICS].cmds[consoleplayer] = cmd; + ticdata[maketic % BACKUPTICS].ingame[consoleplayer] = true; ++maketic; - nettics[consoleplayer] = maketic; } } @@ -245,8 +253,6 @@ static void D_PlayerQuitGame(player_t *player) static void D_Disconnected(void) { - int i; - // In drone mode, the game cannot continue once disconnected. if (drone) @@ -257,14 +263,6 @@ static void D_Disconnected(void) // disconnected from server printf("Disconnected from server.\n"); - - for (i=0; i recvtic; + oldnettics = maketic; + + if (frameskip[0] && frameskip[1] && frameskip[2] && frameskip[3]) + { + skiptics = 1; + // printf ("+"); + } + } } -static int GetLowTic(void) +// Returns true if there are players in the game: + +static boolean PlayersInGame(void) { - int lowtic; + boolean result = false; + unsigned int i; + + // If we are connected to a server, check if there are any players + // in the game. -#ifdef FEATURE_MULTIPLAYER if (net_client_connected) { - int i; - - lowtic = INT_MAX; - - for (i=0; icmds[i]; + cmd->chatchar = 0; + if (cmd->buttons & BT_SPECIAL) + cmd->buttons = 0; + } +} + +static void D_RunTic(ticcmd_set_t *set) +{ + extern boolean advancedemo; + unsigned int i; + + // Check for player quits. + + for (i = 0; i < MAXPLAYERS; ++i) + { + if (playeringame[i] && !set->ingame[i]) + { + D_PlayerQuitGame(&players[i]); + } + } + + netcmds = set->cmds; + + // check that there are players in the game. if not, we cannot + // run a tic. + + if (advancedemo) + D_DoAdvanceDemo (); + + G_Ticker (); +} + +// When running in single player mode, clear all the ingame[] array +// except the consoleplayer. + +static void SinglePlayerClear(ticcmd_set_t *set) +{ + unsigned int i; + + for (i = 0; i < MAXPLAYERS; ++i) + { + if (i != consoleplayer) + { + set->ingame[i] = false; + } + } } // // TryRunTics // -int oldnettics; -int frametics[4]; -int frameon; -int frameskip[4]; -int oldnettics; - -extern boolean advancedemo; void TryRunTics (void) { @@ -601,52 +704,9 @@ void TryRunTics (void) if (counts < 1) counts = 1; - frameon++; - - if (!demoplayback) + if (net_client_connected) { - int keyplayer = -1; - - // ideally maketic should be 1 - 3 tics above lowtic - // if we are consistantly slower, speed up time - - for (i=0 ; i nettics[keyplayer]); - oldnettics = maketic; - - if (frameskip[0] && frameskip[1] && frameskip[2] && frameskip[3]) - { - skiptics = 1; - // printf ("+"); - } - } + OldNetSync(); } } @@ -678,41 +738,33 @@ void TryRunTics (void) // run the count * ticdup dics while (counts--) { + ticcmd_set_t *set; + + if (!PlayersInGame()) + { + return; + } + + set = &ticdata[(gametic / ticdup) % BACKUPTICS]; + + if (!net_client_connected) + { + SinglePlayerClear(set); + } + for (i=0 ; i lowtic) - I_Error ("gametic>lowtic"); - if (advancedemo) - D_DoAdvanceDemo (); + if (gametic/ticdup > lowtic) + I_Error ("gametic>lowtic"); - G_Ticker (); + D_RunTic(set); gametic++; // modify command for duplicated tics - if (i != ticdup-1) - { - ticcmd_t *cmd; - int buf; - int j; - - buf = (gametic/ticdup)%BACKUPTICS; - for (j=0 ; jchatchar = 0; - if (cmd->buttons & BT_SPECIAL) - cmd->buttons = 0; - } - } + + TicdupSquash(set); } + NetUpdate (); // check for new console commands } } diff --git a/src/doom/doomstat.h b/src/doom/doomstat.h index 40147833..15a8d743 100644 --- a/src/doom/doomstat.h +++ b/src/doom/doomstat.h @@ -289,7 +289,7 @@ extern int rndindex; extern int maketic; extern int nettics[MAXPLAYERS]; -extern ticcmd_t netcmds[MAXPLAYERS][BACKUPTICS]; +extern ticcmd_t *netcmds; extern int ticdup; diff --git a/src/doom/g_game.c b/src/doom/g_game.c index ad7155a0..0aaf8ee7 100644 --- a/src/doom/g_game.c +++ b/src/doom/g_game.c @@ -986,9 +986,9 @@ void G_Ticker (void) if (playeringame[i]) { cmd = &players[i].cmd; - - memcpy (cmd, &netcmds[i][buf], sizeof(ticcmd_t)); - + + memcpy(cmd, &netcmds[i], sizeof(ticcmd_t)); + if (demoplayback) G_ReadDemoTiccmd (cmd); if (demorecording) -- cgit v1.2.3 From 005747a6174d2d5b72e1af196a72cafb9b801a58 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 20 Nov 2010 16:45:27 +0000 Subject: Remove dependency of network code on Doom code. Subversion-branch: /branches/raven-branch Subversion-revision: 2163 --- src/doom/d_net.c | 354 ++++++++++++++++++++++++++++++++++++++--------------- src/doom/d_net.h | 1 - src/net_client.c | 183 +++++++-------------------- src/net_client.h | 6 +- src/net_defs.h | 25 ++++ src/net_gui.c | 14 ++- src/net_gui.h | 2 +- src/net_server.c | 31 +++-- src/net_structrw.c | 22 +++- src/net_structrw.h | 3 + 10 files changed, 372 insertions(+), 269 deletions(-) (limited to 'src') diff --git a/src/doom/d_net.c b/src/doom/d_net.c index a15d3b1a..05d1875f 100644 --- a/src/doom/d_net.c +++ b/src/doom/d_net.c @@ -25,7 +25,7 @@ // //----------------------------------------------------------------------------- - +#include #include "doomfeatures.h" @@ -76,8 +76,7 @@ int recvtic; // Used for original sync code. -int lastnettic; -int skiptics = 0; +static int skiptics = 0; // Reduce the bandwidth needed by sampling game input less and transmitting // less. If ticdup is 2, sample half normal, 3 = one third normal, etc. @@ -94,11 +93,7 @@ fixed_t offsetms; // Use new client syncronisation code -boolean net_cl_new_sync = true; - -// Connected but not participating in the game (observer) - -boolean drone = false; +boolean new_sync = true; // 35 fps clock adjusted by offsetms milliseconds @@ -108,7 +103,7 @@ static int GetAdjustedTime(void) time_ms = I_GetTimeMS(); - if (net_cl_new_sync) + if (new_sync) { // Use the adjustments from net_client.c only if we are // using the new sync mode. @@ -186,7 +181,7 @@ void NetUpdate (void) continue; } - if (net_cl_new_sync) + if (new_sync) { // If playing single player, do not allow tics to buffer // up very far @@ -309,21 +304,144 @@ void D_StartGameLoop(void) lasttime = GetAdjustedTime() / ticdup; } +// Load game settings from the specified structure and +// set global variables. -// -// D_CheckNetGame -// Works out player numbers among the net participants -// -extern int viewangleoffset; +static void LoadGameSettings(net_gamesettings_t *settings) +{ + unsigned int i; -void D_CheckNetGame (void) + deathmatch = settings->deathmatch; + ticdup = settings->ticdup; + extratics = settings->extratics; + startepisode = settings->episode; + startmap = settings->map; + startskill = settings->skill; + startloadgame = settings->loadgame; + lowres_turn = settings->lowres_turn; + nomonsters = settings->nomonsters; + fastparm = settings->fast_monsters; + respawnparm = settings->respawn_monsters; + timelimit = settings->timelimit; + + if (lowres_turn) + { + printf("NOTE: Turning resolution is reduced; this is probably " + "because there is a client recording a Vanilla demo.\n"); + } + + new_sync = settings->new_sync; + + if (new_sync == false) + { + printf("Syncing netgames like Vanilla Doom.\n"); + } + + netgame = true; + autostart = true; + + if (!drone) + { + consoleplayer = settings->consoleplayer; + } + else + { + consoleplayer = 0; + } + + for (i=0; inum_players; + } +} + +// Save the game settings from global variables to the specified +// game settings structure. + +static void SaveGameSettings(net_gamesettings_t *settings, + net_connect_data_t *connect_data) { int i; - int num_players; - // Call D_QuitNetGame on exit + // Fill in game settings structure with appropriate parameters + // for the new game + + settings->deathmatch = deathmatch; + settings->episode = startepisode; + settings->map = startmap; + settings->skill = startskill; + settings->loadgame = startloadgame; + settings->gameversion = gameversion; + settings->nomonsters = nomonsters; + settings->fast_monsters = fastparm; + settings->respawn_monsters = respawnparm; + settings->timelimit = timelimit; + + settings->lowres_turn = M_CheckParm("-record") > 0 + && M_CheckParm("-longtics") == 0; + + //! + // @category net + // + // Use original game sync code. + // + + if (M_CheckParm("-oldsync") > 0) + settings->new_sync = 0; + else + settings->new_sync = 1; + + //! + // @category net + // @arg + // + // Send n extra tics in every packet as insurance against dropped + // packets. + // + + i = M_CheckParm("-extratics"); + + if (i > 0) + settings->extratics = atoi(myargv[i+1]); + else + settings->extratics = 1; - I_AtExit(D_QuitNetGame, true); + //! + // @category net + // @arg + // + // Reduce the resolution of the game by a factor of n, reducing + // the amount of network bandwidth needed. + // + + i = M_CheckParm("-dup"); + + if (i > 0) + settings->ticdup = atoi(myargv[i+1]); + else + settings->ticdup = 1; + + // + // Connect data + // + + // Game type fields: + + connect_data->gamemode = gamemode; + connect_data->gamemission = gamemission; + + // Drone mode? + + connect_data->drone = M_CheckParm("-drone") > 0; + + // Are we recording a demo? Possibly set lowres turn mode + + connect_data->lowres_turn = settings->lowres_turn; +} + +void D_InitSinglePlayerGame(void) +{ + int i; // default values for single player @@ -342,128 +460,160 @@ void D_CheckNetGame (void) recvtic = 0; playeringame[0] = true; +} + +boolean D_InitNetGame(net_connect_data_t *connect_data, + net_gamesettings_t *settings) +{ + net_addr_t *addr = NULL; + int i; #ifdef FEATURE_MULTIPLAYER + //! + // @category net + // + // Start a multiplayer server, listening for connections. + // + + if (M_CheckParm("-server") > 0) { - net_addr_t *addr = NULL; + NET_SV_Init(); + NET_SV_AddModule(&net_loop_server_module); + NET_SV_AddModule(&net_sdl_module); - //! + net_loop_client_module.InitClient(); + addr = net_loop_client_module.ResolveAddress(NULL); + } + else + { + //! // @category net // - // Start a multiplayer server, listening for connections. + // Automatically search the local LAN for a multiplayer + // server and join it. // - if (M_CheckParm("-server") > 0) + i = M_CheckParm("-autojoin"); + + if (i > 0) { - NET_SV_Init(); - NET_SV_AddModule(&net_loop_server_module); - NET_SV_AddModule(&net_sdl_module); + addr = NET_FindLANServer(); - net_loop_client_module.InitClient(); - addr = net_loop_client_module.ResolveAddress(NULL); + if (addr == NULL) + { + I_Error("No server found on local LAN"); + } } - else - { - //! - // @category net - // - // Automatically search the local LAN for a multiplayer - // server and join it. - // - i = M_CheckParm("-autojoin"); + //! + // @arg
+ // @category net + // + // Connect to a multiplayer server running on the given + // address. + // + + i = M_CheckParm("-connect"); - if (i > 0) - { - addr = NET_FindLANServer(); + if (i > 0) + { + net_sdl_module.InitClient(); + addr = net_sdl_module.ResolveAddress(myargv[i+1]); - if (addr == NULL) - { - I_Error("No server found on local LAN"); - } + if (addr == NULL) + { + I_Error("Unable to resolve '%s'\n", myargv[i+1]); } + } + } - //! - // @arg
- // @category net - // - // Connect to a multiplayer server running on the given - // address. - // - - i = M_CheckParm("-connect"); - - if (i > 0) - { - net_sdl_module.InitClient(); - addr = net_sdl_module.ResolveAddress(myargv[i+1]); + if (addr != NULL) + { + if (M_CheckParm("-drone") > 0) + { + connect_data->drone = true; + } - if (addr == NULL) - { - I_Error("Unable to resolve '%s'\n", myargv[i+1]); - } - } + //! + // @category net + // + // Run as the left screen in three screen mode. + // + + if (M_CheckParm("-left") > 0) + { + viewangleoffset = ANG90; + connect_data->drone = true; } - if (addr != NULL) + //! + // @category net + // + // Run as the right screen in three screen mode. + // + + if (M_CheckParm("-right") > 0) { - if (M_CheckParm("-drone") > 0) - { - drone = true; - } + viewangleoffset = ANG270; + connect_data->drone = true; + } - //! - // @category net - // - // Run as the left screen in three screen mode. - // + if (!NET_CL_Connect(addr, connect_data)) + { + I_Error("D_CheckNetGame: Failed to connect to %s\n", + NET_AddrToString(addr)); + } - if (M_CheckParm("-left") > 0) - { - viewangleoffset = ANG90; - drone = true; - } + printf("D_CheckNetGame: Connected to %s\n", NET_AddrToString(addr)); - //! - // @category net - // - // Run as the right screen in three screen mode. - // + // Wait for game start message received from server. - if (M_CheckParm("-right") > 0) - { - viewangleoffset = ANG270; - drone = true; - } + NET_WaitForStart(settings); - if (!NET_CL_Connect(addr)) - { - I_Error("D_CheckNetGame: Failed to connect to %s\n", - NET_AddrToString(addr)); - } + // Read the game settings that were received. - printf("D_CheckNetGame: Connected to %s\n", NET_AddrToString(addr)); + NET_CL_GetSettings(settings); - NET_WaitForStart(); - } + return true; } #endif - num_players = 0; + return false; +} + +// +// D_CheckNetGame +// Works out player numbers among the net participants +// +extern int viewangleoffset; + +void D_CheckNetGame (void) +{ + net_connect_data_t connect_data; + net_gamesettings_t settings; + + // Call D_QuitNetGame on exit - for (i=0; i 0) - settings.new_sync = 0; - else - settings.new_sync = 1; - - //! - // @category net - // @arg - // - // Send n extra tics in every packet as insurance against dropped - // packets. - // - - i = M_CheckParm("-extratics"); - - if (i > 0) - settings.extratics = atoi(myargv[i+1]); - else - settings.extratics = 1; - - //! - // @category net - // @arg - // - // Reduce the resolution of the game by a factor of n, reducing - // the amount of network bandwidth needed. - // - - i = M_CheckParm("-dup"); - - if (i > 0) - settings.ticdup = atoi(myargv[i+1]); - else - settings.ticdup = 1; // Start from a ticcmd of all zeros @@ -397,7 +347,7 @@ void NET_CL_StartGame(void) packet = NET_Conn_NewReliable(&client_connection, NET_PACKET_TYPE_GAMESTART); - NET_WriteSettings(packet, &settings); + NET_WriteSettings(packet, settings); } static void NET_CL_SendGameDataACK(void) @@ -407,7 +357,7 @@ static void NET_CL_SendGameDataACK(void) packet = NET_NewPacket(10); NET_WriteInt16(packet, NET_PACKET_TYPE_GAMEDATA_ACK); - NET_WriteInt8(packet, (gametic / ticdup) & 0xff); + NET_WriteInt8(packet, recvwindow_start & 0xff); NET_Conn_SendPacket(&client_connection, packet); @@ -439,7 +389,7 @@ static void NET_CL_SendTics(int start, int end) // Write the start tic and number of tics. Send only the low byte // of start - it can be inferred by the server. - NET_WriteInt8(packet, (gametic / ticdup) & 0xff); + NET_WriteInt8(packet, recvwindow_start & 0xff); NET_WriteInt8(packet, start & 0xff); NET_WriteInt8(packet, end - start + 1); @@ -453,7 +403,7 @@ static void NET_CL_SendTics(int start, int end) NET_WriteInt16(packet, average_latency / FRACUNIT); - NET_WriteTiccmdDiff(packet, &sendobj->cmd, lowres_turn); + NET_WriteTiccmdDiff(packet, &sendobj->cmd, settings.lowres_turn); } // Send the packet @@ -493,7 +443,7 @@ void NET_CL_SendTiccmd(ticcmd_t *ticcmd, int maketic) // Send to server. - starttic = maketic - extratics; + starttic = maketic - settings.extratics; endtic = maketic; if (starttic < 0) @@ -584,14 +534,7 @@ static void NET_CL_ParseWaitingData(net_packet_t *packet) static void NET_CL_ParseGameStart(net_packet_t *packet) { - net_gamesettings_t settings; - unsigned int num_players; - signed int player_number; - unsigned int i; - - if (!NET_ReadInt8(packet, &num_players) - || !NET_ReadSInt8(packet, &player_number) - || !NET_ReadSettings(packet, &settings)) + if (!NET_ReadSettings(packet, &settings)) { return; } @@ -601,14 +544,15 @@ static void NET_CL_ParseGameStart(net_packet_t *packet) return; } - if (num_players > MAXPLAYERS || player_number >= (signed int) num_players) + if (settings.num_players > MAXPLAYERS + || settings.consoleplayer >= (signed int) settings.num_players) { // insane values return; } - if ((drone && player_number >= 0) - || (!drone && player_number < 0)) + if ((drone && settings.consoleplayer >= 0) + || (!drone && settings.consoleplayer < 0)) { // Invalid player number: must be positive for real players, // negative for drones @@ -616,49 +560,8 @@ static void NET_CL_ParseGameStart(net_packet_t *packet) return; } - // Start the game - - if (!drone) - { - consoleplayer = player_number; - } - else - { - consoleplayer = 0; - } - - for (i=0; i 0 && M_CheckParm("-longtics") == 0) - { - lowres_turn = true; - } - // Read checksums of our WAD directory and dehacked information W_Checksum(net_local_wad_md5sum); @@ -1107,7 +997,7 @@ boolean NET_CL_Connect(net_addr_t *addr) // necessary module client_context = NET_NewContext(); - + // initialize module for client mode if (!addr->module->InitClient()) @@ -1137,7 +1027,7 @@ boolean NET_CL_Connect(net_addr_t *addr) if (nowtime - last_send_time > 1000 || last_send_time < 0) { - NET_CL_SendSYN(); + NET_CL_SendSYN(data); last_send_time = nowtime; } @@ -1151,7 +1041,7 @@ boolean NET_CL_Connect(net_addr_t *addr) // run client code NET_CL_Run(); - + // run the server, just incase we are doing a loopback // connect @@ -1167,6 +1057,7 @@ boolean NET_CL_Connect(net_addr_t *addr) // connected ok! client_state = CLIENT_STATE_WAITING_START; + drone = data->drone; return true; } @@ -1175,11 +1066,25 @@ boolean NET_CL_Connect(net_addr_t *addr) // failed to connect NET_CL_Shutdown(); - + return false; } } +// read game settings received from server + +boolean NET_CL_GetSettings(net_gamesettings_t *_settings) +{ + if (client_state != CLIENT_STATE_IN_GAME) + { + return false; + } + + memcpy(_settings, &settings, sizeof(net_gamesettings_t)); + + return true; +} + // disconnect from the server void NET_CL_Disconnect(void) diff --git a/src/net_client.h b/src/net_client.h index 078a19a2..b071d32a 100644 --- a/src/net_client.h +++ b/src/net_client.h @@ -31,12 +31,13 @@ #define MAXPLAYERNAME 30 -boolean NET_CL_Connect(net_addr_t *addr); +boolean NET_CL_Connect(net_addr_t *addr, net_connect_data_t *data); void NET_CL_Disconnect(void); void NET_CL_Run(void); void NET_CL_Init(void); -void NET_CL_StartGame(); +void NET_CL_StartGame(net_gamesettings_t *settings); void NET_CL_SendTiccmd(ticcmd_t *ticcmd, int maketic); +boolean NET_CL_GetSettings(net_gamesettings_t *_settings); void NET_Init(void); void NET_BindVariables(void); @@ -59,6 +60,7 @@ extern md5_digest_t net_local_wad_md5sum; extern md5_digest_t net_local_deh_md5sum; extern unsigned int net_local_is_freedoom; +extern boolean drone; #endif /* #ifndef NET_CLIENT_H */ diff --git a/src/net_defs.h b/src/net_defs.h index a5fddc4d..72e0e6d2 100644 --- a/src/net_defs.h +++ b/src/net_defs.h @@ -128,6 +128,22 @@ typedef enum NET_PACKET_TYPE_QUERY_RESPONSE, } net_packet_type_t; +// Settings specified when the client connects to the server. + +typedef struct +{ + int gamemode; + int gamemission; + int lowres_turn; + int drone; + // TODO: is_freedoom in here? WAD/DEH checksums? + // TODO: [Hexen] Requested player class + +} net_connect_data_t; + +// Game settings sent by client to server when initiating game start, +// and received from the server by clients when the game starts. + typedef struct { int ticdup; @@ -144,6 +160,15 @@ typedef struct int new_sync; int timelimit; int loadgame; + + // These fields are only used by the server when sending a game + // start message: + + int num_players; + int consoleplayer; + + // TODO: [Hexen] Array of player classes, one for each player. + } net_gamesettings_t; #define NET_TICDIFF_FORWARD (1 << 0) diff --git a/src/net_gui.c b/src/net_gui.c index 913b083d..7473c948 100644 --- a/src/net_gui.c +++ b/src/net_gui.c @@ -53,9 +53,11 @@ static void EscapePressed(TXT_UNCAST_ARG(widget), void *unused) I_Quit(); } -static void StartGame(TXT_UNCAST_ARG(widget), void *unused) +static void StartGame(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(settings)) { - NET_CL_StartGame(); + TXT_CAST_ARG(net_gamesettings_t, settings); + + NET_CL_StartGame(settings); } static void BuildGUI(void) @@ -101,7 +103,7 @@ static void BuildGUI(void) TXT_SetWindowAction(window, TXT_HORIZ_LEFT, cancel); } -static void UpdateGUI(void) +static void UpdateGUI(net_gamesettings_t *settings) { txt_window_action_t *startgame; char buf[50]; @@ -144,7 +146,7 @@ static void UpdateGUI(void) if (net_client_controller) { startgame = TXT_NewWindowAction(' ', "Start game"); - TXT_SignalConnect(startgame, "pressed", StartGame, NULL); + TXT_SignalConnect(startgame, "pressed", StartGame, settings); } else { @@ -259,7 +261,7 @@ static void CheckMD5Sums(void) had_warning = true; } -void NET_WaitForStart(void) +void NET_WaitForStart(net_gamesettings_t *settings) { if (!TXT_Init()) { @@ -274,7 +276,7 @@ void NET_WaitForStart(void) while (net_waiting_for_start) { - UpdateGUI(); + UpdateGUI(settings); CheckMD5Sums(); TXT_DispatchEvents(); diff --git a/src/net_gui.h b/src/net_gui.h index fdcc81be..9d40b0d0 100644 --- a/src/net_gui.h +++ b/src/net_gui.h @@ -30,7 +30,7 @@ #include "doomtype.h" -extern void NET_WaitForStart(); +extern void NET_WaitForStart(net_gamesettings_t *settings); #endif /* #ifndef NET_GUI_H */ diff --git a/src/net_server.c b/src/net_server.c index 904d932e..058e61f7 100644 --- a/src/net_server.c +++ b/src/net_server.c @@ -447,10 +447,8 @@ static void NET_SV_ParseSYN(net_packet_t *packet, net_addr_t *addr) { unsigned int magic; - unsigned int cl_gamemode, cl_gamemission; - unsigned int cl_recording_lowres; - unsigned int cl_drone; unsigned int is_freedoom; + net_connect_data_t data; md5_digest_t deh_md5sum, wad_md5sum; char *player_name; char *client_version; @@ -501,10 +499,7 @@ static void NET_SV_ParseSYN(net_packet_t *packet, // read the game mode and mission - if (!NET_ReadInt16(packet, &cl_gamemode) - || !NET_ReadInt16(packet, &cl_gamemission) - || !NET_ReadInt8(packet, &cl_recording_lowres) - || !NET_ReadInt8(packet, &cl_drone) + if (!NET_ReadConnectData(packet, &data) || !NET_ReadMD5Sum(packet, wad_md5sum) || !NET_ReadMD5Sum(packet, deh_md5sum) || !NET_ReadInt8(packet, &is_freedoom)) @@ -512,7 +507,7 @@ static void NET_SV_ParseSYN(net_packet_t *packet, return; } - if (!D_ValidGameMode(cl_gamemission, cl_gamemode)) + if (!D_ValidGameMode(data.gamemission, data.gamemode)) { return; } @@ -579,7 +574,7 @@ static void NET_SV_ParseSYN(net_packet_t *packet, NET_SV_AssignPlayers(); num_players = NET_SV_NumPlayers(); - if ((!cl_drone && num_players >= MAXPLAYERS) + if ((!data.drone && num_players >= MAXPLAYERS) || NET_SV_NumClients() >= MAXNETNODES) { NET_SV_SendReject(addr, "Server is full!"); @@ -592,10 +587,10 @@ static void NET_SV_ParseSYN(net_packet_t *packet, // Adopt the game mode and mission of the first connecting client - if (num_players == 0 && !cl_drone) + if (num_players == 0 && !data.drone) { - sv_gamemode = cl_gamemode; - sv_gamemission = cl_gamemission; + sv_gamemode = data.gamemode; + sv_gamemission = data.gamemission; } // Save the MD5 checksums @@ -607,7 +602,7 @@ static void NET_SV_ParseSYN(net_packet_t *packet, // Check the connecting client is playing the same game as all // the other clients - if (cl_gamemode != sv_gamemode || cl_gamemission != sv_gamemission) + if (data.gamemode != sv_gamemode || data.gamemission != sv_gamemission) { NET_SV_SendReject(addr, "You are playing the wrong game!"); return; @@ -617,8 +612,8 @@ static void NET_SV_ParseSYN(net_packet_t *packet, NET_SV_InitNewClient(client, addr, player_name); - client->recording_lowres = cl_recording_lowres; - client->drone = cl_drone; + client->recording_lowres = data.lowres_turn; + client->drone = data.drone; } if (client->connection.state == NET_CONN_STATE_WAITING_ACK) @@ -681,6 +676,8 @@ static void NET_SV_ParseGameStart(net_packet_t *packet, net_client_t *client) } } + settings.num_players = NET_SV_NumPlayers(); + nowtime = I_GetTimeMS(); // Send start packets to each connected node @@ -695,8 +692,8 @@ static void NET_SV_ParseGameStart(net_packet_t *packet, net_client_t *client) startpacket = NET_Conn_NewReliable(&clients[i].connection, NET_PACKET_TYPE_GAMESTART); - NET_WriteInt8(startpacket, NET_SV_NumPlayers()); - NET_WriteInt8(startpacket, clients[i].player_number); + settings.consoleplayer = clients[i].player_number; + NET_WriteSettings(startpacket, &settings); } diff --git a/src/net_structrw.c b/src/net_structrw.c index 01933ebb..7380e334 100644 --- a/src/net_structrw.c +++ b/src/net_structrw.c @@ -30,6 +30,22 @@ #include "net_packet.h" #include "net_structrw.h" +void NET_WriteConnectData(net_packet_t *packet, net_connect_data_t *data) +{ + NET_WriteInt8(packet, data->gamemode); + NET_WriteInt8(packet, data->gamemission); + NET_WriteInt8(packet, data->lowres_turn); + NET_WriteInt8(packet, data->drone); +} + +boolean NET_ReadConnectData(net_packet_t *packet, net_connect_data_t *data) +{ + return NET_ReadInt8(packet, (unsigned int *) &data->gamemode) + && NET_ReadInt8(packet, (unsigned int *) &data->gamemission) + && NET_ReadInt8(packet, (unsigned int *) &data->lowres_turn) + && NET_ReadInt8(packet, (unsigned int *) &data->drone); +} + void NET_WriteSettings(net_packet_t *packet, net_gamesettings_t *settings) { NET_WriteInt8(packet, settings->ticdup); @@ -46,6 +62,8 @@ void NET_WriteSettings(net_packet_t *packet, net_gamesettings_t *settings) NET_WriteInt8(packet, settings->new_sync); NET_WriteInt32(packet, settings->timelimit); NET_WriteInt8(packet, settings->loadgame); + NET_WriteInt8(packet, settings->num_players); + NET_WriteInt8(packet, settings->consoleplayer); } boolean NET_ReadSettings(net_packet_t *packet, net_gamesettings_t *settings) @@ -63,7 +81,9 @@ boolean NET_ReadSettings(net_packet_t *packet, net_gamesettings_t *settings) && NET_ReadInt8(packet, (unsigned int *) &settings->lowres_turn) && NET_ReadInt8(packet, (unsigned int *) &settings->new_sync) && NET_ReadInt32(packet, (unsigned int *) &settings->timelimit) - && NET_ReadSInt8(packet, (signed int *) &settings->loadgame); + && NET_ReadSInt8(packet, (signed int *) &settings->loadgame) + && NET_ReadInt8(packet, (unsigned int *) &settings->num_players) + && NET_ReadSInt8(packet, (signed int *) &settings->consoleplayer); } boolean NET_ReadQueryData(net_packet_t *packet, net_querydata_t *query) diff --git a/src/net_structrw.h b/src/net_structrw.h index 13209778..68971cd3 100644 --- a/src/net_structrw.h +++ b/src/net_structrw.h @@ -26,6 +26,9 @@ #include "net_defs.h" #include "net_packet.h" +void NET_WriteConnectData(net_packet_t *packet, net_connect_data_t *data); +boolean NET_ReadConnectData(net_packet_t *packet, net_connect_data_t *data); + extern void NET_WriteSettings(net_packet_t *packet, net_gamesettings_t *settings); extern boolean NET_ReadSettings(net_packet_t *packet, net_gamesettings_t *settings); -- cgit v1.2.3 From b03de59700f80c75308849ac5f89310d010af066 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 21 Nov 2010 15:44:43 +0000 Subject: Add -8in32 command line parameter to make the game run in 32-bit color mode, scaling up into an intermediate 8-bit buffer first. This should help with the palette problems experienced by Windows Vista/7 users. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2164 --- src/i_video.c | 98 ++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 67 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/i_video.c b/src/i_video.c index ee10a12e..1139157d 100644 --- a/src/i_video.c +++ b/src/i_video.c @@ -93,6 +93,12 @@ char *video_driver = ""; static SDL_Surface *screen; +// Intermediate 8-bit buffer that we draw to instead of 'screen'. +// This is used when we are rendering in 32-bit screen mode. +// When in a real 8-bit screen mode, screenbuffer == screen. + +static SDL_Surface *screenbuffer; + // palette static SDL_Color palette[256]; @@ -750,17 +756,18 @@ static boolean BlitArea(int x1, int y1, int x2, int y2) return true; } - x_offset = (screen->w - screen_mode->width) / 2; - y_offset = (screen->h - screen_mode->height) / 2; + x_offset = (screenbuffer->w - screen_mode->width) / 2; + y_offset = (screenbuffer->h - screen_mode->height) / 2; - if (SDL_LockSurface(screen) >= 0) + if (SDL_LockSurface(screenbuffer) >= 0) { - I_InitScale(screens[0], - (byte *) screen->pixels + (y_offset * screen->pitch) - + x_offset, - screen->pitch); + I_InitScale(screens[0], + (byte *) screenbuffer->pixels + + (y_offset * screenbuffer->pitch) + + x_offset, + screenbuffer->pitch); result = screen_mode->DrawScreen(x1, y1, x2, y2); - SDL_UnlockSurface(screen); + SDL_UnlockSurface(screenbuffer); } else { @@ -895,19 +902,30 @@ void I_FinishUpdate (void) // draw to screen BlitArea(0, 0, SCREENWIDTH, SCREENHEIGHT); - - // If we have a palette to set, the act of setting the palette - // updates the screen if (palette_to_set) { - SDL_SetColors(screen, palette, 0, 256); + SDL_SetColors(screenbuffer, palette, 0, 256); palette_to_set = false; + + // In native 8-bit mode, if we have a palette to set, the act + // of setting the palette updates the screen + + if (screenbuffer == screen) + { + return; + } } - else + + // In 8in32 mode, we must blit from the fake 8-bit screen buffer + // to the real screen before doing a screen flip. + + if (screenbuffer != screen) { - SDL_Flip(screen); + SDL_BlitSurface(screenbuffer, NULL, screen, NULL); } + + SDL_Flip(screen); } @@ -1540,6 +1558,7 @@ static void SetVideoMode(screen_mode_t *mode, int w, int h) { byte *doompal; int flags = 0; + int bpp = 8; doompal = W_CacheLumpName(DEH_String("PLAYPAL"), PU_CACHE); @@ -1552,7 +1571,16 @@ static void SetVideoMode(screen_mode_t *mode, int w, int h) // Set the video mode. - flags |= SDL_SWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF; + flags |= SDL_SWSURFACE; + + if (M_CheckParm("-8in32")) + { + bpp = 32; + } + else + { + flags |= SDL_HWPALETTE | SDL_DOUBLEBUF; + } if (fullscreen) { @@ -1563,11 +1591,23 @@ static void SetVideoMode(screen_mode_t *mode, int w, int h) flags |= SDL_RESIZABLE; } - screen = SDL_SetVideoMode(w, h, 8, flags); + screen = SDL_SetVideoMode(w, h, bpp, flags); if (screen == NULL) { - I_Error("Error setting video mode: %s\n", SDL_GetError()); + I_Error("Error setting video mode %ix%ix%ibpp: %s\n", + w, h, bpp, SDL_GetError()); + } + + if (screen->format->BitsPerPixel == 8) + { + screenbuffer = screen; + } + else + { + screenbuffer = SDL_CreateRGBSurface(SDL_SWSURFACE, + screen->w, screen->h, 8, + 0, 0, 0, 0); } // If mode was not set, it must be set now that we know the @@ -1708,24 +1748,19 @@ void I_InitGraphics(void) // Start with a clear black screen // (screen will be flipped after we set the palette) - if (SDL_LockSurface(screen) >= 0) - { - byte *screenpixels; - int y; - - screenpixels = (byte *) screen->pixels; - - for (y=0; yh; ++y) - memset(screenpixels + screen->pitch * y, 0, screen->w); - - SDL_UnlockSurface(screen); - } + SDL_FillRect(screenbuffer, NULL, 0); // Set the palette doompal = W_CacheLumpName(DEH_String("PLAYPAL"), PU_CACHE); I_SetPalette(doompal); - SDL_SetColors(screen, palette, 0, 256); + SDL_SetColors(screenbuffer, palette, 0, 256); + + if (screen != screenbuffer) + { + SDL_BlitSurface(screenbuffer, NULL, screen, NULL); + SDL_Flip(screen); + } CreateCursors(); @@ -1747,7 +1782,8 @@ void I_InitGraphics(void) // Likewise if the screen pitch is not the same as the width // If we have to multiply, drawing is done to a separate 320x200 buf - native_surface = !SDL_MUSTLOCK(screen) + native_surface = screen == screenbuffer + && !SDL_MUSTLOCK(screen) && screen_mode == &mode_scale_1x && screen->pitch == SCREENWIDTH && aspect_ratio_correct; -- cgit v1.2.3 From cf82ce9d7bb8d71ae583753aab642c5ba4ee8d06 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 24 Nov 2010 08:09:48 +0000 Subject: Add workaround to stop freezeups with old versions of SDL_mixer. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2165 --- src/i_sdlsound.c | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/i_sdlsound.c b/src/i_sdlsound.c index a758289a..a26a81dd 100644 --- a/src/i_sdlsound.c +++ b/src/i_sdlsound.c @@ -53,6 +53,8 @@ #define MAX_SOUND_SLICE_TIME 70 /* ms */ #define NUM_CHANNELS 16 +static boolean setpanning_workaround = false; + static boolean sound_initialized = false; static Mix_Chunk sound_chunks[NUMSFX]; @@ -620,10 +622,19 @@ static void I_SDL_UpdateSoundParams(int handle, int vol, int sep) left = ((254 - sep) * vol) / 127; right = ((sep) * vol) / 127; + // SDL_mixer version 1.2.8 and earlier has a bug in the Mix_SetPanning + // function. A workaround is to call Mix_UnregisterAllEffects for + // the channel before calling it. This is undesirable as it may lead + // to the channel volumes resetting briefly. + + if (setpanning_workaround) + { + Mix_UnregisterAllEffects(handle); + } + Mix_SetPanning(handle, left, right); } - // // Starting a sound means adding it // to the current list of active sounds @@ -811,8 +822,34 @@ static boolean I_SDL_InitSound(void) } #endif + // SDL_mixer version 1.2.8 and earlier has a bug in the Mix_SetPanning + // function that can cause the game to lock up. If we're using an old + // version, we need to apply a workaround. But the workaround has its + // own drawbacks ... + + { + const SDL_version *mixer_version; + int v; + + mixer_version = Mix_Linked_Version(); + v = SDL_VERSIONNUM(mixer_version->major, + mixer_version->minor, + mixer_version->patch); + + if (v <= SDL_VERSIONNUM(1, 2, 8)) + { + setpanning_workaround = true; + fprintf(stderr, "\n" + "ATTENTION: You are using an old version of SDL_mixer!\n" + " This version has a bug that may cause " + "your sound to stutter.\n" + " Please upgrade to a newer version!\n" + "\n"); + } + } + Mix_AllocateChannels(NUM_CHANNELS); - + SDL_PauseAudio(0); sound_initialized = true; -- cgit v1.2.3 From 288d322c0b679675a80c0fc763b1063613c77ce5 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 24 Nov 2010 22:43:37 +0000 Subject: Add configuration file parameter and command line option to specify the screen pixel depth. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2166 --- src/i_video.c | 42 ++++++++++++++++++++++++++++++++++-------- src/i_video.h | 1 + src/m_config.c | 6 ++++++ 3 files changed, 41 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/i_video.c b/src/i_video.c index 1139157d..577b7415 100644 --- a/src/i_video.c +++ b/src/i_video.c @@ -126,6 +126,10 @@ static boolean native_surface; int screen_width = SCREENWIDTH; int screen_height = SCREENHEIGHT; +// Color depth. + +int screen_bpp = 8; + // Automatically adjust video settings if the selected mode is // not a valid video mode. @@ -1405,6 +1409,33 @@ static void CheckCommandLine(void) screen_height = atoi(myargv[i + 1]); } + //! + // @category video + // @arg + // + // Specify the color depth of the screen, in bits per pixel. + // + + i = M_CheckParm("-bpp"); + + if (i > 0) + { + screen_bpp = atoi(myargv[i + 1]); + } + + // Because we love Eternity: + + //! + // @category video + // + // Set the color depth of the screen to 32 bits per pixel. + // + + if (M_CheckParm("-8in32")) + { + screen_bpp = 32; + } + //! // @category video // @arg @@ -1558,7 +1589,6 @@ static void SetVideoMode(screen_mode_t *mode, int w, int h) { byte *doompal; int flags = 0; - int bpp = 8; doompal = W_CacheLumpName(DEH_String("PLAYPAL"), PU_CACHE); @@ -1573,11 +1603,7 @@ static void SetVideoMode(screen_mode_t *mode, int w, int h) flags |= SDL_SWSURFACE; - if (M_CheckParm("-8in32")) - { - bpp = 32; - } - else + if (screen_bpp == 8) { flags |= SDL_HWPALETTE | SDL_DOUBLEBUF; } @@ -1591,12 +1617,12 @@ static void SetVideoMode(screen_mode_t *mode, int w, int h) flags |= SDL_RESIZABLE; } - screen = SDL_SetVideoMode(w, h, bpp, flags); + screen = SDL_SetVideoMode(w, h, screen_bpp, flags); if (screen == NULL) { I_Error("Error setting video mode %ix%ix%ibpp: %s\n", - w, h, bpp, SDL_GetError()); + w, h, screen_bpp, SDL_GetError()); } if (screen->format->BitsPerPixel == 8) diff --git a/src/i_video.h b/src/i_video.h index 94ffcc29..44fe1cd2 100644 --- a/src/i_video.h +++ b/src/i_video.h @@ -89,6 +89,7 @@ extern char *video_driver; extern int autoadjust_video_settings; extern boolean screenvisible; extern int screen_width, screen_height; +extern int screen_bpp; extern int fullscreen; extern int aspect_ratio_correct; extern int grabmouse; diff --git a/src/m_config.c b/src/m_config.c index 2065700e..a4cacd95 100644 --- a/src/m_config.c +++ b/src/m_config.c @@ -615,6 +615,12 @@ static default_t extra_defaults_list[] = CONFIG_VARIABLE_INT(screen_height, screen_height), + //! + // Color depth of the screen, in bits. + // + + CONFIG_VARIABLE_INT(screen_bpp, screen_bpp), + //! // If this is non-zero, the mouse will be "grabbed" when running // in windowed mode so that it can be used as an input device. -- cgit v1.2.3 From 9de2b29cdc8e85c525589badc5af636005ca8e66 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 24 Nov 2010 23:34:18 +0000 Subject: Detect when running on Windows Vista or later, and switch to 32 bpp screen mode. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2167 --- src/m_config.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src') diff --git a/src/m_config.c b/src/m_config.c index a4cacd95..3abe7c63 100644 --- a/src/m_config.c +++ b/src/m_config.c @@ -1598,5 +1598,26 @@ void M_ApplyPlatformDefaults(void) } } #endif + + // Windows Vista or later? Set screen color depth to + // 32 bits per pixel, as 8-bit palettized screen modes + // don't work properly in recent versions. + +#if defined(_WIN32) && !defined(_WIN32_WCE) + { + OSVERSIONINFOEX version_info; + + ZeroMemory(&version_info, sizeof(OSVERSIONINFOEX)); + version_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + + GetVersionEx((OSVERSIONINFO *) &version_info); + + if (version_info.dwPlatformId == VER_PLATFORM_WIN32_NT + && version_info.dwMajorVersion >= 6) + { + screen_bpp = 32; + } + } +#endif } -- cgit v1.2.3 From ca81122db362eb01660598a4f3e980ed5274220d Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 26 Nov 2010 18:36:48 +0000 Subject: Turn double buffering on for non-palettized screen modes, as this may be the cause of screen tearing reports. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2169 --- src/i_video.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/i_video.c b/src/i_video.c index 577b7415..dab0e09d 100644 --- a/src/i_video.c +++ b/src/i_video.c @@ -1601,11 +1601,11 @@ static void SetVideoMode(screen_mode_t *mode, int w, int h) // Set the video mode. - flags |= SDL_SWSURFACE; + flags |= SDL_SWSURFACE | SDL_DOUBLEBUF; if (screen_bpp == 8) { - flags |= SDL_HWPALETTE | SDL_DOUBLEBUF; + flags |= SDL_HWPALETTE; } if (fullscreen) -- cgit v1.2.3 From 74c2dc333a383f27ebddf479e3b666a9068d6d36 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 26 Nov 2010 18:56:45 +0000 Subject: In non-palettized boxed screen modes, don't update the border areas of the screen. This is more CPU and memory efficient, and also fixes the "flashing border" bug when palette flashes occur. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2170 --- src/i_video.c | 45 ++++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/i_video.c b/src/i_video.c index dab0e09d..62c74b73 100644 --- a/src/i_video.c +++ b/src/i_video.c @@ -926,7 +926,14 @@ void I_FinishUpdate (void) if (screenbuffer != screen) { - SDL_BlitSurface(screenbuffer, NULL, screen, NULL); + SDL_Rect dst_rect; + + // Center the buffer within the full screen space. + + dst_rect.x = (screen->w - screenbuffer->w) / 2; + dst_rect.y = (screen->h - screenbuffer->h) / 2; + + SDL_BlitSurface(screenbuffer, NULL, screen, &dst_rect); } SDL_Flip(screen); @@ -1625,16 +1632,10 @@ static void SetVideoMode(screen_mode_t *mode, int w, int h) w, h, screen_bpp, SDL_GetError()); } - if (screen->format->BitsPerPixel == 8) - { - screenbuffer = screen; - } - else - { - screenbuffer = SDL_CreateRGBSurface(SDL_SWSURFACE, - screen->w, screen->h, 8, - 0, 0, 0, 0); - } + // Blank out the full screen area in case there is any junk in + // the borders that won't otherwise be overwritten. + + SDL_FillRect(screen, NULL, 0); // If mode was not set, it must be set now that we know the // screen size. @@ -1657,6 +1658,22 @@ static void SetVideoMode(screen_mode_t *mode, int w, int h) } } + // Create the screenbuffer surface; if we have a real 8-bit palettized + // screen, then we can use the screen as the screenbuffer. + + if (screen->format->BitsPerPixel == 8) + { + screenbuffer = screen; + } + else + { + screenbuffer = SDL_CreateRGBSurface(SDL_SWSURFACE, + mode->width, mode->height, 8, + 0, 0, 0, 0); + + SDL_FillRect(screenbuffer, NULL, 0); + } + // Save screen mode. screen_mode = mode; @@ -1782,12 +1799,6 @@ void I_InitGraphics(void) I_SetPalette(doompal); SDL_SetColors(screenbuffer, palette, 0, 256); - if (screen != screenbuffer) - { - SDL_BlitSurface(screenbuffer, NULL, screen, NULL); - SDL_Flip(screen); - } - CreateCursors(); UpdateFocus(); -- cgit v1.2.3 From 79446c49acfeb8b97fc535268cea4d9343cbaadf Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 27 Nov 2010 15:36:43 +0000 Subject: Fix -timer / -avg options to work like Vanilla when playing demos. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2171 --- src/d_main.c | 7 ++----- src/d_net.c | 20 +++++++++++++++----- src/p_spec.c | 5 ++--- 3 files changed, 19 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/d_main.c b/src/d_main.c index 671c4e9c..a5b38949 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1305,10 +1305,9 @@ void D_DoomMain (void) p = M_CheckParm ("-timer"); - if (p && p < myargc-1 && deathmatch) + if (p && p < myargc-1) { timelimit = atoi(myargv[p+1]); - printf("timer: %i\n", timelimit); } //! @@ -1320,10 +1319,8 @@ void D_DoomMain (void) p = M_CheckParm ("-avg"); - if (p && p < myargc-1 && deathmatch) + if (p && p < myargc-1) { - DEH_printf("Austin Virtual Gaming: Levels will end " - "after 20 minutes\n"); timelimit = 20; } diff --git a/src/d_net.c b/src/d_net.c index faf47821..b8e34dec 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -378,12 +378,22 @@ void D_CheckNetGame (void) // Show players here; the server might have specified a time limit - if (timelimit > 0) + if (timelimit > 0 && deathmatch) { - DEH_printf("Levels will end after %d minute", timelimit); - if (timelimit > 1) - printf("s"); - printf(".\n"); + // Gross hack to work like Vanilla: + + if (timelimit == 20 && M_CheckParm("-avg")) + { + DEH_printf("Austin Virtual Gaming: Levels will end " + "after 20 minutes\n"); + } + else + { + DEH_printf("Levels will end after %d minute", timelimit); + if (timelimit > 1) + printf("s"); + printf(".\n"); + } } } diff --git a/src/p_spec.c b/src/p_spec.c index 37beb850..fa3ec335 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1389,10 +1389,9 @@ void P_SpawnSpecials (void) if (W_CheckNumForName(DEH_String("texture2")) >= 0) episode = 2; - // See if -TIMER was specified. - if (timelimit > 0) + if (timelimit > 0 && deathmatch) { levelTimer = true; levelTimeCount = timelimit * 60 * TICRATE; @@ -1401,7 +1400,7 @@ void P_SpawnSpecials (void) { levelTimer = false; } - + // Init special SECTORs. sector = sectors; for (i=0 ; iindex = i; - // Hook into hash table + // Vanilla Doom does a linear search of the texures array + // and stops at the first entry it finds. If there are two + // entries with the same name, the first one in the array + // wins. The new entry must therefore be added at the end + // of the hash chain, so that earlier entries win. key = W_LumpNameHash(textures[i]->name) % numtextures; - textures[i]->next = textures_hashtable[key]; - textures_hashtable[key] = textures[i]; + rover = &textures_hashtable[key]; + + while (*rover != NULL) + { + rover = &(*rover)->next; + } + + // Hook into hash table + + textures[i]->next = NULL; + *rover = textures[i]; } } -- cgit v1.2.3 From 6307e5e2519c165ea0c9496849e8013cd92315e1 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 29 Nov 2010 20:18:10 +0000 Subject: Auto-adjust the screen color depth if the configured color depth is not supported by the hardware. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2174 --- src/i_video.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/i_video.c b/src/i_video.c index 62c74b73..488c08a0 100644 --- a/src/i_video.c +++ b/src/i_video.c @@ -1207,15 +1207,61 @@ static void AutoAdjustWindowed(void) } } +// Auto-adjust to a valid color depth. + +static void AutoAdjustColorDepth(void) +{ + SDL_Rect **modes; + SDL_PixelFormat format; + const SDL_VideoInfo *info; + int flags; + + if (fullscreen) + { + flags = SDL_FULLSCREEN; + } + else + { + flags = 0; + } + + format.BitsPerPixel = screen_bpp; + format.BytesPerPixel = (screen_bpp + 7) / 8; + + // Are any screen modes supported at the configured color depth? + + modes = SDL_ListModes(&format, flags); + + // If not, we must autoadjust to something sensible. + + if (modes == NULL) + { + printf("I_InitGraphics: %ibpp color depth not supported.\n", + screen_bpp); + + info = SDL_GetVideoInfo(); + + if (info != NULL && info->vfmt != NULL) + { + screen_bpp = info->vfmt->BitsPerPixel; + } + } +} + // If the video mode set in the configuration file is not available, // try to choose a different mode. static void I_AutoAdjustSettings(void) { - int old_screen_w, old_screen_h; + int old_screen_w, old_screen_h, old_screen_bpp; old_screen_w = screen_width; old_screen_h = screen_height; + old_screen_bpp = screen_bpp; + + // Possibly adjust color depth. + + AutoAdjustColorDepth(); // If we are running fullscreen, try to autoadjust to a valid fullscreen // mode. If this is impossible, switch to windowed. @@ -1234,10 +1280,11 @@ static void I_AutoAdjustSettings(void) // Have the settings changed? Show a message. - if (screen_width != old_screen_w || screen_height != old_screen_h) + if (screen_width != old_screen_w || screen_height != old_screen_h + || screen_bpp != old_screen_bpp) { - printf("I_InitGraphics: Auto-adjusted to %ix%i.\n", - screen_width, screen_height); + printf("I_InitGraphics: Auto-adjusted to %ix%ix%ibpp.\n", + screen_width, screen_height, screen_bpp); printf("NOTE: Your video settings have been adjusted. " "To disable this behavior,\n" -- cgit v1.2.3 From 9e54684b11cf8e8e4ae19ebd2d754ee472c70089 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Tue, 30 Nov 2010 20:00:06 +0000 Subject: Add support for HACX v1.2 IWAD file. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2176 --- src/d_iwad.c | 35 ++++++++++----- src/d_main.c | 18 +++++++- src/deh_io.c | 139 +++++++++++++++++++++++++++++++++++++++++++++++---------- src/deh_io.h | 1 + src/deh_main.c | 54 ++++++++++++++++++++-- src/deh_main.h | 2 + src/doomdef.h | 1 + src/m_menu.c | 2 + 8 files changed, 213 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/d_iwad.c b/src/d_iwad.c index ea0d29d0..89a7fba3 100644 --- a/src/d_iwad.c +++ b/src/d_iwad.c @@ -326,16 +326,22 @@ static struct {"doom.wad", doom}, {"doom1.wad", doom}, {"chex.wad", doom}, + {"hacx.wad", doom2}, }; - + // Hack for chex quest mode -static void CheckChex(char *iwad_name) +static void CheckSpecialIWADs(char *iwad_name) { - if (!strcmp(iwad_name, "chex.wad")) + if (!strcasecmp(iwad_name, "chex.wad")) { gameversion = exe_chex; } + + if (!strcasecmp(iwad_name, "hacx.wad")) + { + gameversion = exe_hacx; + } } // Returns true if the specified path is a path to a file @@ -408,7 +414,7 @@ static char *SearchDirectoryForIWAD(char *dir) if (filename != NULL) { - CheckChex(iwads[i].name); + CheckSpecialIWADs(iwads[i].name); gamemission = iwads[i].mission; return filename; @@ -441,7 +447,7 @@ static void IdentifyIWADByName(char *name) if (!strcasecmp(name + strlen(name) - strlen(iwadname), iwadname)) { - CheckChex(iwads[i].name); + CheckSpecialIWADs(iwads[i].name); gamemission = iwads[i].mission; break; } @@ -701,6 +707,13 @@ static char *SaveGameIWADName(void) return "chex.wad"; } + // Hacx hack + + if (gameversion == exe_hacx) + { + return "hacx.wad"; + } + // Find what subdirectory to use for savegames // // They should be stored in something like @@ -770,6 +783,10 @@ void D_SetSaveGameDir(void) static char *banners[] = { + // doom2.wad + " " + "DOOM 2: Hell on Earth v%i.%i" + " ", // doom1.wad " " "DOOM Shareware Startup v%i.%i" @@ -786,10 +803,6 @@ static char *banners[] = " " "The Ultimate DOOM Startup v%i.%i" " ", - // doom2.wad - " " - "DOOM 2: Hell on Earth v%i.%i" - " ", // tnt.wad " " "DOOM 2: TNT - Evilution v%i.%i" @@ -809,13 +822,13 @@ static char *GetGameName(char *gamename) { size_t i; char *deh_sub; - + for (i=0; i #include "i_system.h" +#include "w_wad.h" #include "z_zone.h" #include "deh_defs.h" #include "deh_io.h" +typedef enum +{ + DEH_INPUT_FILE, + DEH_INPUT_LUMP +} deh_input_type_t; + struct deh_context_s { - FILE *stream; + deh_input_type_t type; char *filename; + + // If the input comes from a memory buffer, pointer to the memory + // buffer. + + unsigned char *input_buffer; + size_t input_buffer_len; + unsigned int input_buffer_pos; + int lumpnum; + + // If the input comes from a file, the file stream for reading + // data. + + FILE *stream; + + // Current line number that we have reached: + int linenum; + + // Used by DEH_ReadLine: + boolean last_was_newline; char *readbuffer; int readbuffer_size; }; +static deh_context_t *DEH_NewContext(void) +{ + deh_context_t *context; + + context = Z_Malloc(sizeof(*context), PU_STATIC, NULL); + + // Initial read buffer size of 128 bytes + + context->readbuffer_size = 128; + context->readbuffer = Z_Malloc(context->readbuffer_size, PU_STATIC, NULL); + context->linenum = 0; + context->last_was_newline = true; + + return context; +} + // Open a dehacked file for reading // Returns NULL if open failed @@ -52,22 +94,41 @@ deh_context_t *DEH_OpenFile(char *filename) { FILE *fstream; deh_context_t *context; - + fstream = fopen(filename, "r"); if (fstream == NULL) return NULL; - context = Z_Malloc(sizeof(*context), PU_STATIC, NULL); + context = DEH_NewContext(); + + context->type = DEH_INPUT_FILE; context->stream = fstream; - - // Initial read buffer size of 128 bytes + context->filename = strdup(filename); - context->readbuffer_size = 128; - context->readbuffer = Z_Malloc(context->readbuffer_size, PU_STATIC, NULL); - context->filename = filename; - context->linenum = 0; - context->last_was_newline = true; + return context; +} + +// Open a WAD lump for reading. + +deh_context_t *DEH_OpenLump(int lumpnum) +{ + deh_context_t *context; + void *lump; + + lump = W_CacheLumpNum(lumpnum, PU_STATIC); + + context = DEH_NewContext(); + + context->type = DEH_INPUT_LUMP; + context->lumpnum = lumpnum; + context->input_buffer = lump; + context->input_buffer_len = W_LumpLength(lumpnum); + context->input_buffer_pos = 0; + + context->filename = malloc(9); + strncpy(context->filename, lumpinfo[lumpnum].name, 8); + context->filename[8] = '\0'; return context; } @@ -76,33 +137,65 @@ deh_context_t *DEH_OpenFile(char *filename) void DEH_CloseFile(deh_context_t *context) { - fclose(context->stream); + if (context->type == DEH_INPUT_FILE) + { + fclose(context->stream); + } + else if (context->type == DEH_INPUT_LUMP) + { + W_ReleaseLumpNum(context->lumpnum); + } + Z_Free(context->readbuffer); Z_Free(context); } +int DEH_GetCharFile(deh_context_t *context) +{ + if (feof(context->stream)) + { + // end of file + + return -1; + } + + return fgetc(context->stream); +} + +int DEH_GetCharLump(deh_context_t *context) +{ + int result; + + if (context->input_buffer_pos >= context->input_buffer_len) + { + return -1; + } + + result = context->input_buffer[context->input_buffer_pos]; + ++context->input_buffer_pos; + + return result; +} + // Reads a single character from a dehacked file int DEH_GetChar(deh_context_t *context) { int result; - + // Read characters, but ignore carriage returns // Essentially this is a DOS->Unix conversion - do + do { - if (feof(context->stream)) + switch (context->type) { - // end of file + case DEH_INPUT_FILE: + result = DEH_GetCharFile(context); - result = -1; + case DEH_INPUT_LUMP: + result = DEH_GetCharLump(context); } - else - { - result = fgetc(context->stream); - } - } while (result == '\r'); // Track the current line number @@ -111,9 +204,9 @@ int DEH_GetChar(deh_context_t *context) { ++context->linenum; } - + context->last_was_newline = result == '\n'; - + return result; } diff --git a/src/deh_io.h b/src/deh_io.h index 061a5a0e..9d22b360 100644 --- a/src/deh_io.h +++ b/src/deh_io.h @@ -30,6 +30,7 @@ #include "deh_defs.h" deh_context_t *DEH_OpenFile(char *filename); +deh_context_t *DEH_OpenLump(int lumpnum); void DEH_CloseFile(deh_context_t *context); int DEH_GetChar(deh_context_t *context); char *DEH_ReadLine(deh_context_t *context); diff --git a/src/deh_main.c b/src/deh_main.c index dcdfb00d..20498375 100644 --- a/src/deh_main.c +++ b/src/deh_main.c @@ -30,6 +30,7 @@ #include "doomtype.h" #include "d_iwad.h" #include "m_argv.h" +#include "w_wad.h" #include "deh_defs.h" #include "deh_io.h" @@ -281,9 +282,6 @@ static void DEH_ParseContext(deh_context_t *context) DEH_Error(context, "This is not a valid dehacked patch file!"); } - deh_allow_long_strings = false; - deh_allow_long_cheats = false; - // Read the file for (;;) @@ -295,7 +293,9 @@ static void DEH_ParseContext(deh_context_t *context) // end of file? if (line == NULL) + { return; + } while (line[0] != '\0' && isspace(line[0])) ++line; @@ -359,6 +359,11 @@ int DEH_LoadFile(char *filename) { deh_context_t *context; + // Vanilla dehacked files don't allow long string or cheat replacements. + + deh_allow_long_strings = false; + deh_allow_long_cheats = false; + printf(" loading %s\n", filename); context = DEH_OpenFile(filename); @@ -376,6 +381,48 @@ int DEH_LoadFile(char *filename) return 1; } +// Load dehacked file from WAD lump. + +int DEH_LoadLump(int lumpnum) +{ + deh_context_t *context; + + // If it's in a lump, it's probably designed for a modern source port, + // so allow it to do long string and cheat replacements. + + deh_allow_long_strings = true; + deh_allow_long_cheats = true; + + context = DEH_OpenLump(lumpnum); + + if (context == NULL) + { + fprintf(stderr, "DEH_LoadFile: Unable to open lump %i\n", lumpnum); + return 0; + } + + DEH_ParseContext(context); + + DEH_CloseFile(context); + + return 1; +} + +int DEH_LoadLumpByName(char *name) +{ + int lumpnum; + + lumpnum = W_CheckNumForName(name); + + if (lumpnum == -1) + { + fprintf(stderr, "DEH_LoadLumpByName: '%s' lump not found\n", name); + return 0; + } + + return DEH_LoadLump(lumpnum); +} + // Checks the command line for -deh argument void DEH_Init(void) @@ -418,4 +465,3 @@ void DEH_Init(void) } } - diff --git a/src/deh_main.h b/src/deh_main.h index 9248e982..4b58a1ad 100644 --- a/src/deh_main.h +++ b/src/deh_main.h @@ -42,6 +42,8 @@ void DEH_Init(void); int DEH_LoadFile(char *filename); +int DEH_LoadLump(int lumpnum); +int DEH_LoadLumpByName(char *name); boolean DEH_ParseAssignment(char *line, char **variable_name, char **value); diff --git a/src/doomdef.h b/src/doomdef.h index ff4d59a9..f9cd4fd9 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -104,6 +104,7 @@ typedef enum typedef enum { exe_doom_1_9, // Doom 1.9: used for shareware, registered and commercial + exe_hacx, // Hacx executable (Doom 1.9 with patch applied) exe_ultimate, // Ultimate Doom (retail) exe_final, // Final Doom exe_chex, // Chex Quest executable (based on Final Doom) diff --git a/src/m_menu.c b/src/m_menu.c index 5fb1ae7c..7b1c5a6e 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -784,6 +784,8 @@ void M_DrawReadThis1(void) switch (gameversion) { case exe_doom_1_9: + case exe_hacx: + if (gamemode == commercial) { // Doom 2 -- cgit v1.2.3 From b8db918b1d45aa8124a4953305edba550a52db6e Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Tue, 30 Nov 2010 20:44:20 +0000 Subject: Remove "-debugfile" command line option and associated variable. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2179 --- src/d_main.c | 10 ---------- src/d_net.c | 3 --- src/doomstat.h | 1 - src/p_setup.c | 12 +----------- 4 files changed, 1 insertion(+), 25 deletions(-) (limited to 'src') diff --git a/src/d_main.c b/src/d_main.c index 10eab2b0..378cc5f3 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -124,8 +124,6 @@ int startmap; boolean autostart; int startloadgame; -FILE* debugfile; - boolean advancedemo; // Store demo, do not accept any inputs @@ -399,14 +397,6 @@ void D_DoomLoop (void) if (demorecording) G_BeginRecording (); - if (M_CheckParm ("-debugfile")) - { - char filename[20]; - sprintf (filename,"debug%i.txt",consoleplayer); - printf ("debug output to: %s\n",filename); - debugfile = fopen (filename,"w"); - } - TryRunTics(); I_InitGraphics (); diff --git a/src/d_net.c b/src/d_net.c index b8e34dec..56f04876 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -405,9 +405,6 @@ void D_CheckNetGame (void) // void D_QuitNetGame (void) { - if (debugfile) - fclose (debugfile); - #ifdef FEATURE_MULTIPLAYER NET_SV_Shutdown(); diff --git a/src/doomstat.h b/src/doomstat.h index 4fc174cd..a0e21a25 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -258,7 +258,6 @@ extern int maxammo[NUMAMMO]; // File handling stuff. extern char * savegamedir; extern char basedefault[1024]; -extern FILE* debugfile; // if true, load all graphics at level load extern boolean precache; diff --git a/src/p_setup.c b/src/p_setup.c index 7d9d4318..3fc95cab 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -755,17 +755,7 @@ P_SetupLevel // Make sure all sounds are stopped before Z_FreeTags. S_Start (); - -#if 0 // UNUSED - if (debugfile) - { - Z_FreeTags (PU_LEVEL, INT_MAX); - Z_FileDumpHeap (debugfile); - } - else -#endif - Z_FreeTags (PU_LEVEL, PU_PURGELEVEL-1); - + Z_FreeTags (PU_LEVEL, PU_PURGELEVEL-1); // UNUSED W_Profile (); P_InitThinkers (); -- cgit v1.2.3 From 74034c0c1bd68fbc8c57daee922103f69c7ddf6d Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Tue, 30 Nov 2010 21:52:38 +0000 Subject: Oops. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2180 --- src/deh_io.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/deh_io.c b/src/deh_io.c index 12fc7d56..92c81632 100644 --- a/src/deh_io.c +++ b/src/deh_io.c @@ -192,9 +192,11 @@ int DEH_GetChar(deh_context_t *context) { case DEH_INPUT_FILE: result = DEH_GetCharFile(context); + break; case DEH_INPUT_LUMP: result = DEH_GetCharLump(context); + break; } } while (result == '\r'); -- cgit v1.2.3 From f9ab444cc614db3b2380d02750d142f9b17a8b90 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Thu, 2 Dec 2010 18:23:09 +0000 Subject: Register servers with Internet master server. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2181 --- src/Makefile.am | 1 + src/d_net.c | 1 + src/net_dedicated.c | 2 +- src/net_defs.h | 8 ++++++ src/net_query.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/net_query.h | 4 +++ src/net_server.c | 55 ++++++++++++++++++++++++++++++++++++++++- src/net_server.h | 4 +++ 8 files changed, 144 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 8b827131..26fe7c7d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -16,6 +16,7 @@ net_dedicated.c net_dedicated.h \ net_io.c net_io.h \ net_packet.c net_packet.h \ net_sdl.c net_sdl.h \ +net_query.c net_query.h \ net_server.c net_server.h \ net_structrw.c net_structrw.h \ z_native.c z_zone.h diff --git a/src/d_net.c b/src/d_net.c index 56f04876..bf9fbf2b 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -270,6 +270,7 @@ void D_CheckNetGame (void) NET_SV_Init(); NET_SV_AddModule(&net_loop_server_module); NET_SV_AddModule(&net_sdl_module); + NET_SV_RegisterWithMaster(); net_loop_client_module.InitClient(); addr = net_loop_client_module.ResolveAddress(NULL); diff --git a/src/net_dedicated.c b/src/net_dedicated.c index 6a153300..82909210 100644 --- a/src/net_dedicated.c +++ b/src/net_dedicated.c @@ -71,8 +71,8 @@ void NET_DedicatedServer(void) CheckForClientOptions(); NET_SV_Init(); - NET_SV_AddModule(&net_sdl_module); + NET_SV_RegisterWithMaster(); while (true) { diff --git a/src/net_defs.h b/src/net_defs.h index 66b17c77..d9e3b920 100644 --- a/src/net_defs.h +++ b/src/net_defs.h @@ -113,6 +113,14 @@ typedef enum NET_PACKET_TYPE_QUERY_RESPONSE, } net_packet_type_t; +typedef enum +{ + NET_MASTER_PACKET_TYPE_ADD, + NET_MASTER_PACKET_TYPE_ADD_RESPONSE, + NET_MASTER_PACKET_TYPE_QUERY, + NET_MASTER_PACKET_TYPE_QUERY_RESPONSE +} net_master_packet_type_t; + typedef struct { int ticdup; diff --git a/src/net_query.c b/src/net_query.c index 72650ac2..deb3744a 100644 --- a/src/net_query.c +++ b/src/net_query.c @@ -36,16 +36,86 @@ #include "net_structrw.h" #include "net_sdl.h" +#define MASTER_SERVER_ADDRESS "master.chocolate-doom.org" + typedef struct { net_addr_t *addr; net_querydata_t data; } queryresponse_t; +static boolean registered_with_master = false; + static net_context_t *query_context; static queryresponse_t *responders; static int num_responses; +// Resolve the master server address. + +net_addr_t *NET_Query_ResolveMaster(net_context_t *context) +{ + net_addr_t *addr; + + addr = NET_ResolveAddress(context, MASTER_SERVER_ADDRESS); + + if (addr == NULL) + { + fprintf(stderr, "Warning: Failed to resolve address " + "for master server: %s\n", MASTER_SERVER_ADDRESS); + } + + return addr; +} + +// Send a registration packet to the master server to register +// ourselves with the global list. + +void NET_Query_AddToMaster(net_addr_t *master_addr) +{ + net_packet_t *packet; + + packet = NET_NewPacket(10); + NET_WriteInt16(packet, NET_MASTER_PACKET_TYPE_ADD); + NET_SendPacket(master_addr, packet); + NET_FreePacket(packet); +} + +// Process a packet received from the master server. + +void NET_Query_MasterResponse(net_packet_t *packet) +{ + unsigned int packet_type; + unsigned int result; + + if (!NET_ReadInt16(packet, &packet_type) + || !NET_ReadInt16(packet, &result)) + { + return; + } + + if (packet_type == NET_MASTER_PACKET_TYPE_ADD_RESPONSE) + { + if (result != 0) + { + // Only show the message once. + + if (!registered_with_master) + { + printf("Registered with master server at %s\n", + MASTER_SERVER_ADDRESS); + registered_with_master = true; + } + } + else + { + // Always show rejections. + + printf("Failed to register with master server at %s\n", + MASTER_SERVER_ADDRESS); + } + } +} + // Add a new address to the list of hosts that has responded static queryresponse_t *AddResponder(net_addr_t *addr, @@ -319,3 +389,4 @@ void NET_LANQuery(void) exit(0); } + diff --git a/src/net_query.h b/src/net_query.h index f682d320..0ed098f1 100644 --- a/src/net_query.h +++ b/src/net_query.h @@ -31,5 +31,9 @@ extern void NET_QueryAddress(char *addr); extern void NET_LANQuery(void); extern net_addr_t *NET_FindLANServer(void); +net_addr_t *NET_Query_ResolveMaster(net_context_t *context); +void NET_Query_AddToMaster(net_addr_t *master_addr); +void NET_Query_MasterResponse(net_packet_t *packet); + #endif /* #ifndef NET_QUERY_H */ diff --git a/src/net_server.c b/src/net_server.c index 383608be..7b67ea56 100644 --- a/src/net_server.c +++ b/src/net_server.c @@ -40,10 +40,15 @@ #include "net_io.h" #include "net_loop.h" #include "net_packet.h" +#include "net_query.h" #include "net_server.h" #include "net_sdl.h" #include "net_structrw.h" +// How often to refresh our registration with the master server. + +#define MASTER_REFRESH_PERIOD 20 * 60 /* 20 minutes */ + typedef enum { // waiting for the game to start @@ -127,6 +132,11 @@ static unsigned int sv_gamemode; static unsigned int sv_gamemission; static net_gamesettings_t sv_settings; +// For registration with master server: + +static net_addr_t *master_server = NULL; +static unsigned int master_refresh_time; + // receive window static unsigned int recvwindow_start; @@ -1108,6 +1118,14 @@ static void NET_SV_Packet(net_packet_t *packet, net_addr_t *addr) net_client_t *client; unsigned int packet_type; + // Response from master server? + + if (addr != NULL && addr == master_server) + { + NET_Query_MasterResponse(packet); + return; + } + // Find which client this packet came from client = NET_SV_FindClient(addr); @@ -1513,6 +1531,32 @@ void NET_SV_Init(void) server_initialized = true; } +void NET_SV_RegisterWithMaster(void) +{ + //! + // When running a server, don't register with the global master server. + // + // @category net + // + + if (!M_CheckParm("-privateserver")) + { + master_server = NET_Query_ResolveMaster(server_context); + } + else + { + master_server = NULL; + } + + // Send request. + + if (master_server != NULL) + { + NET_Query_AddToMaster(master_server); + master_refresh_time = I_GetTimeMS(); + } +} + // Run server code to check for new packets/send packets as the server // requires @@ -1527,12 +1571,21 @@ void NET_SV_Run(void) return; } - while (NET_RecvPacket(server_context, &addr, &packet)) + while (NET_RecvPacket(server_context, &addr, &packet)) { NET_SV_Packet(packet, addr); NET_FreePacket(packet); } + // Possibly refresh our registration with the master server. + + if (master_server != NULL + && I_GetTimeMS() - master_refresh_time > MASTER_REFRESH_PERIOD * 1000) + { + NET_Query_AddToMaster(master_server); + master_refresh_time = I_GetTimeMS(); + } + // "Run" any clients that may have things to do, independent of responses // to received packets diff --git a/src/net_server.h b/src/net_server.h index 93b22fc3..1debbd79 100644 --- a/src/net_server.h +++ b/src/net_server.h @@ -41,5 +41,9 @@ void NET_SV_Shutdown(void); void NET_SV_AddModule(net_module_t *module); +// Register server with master server. + +void NET_SV_RegisterWithMaster(void); + #endif /* #ifndef NET_SERVER_H */ -- cgit v1.2.3 From bfbffcf197a5d78e90d463945d12c84d0f7deadf Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Thu, 2 Dec 2010 19:26:05 +0000 Subject: Refactor query code and add a -masterquery command line parameter to query the master server. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2182 --- src/d_main.c | 12 ++ src/net_query.c | 472 ++++++++++++++++++++++++++++++++++++++++++++------------ src/net_query.h | 7 +- 3 files changed, 388 insertions(+), 103 deletions(-) (limited to 'src') diff --git a/src/d_main.c b/src/d_main.c index 378cc5f3..22fdb142 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -843,6 +843,18 @@ void D_DoomMain (void) // Never returns } + //! + // @category net + // + // Query the Internet master server for a global list of active + // servers. + // + + if (M_CheckParm("-masterquery")) + { + NET_MasterQuery(); + } + //! // @arg
// @category net diff --git a/src/net_query.c b/src/net_query.c index deb3744a..681411c2 100644 --- a/src/net_query.c +++ b/src/net_query.c @@ -38,17 +38,40 @@ #define MASTER_SERVER_ADDRESS "master.chocolate-doom.org" -typedef struct +typedef enum { + QUERY_TARGET_SERVER, // Normal server target. + QUERY_TARGET_MASTER, // The master server. + QUERY_TARGET_BROADCAST // Send a broadcast query +} query_target_type_t; + +typedef enum +{ + QUERY_TARGET_QUEUED, // Query not yet sent + QUERY_TARGET_QUERIED, // Query sent, waiting response + QUERY_TARGET_RESPONDED, // Response received + QUERY_TARGET_TIMED_OUT +} query_target_state_t; + +typedef struct +{ + query_target_type_t type; + query_target_state_t state; net_addr_t *addr; net_querydata_t data; -} queryresponse_t; + unsigned int query_time; + boolean printed; +} query_target_t; + +// Transmit a query packet static boolean registered_with_master = false; static net_context_t *query_context; -static queryresponse_t *responders; -static int num_responses; +static query_target_t *targets; +static int num_targets; + +static boolean printed_header = false; // Resolve the master server address. @@ -116,40 +139,49 @@ void NET_Query_MasterResponse(net_packet_t *packet) } } -// Add a new address to the list of hosts that has responded +// Send a query to the master server. -static queryresponse_t *AddResponder(net_addr_t *addr, - net_querydata_t *data) +static void NET_Query_SendMasterQuery(net_addr_t *addr) { - queryresponse_t *response; - - responders = realloc(responders, - sizeof(queryresponse_t) * (num_responses + 1)); - - response = &responders[num_responses]; - response->addr = addr; - response->data = *data; - ++num_responses; + net_packet_t *packet; - return response; + packet = NET_NewPacket(10); + NET_WriteInt16(packet, NET_MASTER_PACKET_TYPE_QUERY); + NET_SendPacket(addr, packet); + NET_FreePacket(packet); } -// Returns true if the reply is from a host that has not previously -// responded. +// Given the specified address, find the target associated. If no +// target is found, and 'create' is true, a new target is created. -static boolean CheckResponder(net_addr_t *addr) +static query_target_t *GetTargetForAddr(net_addr_t *addr, boolean create) { + query_target_t *target; int i; - for (i=0; itype = QUERY_TARGET_SERVER; + target->state = QUERY_TARGET_QUEUED; + target->printed = false; + target->addr = addr; + ++num_targets; + + return target; } // Transmit a query packet @@ -173,20 +205,225 @@ static void NET_Query_SendQuery(net_addr_t *addr) NET_FreePacket(request); } +static void NET_Query_ParseResponse(net_addr_t *addr, net_packet_t *packet) +{ + unsigned int packet_type; + net_querydata_t querydata; + query_target_t *target; + + // Read the header + + if (!NET_ReadInt16(packet, &packet_type) + || packet_type != NET_PACKET_TYPE_QUERY_RESPONSE) + { + return; + } + + // Read query data + + if (!NET_ReadQueryData(packet, &querydata)) + { + return; + } + + // Find the target that responded, or potentially add a new target + // if it was not already known (for LAN broadcast search) + + target = GetTargetForAddr(addr, true); + + target->state = QUERY_TARGET_RESPONDED; + memcpy(&target->data, &querydata, sizeof(net_querydata_t)); +} + +// Parse a response packet from the master server. + +static void NET_Query_ParseMasterResponse(net_addr_t *master_addr, + net_packet_t *packet) +{ + unsigned int packet_type; + query_target_t *target; + char *addr_str; + net_addr_t *addr; + + // Read the header. We are only interested in query responses. + + if (!NET_ReadInt16(packet, &packet_type) + || packet_type != NET_MASTER_PACKET_TYPE_QUERY_RESPONSE) + { + return; + } + + // Read a list of strings containing the addresses of servers + // that the master knows about. + + for (;;) + { + addr_str = NET_ReadString(packet); + + if (addr_str == NULL) + { + break; + } + + // Resolve address and add to targets list if it is not already + // there. + + addr = NET_ResolveAddress(query_context, addr_str); + + if (addr != NULL) + { + GetTargetForAddr(addr, true); + } + } + + // Mark the master as having responded. + + target = GetTargetForAddr(master_addr, true); + target->state = QUERY_TARGET_RESPONDED; +} + +static void NET_Query_ParsePacket(net_addr_t *addr, net_packet_t *packet) +{ + query_target_t *target; + + // This might be the master server responding. + + target = GetTargetForAddr(addr, false); + + if (target != NULL && target->type == QUERY_TARGET_MASTER) + { + NET_Query_ParseMasterResponse(addr, packet); + } + else + { + NET_Query_ParseResponse(addr, packet); + } +} + +static void NET_Query_GetResponse(void) +{ + net_addr_t *addr; + net_packet_t *packet; + + if (NET_RecvPacket(query_context, &addr, &packet)) + { + NET_Query_ParsePacket(addr, packet); + NET_FreePacket(packet); + } +} + +// Find a target we have not yet queried and send a query. + +static void SendOneQuery(void) +{ + unsigned int i; + + for (i = 0; i < num_targets; ++i) + { + if (targets[i].state == QUERY_TARGET_QUEUED) + { + break; + } + } + + if (i >= num_targets) + { + return; + } + + // Found a target to query. Send a query; how to do this depends on + // the target type. + + switch (targets[i].type) + { + case QUERY_TARGET_SERVER: + NET_Query_SendQuery(targets[i].addr); + break; + + case QUERY_TARGET_BROADCAST: + NET_Query_SendQuery(NULL); + break; + + case QUERY_TARGET_MASTER: + NET_Query_SendMasterQuery(targets[i].addr); + break; + } + + //printf("Queried %s\n", NET_AddrToString(targets[i].addr)); + targets[i].state = QUERY_TARGET_QUERIED; + targets[i].query_time = I_GetTimeMS(); +} + +// Search the targets list and find a target that has responded. +// If none have responded yet, returns NULL. + +static query_target_t *FindFirstResponder(void) +{ + unsigned int i; + + for (i = 0; i < num_targets; ++i) + { + if (targets[i].type == QUERY_TARGET_SERVER + && targets[i].state == QUERY_TARGET_RESPONDED) + { + return &targets[i]; + } + } + + return NULL; +} + +// Time out servers that have been queried and not responded. + +static void CheckTargetTimeouts(void) +{ + unsigned int i; + unsigned int now; + + now = I_GetTimeMS(); + + for (i = 0; i < num_targets; ++i) + { + if (targets[i].state == QUERY_TARGET_QUERIED + && now - targets[i].query_time > 5000) + { + targets[i].state = QUERY_TARGET_TIMED_OUT; + } + } +} + +// If all targets have responded or timed out, returns true. + +static boolean AllTargetsDone(void) +{ + unsigned int i; + + for (i = 0; i < num_targets; ++i) + { + if (targets[i].state != QUERY_TARGET_RESPONDED + && targets[i].state != QUERY_TARGET_TIMED_OUT) + { + return false; + } + } + + return true; +} + static void formatted_printf(int wide, char *s, ...) { va_list args; int i; - + va_start(args, s); i = vprintf(s, args); va_end(args); - while (i < wide) + while (i < wide) { putchar(' '); ++i; - } + } } static char *GameDescription(GameMode_t mode, GameMission_t mission) @@ -224,115 +461,104 @@ static void PrintHeader(void) putchar('\n'); } -static void PrintResponse(queryresponse_t *response) +static void PrintResponse(query_target_t *target) { - formatted_printf(18, "%s: ", NET_AddrToString(response->addr)); - formatted_printf(8, "%i/%i", response->data.num_players, - response->data.max_players); + formatted_printf(18, "%s: ", NET_AddrToString(target->addr)); + formatted_printf(8, "%i/%i", target->data.num_players, + target->data.max_players); - if (response->data.gamemode != indetermined) + if (target->data.gamemode != indetermined) { - printf("(%s) ", GameDescription(response->data.gamemode, - response->data.gamemission)); + printf("(%s) ", GameDescription(target->data.gamemode, + target->data.gamemission)); } - if (response->data.server_state) + if (target->data.server_state) { printf("(game running) "); } - NET_SafePuts(response->data.description); + NET_SafePuts(target->data.description); } -static void NET_Query_ParsePacket(net_addr_t *addr, net_packet_t *packet) -{ - unsigned int packet_type; - net_querydata_t querydata; - queryresponse_t *response; - - // Have we already received a packet from this host? +// Check for printing information about servers that have responded. - if (!CheckResponder(addr)) - { - return; - } - - // Read the header - - if (!NET_ReadInt16(packet, &packet_type) - || packet_type != NET_PACKET_TYPE_QUERY_RESPONSE) - { - return; - } - - // Read query data - - if (!NET_ReadQueryData(packet, &querydata)) - { - return; - } +static void CheckPrintOutput(void) +{ + unsigned int i; - if (num_responses <= 0) + for (i = 0; i < num_targets; ++i) { - // If this is the first response, print the table header + if (targets[i].type == QUERY_TARGET_SERVER + && targets[i].state == QUERY_TARGET_RESPONDED + && !targets[i].printed) + { + if (!printed_header) + { + PrintHeader(); + printed_header = true; + } - PrintHeader(); + PrintResponse(&targets[i]); + targets[i].printed = true; + } } - - response = AddResponder(addr, &querydata); - - PrintResponse(response); } -static void NET_Query_GetResponse(void) -{ - net_addr_t *addr; - net_packet_t *packet; +// Loop waiting for responses. - if (NET_RecvPacket(query_context, &addr, &packet)) - { - NET_Query_ParsePacket(addr, packet); - NET_FreePacket(packet); - } -} - -static net_addr_t *NET_Query_QueryLoop(net_addr_t *addr, - boolean find_one) +static net_addr_t *NET_Query_QueryLoop(boolean find_first, + boolean silent) { + query_target_t *responder; int start_time; int last_send_time; last_send_time = -1; start_time = I_GetTimeMS(); - while (I_GetTimeMS() < start_time + 5000) + while (!AllTargetsDone()) { - // Send a query once every second + // Send a query. This will only send a single query. + // Because of the delay below, this is therefore rate limited. - if (last_send_time < 0 || I_GetTimeMS() > last_send_time + 1000) - { - NET_Query_SendQuery(addr); - last_send_time = I_GetTimeMS(); - } + SendOneQuery(); // Check for a response NET_Query_GetResponse(); + // Output the responses + + if (!silent) + { + CheckPrintOutput(); + } + // Found a response? - if (find_one && num_responses > 0) + if (find_first && FindFirstResponder()) + { break; - + } + // Don't thrash the CPU - + I_Sleep(100); + + CheckTargetTimeouts(); } - if (num_responses > 0) - return responders[0].addr; + responder = FindFirstResponder(); + + if (responder != NULL) + { + return responder->addr; + } else + { return NULL; + } } void NET_Query_Init(void) @@ -341,14 +567,16 @@ void NET_Query_Init(void) NET_AddModule(query_context, &net_sdl_module); net_sdl_module.InitClient(); - responders = NULL; - num_responses = 0; + targets = NULL; + num_targets = 0; + + printed_header = false; } void NET_QueryAddress(char *addr) { net_addr_t *net_addr; - + NET_Query_Init(); net_addr = NET_ResolveAddress(query_context, addr); @@ -358,9 +586,13 @@ void NET_QueryAddress(char *addr) I_Error("NET_QueryAddress: Host '%s' not found!", addr); } + // Add the address to the list of targets. + + GetTargetForAddr(net_addr, true); + printf("\nQuerying '%s'...\n\n", addr); - if (!NET_Query_QueryLoop(net_addr, true)) + if (!NET_Query_QueryLoop(true, false)) { I_Error("No response from '%s'", addr); } @@ -370,18 +602,32 @@ void NET_QueryAddress(char *addr) net_addr_t *NET_FindLANServer(void) { + query_target_t *target; + NET_Query_Init(); - return NET_Query_QueryLoop(NULL, true); + // Add a broadcast target to the list. + + target = GetTargetForAddr(NULL, true); + target->type = QUERY_TARGET_BROADCAST; + + return NET_Query_QueryLoop(true, true); } void NET_LANQuery(void) { + query_target_t *target; + NET_Query_Init(); printf("\nSearching for servers on local LAN ...\n\n"); - if (!NET_Query_QueryLoop(NULL, false)) + // Add a broadcast target to the list. + + target = GetTargetForAddr(NULL, true); + target->type = QUERY_TARGET_BROADCAST; + + if (!NET_Query_QueryLoop(false, false)) { I_Error("No servers found"); } @@ -389,4 +635,30 @@ void NET_LANQuery(void) exit(0); } +void NET_MasterQuery(void) +{ + net_addr_t *master; + query_target_t *target; + + NET_Query_Init(); + + printf("\nSearching for servers on Internet ...\n\n"); + + // Resolve master address and add to targets list. + + master = NET_Query_ResolveMaster(query_context); + + if (master == NULL) + { + I_Error("Failed to resolve master server address"); + } + + target = GetTargetForAddr(master, true); + target->type = QUERY_TARGET_MASTER; + + if (!NET_Query_QueryLoop(false, false)) + { + I_Error("No servers found"); + } +} diff --git a/src/net_query.h b/src/net_query.h index 0ed098f1..21c89ecb 100644 --- a/src/net_query.h +++ b/src/net_query.h @@ -30,10 +30,11 @@ extern void NET_QueryAddress(char *addr); extern void NET_LANQuery(void); extern net_addr_t *NET_FindLANServer(void); +extern void NET_MasterQuery(void); -net_addr_t *NET_Query_ResolveMaster(net_context_t *context); -void NET_Query_AddToMaster(net_addr_t *master_addr); -void NET_Query_MasterResponse(net_packet_t *packet); +extern net_addr_t *NET_Query_ResolveMaster(net_context_t *context); +extern void NET_Query_AddToMaster(net_addr_t *master_addr); +extern void NET_Query_MasterResponse(net_packet_t *packet); #endif /* #ifndef NET_QUERY_H */ -- cgit v1.2.3 From b11030cbfee0d4d4a46673001992e94abc146c8c Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Thu, 2 Dec 2010 20:11:24 +0000 Subject: More refactoring of querying code, to not be specific to the purpose of printing out a list. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2184 --- src/d_main.c | 13 +- src/net_query.c | 372 ++++++++++++++++++++++++++++++-------------------------- src/net_query.h | 11 +- 3 files changed, 218 insertions(+), 178 deletions(-) (limited to 'src') diff --git a/src/d_main.c b/src/d_main.c index 22fdb142..c0804b5d 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -852,7 +852,10 @@ void D_DoomMain (void) if (M_CheckParm("-masterquery")) { - NET_MasterQuery(); + printf("\nSearching for servers on Internet ...\n\n"); + p = NET_MasterQuery(NET_QueryPrintCallback, NULL); + printf("%i server(s) found.\n", p); + exit(0); } //! @@ -868,6 +871,7 @@ void D_DoomMain (void) if (p > 0) { NET_QueryAddress(myargv[p+1]); + exit(0); } //! @@ -877,7 +881,12 @@ void D_DoomMain (void) // if (M_CheckParm("-search")) - NET_LANQuery(); + { + printf("\nSearching for servers on local LAN ...\n"); + p = NET_LANQuery(NET_QueryPrintCallback, NULL); + printf("\n%i server(s) found.\n", p); + exit(0); + } #endif diff --git a/src/net_query.c b/src/net_query.c index 681411c2..3dee1b00 100644 --- a/src/net_query.c +++ b/src/net_query.c @@ -71,6 +71,7 @@ static net_context_t *query_context; static query_target_t *targets; static int num_targets; +static boolean query_loop_running = false; static boolean printed_header = false; // Resolve the master server address. @@ -205,7 +206,9 @@ static void NET_Query_SendQuery(net_addr_t *addr) NET_FreePacket(request); } -static void NET_Query_ParseResponse(net_addr_t *addr, net_packet_t *packet) +static void NET_Query_ParseResponse(net_addr_t *addr, net_packet_t *packet, + net_query_callback_t callback, + void *user_data) { unsigned int packet_type; net_querydata_t querydata; @@ -231,8 +234,15 @@ static void NET_Query_ParseResponse(net_addr_t *addr, net_packet_t *packet) target = GetTargetForAddr(addr, true); - target->state = QUERY_TARGET_RESPONDED; - memcpy(&target->data, &querydata, sizeof(net_querydata_t)); + if (target->state != QUERY_TARGET_RESPONDED) + { + target->state = QUERY_TARGET_RESPONDED; + memcpy(&target->data, &querydata, sizeof(net_querydata_t)); + + // Invoke callback to signal that we have a new address. + + callback(addr, &target->data, user_data); + } } // Parse a response packet from the master server. @@ -282,7 +292,9 @@ static void NET_Query_ParseMasterResponse(net_addr_t *master_addr, target->state = QUERY_TARGET_RESPONDED; } -static void NET_Query_ParsePacket(net_addr_t *addr, net_packet_t *packet) +static void NET_Query_ParsePacket(net_addr_t *addr, net_packet_t *packet, + net_query_callback_t callback, + void *user_data) { query_target_t *target; @@ -296,18 +308,19 @@ static void NET_Query_ParsePacket(net_addr_t *addr, net_packet_t *packet) } else { - NET_Query_ParseResponse(addr, packet); + NET_Query_ParseResponse(addr, packet, callback, user_data); } } -static void NET_Query_GetResponse(void) +static void NET_Query_GetResponse(net_query_callback_t callback, + void *user_data) { net_addr_t *addr; net_packet_t *packet; if (NET_RecvPacket(query_context, &addr, &packet)) { - NET_Query_ParsePacket(addr, packet); + NET_Query_ParsePacket(addr, packet, callback, user_data); NET_FreePacket(packet); } } @@ -354,25 +367,6 @@ static void SendOneQuery(void) targets[i].query_time = I_GetTimeMS(); } -// Search the targets list and find a target that has responded. -// If none have responded yet, returns NULL. - -static query_target_t *FindFirstResponder(void) -{ - unsigned int i; - - for (i = 0; i < num_targets; ++i) - { - if (targets[i].type == QUERY_TARGET_SERVER - && targets[i].state == QUERY_TARGET_RESPONDED) - { - return &targets[i]; - } - } - - return NULL; -} - // Time out servers that have been queried and not responded. static void CheckTargetTimeouts(void) @@ -410,197 +404,165 @@ static boolean AllTargetsDone(void) return true; } -static void formatted_printf(int wide, char *s, ...) -{ - va_list args; - int i; - - va_start(args, s); - i = vprintf(s, args); - va_end(args); +// Stop the query loop - while (i < wide) - { - putchar(' '); - ++i; - } +static void NET_Query_ExitLoop(void) +{ + query_loop_running = false; } -static char *GameDescription(GameMode_t mode, GameMission_t mission) +// Loop waiting for responses. +// The specified callback is invoked when a new server responds. + +static void NET_Query_QueryLoop(net_query_callback_t callback, + void *user_data) { - switch (mode) + query_loop_running = true; + + while (query_loop_running && !AllTargetsDone()) { - case shareware: - return "shareware"; - case registered: - return "registered"; - case retail: - return "ultimate"; - case commercial: - if (mission == doom2) - return "doom2"; - else if (mission == pack_tnt) - return "tnt"; - else if (mission == pack_plut) - return "plutonia"; - default: - return "unknown"; - } -} + // Send a query. This will only send a single query. + // Because of the delay below, this is therefore rate limited. -static void PrintHeader(void) -{ - int i; + SendOneQuery(); - formatted_printf(18, "Address"); - formatted_printf(8, "Players"); - puts("Description"); + // Check for a response - for (i=0; i<70; ++i) - putchar('='); - putchar('\n'); + NET_Query_GetResponse(callback, user_data); + + // Don't thrash the CPU + + I_Sleep(100); + + CheckTargetTimeouts(); + } } -static void PrintResponse(query_target_t *target) +void NET_Query_Init(void) { - formatted_printf(18, "%s: ", NET_AddrToString(target->addr)); - formatted_printf(8, "%i/%i", target->data.num_players, - target->data.max_players); + query_context = NET_NewContext(); + NET_AddModule(query_context, &net_sdl_module); + net_sdl_module.InitClient(); - if (target->data.gamemode != indetermined) - { - printf("(%s) ", GameDescription(target->data.gamemode, - target->data.gamemission)); - } + targets = NULL; + num_targets = 0; - if (target->data.server_state) - { - printf("(game running) "); - } + printed_header = false; +} + +// Callback that exits the query loop when the first server is found. - NET_SafePuts(target->data.description); +static void NET_Query_ExitCallback(net_addr_t *addr, net_querydata_t *data, + void *user_data) +{ + NET_Query_ExitLoop(); } -// Check for printing information about servers that have responded. +// Search the targets list and find a target that has responded. +// If none have responded, returns NULL. -static void CheckPrintOutput(void) +static query_target_t *FindFirstResponder(void) { unsigned int i; for (i = 0; i < num_targets; ++i) { if (targets[i].type == QUERY_TARGET_SERVER - && targets[i].state == QUERY_TARGET_RESPONDED - && !targets[i].printed) + && targets[i].state == QUERY_TARGET_RESPONDED) { - if (!printed_header) - { - PrintHeader(); - printed_header = true; - } - - PrintResponse(&targets[i]); - targets[i].printed = true; + return &targets[i]; } } + + return NULL; } -// Loop waiting for responses. +// Return a count of the number of responses. -static net_addr_t *NET_Query_QueryLoop(boolean find_first, - boolean silent) +static int GetNumResponses(void) { - query_target_t *responder; - int start_time; - int last_send_time; + unsigned int i; + int result; - last_send_time = -1; - start_time = I_GetTimeMS(); + result = 0; - while (!AllTargetsDone()) + for (i = 0; i < num_targets; ++i) { - // Send a query. This will only send a single query. - // Because of the delay below, this is therefore rate limited. + if (targets[i].type == QUERY_TARGET_SERVER + && targets[i].state == QUERY_TARGET_RESPONDED) + { + ++result; + } + } - SendOneQuery(); + return result; +} - // Check for a response +void NET_QueryAddress(char *addr_str) +{ + net_addr_t *addr; + query_target_t *target; - NET_Query_GetResponse(); + NET_Query_Init(); - // Output the responses + addr = NET_ResolveAddress(query_context, addr_str); - if (!silent) - { - CheckPrintOutput(); - } + if (addr == NULL) + { + I_Error("NET_QueryAddress: Host '%s' not found!", addr_str); + } - // Found a response? + // Add the address to the list of targets. - if (find_first && FindFirstResponder()) - { - break; - } + target = GetTargetForAddr(addr, true); - // Don't thrash the CPU + printf("\nQuerying '%s'...\n", addr_str); - I_Sleep(100); + // Run query loop. - CheckTargetTimeouts(); - } + NET_Query_QueryLoop(NET_Query_ExitCallback, NULL); - responder = FindFirstResponder(); + // Check if the target responded. - if (responder != NULL) + if (target->state == QUERY_TARGET_RESPONDED) { - return responder->addr; + NET_QueryPrintCallback(addr, &target->data, NULL); } else { - return NULL; + I_Error("No response from '%s'", addr_str); } } -void NET_Query_Init(void) -{ - query_context = NET_NewContext(); - NET_AddModule(query_context, &net_sdl_module); - net_sdl_module.InitClient(); - - targets = NULL; - num_targets = 0; - - printed_header = false; -} - -void NET_QueryAddress(char *addr) +net_addr_t *NET_FindLANServer(void) { - net_addr_t *net_addr; + query_target_t *target; + query_target_t *responder; NET_Query_Init(); - net_addr = NET_ResolveAddress(query_context, addr); + // Add a broadcast target to the list. - if (net_addr == NULL) - { - I_Error("NET_QueryAddress: Host '%s' not found!", addr); - } + target = GetTargetForAddr(NULL, true); + target->type = QUERY_TARGET_BROADCAST; - // Add the address to the list of targets. + // Run the query loop, and stop at the first target found. - GetTargetForAddr(net_addr, true); + NET_Query_QueryLoop(NET_Query_ExitCallback, NULL); - printf("\nQuerying '%s'...\n\n", addr); + responder = FindFirstResponder(); - if (!NET_Query_QueryLoop(true, false)) + if (responder != NULL) { - I_Error("No response from '%s'", addr); + return responder->addr; + } + else + { + return NULL; } - - exit(0); } -net_addr_t *NET_FindLANServer(void) +int NET_LANQuery(net_query_callback_t callback, void *user_data) { query_target_t *target; @@ -611,54 +573,116 @@ net_addr_t *NET_FindLANServer(void) target = GetTargetForAddr(NULL, true); target->type = QUERY_TARGET_BROADCAST; - return NET_Query_QueryLoop(true, true); + NET_Query_QueryLoop(callback, user_data); + + return GetNumResponses(); } -void NET_LANQuery(void) +int NET_MasterQuery(net_query_callback_t callback, void *user_data) { + net_addr_t *master; query_target_t *target; NET_Query_Init(); - printf("\nSearching for servers on local LAN ...\n\n"); + // Resolve master address and add to targets list. - // Add a broadcast target to the list. + master = NET_Query_ResolveMaster(query_context); - target = GetTargetForAddr(NULL, true); - target->type = QUERY_TARGET_BROADCAST; + if (master == NULL) + { + return 0; + } + + target = GetTargetForAddr(master, true); + target->type = QUERY_TARGET_MASTER; - if (!NET_Query_QueryLoop(false, false)) + NET_Query_QueryLoop(callback, user_data); + + return GetNumResponses(); +} + +static void formatted_printf(int wide, char *s, ...) +{ + va_list args; + int i; + + va_start(args, s); + i = vprintf(s, args); + va_end(args); + + while (i < wide) { - I_Error("No servers found"); + putchar(' '); + ++i; } +} - exit(0); +static char *GameDescription(GameMode_t mode, GameMission_t mission) +{ + switch (mode) + { + case shareware: + return "shareware"; + case registered: + return "registered"; + case retail: + return "ultimate"; + case commercial: + if (mission == doom2) + return "doom2"; + else if (mission == pack_tnt) + return "tnt"; + else if (mission == pack_plut) + return "plutonia"; + default: + return "unknown"; + } } -void NET_MasterQuery(void) +static void PrintHeader(void) { - net_addr_t *master; - query_target_t *target; + int i; - NET_Query_Init(); + putchar('\n'); + formatted_printf(18, "Address"); + formatted_printf(8, "Players"); + puts("Description"); - printf("\nSearching for servers on Internet ...\n\n"); + for (i=0; i<70; ++i) + putchar('='); + putchar('\n'); +} - // Resolve master address and add to targets list. +// Callback function that just prints information in a table. - master = NET_Query_ResolveMaster(query_context); +void NET_QueryPrintCallback(net_addr_t *addr, + net_querydata_t *data, + void *user_data) +{ + // If this is the first server, print the header. - if (master == NULL) + if (!printed_header) { - I_Error("Failed to resolve master server address"); + PrintHeader(); + printed_header = true; } - target = GetTargetForAddr(master, true); - target->type = QUERY_TARGET_MASTER; + formatted_printf(18, "%s: ", NET_AddrToString(addr)); + formatted_printf(8, "%i/%i", data->num_players, + data->max_players); - if (!NET_Query_QueryLoop(false, false)) + if (data->gamemode != indetermined) { - I_Error("No servers found"); + printf("(%s) ", GameDescription(data->gamemode, + data->gamemission)); } + + if (data->server_state) + { + printf("(game running) "); + } + + NET_SafePuts(data->description); } diff --git a/src/net_query.h b/src/net_query.h index 21c89ecb..98931593 100644 --- a/src/net_query.h +++ b/src/net_query.h @@ -27,10 +27,17 @@ #include "net_defs.h" +typedef void (*net_query_callback_t)(net_addr_t *addr, + net_querydata_t *querydata, + void *user_data); + +extern int NET_LANQuery(net_query_callback_t callback, void *user_data); +extern int NET_MasterQuery(net_query_callback_t callback, void *user_data); extern void NET_QueryAddress(char *addr); -extern void NET_LANQuery(void); extern net_addr_t *NET_FindLANServer(void); -extern void NET_MasterQuery(void); + +extern void NET_QueryPrintCallback(net_addr_t *addr, net_querydata_t *data, + void *user_data); extern net_addr_t *NET_Query_ResolveMaster(net_context_t *context); extern void NET_Query_AddToMaster(net_addr_t *master_addr); -- cgit v1.2.3 From 59d2ed0f2de6b2156142c87d48b0f55fa56b2acf Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Thu, 2 Dec 2010 20:32:52 +0000 Subject: Add -servername parameter to allow the owner to change the name returned in response to queries (thanks AlexMax). Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2185 --- src/net_server.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/net_server.c b/src/net_server.c index 7b67ea56..43584170 100644 --- a/src/net_server.c +++ b/src/net_server.c @@ -1079,6 +1079,7 @@ void NET_SV_SendQueryResponse(net_addr_t *addr) { net_packet_t *reply; net_querydata_t querydata; + int p; // Version @@ -1098,9 +1099,22 @@ void NET_SV_SendQueryResponse(net_addr_t *addr) querydata.gamemode = sv_gamemode; querydata.gamemission = sv_gamemission; - // Server description. This is currently hard-coded. + //! + // @arg + // + // When starting a network server, specify a name for the server. + // - querydata.description = "Chocolate Doom server"; + p = M_CheckParm("-servername"); + + if (p > 0 && p + 1 < myargc) + { + querydata.description = myargv[p + 1]; + } + else + { + querydata.description = "Unnamed server"; + } // Send it and we're done. -- cgit v1.2.3 From 0ff67f43d6d13d9675e305abc652188ea95a88fe Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Thu, 2 Dec 2010 21:34:51 +0000 Subject: Make multiple query attempts to servers before giving up. Display a warning if the master server does not respond. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2187 --- src/net_query.c | 46 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/net_query.c b/src/net_query.c index 3dee1b00..6a934413 100644 --- a/src/net_query.c +++ b/src/net_query.c @@ -36,8 +36,18 @@ #include "net_structrw.h" #include "net_sdl.h" +// DNS address of the Internet master server. + #define MASTER_SERVER_ADDRESS "master.chocolate-doom.org" +// Time to wait for a response before declaring a timeout. + +#define QUERY_TIMEOUT_SECS 1 + +// Number of query attempts to make before giving up on a server. + +#define QUERY_MAX_ATTEMPTS 5 + typedef enum { QUERY_TARGET_SERVER, // Normal server target. @@ -50,7 +60,7 @@ typedef enum QUERY_TARGET_QUEUED, // Query not yet sent QUERY_TARGET_QUERIED, // Query sent, waiting response QUERY_TARGET_RESPONDED, // Response received - QUERY_TARGET_TIMED_OUT + QUERY_TARGET_NO_RESPONSE } query_target_state_t; typedef struct @@ -60,6 +70,7 @@ typedef struct net_addr_t *addr; net_querydata_t data; unsigned int query_time; + unsigned int query_attempts; boolean printed; } query_target_t; @@ -179,6 +190,7 @@ static query_target_t *GetTargetForAddr(net_addr_t *addr, boolean create) target->type = QUERY_TARGET_SERVER; target->state = QUERY_TARGET_QUEUED; target->printed = false; + target->query_attempts = 0; target->addr = addr; ++num_targets; @@ -329,11 +341,19 @@ static void NET_Query_GetResponse(net_query_callback_t callback, static void SendOneQuery(void) { + unsigned int now; unsigned int i; + now = I_GetTimeMS(); + for (i = 0; i < num_targets; ++i) { - if (targets[i].state == QUERY_TARGET_QUEUED) + // Not queried yet? + // Or last query timed out without a response? + + if (targets[i].state == QUERY_TARGET_QUEUED + || (targets[i].state == QUERY_TARGET_QUERIED + && now - targets[i].query_time > QUERY_TIMEOUT_SECS * 1000)) { break; } @@ -365,6 +385,7 @@ static void SendOneQuery(void) //printf("Queried %s\n", NET_AddrToString(targets[i].addr)); targets[i].state = QUERY_TARGET_QUERIED; targets[i].query_time = I_GetTimeMS(); + ++targets[i].query_attempts; } // Time out servers that have been queried and not responded. @@ -378,10 +399,15 @@ static void CheckTargetTimeouts(void) for (i = 0; i < num_targets; ++i) { + // We declare a target to be "no response" when we've sent + // multiple query packets to it (QUERY_MAX_ATTEMPTS) and + // received no response to any of them. + if (targets[i].state == QUERY_TARGET_QUERIED - && now - targets[i].query_time > 5000) + && targets[i].query_attempts >= QUERY_MAX_ATTEMPTS + && now - targets[i].query_time > QUERY_TIMEOUT_SECS * 1000) { - targets[i].state = QUERY_TARGET_TIMED_OUT; + targets[i].state = QUERY_TARGET_NO_RESPONSE; } } } @@ -395,7 +421,7 @@ static boolean AllTargetsDone(void) for (i = 0; i < num_targets; ++i) { if (targets[i].state != QUERY_TARGET_RESPONDED - && targets[i].state != QUERY_TARGET_TIMED_OUT) + && targets[i].state != QUERY_TARGET_NO_RESPONSE) { return false; } @@ -432,7 +458,7 @@ static void NET_Query_QueryLoop(net_query_callback_t callback, // Don't thrash the CPU - I_Sleep(100); + I_Sleep(50); CheckTargetTimeouts(); } @@ -599,6 +625,14 @@ int NET_MasterQuery(net_query_callback_t callback, void *user_data) NET_Query_QueryLoop(callback, user_data); + // Check that we got a response from the master, and display + // a warning if we didn't. + + if (target->state == QUERY_TARGET_NO_RESPONSE) + { + fprintf(stderr, "NET_MasterQuery: no response from master server.\n"); + } + return GetNumResponses(); } -- cgit v1.2.3 From 863afa816738407f639618fb43659b97dcc3430d Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 4 Dec 2010 20:34:39 +0000 Subject: Fix bug when running with -server option. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2190 --- src/net_loop.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/net_loop.c b/src/net_loop.c index abba96e0..b8387794 100644 --- a/src/net_loop.c +++ b/src/net_loop.c @@ -137,9 +137,16 @@ static void NET_CL_FreeAddress(net_addr_t *addr) static net_addr_t *NET_CL_ResolveAddress(char *address) { - client_addr.module = &net_loop_client_module; + if (address == NULL) + { + client_addr.module = &net_loop_client_module; - return &client_addr; + return &client_addr; + } + else + { + return NULL; + } } net_module_t net_loop_client_module = @@ -206,8 +213,15 @@ static void NET_SV_FreeAddress(net_addr_t *addr) static net_addr_t *NET_SV_ResolveAddress(char *address) { - server_addr.module = &net_loop_server_module; - return &server_addr; + if (address == NULL) + { + server_addr.module = &net_loop_server_module; + return &server_addr; + } + else + { + return NULL; + } } net_module_t net_loop_server_module = -- cgit v1.2.3 From 0194038cac0092499668d849a300eaffaa448421 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 4 Dec 2010 20:40:10 +0000 Subject: Fix formatting for -masterquery to match -search. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2191 --- src/d_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/d_main.c b/src/d_main.c index c0804b5d..2f787694 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -852,9 +852,9 @@ void D_DoomMain (void) if (M_CheckParm("-masterquery")) { - printf("\nSearching for servers on Internet ...\n\n"); + printf("\nSearching for servers on Internet ...\n"); p = NET_MasterQuery(NET_QueryPrintCallback, NULL); - printf("%i server(s) found.\n", p); + printf("\n%i server(s) found.\n", p); exit(0); } -- cgit v1.2.3 From 3c57887b0a5352da1c7c4fe7f149c94bb6d70c31 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 4 Dec 2010 20:48:07 +0000 Subject: Add ping time to query output. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2192 --- src/net_query.c | 18 +++++++++++++----- src/net_query.h | 3 ++- 2 files changed, 15 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/net_query.c b/src/net_query.c index 6a934413..265e3804 100644 --- a/src/net_query.c +++ b/src/net_query.c @@ -42,11 +42,11 @@ // Time to wait for a response before declaring a timeout. -#define QUERY_TIMEOUT_SECS 1 +#define QUERY_TIMEOUT_SECS 2 // Number of query attempts to make before giving up on a server. -#define QUERY_MAX_ATTEMPTS 5 +#define QUERY_MAX_ATTEMPTS 3 typedef enum { @@ -69,6 +69,7 @@ typedef struct query_target_state_t state; net_addr_t *addr; net_querydata_t data; + unsigned int ping_time; unsigned int query_time; unsigned int query_attempts; boolean printed; @@ -251,9 +252,13 @@ static void NET_Query_ParseResponse(net_addr_t *addr, net_packet_t *packet, target->state = QUERY_TARGET_RESPONDED; memcpy(&target->data, &querydata, sizeof(net_querydata_t)); + // Calculate RTT. + + target->ping_time = I_GetTimeMS() - target->query_time; + // Invoke callback to signal that we have a new address. - callback(addr, &target->data, user_data); + callback(addr, &target->data, target->ping_time, user_data); } } @@ -479,7 +484,7 @@ void NET_Query_Init(void) // Callback that exits the query loop when the first server is found. static void NET_Query_ExitCallback(net_addr_t *addr, net_querydata_t *data, - void *user_data) + unsigned int ping_time, void *user_data) { NET_Query_ExitLoop(); } @@ -552,7 +557,7 @@ void NET_QueryAddress(char *addr_str) if (target->state == QUERY_TARGET_RESPONDED) { - NET_QueryPrintCallback(addr, &target->data, NULL); + NET_QueryPrintCallback(addr, &target->data, target->ping_time, NULL); } else { @@ -679,6 +684,7 @@ static void PrintHeader(void) int i; putchar('\n'); + formatted_printf(5, "Ping"); formatted_printf(18, "Address"); formatted_printf(8, "Players"); puts("Description"); @@ -692,6 +698,7 @@ static void PrintHeader(void) void NET_QueryPrintCallback(net_addr_t *addr, net_querydata_t *data, + unsigned int ping_time, void *user_data) { // If this is the first server, print the header. @@ -702,6 +709,7 @@ void NET_QueryPrintCallback(net_addr_t *addr, printed_header = true; } + formatted_printf(5, "%4i", ping_time); formatted_printf(18, "%s: ", NET_AddrToString(addr)); formatted_printf(8, "%i/%i", data->num_players, data->max_players); diff --git a/src/net_query.h b/src/net_query.h index 98931593..01e059cb 100644 --- a/src/net_query.h +++ b/src/net_query.h @@ -29,6 +29,7 @@ typedef void (*net_query_callback_t)(net_addr_t *addr, net_querydata_t *querydata, + unsigned int ping_time, void *user_data); extern int NET_LANQuery(net_query_callback_t callback, void *user_data); @@ -37,7 +38,7 @@ extern void NET_QueryAddress(char *addr); extern net_addr_t *NET_FindLANServer(void); extern void NET_QueryPrintCallback(net_addr_t *addr, net_querydata_t *data, - void *user_data); + unsigned int ping_time, void *user_data); extern net_addr_t *NET_Query_ResolveMaster(net_context_t *context); extern void NET_Query_AddToMaster(net_addr_t *master_addr); -- cgit v1.2.3 From d3c8d42bc4edf892557875a83c3f5ae65880e074 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 4 Dec 2010 20:56:04 +0000 Subject: Rename search command line options: -search to search the Internet, -localsearch to search local LAN. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2193 --- src/d_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/d_main.c b/src/d_main.c index 2f787694..032c5caa 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -850,7 +850,7 @@ void D_DoomMain (void) // servers. // - if (M_CheckParm("-masterquery")) + if (M_CheckParm("-search")) { printf("\nSearching for servers on Internet ...\n"); p = NET_MasterQuery(NET_QueryPrintCallback, NULL); @@ -880,7 +880,7 @@ void D_DoomMain (void) // Search the local LAN for running servers. // - if (M_CheckParm("-search")) + if (M_CheckParm("-localsearch")) { printf("\nSearching for servers on local LAN ...\n"); p = NET_LANQuery(NET_QueryPrintCallback, NULL); -- cgit v1.2.3 From 35104488f0c896dbb43d6841a89a629b2ed248a4 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 6 Dec 2010 22:38:24 +0000 Subject: Rename -netdemo command line parameter to -solo-net, for consistency with other ports (-netdemo is still recognised). Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2197 --- src/g_game.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/g_game.c b/src/g_game.c index 95cd77a6..d2694250 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2223,10 +2223,11 @@ void G_DoPlayDemo (void) // Play back a demo recorded in a netgame with a single player. // - if (playeringame[1] || M_CheckParm("-netdemo") > 0) - { - netgame = true; - netdemo = true; + if (playeringame[1] || M_CheckParm("-solo-net") > 0 + || M_CheckParm("-netdemo") > 0) + { + netgame = true; + netdemo = true; } // don't spend a lot of time in loadlevel -- cgit v1.2.3 From e4025e0a6a5e648ff59dd23973c5e7076a07eaa6 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Mon, 6 Dec 2010 23:37:27 +0000 Subject: Fix -solo-net to actually behave the same as other ports. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2198 --- src/d_net.c | 17 +++++++++++++++-- src/g_game.c | 6 ------ 2 files changed, 15 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/d_net.c b/src/d_net.c index bf9fbf2b..ae5a6d62 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -200,8 +200,8 @@ void NetUpdate (void) G_BuildTiccmd(&cmd); #ifdef FEATURE_MULTIPLAYER - - if (netgame && !demoplayback) + + if (net_client_connected) { NET_CL_SendTiccmd(&cmd, maketic); } @@ -254,6 +254,19 @@ void D_CheckNetGame (void) playeringame[0] = true; + //! + // @category net + // + // Start the game playing as though in a netgame with a single + // player. This can also be used to play back single player netgame + // demos. + // + + if (M_CheckParm("-solo-net") > 0) + { + netgame = true; + } + #ifdef FEATURE_MULTIPLAYER { diff --git a/src/g_game.c b/src/g_game.c index d2694250..59550513 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2217,12 +2217,6 @@ void G_DoPlayDemo (void) for (i=0 ; i 0 || M_CheckParm("-netdemo") > 0) { -- cgit v1.2.3 From 6727d54e95153c083acbba5ab77f1f9bce92b331 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Tue, 7 Dec 2010 22:35:17 +0000 Subject: Assign the oldest client to be the controller, not the first found in the clients[] array. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2201 --- src/net_server.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/net_server.c b/src/net_server.c index 43584170..4307e2e2 100644 --- a/src/net_server.c +++ b/src/net_server.c @@ -69,6 +69,11 @@ typedef struct int last_send_time; char *name; + // Time that this client connected to the server. + // This is used to determine the controller (oldest client). + + unsigned int connect_time; + // Last time new gamedata was received from this client int last_gamedata_time; @@ -381,19 +386,29 @@ static void NET_SV_AdvanceWindow(void) static net_client_t *NET_SV_Controller(void) { + net_client_t *best; int i; - // first client in the list is the controller + // Find the oldest client (first to connect). + + best = NULL; for (i=0; iconnect_time) + { + best = &clients[i]; } } - return NULL; + return best; } // Given an address, find the corresponding client @@ -433,6 +448,7 @@ static void NET_SV_InitNewClient(net_client_t *client, char *player_name) { client->active = true; + client->connect_time = I_GetTimeMS(); NET_Conn_InitServer(&client->connection, addr); client->addr = addr; client->last_send_time = -1; -- cgit v1.2.3 From 4a76f500f78acc36cf02374ac227f71d173d47bd Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 10 Dec 2010 17:53:50 +0000 Subject: Specify master server port explicitly, so that server registration works when using -port. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2203 --- src/net_query.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/net_query.c b/src/net_query.c index 265e3804..2797ea2e 100644 --- a/src/net_query.c +++ b/src/net_query.c @@ -38,7 +38,7 @@ // DNS address of the Internet master server. -#define MASTER_SERVER_ADDRESS "master.chocolate-doom.org" +#define MASTER_SERVER_ADDRESS "master.chocolate-doom.org:2342" // Time to wait for a response before declaring a timeout. -- cgit v1.2.3 From c7b77349a83c70ce50acae28d1ed3606cdbb8ba9 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 10 Dec 2010 22:21:56 +0000 Subject: Remove "Error:" from the message displayed by I_Error, to match Vanilla. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2210 --- src/i_system.c | 6 +++--- src/net_gui.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/i_system.c b/src/i_system.c index f37b5bec..aa7875ff 100644 --- a/src/i_system.c +++ b/src/i_system.c @@ -328,9 +328,9 @@ void I_Error (char *error, ...) // Message first. va_start(argptr, error); - fprintf(stderr, "\nError: "); + //fprintf(stderr, "\nError: "); vfprintf(stderr, error, argptr); - fprintf(stderr, "\n"); + fprintf(stderr, "\n\n"); va_end(argptr); fflush(stderr); @@ -360,7 +360,7 @@ void I_Error (char *error, ...) msgbuf, strlen(msgbuf) + 1, wmsgbuf, sizeof(wmsgbuf)); - MessageBoxW(NULL, wmsgbuf, L"Error", MB_OK); + MessageBoxW(NULL, wmsgbuf, L"" PACKAGE_NAME, MB_OK); } #endif diff --git a/src/net_gui.c b/src/net_gui.c index ed9a58e9..600b6ee8 100644 --- a/src/net_gui.c +++ b/src/net_gui.c @@ -284,7 +284,7 @@ void NET_WaitForStart(void) if (!net_client_connected) { - I_Error("Disconnected from server"); + I_Error("Lost connection to server"); } TXT_Sleep(100); -- cgit v1.2.3 From e225e0c93ce58bb0e33c174847305d39800fd755 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 10 Dec 2010 22:37:29 +0000 Subject: Fix build problem (thanks Proteh). Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2211 --- src/i_system.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/i_system.c b/src/i_system.c index aa7875ff..afff1a95 100644 --- a/src/i_system.c +++ b/src/i_system.c @@ -360,7 +360,7 @@ void I_Error (char *error, ...) msgbuf, strlen(msgbuf) + 1, wmsgbuf, sizeof(wmsgbuf)); - MessageBoxW(NULL, wmsgbuf, L"" PACKAGE_NAME, MB_OK); + MessageBoxW(NULL, wmsgbuf, L"", MB_OK); } #endif -- cgit v1.2.3 From 6a2d4763a9080cf88ca9f0b588b8187963eeacf5 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 10 Dec 2010 23:20:29 +0000 Subject: Fix crash introduced by merge. Subversion-branch: /branches/raven-branch Subversion-revision: 2213 --- src/i_video.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/i_video.c b/src/i_video.c index aa9640bf..99972e9a 100644 --- a/src/i_video.c +++ b/src/i_video.c @@ -928,9 +928,9 @@ static boolean BlitArea(int x1, int y1, int x2, int y2) { I_InitScale(I_VideoBuffer, (byte *) screenbuffer->pixels - + (y_offset * screen->pitch) + + (y_offset * screenbuffer->pitch) + x_offset, - screen->pitch); + screenbuffer->pitch); result = screen_mode->DrawScreen(x1, y1, x2, y2); SDL_UnlockSurface(screenbuffer); } -- cgit v1.2.3 From 57a9f56e2cba50249ee8a96533c8baed47814f92 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Fri, 10 Dec 2010 23:56:32 +0000 Subject: Fix memory leak when dynamically resizing window in true color video modes. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2215 --- src/i_video.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/i_video.c b/src/i_video.c index 488c08a0..ad4d7f39 100644 --- a/src/i_video.c +++ b/src/i_video.c @@ -97,7 +97,7 @@ static SDL_Surface *screen; // This is used when we are rendering in 32-bit screen mode. // When in a real 8-bit screen mode, screenbuffer == screen. -static SDL_Surface *screenbuffer; +static SDL_Surface *screenbuffer = NULL; // palette @@ -1646,6 +1646,14 @@ static void SetVideoMode(screen_mode_t *mode, int w, int h) doompal = W_CacheLumpName(DEH_String("PLAYPAL"), PU_CACHE); + // If we are already running and in a true color mode, we need + // to free the screenbuffer surface before setting the new mode. + + if (screenbuffer != NULL && screen != screenbuffer) + { + SDL_FreeSurface(screenbuffer); + } + // Generate lookup tables before setting the video mode. if (mode != NULL && mode->InitMode != NULL) -- cgit v1.2.3 From 0688ecda7a802723ae64ab516cfe6508d9890ec7 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 11 Dec 2010 00:10:10 +0000 Subject: Rearrange single player init to always use net_gamesettings_t structure. Subversion-branch: /branches/raven-branch Subversion-revision: 2216 --- src/doom/d_net.c | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/doom/d_net.c b/src/doom/d_net.c index 70359ebd..93a48b41 100644 --- a/src/doom/d_net.c +++ b/src/doom/d_net.c @@ -337,9 +337,6 @@ static void LoadGameSettings(net_gamesettings_t *settings) printf("Syncing netgames like Vanilla Doom.\n"); } - netgame = true; - autostart = true; - if (!drone) { consoleplayer = settings->consoleplayer; @@ -439,27 +436,14 @@ static void SaveGameSettings(net_gamesettings_t *settings, connect_data->lowres_turn = settings->lowres_turn; } -void D_InitSinglePlayerGame(void) +void D_InitSinglePlayerGame(net_gamesettings_t *settings) { - int i; - // default values for single player - consoleplayer = 0; - netgame = false; - ticdup = 1; - extratics = 1; - lowres_turn = false; - offsetms = 0; - - for (i=0; iconsoleplayer = 0; + settings->num_players = 1; - playeringame[0] = true; + netgame = false; //! // @category net @@ -609,6 +593,9 @@ void D_CheckNetGame (void) net_connect_data_t connect_data; net_gamesettings_t settings; + offsetms = 0; + recvtic = 0; + // Call D_QuitNetGame on exit I_AtExit(D_QuitNetGame, true); @@ -617,13 +604,16 @@ void D_CheckNetGame (void) if (D_InitNetGame(&connect_data, &settings)) { - LoadGameSettings(&settings); + netgame = true; + autostart = true; } else { - D_InitSinglePlayerGame(); + D_InitSinglePlayerGame(&settings); } + LoadGameSettings(&settings); + DEH_printf("startskill %i deathmatch: %i startmap: %i startepisode: %i\n", startskill, deathmatch, startmap, startepisode); -- cgit v1.2.3 From ec3323b9ec5adbb2f24ec67dab1ef776ec7fc559 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 11 Dec 2010 00:33:47 +0000 Subject: Bind new screen_bpp variable to configuration file. Subversion-branch: /branches/raven-branch Subversion-revision: 2217 --- src/i_video.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/i_video.c b/src/i_video.c index 99972e9a..0919bccf 100644 --- a/src/i_video.c +++ b/src/i_video.c @@ -2131,6 +2131,7 @@ void I_BindVideoVariables(void) M_BindVariable("startup_delay", &startup_delay); M_BindVariable("screen_width", &screen_width); M_BindVariable("screen_height", &screen_height); + M_BindVariable("screen_bpp", &screen_bpp); M_BindVariable("grabmouse", &grabmouse); M_BindVariable("mouse_acceleration", &mouse_acceleration); M_BindVariable("mouse_threshold", &mouse_threshold); -- cgit v1.2.3 From 59d5d0d646f3d4ca1eb2370154db4b4371185e2f Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 11 Dec 2010 01:01:45 +0000 Subject: Fix problem with -autojoin apparently caused by merge error. Subversion-branch: /branches/raven-branch Subversion-revision: 2218 --- src/doom/d_net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/doom/d_net.c b/src/doom/d_net.c index 93a48b41..73e7368f 100644 --- a/src/doom/d_net.c +++ b/src/doom/d_net.c @@ -479,6 +479,7 @@ boolean D_InitNetGame(net_connect_data_t *connect_data, NET_SV_Init(); NET_SV_AddModule(&net_loop_server_module); NET_SV_AddModule(&net_sdl_module); + NET_SV_RegisterWithMaster(); net_loop_client_module.InitClient(); addr = net_loop_client_module.ResolveAddress(NULL); @@ -497,7 +498,6 @@ boolean D_InitNetGame(net_connect_data_t *connect_data, if (i > 0) { addr = NET_FindLANServer(); - NET_SV_RegisterWithMaster(); if (addr == NULL) { -- cgit v1.2.3 From 1ef81eb5f7c336972fe56f15285f389cafdc96f5 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Tue, 14 Dec 2010 20:55:30 +0000 Subject: Check that an address is provided to the -query command line option (thanks Sander van Dijk). Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2221 --- src/d_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/d_main.c b/src/d_main.c index 032c5caa..36382fb6 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -868,7 +868,7 @@ void D_DoomMain (void) p = M_CheckParm("-query"); - if (p > 0) + if (p && p < myargc-1) { NET_QueryAddress(myargv[p+1]); exit(0); -- cgit v1.2.3 From 7d7b5087d2288fc6e2493448968f7d786043b389 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Tue, 14 Dec 2010 23:32:07 +0000 Subject: Add missing windows.h #include for Windows build (thanks Blondie and exp(x)). Subversion-branch: /branches/raven-branch Subversion-revision: 2222 --- src/i_video.c | 5 +++++ src/setup/display.c | 5 +++++ 2 files changed, 10 insertions(+) (limited to 'src') diff --git a/src/i_video.c b/src/i_video.c index 0919bccf..243663d5 100644 --- a/src/i_video.c +++ b/src/i_video.c @@ -31,6 +31,11 @@ #include #include +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#endif + #include "icon.c" #include "config.h" diff --git a/src/setup/display.c b/src/setup/display.c index 0def546f..fd7c0a9a 100644 --- a/src/setup/display.c +++ b/src/setup/display.c @@ -26,6 +26,11 @@ #include "libc_wince.h" #endif +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include +#endif + #include "textscreen.h" #include "m_config.h" #include "mode.h" -- cgit v1.2.3 From 463bcf013ce355398974953508d232ac88a6b2d6 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 18 Dec 2010 23:55:07 +0000 Subject: Add a M_CheckParmWithArgs function, that behaves like M_CheckParm but also checks that extra options were provided on the command line (thanks Sander van Dijk). Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2223 --- src/d_iwad.c | 2 +- src/d_main.c | 62 ++++++++++++++++++++++++++++---------------------------- src/d_net.c | 2 +- src/g_game.c | 4 ++-- src/i_system.c | 2 +- src/i_video.c | 8 ++++---- src/m_argv.c | 13 ++++++++---- src/m_argv.h | 4 ++++ src/m_config.c | 8 ++++---- src/net_client.c | 4 ++-- src/net_sdl.c | 4 ++-- src/net_server.c | 4 ++-- src/p_map.c | 2 +- src/p_spec.c | 4 ++-- 14 files changed, 66 insertions(+), 57 deletions(-) (limited to 'src') diff --git a/src/d_iwad.c b/src/d_iwad.c index 89a7fba3..c0d33707 100644 --- a/src/d_iwad.c +++ b/src/d_iwad.c @@ -658,7 +658,7 @@ char *D_FindIWAD(void) // @arg // - iwadparm = M_CheckParm("-iwad"); + iwadparm = M_CheckParmWithArgs("-iwad", 1); if (iwadparm) { diff --git a/src/d_main.c b/src/d_main.c index 36382fb6..465ed45b 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -672,9 +672,9 @@ static void InitGameVersion(void) // "ultimate" and "final". // - p = M_CheckParm("-gameversion"); + p = M_CheckParmWithArgs("-gameversion", 1); - if (p > 0) + if (p) { for (i=0; gameversions[i].description != NULL; ++i) { @@ -866,9 +866,9 @@ void D_DoomMain (void) // address. // - p = M_CheckParm("-query"); + p = M_CheckParmWithArgs("-query", 1); - if (p && p < myargc-1) + if (p) { NET_QueryAddress(myargv[p+1]); exit(0); @@ -1019,7 +1019,7 @@ void D_DoomMain (void) // into the main IWAD. Multiple files may be specified. // - p = M_CheckParm("-merge"); + p = M_CheckParmWithArgs("-merge", 1); if (p > 0) { @@ -1045,7 +1045,7 @@ void D_DoomMain (void) // Simulates the behavior of NWT's -merge option. Multiple files // may be specified. - p = M_CheckParm("-nwtmerge"); + p = M_CheckParmWithArgs("-nwtmerge", 1); if (p > 0) { @@ -1070,7 +1070,7 @@ void D_DoomMain (void) // the main IWAD directory. Multiple files may be specified. // - p = M_CheckParm("-af"); + p = M_CheckParmWithArgs("-af", 1); if (p > 0) { @@ -1093,7 +1093,7 @@ void D_DoomMain (void) // into the main IWAD directory. Multiple files may be specified. // - p = M_CheckParm("-as"); + p = M_CheckParmWithArgs("-as", 1); if (p > 0) { @@ -1115,7 +1115,7 @@ void D_DoomMain (void) // Equivalent to "-af -as ". // - p = M_CheckParm("-aa"); + p = M_CheckParmWithArgs("-aa", 1); if (p > 0) { @@ -1139,7 +1139,7 @@ void D_DoomMain (void) // Load the specified PWAD files. // - p = M_CheckParm ("-file"); + p = M_CheckParmWithArgs("-file", 1); if (p) { // the parms after p are wadfile/lump names, @@ -1163,7 +1163,7 @@ void D_DoomMain (void) // // convenience hack to allow -wart e m to add a wad file // prepend a tilde to the filename so wadfile will be reloadable - p = M_CheckParm ("-wart"); + p = M_CheckParmWithArgs("-wart", 1); if (p) { myargv[p][4] = 'p'; // big hack, change to -warp @@ -1200,7 +1200,7 @@ void D_DoomMain (void) // Play back the demo named demo.lmp. // - p = M_CheckParm ("-playdemo"); + p = M_CheckParmWithArgs ("-playdemo", 1); if (!p) { @@ -1212,11 +1212,11 @@ void D_DoomMain (void) // Play back the demo named demo.lmp, determining the framerate // of the screen. // - p = M_CheckParm ("-timedemo"); + p = M_CheckParmWithArgs("-timedemo", 1); } - if (p && p < myargc-1) + if (p) { if (!strcasecmp(myargv[p+1] + strlen(myargv[p+1]) - 4, ".lmp")) { @@ -1296,9 +1296,9 @@ void D_DoomMain (void) // 0 disables all monsters. // - p = M_CheckParm ("-skill"); + p = M_CheckParmWithArgs("-skill", 1); - if (p && p < myargc-1) + if (p) { startskill = myargv[p+1][0]-'1'; autostart = true; @@ -1311,9 +1311,9 @@ void D_DoomMain (void) // Start playing on episode n (1-4) // - p = M_CheckParm ("-episode"); + p = M_CheckParmWithArgs("-episode", 1); - if (p && p < myargc-1) + if (p) { startepisode = myargv[p+1][0]-'0'; startmap = 1; @@ -1330,9 +1330,9 @@ void D_DoomMain (void) // For multiplayer games: exit each level after n minutes. // - p = M_CheckParm ("-timer"); + p = M_CheckParmWithArgs("-timer", 1); - if (p && p < myargc-1) + if (p) { timelimit = atoi(myargv[p+1]); } @@ -1346,7 +1346,7 @@ void D_DoomMain (void) p = M_CheckParm ("-avg"); - if (p && p < myargc-1) + if (p) { timelimit = 20; } @@ -1359,9 +1359,9 @@ void D_DoomMain (void) // (Doom 2) // - p = M_CheckParm ("-warp"); + p = M_CheckParmWithArgs("-warp", 1); - if (p && p < myargc-1) + if (p) { if (gamemode == commercial) startmap = atoi (myargv[p+1]); @@ -1405,9 +1405,9 @@ void D_DoomMain (void) // Load the game in slot s. // - p = M_CheckParm ("-loadgame"); + p = M_CheckParmWithArgs("-loadgame", 1); - if (p && p < myargc-1) + if (p) { startloadgame = atoi(myargv[p+1]); } @@ -1507,24 +1507,24 @@ void D_DoomMain (void) // Record a demo named x.lmp. // - p = M_CheckParm ("-record"); + p = M_CheckParmWithArgs("-record", 1); - if (p && p < myargc-1) + if (p) { G_RecordDemo (myargv[p+1]); autostart = true; } - p = M_CheckParm ("-playdemo"); - if (p && p < myargc-1) + p = M_CheckParmWithArgs("-playdemo", 1); + if (p) { singledemo = true; // quit after one demo G_DeferedPlayDemo (demolumpname); D_DoomLoop (); // never returns } - p = M_CheckParm ("-timedemo"); - if (p && p < myargc-1) + p = M_CheckParmWithArgs("-timedemo", 1); + if (p) { G_TimeDemo (demolumpname); D_DoomLoop (); // never returns diff --git a/src/d_net.c b/src/d_net.c index ae5a6d62..57fe2399 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -317,7 +317,7 @@ void D_CheckNetGame (void) // address. // - i = M_CheckParm("-connect"); + i = M_CheckParmWithArgs("-connect", 1); if (i > 0) { diff --git a/src/g_game.c b/src/g_game.c index 59550513..7790b83e 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2068,8 +2068,8 @@ void G_RecordDemo (char* name) // Specify the demo buffer size (KiB) // - i = M_CheckParm ("-maxdemo"); - if (i && i 0) { diff --git a/src/i_video.c b/src/i_video.c index ad4d7f39..55fd21e1 100644 --- a/src/i_video.c +++ b/src/i_video.c @@ -1442,7 +1442,7 @@ static void CheckCommandLine(void) // Specify the screen width, in pixels. // - i = M_CheckParm("-width"); + i = M_CheckParmWithArgs("-width", 1); if (i > 0) { @@ -1456,7 +1456,7 @@ static void CheckCommandLine(void) // Specify the screen height, in pixels. // - i = M_CheckParm("-height"); + i = M_CheckParmWithArgs("-height", 1); if (i > 0) { @@ -1470,7 +1470,7 @@ static void CheckCommandLine(void) // Specify the color depth of the screen, in bits per pixel. // - i = M_CheckParm("-bpp"); + i = M_CheckParmWithArgs("-bpp", 1); if (i > 0) { @@ -1497,7 +1497,7 @@ static void CheckCommandLine(void) // Specify the screen mode (when running fullscreen) or the window // dimensions (when running in windowed mode). - i = M_CheckParm("-geometry"); + i = M_CheckParmWithArgs("-geometry", 1); if (i > 0) { diff --git a/src/m_argv.c b/src/m_argv.c index 99295c6d..4d321bbc 100644 --- a/src/m_argv.c +++ b/src/m_argv.c @@ -47,19 +47,24 @@ char** myargv; // or 0 if not present // -int M_CheckParm (char *check) +int M_CheckParmWithArgs(char *check, int num_args) { - int i; + int i; - for (i = 1;i 0) settings.extratics = atoi(myargv[i+1]); @@ -426,7 +426,7 @@ void NET_CL_StartGame(void) // the amount of network bandwidth needed. // - i = M_CheckParm("-dup"); + i = M_CheckParmWithArgs("-dup", 1); if (i > 0) settings.ticdup = atoi(myargv[i+1]); diff --git a/src/net_sdl.c b/src/net_sdl.c index 9c647cc9..2589540d 100644 --- a/src/net_sdl.c +++ b/src/net_sdl.c @@ -170,7 +170,7 @@ static boolean NET_SDL_InitClient(void) // the default (2342). // - p = M_CheckParm("-port"); + p = M_CheckParmWithArgs("-port", 1); if (p > 0) port = atoi(myargv[p+1]); @@ -196,7 +196,7 @@ static boolean NET_SDL_InitServer(void) { int p; - p = M_CheckParm("-port"); + p = M_CheckParmWithArgs("-port", 1); if (p > 0) port = atoi(myargv[p+1]); diff --git a/src/net_server.c b/src/net_server.c index 4307e2e2..b3a9ea92 100644 --- a/src/net_server.c +++ b/src/net_server.c @@ -1121,9 +1121,9 @@ void NET_SV_SendQueryResponse(net_addr_t *addr) // When starting a network server, specify a name for the server. // - p = M_CheckParm("-servername"); + p = M_CheckParmWithArgs("-servername", 1); - if (p > 0 && p + 1 < myargc) + if (p > 0) { querydata.description = myargv[p + 1]; } diff --git a/src/p_map.c b/src/p_map.c index b50fff2c..1ac76349 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1426,7 +1426,7 @@ static void SpechitOverrun(line_t *ld) // Use the specified magic value when emulating spechit overruns. // - p = M_CheckParm("-spechit"); + p = M_CheckParmWithArgs("-spechit", 1); if (p > 0) { diff --git a/src/p_spec.c b/src/p_spec.c index fa3ec335..90d0bb7c 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1213,9 +1213,9 @@ static void DonutOverrun(fixed_t *s3_floorheight, short *s3_floorpic, // system. The default (if this option is not specified) is to // emulate the behavior when running under Windows 98. - p = M_CheckParm("-donut"); + p = M_CheckParmWithArgs("-donut", 2); - if (p > 0 && p < myargc - 2) + if (p > 0) { // Dump of needed memory: (fixed_t)0000:0000 and (short)0000:0008 // -- cgit v1.2.3 From c67b4c15dc32f9824951f37c9b1fa665b7d1307f Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 25 Dec 2010 20:55:30 +0000 Subject: Remove the 32 character limit on the lengths of filenames specified to -record (thanks AlexXav). Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2225 --- src/g_game.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/g_game.c b/src/g_game.c index 7790b83e..f91e630e 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -139,7 +139,7 @@ int gametic; int levelstarttic; // gametic at level start int totalkills, totalitems, totalsecret; // for intermission -char demoname[32]; +char *demoname; boolean demorecording; boolean longtics; // cph's doom 1.91 longtics hack boolean lowres_turn; // low resolution turning for longtics @@ -2050,14 +2050,14 @@ void G_WriteDemoTiccmd (ticcmd_t* cmd) // // G_RecordDemo // -void G_RecordDemo (char* name) +void G_RecordDemo (char *name) { int i; int maxsize; usergame = false; - strcpy (demoname, name); - strcat (demoname, ".lmp"); + demoname = Z_Malloc(strlen(name) + 5, PU_STATIC, NULL); + sprintf(demoname, "%s.lmp", name); maxsize = 0x20000; //! -- cgit v1.2.3 From a854f3e246be1373200a296413b31ece296c2914 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sat, 25 Dec 2010 21:04:10 +0000 Subject: Remove the -wart parameter (thanks Sander van Dijk). Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2226 --- src/d_main.c | 34 ---------------------------------- src/dstrings.h | 9 --------- 2 files changed, 43 deletions(-) (limited to 'src') diff --git a/src/d_main.c b/src/d_main.c index 465ed45b..397062a9 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1158,40 +1158,6 @@ void D_DoomMain (void) // Debug: // W_PrintDirectory(); - // add any files specified on the command line with -file wadfile - // to the wad list - // - // convenience hack to allow -wart e m to add a wad file - // prepend a tilde to the filename so wadfile will be reloadable - p = M_CheckParmWithArgs("-wart", 1); - if (p) - { - myargv[p][4] = 'p'; // big hack, change to -warp - - // Map name handling. - switch (gamemode ) - { - case shareware: - case retail: - case registered: - sprintf (file,"~"DEVMAPS"E%cM%c.wad", - myargv[p+1][0], myargv[p+2][0]); - printf("Warping to Episode %s, Map %s.\n", - myargv[p+1],myargv[p+2]); - break; - - case commercial: - default: - p = atoi (myargv[p+1]); - if (p<10) - sprintf (file,"~"DEVMAPS"cdata/map0%i.wad", p); - else - sprintf (file,"~"DEVMAPS"cdata/map%i.wad", p); - break; - } - D_AddFile (file); - } - //! // @arg // @category demo diff --git a/src/dstrings.h b/src/dstrings.h index bdc6b2ce..d47fc1af 100644 --- a/src/dstrings.h +++ b/src/dstrings.h @@ -38,15 +38,6 @@ #define SAVEGAMENAME "doomsav" -// -// File locations, -// relative to current position. -// Path names are OS-sensitive. -// -#define DEVMAPS "devmaps" -#define DEVDATA "devdata" - - // QuitDOOM messages // 8 per each game type #define NUM_QUITMESSAGES 8 -- cgit v1.2.3 From fc09dbdf6703e62146a74a164be475ba965d00ab Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Tue, 28 Dec 2010 16:43:41 +0000 Subject: Make demo loop handling of DEMO4 case depend on the executable version being emulated: the Vanilla versions did not have any conditional behavior based on gamemode/gamemission. This has the side effect of causing the game to exit with an error when playing with Final Doom, but this is Vanilla behavior. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2230 --- src/d_main.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/d_main.c b/src/d_main.c index 397062a9..73978c2f 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -494,7 +494,13 @@ void D_DoAdvanceDemo (void) paused = false; gameaction = ga_nothing; - if (gamemode == retail && gameversion != exe_chex) + // The Ultimate Doom executable changed the demo sequence to add + // a DEMO4 demo. Final Doom was based on Ultimate, so also + // includes this change; however, the Final Doom IWADs do not + // include a DEMO4 lump, so the game bombs out with an error + // when it reaches this point in the demo sequence. + + if (gameversion == exe_ultimate || gameversion == exe_final) demosequence = (demosequence+1)%7; else demosequence = (demosequence+1)%6; -- cgit v1.2.3 From e63839de20c56649ce16adfe7e849735223ad130 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Sun, 2 Jan 2011 02:31:20 +0000 Subject: Turn off dynamic window resizing feature on OS X, as it adds an ugly resize handle to the corner of the window that overlaps the view of the game. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2231 --- src/i_video.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/i_video.c b/src/i_video.c index 55fd21e1..cd5d2ace 100644 --- a/src/i_video.c +++ b/src/i_video.c @@ -1676,7 +1676,13 @@ static void SetVideoMode(screen_mode_t *mode, int w, int h) } else { + // In windowed mode, the window can be resized while the game is + // running. This feature is disabled on OS X, as it adds an ugly + // scroll handle to the corner of the screen. + +#ifndef __MACOSX__ flags |= SDL_RESIZABLE; +#endif } screen = SDL_SetVideoMode(w, h, screen_bpp, flags); -- cgit v1.2.3 From 5130b54658ab03f3fc18727615b529d6e241566c Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Wed, 12 Jan 2011 23:22:20 +0000 Subject: Fix menu navigation when using joystick / joypad (thanks AlexXav). Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2237 --- src/m_menu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/m_menu.c b/src/m_menu.c index 7b1c5a6e..efc4fefe 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1450,23 +1450,23 @@ boolean M_Responder (event_t* ev) if (ev->type == ev_joystick && joywait < I_GetTime()) { - if (ev->data3 == -1) + if (ev->data3 < 0) { key = key_menu_up; joywait = I_GetTime() + 5; } - else if (ev->data3 == 1) + else if (ev->data3 > 0) { key = key_menu_down; joywait = I_GetTime() + 5; } - if (ev->data2 == -1) + if (ev->data2 < 0) { key = key_menu_left; joywait = I_GetTime() + 2; } - else if (ev->data2 == 1) + else if (ev->data2 > 0) { key = key_menu_right; joywait = I_GetTime() + 2; -- cgit v1.2.3 From ec169fd1c28b2ba3b6b6fc7e7123e9d27516dd5f Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Thu, 13 Jan 2011 20:34:55 +0000 Subject: In configuration files, use the scan code for right shift, not left shift, to match Vanilla (thanks AlexXav). Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2238 --- src/m_config.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/m_config.c b/src/m_config.c index 332b8b95..04d0a963 100644 --- a/src/m_config.c +++ b/src/m_config.c @@ -1217,8 +1217,18 @@ static void SaveDefaultCollection(default_collection_t *collection) v = * (int *) defaults[i].location; - if (defaults[i].untranslated - && v == defaults[i].original_translated) + if (v == KEY_RSHIFT) + { + // Special case: for shift, force scan code for + // right shift, as this is what Vanilla uses. + // This overrides the change check below, to fix + // configuration files made by old versions that + // mistakenly used the scan code for left shift. + + v = 54; + } + else if (defaults[i].untranslated + && v == defaults[i].original_translated) { // Has not been changed since the last time we // read the config file. -- cgit v1.2.3