foxygit / doom Log in
commit f1bde3d5212cab46aa9f40bec29e8a72013f8a41
Author:     Simon Howard <fraggle@gmail.com>
AuthorDate: Fri Apr 5 21:01:45 2013 +0000
Commit:     Simon Howard <fraggle@gmail.com>
CommitDate: Fri Apr 5 21:01:45 2013 +0000

    Use two-stage startup for Hexen, and add netgame startup callback for
    the spinal loading screen.

    Subversion-branch: /branches/v2-branch
    Subversion-revision: 2585
---
 src/d_loop.c        | 14 +++++++++++---
 src/d_loop.h        | 10 +++++++++-
 src/doom/d_net.c    |  2 +-
 src/heretic/d_net.c |  2 +-
 src/hexen/d_net.c   | 47 +++++++++++++++++++++++++++++++++++++----------
 src/hexen/h2_main.c | 19 +++++++++----------
 src/strife/d_net.c  |  2 +-
 7 files changed, 69 insertions(+), 27 deletions(-)

diff --git a/src/d_loop.c b/src/d_loop.c
index 04d6ef0f..8dad478d 100644
--- a/src/d_loop.c
+++ b/src/d_loop.c
@@ -313,7 +313,8 @@ void D_StartGameLoop(void)
 // Block until the game start message is received from the server.
 //

-void D_BlockUntilStart(net_gamesettings_t *settings)
+static void BlockUntilStart(net_gamesettings_t *settings,
+                            netgame_startup_callback_t callback)
 {
     while (!NET_CL_GetSettings(settings))
     {
@@ -324,10 +325,17 @@ void D_BlockUntilStart(net_gamesettings_t *settings)
         {
             I_Error("Lost connection to server");
         }
+
+        if (callback != NULL && !callback(net_client_wait_data.ready_players,
+                                          net_client_wait_data.num_players))
+        {
+            I_Error("Netgame startup aborted.");
+        }
     }
 }

-void D_StartNetGame(net_gamesettings_t *settings)
+void D_StartNetGame(net_gamesettings_t *settings,
+                    netgame_startup_callback_t callback)
 {
     int i;

@@ -384,7 +392,7 @@ void D_StartNetGame(net_gamesettings_t *settings)
         // from the server.

         NET_CL_StartGame(settings);
-        D_BlockUntilStart(settings);
+        BlockUntilStart(settings, callback);

         // Read the game settings that were received.

diff --git a/src/d_loop.h b/src/d_loop.h
index 7eed035b..4e0d8625 100644
--- a/src/d_loop.h
+++ b/src/d_loop.h
@@ -29,6 +29,13 @@

 #include "net_defs.h"

+// Callback function invoked while waiting for the netgame to start.
+// The callback is invoked when new players are ready. The callback
+// should return true, or return false to abort startup.
+
+typedef boolean (*netgame_startup_callback_t)(int ready_players,
+                                              int num_players);
+
 typedef struct
 {
     // Read events from the event queue, and process them.
@@ -72,7 +79,8 @@ boolean D_InitNetGame(net_connect_data_t *connect_data);
 // Start game with specified settings. The structure will be updated
 // with the actual settings for the game.

-void D_StartNetGame(net_gamesettings_t *settings);
+void D_StartNetGame(net_gamesettings_t *settings,
+                    netgame_startup_callback_t callback);

 extern boolean singletics;
 extern int gametic, ticdup;
diff --git a/src/doom/d_net.c b/src/doom/d_net.c
index 15f1098e..9594d0f7 100644
--- a/src/doom/d_net.c
+++ b/src/doom/d_net.c
@@ -253,7 +253,7 @@ void D_CheckNetGame (void)
     D_RegisterLoopCallbacks(&doom_loop_interface);

     SaveGameSettings(&settings);
-    D_StartNetGame(&settings);
+    D_StartNetGame(&settings, NULL);
     LoadGameSettings(&settings);

     DEH_printf("startskill %i  deathmatch: %i  startmap: %i  startepisode: %i\n",
diff --git a/src/heretic/d_net.c b/src/heretic/d_net.c
index 7218eec9..8b10df07 100644
--- a/src/heretic/d_net.c
+++ b/src/heretic/d_net.c
@@ -214,7 +214,7 @@ void D_CheckNetGame (void)
     }

     SaveGameSettings(&settings);
-    D_StartNetGame(&settings);
+    D_StartNetGame(&settings, NULL);
     LoadGameSettings(&settings);
 }

diff --git a/src/hexen/d_net.c b/src/hexen/d_net.c
index bacd1332..2483cd5e 100644
--- a/src/hexen/d_net.c
+++ b/src/hexen/d_net.c
@@ -206,17 +206,9 @@ static void InitConnectData(net_connect_data_t *connect_data)
     connect_data->is_freedoom = 0;
 }

-//
-// D_CheckNetGame
-// Works out player numbers among the net participants
-//
-
-void D_CheckNetGame (void)
+void D_ConnectNetGame(void)
 {
     net_connect_data_t connect_data;
-    net_gamesettings_t settings;
-
-    D_RegisterLoopCallbacks(&hexen_loop_interface);

     InitConnectData(&connect_data);
     netgame = D_InitNetGame(&connect_data);
@@ -233,6 +225,33 @@ void D_CheckNetGame (void)
     {
         netgame = true;
     }
+}
+
+static boolean StartupProgress(int now_ready, int total)
+{
+    static int ready = 0;
+
+    while (ready < now_ready)
+    {
+        ST_NetProgress();
+        ++ready;
+    }
+
+    ready = now_ready;
+
+    return true;
+}
+
+//
+// D_CheckNetGame
+// Works out player numbers among the net participants
+//
+
+void D_CheckNetGame(void)
+{
+    net_gamesettings_t settings;
+
+    D_RegisterLoopCallbacks(&hexen_loop_interface);

     if (netgame)
     {
@@ -240,8 +259,16 @@ void D_CheckNetGame (void)
     }

     SaveGameSettings(&settings);
-    D_StartNetGame(&settings);
+    D_StartNetGame(&settings, StartupProgress);
     LoadGameSettings(&settings);
+
+    // Finish netgame progress on startup screen.
+
+    if (netgame)
+    {
+        StartupProgress(settings.num_players, settings.num_players);
+        ST_NetDone();
+    }
 }

 //==========================================================================
diff --git a/src/hexen/h2_main.c b/src/hexen/h2_main.c
index 3d9ae87d..7b7a8168 100644
--- a/src/hexen/h2_main.c
+++ b/src/hexen/h2_main.c
@@ -76,6 +76,7 @@ typedef struct
 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------

 void R_ExecuteSetViewSize(void);
+void D_ConnectNetGame(void);
 void D_CheckNetGame(void);
 boolean F_Responder(event_t * ev);
 void I_StartupKeyboard(void);
@@ -331,11 +332,6 @@ void D_DoomMain(void)
     ST_Message("MN_Init: Init menu system.\n");
     MN_Init();

-#ifdef FEATURE_MULTIPLAYER
-    ST_Message("NET_Init: Init networking subsystem.\n");
-    NET_Init();
-#endif
-
     ST_Message("CT_Init: Init chat mode data.\n");
     CT_Init();

@@ -351,6 +347,12 @@ void D_DoomMain(void)
     I_InitTimer();
     I_InitJoystick();

+#ifdef FEATURE_MULTIPLAYER
+    ST_Message("NET_Init: Init networking subsystem.\n");
+    NET_Init();
+#endif
+    D_ConnectNetGame();
+
     S_Init();
     S_Start();

@@ -372,17 +374,14 @@ void D_DoomMain(void)
     // MAPINFO.TXT script must be already processed.
     WarpCheck();

-    ST_Done();
-
-    // Netgame start must be here, after the splash screen has finished.
     ST_Message("D_CheckNetGame: Checking network game status.\n");
     D_CheckNetGame();

-    // SB_Init has been moved here; the status bar must be initialized
-    // *after* the netgame has started.
     ST_Message("SB_Init: Loading patches.\n");
     SB_Init();

+    ST_Done();
+
     if (autostart)
     {
         ST_Message("Warp to Map %d (\"%s\":%d), Skill %d\n",
diff --git a/src/strife/d_net.c b/src/strife/d_net.c
index 42de5bd0..0a5caa90 100644
--- a/src/strife/d_net.c
+++ b/src/strife/d_net.c
@@ -253,7 +253,7 @@ void D_CheckNetGame (void)
     }

     SaveGameSettings(&settings);
-    D_StartNetGame(&settings);
+    D_StartNetGame(&settings, NULL);
     LoadGameSettings(&settings);

     // Strife games are always deathmatch, though -altdeath is