ref: 460c3748565ba1f0fee9e39fd33e76436c6ddc78
parent: 6444493dbd51c95c2adf01526dfeeebc74c186fd
author: Simon Howard <[email protected]>
date: Tue Oct 11 16:21:32 EDT 2011
Refactor and rearrange d_net.c so that the loop code is agnostic and separate from the Doom-specific code. Subversion-branch: /branches/v2-branch Subversion-revision: 2412
--- a/src/doom/d_net.c
+++ b/src/doom/d_net.c
@@ -49,6 +49,13 @@
#include "net_sdl.h"
#include "net_loop.h"
+typedef struct
+{
+ void (*BuildTiccmd)(ticcmd_t *cmd);
+ void (*RunTic)(ticcmd_t *cmds, boolean *ingame);
+ void (*RunMenu)();
+} loop_interface_t;
+
// The complete set of data for a particular tic.
typedef struct
@@ -69,7 +76,6 @@
//
ticcmd_set_t ticdata[BACKUPTICS];
-ticcmd_t *netcmds;
int maketic;
int recvtic;
@@ -95,6 +101,10 @@
boolean new_sync = true;
+// Callback functions for loop code.
+
+static loop_interface_t *loop_interface = NULL;
+
// 35 fps clock adjusted by offsetms milliseconds
static int GetAdjustedTime(void)
@@ -172,7 +182,7 @@
// Always run the menu
- M_Ticker ();
+ loop_interface->RunMenu();
if (drone)
{
@@ -186,7 +196,7 @@
// If playing single player, do not allow tics to buffer
// up very far
- if ((!netgame || demoplayback) && maketic - gameticdiv > 2)
+ if (!net_client_connected && maketic - gameticdiv > 2)
break;
// Never go more than ~200ms ahead
@@ -201,7 +211,7 @@
}
//printf ("mk:%i ",maketic);
- G_BuildTiccmd(&cmd);
+ loop_interface->BuildTiccmd(&cmd);
#ifdef FEATURE_MULTIPLAYER
@@ -218,34 +228,6 @@
}
}
-// 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)
{
// In drone mode, the game cannot continue once disconnected.
@@ -304,79 +286,13 @@
lasttime = GetAdjustedTime() / ticdup;
}
-// Load game settings from the specified structure and
-// set global variables.
-
-static void LoadGameSettings(net_gamesettings_t *settings)
+boolean D_InitNetGame(net_connect_data_t *connect_data,
+ net_gamesettings_t *settings)
{
- unsigned int i;
-
- 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");
- }
-
- if (!drone)
- {
- consoleplayer = settings->consoleplayer;
- }
- else
- {
- consoleplayer = 0;
- }
-
- for (i=0; i<MAXPLAYERS; ++i)
- {
- playeringame[i] = i < settings->num_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)
-{
+ net_addr_t *addr = NULL;
+ boolean result = false;
int i;
- // 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
//
@@ -418,54 +334,6 @@
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(net_gamesettings_t *settings)
-{
- // default values for single player
-
- settings->consoleplayer = 0;
- settings->num_players = 1;
-
- netgame = false;
-
- //!
- // @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;
- }
-}
-
-boolean D_InitNetGame(net_connect_data_t *connect_data,
- net_gamesettings_t *settings)
-{
- net_addr_t *addr = NULL;
- int i;
-
-
#ifdef FEATURE_MULTIPLAYER
//!
@@ -535,30 +403,6 @@
connect_data->drone = true;
}
- //!
- // @category net
- //
- // Run as the left screen in three screen mode.
- //
-
- if (M_CheckParm("-left") > 0)
- {
- viewangleoffset = ANG90;
- connect_data->drone = true;
- }
-
- //!
- // @category net
- //
- // Run as the right screen in three screen mode.
- //
-
- if (M_CheckParm("-right") > 0)
- {
- viewangleoffset = ANG270;
- connect_data->drone = true;
- }
-
if (!NET_CL_Connect(addr, connect_data))
{
I_Error("D_CheckNetGame: Failed to connect to %s\n",
@@ -575,71 +419,19 @@
NET_CL_GetSettings(settings);
- return true;
+ result = true;
}
#endif
- return false;
-}
+ new_sync = settings->new_sync;
-//
-// 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;
-
- offsetms = 0;
- recvtic = 0;
-
- // Call D_QuitNetGame on exit
-
- I_AtExit(D_QuitNetGame, true);
-
- SaveGameSettings(&settings, &connect_data);
-
- if (D_InitNetGame(&connect_data, &settings))
+ if (new_sync == false)
{
- netgame = true;
- autostart = true;
+ printf("Syncing netgames like Vanilla Doom.\n");
}
- else
- {
- D_InitSinglePlayerGame(&settings);
- }
- LoadGameSettings(&settings);
-
- DEH_printf("startskill %i deathmatch: %i startmap: %i startepisode: %i\n",
- startskill, deathmatch, startmap, startepisode);
-
- DEH_printf("player %i of %i (%i nodes)\n",
- consoleplayer+1, settings.num_players, settings.num_players);
-
- // Show players here; the server might have specified a time limit
-
- if (timelimit > 0 && deathmatch)
- {
- // 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");
- }
- }
+ return result;
}
@@ -678,10 +470,9 @@
return lowtic;
}
-int frametics[4];
-int frameon;
-int frameskip[4];
-int oldnettics;
+static int frameon;
+static int frameskip[4];
+static int oldnettics;
static void OldNetSync(void)
{
@@ -780,32 +571,6 @@
}
}
-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.
@@ -920,9 +685,9 @@
if (gametic/ticdup > lowtic)
I_Error ("gametic>lowtic");
- D_RunTic(set);
+ loop_interface->RunTic(set->cmds, set->ingame);
gametic++;
-
+
// modify command for duplicated tics
TicdupSquash(set);
@@ -931,4 +696,264 @@
NetUpdate (); // check for new console commands
}
}
+
+void D_RegisterLoopCallbacks(loop_interface_t *i)
+{
+ loop_interface = i;
+}
+
+//----------------------------------------------------------------------
+
+ticcmd_t *netcmds;
+
+// Called when a player leaves the game
+
+static void 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 RunTic(ticcmd_t *cmds, boolean *ingame)
+{
+ extern boolean advancedemo;
+ unsigned int i;
+
+ // Check for player quits.
+
+ for (i = 0; i < MAXPLAYERS; ++i)
+ {
+ if (playeringame[i] && !ingame[i])
+ {
+ PlayerQuitGame(&players[i]);
+ }
+ }
+
+ netcmds = cmds;
+
+ // check that there are players in the game. if not, we cannot
+ // run a tic.
+
+ if (advancedemo)
+ D_DoAdvanceDemo ();
+
+ G_Ticker ();
+}
+
+static loop_interface_t doom_loop_interface = {
+ G_BuildTiccmd,
+ RunTic,
+ M_Ticker
+};
+
+
+// Load game settings from the specified structure and
+// set global variables.
+
+static void LoadGameSettings(net_gamesettings_t *settings)
+{
+ unsigned int i;
+
+ 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");
+ }
+
+ if (!drone)
+ {
+ consoleplayer = settings->consoleplayer;
+ }
+ else
+ {
+ consoleplayer = 0;
+ }
+
+ for (i=0; i<MAXPLAYERS; ++i)
+ {
+ playeringame[i] = i < settings->num_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)
+{
+ // 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;
+
+ connect_data->drone = false;
+
+ //!
+ // @category net
+ //
+ // Run as the left screen in three screen mode.
+ //
+
+ if (M_CheckParm("-left") > 0)
+ {
+ viewangleoffset = ANG90;
+ connect_data->drone = true;
+ }
+
+ //!
+ // @category net
+ //
+ // Run as the right screen in three screen mode.
+ //
+
+ if (M_CheckParm("-right") > 0)
+ {
+ viewangleoffset = ANG270;
+ connect_data->drone = true;
+ }
+
+ //
+ // Connect data
+ //
+
+ // Game type fields:
+
+ connect_data->gamemode = gamemode;
+ connect_data->gamemission = gamemission;
+
+ // Are we recording a demo? Possibly set lowres turn mode
+
+ connect_data->lowres_turn = settings->lowres_turn;
+}
+
+void D_InitSinglePlayerGame(net_gamesettings_t *settings)
+{
+ // default values for single player
+
+ settings->consoleplayer = 0;
+ settings->num_players = 1;
+
+ netgame = false;
+
+ //!
+ // @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;
+ }
+}
+
+//
+// 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;
+
+ offsetms = 0;
+ recvtic = 0;
+
+ D_RegisterLoopCallbacks(&doom_loop_interface);
+
+ // Call D_QuitNetGame on exit
+
+ I_AtExit(D_QuitNetGame, true);
+
+ SaveGameSettings(&settings, &connect_data);
+
+ if (D_InitNetGame(&connect_data, &settings))
+ {
+ netgame = true;
+ autostart = true;
+ }
+ else
+ {
+ D_InitSinglePlayerGame(&settings);
+ }
+
+ LoadGameSettings(&settings);
+
+ DEH_printf("startskill %i deathmatch: %i startmap: %i startepisode: %i\n",
+ startskill, deathmatch, startmap, startepisode);
+
+ DEH_printf("player %i of %i (%i nodes)\n",
+ consoleplayer+1, settings.num_players, settings.num_players);
+
+ // Show players here; the server might have specified a time limit
+
+ if (timelimit > 0 && deathmatch)
+ {
+ // 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");
+ }
+ }
+}
+
+//----------------------------------------------------------------------