shithub: choc

Download patch

ref: 96f7da6adf5d4b6eb7b6ab66bd1758a2b14d1efa
parent: 4dc7b33e17069c6559e9b1b7cc1ecd878162f629
author: Simon Howard <[email protected]>
date: Sun Sep 18 10:16:27 EDT 2011

Hook query code into setup tool, and add search results window.

Subversion-branch: /branches/v2-branch
Subversion-revision: 2383

--- a/src/net_query.c
+++ b/src/net_query.c
@@ -528,10 +528,14 @@
 
 void NET_Query_Init(void)
 {
-    query_context = NET_NewContext();
-    NET_AddModule(query_context, &net_sdl_module);
-    net_sdl_module.InitClient();
+    if (query_context == NULL)
+    {
+        query_context = NET_NewContext();
+        NET_AddModule(query_context, &net_sdl_module);
+        net_sdl_module.InitClient();
+    }
 
+    free(targets);
     targets = NULL;
     num_targets = 0;
 
--- a/src/setup/multiplayer.c
+++ b/src/setup/multiplayer.c
@@ -35,6 +35,9 @@
 #include "mode.h"
 #include "execute.h"
 
+#include "net_io.h"
+#include "net_query.h"
+
 #define NUM_WADS 10
 #define NUM_EXTRA_PARAMS 10
 
@@ -44,12 +47,6 @@
     WARP_MAPxy,
 } warptype_t;
 
-typedef enum
-{
-    JOIN_AUTO_LAN,
-    JOIN_ADDRESS,
-} jointype_t;
-
 // Fallback IWAD if none are found to be installed
 
 static iwad_t fallback_iwad = { "doom2.wad", doom2, commercial, "Doom II" };
@@ -132,8 +129,6 @@
 static char *net_player_name;
 static char *chat_macros[10];
 
-static int jointype = JOIN_ADDRESS;
-
 static char *wads[NUM_WADS];
 static char *extra_params[NUM_EXTRA_PARAMS];
 static int character_class = 0;
@@ -156,6 +151,9 @@
 
 static char *connect_address = NULL;
 
+static txt_window_t *query_window;
+static int query_servers_found;
+
 // Find an IWAD from its description
 
 static iwad_t *GetCurrentIWAD(void)
@@ -736,14 +734,7 @@
 
     exec = NewExecuteContext();
 
-    if (jointype == JOIN_ADDRESS)
-    {
-        AddCmdLineParameter(exec, "-connect %s", connect_address);
-    }
-    else if (jointype == JOIN_AUTO_LAN)
-    {
-        AddCmdLineParameter(exec, "-autojoin");
-    }
+    AddCmdLineParameter(exec, "-connect %s", connect_address);
 
     if (gamemission == hexen)
     {
@@ -778,13 +769,91 @@
     return action;
 }
 
-// When an address is entered, select "address" mode.
+static void SelectQueryAddress(TXT_UNCAST_ARG(button), TXT_UNCAST_ARG(addr))
+{
+    TXT_CAST_ARG(txt_button_t, button);
 
-static void SelectAddressJoin(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(unused))
+    free(connect_address);
+    connect_address = strdup(button->label);
+    TXT_CloseWindow(query_window);
+}
+
+static void QueryResponseCallback(net_addr_t *addr,
+                                  net_querydata_t *querydata,
+                                  unsigned int ping_time,
+                                  TXT_UNCAST_ARG(results_table))
 {
-    jointype = JOIN_ADDRESS;
+    TXT_CAST_ARG(txt_table_t, results_table);
+    char ping_time_str[16];
+    char description[47];
+
+    sprintf(ping_time_str, "%ims", ping_time);
+    strncpy(description, querydata->description, 46);
+    description[46] = '\0';
+
+    TXT_AddWidgets(results_table,
+                   TXT_NewButton2(NET_AddrToString(addr),
+                                  SelectQueryAddress, addr),
+                   TXT_NewLabel(description),
+                   TXT_NewLabel(ping_time_str),
+                   NULL);
+
+    ++query_servers_found;
 }
 
+static void QueryPeriodicCallback(TXT_UNCAST_ARG(results_table))
+{
+    TXT_CAST_ARG(txt_table_t, results_table);
+
+    if (!NET_Query_Poll(QueryResponseCallback, results_table))
+    {
+        TXT_SetPeriodicCallback(NULL, NULL, 0);
+
+        if (query_servers_found == 0)
+        {
+            TXT_AddWidget(results_table, NULL);
+            TXT_AddWidget(results_table, TXT_NewLabel("No servers found."));
+        }
+    }
+}
+
+static void QueryWindowClosed(TXT_UNCAST_ARG(window), void *unused)
+{
+    TXT_SetPeriodicCallback(NULL, NULL, 0);
+}
+
+static void ServerQueryWindow(char *title)
+{
+    txt_table_t *results_table;
+
+    query_servers_found = 0;
+
+    query_window = TXT_NewWindow(title);
+
+    TXT_AddWidget(query_window,
+                  TXT_NewScrollPane(70, 10,
+                                    results_table = TXT_NewTable(3)));
+
+    TXT_SetColumnWidths(results_table, 16, 46, 8);
+    TXT_SetPeriodicCallback(QueryPeriodicCallback, results_table, 1);
+
+    TXT_SignalConnect(query_window, "closed", QueryWindowClosed, NULL);
+}
+
+static void FindInternetServer(TXT_UNCAST_ARG(widget),
+                               TXT_UNCAST_ARG(user_data))
+{
+    NET_StartMasterQuery();
+    ServerQueryWindow("Find internet server");
+}
+
+static void FindLANServer(TXT_UNCAST_ARG(widget),
+                          TXT_UNCAST_ARG(user_data))
+{
+    NET_StartLANQuery();
+    ServerQueryWindow("Find LAN server");
+}
+
 void JoinMultiGame(void)
 {
     txt_window_t *window;
@@ -823,11 +892,12 @@
                            TXT_NewLabel("Connect to address: "),
                            address_box = TXT_NewInputBox(&connect_address, 30),
                            NULL),
-                   TXT_NewButton("Find server on Internet..."),
-                   TXT_NewButton("Find server on local network..."),
+                   TXT_NewButton2("Find server on Internet...",
+                                  FindInternetServer, NULL),
+                   TXT_NewButton2("Find server on local network...",
+                                  FindLANServer, NULL),
                    NULL);
 
-    TXT_SignalConnect(address_box, "changed", SelectAddressJoin, NULL);
     TXT_SelectWidget(window, address_box);
 
     TXT_SetWindowAction(window, TXT_HORIZ_CENTER, WadWindowAction());
--- a/textscreen/txt_desktop.c
+++ b/textscreen/txt_desktop.c
@@ -39,6 +39,10 @@
 static int num_windows = 0;
 static int main_loop_running = 0;
 
+static TxtIdleCallback periodic_callback = NULL;
+static void *periodic_callback_data;
+static unsigned int periodic_callback_period;
+
 void TXT_AddDesktopWindow(txt_window_t *win)
 {
     all_windows[num_windows] = win;
@@ -197,6 +201,15 @@
     TXT_UpdateScreen();
 }
 
+void TXT_SetPeriodicCallback(TxtIdleCallback callback,
+                             void *user_data,
+                             unsigned int period)
+{
+    periodic_callback = callback;
+    periodic_callback_data = user_data;
+    periodic_callback_period = period;
+}
+
 void TXT_GUIMainLoop(void)
 {
     main_loop_running = 1;
@@ -211,10 +224,20 @@
         {
             TXT_ExitMainLoop();
         }
-        
+
         TXT_DrawDesktop();
 //        TXT_DrawASCIITable();
-        TXT_Sleep(0);
+
+        if (periodic_callback == NULL)
+        {
+            TXT_Sleep(0);
+        }
+        else
+        {
+            TXT_Sleep(periodic_callback_period);
+
+            periodic_callback(periodic_callback_data);
+        }
     }
 }
 
--- a/textscreen/txt_desktop.h
+++ b/textscreen/txt_desktop.h
@@ -30,6 +30,8 @@
 
 #include "txt_window.h"
 
+typedef void (*TxtIdleCallback)(void *user_data);
+
 void TXT_AddDesktopWindow(txt_window_t *win);
 void TXT_RemoveDesktopWindow(txt_window_t *win);
 void TXT_DrawDesktop(void);
@@ -72,6 +74,21 @@
 
 txt_window_t *TXT_GetActiveWindow(void);
 
-#endif /* #ifndef TXT_DESKTOP_H */
+/**
+ * Set a callback function to be invoked periodically by the main
+ * loop code.
+ *
+ * @param callback      The callback to invoke, or NULL to cancel
+ *                      an existing callback.
+ * @param user_data     Extra data to pass to the callback.
+ * @param period        Maximum time between invoking each callback.
+ *                      eg. a value of 200 will cause the callback
+ *                      to be invoked at least once every 200ms.
+ */
 
+void TXT_SetPeriodicCallback(TxtIdleCallback callback,
+                             void *user_data,
+                             unsigned int period);
+
+#endif /* #ifndef TXT_DESKTOP_H */
 
--- a/textscreen/txt_scrollpane.c
+++ b/textscreen/txt_scrollpane.c
@@ -158,6 +158,18 @@
     {
         ++scrollpane->widget.w;
     }
+
+    if (scrollpane->child != NULL)
+    {
+        if (scrollpane->child->w < scrollpane->w)
+        {
+            scrollpane->child->w = scrollpane->w;
+        }
+        if (scrollpane->child->h < scrollpane->h)
+        {
+            scrollpane->child->h = scrollpane->h;
+        }
+    }
 }
 
 static void TXT_ScrollPaneDrawer(TXT_UNCAST_ARG(scrollpane), int selected)
@@ -382,10 +394,10 @@
         // automatically move the scroll pane to show the new
         // selected item.
 
-        if (scrollpane->child->widget_class == &txt_table_class
-         && (key == KEY_UPARROW || key == KEY_DOWNARROW
+        if ((key == KEY_UPARROW || key == KEY_DOWNARROW
           || key == KEY_LEFTARROW || key == KEY_RIGHTARROW
-          || key == KEY_PGUP || key == KEY_PGDN))
+          || key == KEY_PGUP || key == KEY_PGDN)
+         && scrollpane->child->widget_class == &txt_table_class)
         {
             if (PageSelectedWidget(scrollpane, key))
             {