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(-) 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