shithub: choc

Download patch

ref: bb58e40a23c68f51f396babe10db7a6e62cf67f3
parent: d9f9a3b411eb5c2a33527c8a78fa902e07cddd95
author: Simon Howard <fraggle@gmail.com>
date: Fri Dec 5 18:34:04 EST 2008

Auto-select the game type based on detected IWADs. If IWADs from
multiple games are detected, pop up a dialog box to prompt the user to
select a game to configure.

Subversion-branch: /branches/raven-branch
Subversion-revision: 1408

--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -149,7 +149,9 @@
 # Source files needed for chocolate-setup:
 
 SETUP_FILES=                               \
+deh_str.c            deh_str.h             \
 d_mode.c             d_mode.h              \
+d_iwad.c             d_iwad.h              \
 m_config.c           m_config.h            \
 m_controls.c         m_controls.h          \
 z_native.c           z_zone.h
--- a/src/d_iwad.c
+++ b/src/d_iwad.c
@@ -635,3 +635,40 @@
     return result;
 }
 
+// Find all IWADs in the IWAD search path matching the given mask.
+
+iwad_t **D_FindAllIWADs(int mask)
+{
+    iwad_t **result;
+    int result_len;
+    char *filename;
+    int i;
+
+    result = malloc(sizeof(iwad_t *) * (arrlen(iwads) + 1));
+    result_len = 0;
+
+    // Try to find all IWADs
+
+    for (i=0; i<arrlen(iwads); ++i)
+    {
+        if (((1 << iwads[i].mission) & mask) == 0)
+        {
+            continue;
+        }
+
+        filename = D_FindWADByName(iwads[i].name);
+
+        if (filename != NULL)
+        {
+            result[result_len] = &iwads[i];
+            ++result_len;
+        }
+    }
+
+    // End of list
+
+    result[result_len] = NULL;
+
+    return result;
+}
+
--- a/src/d_iwad.h
+++ b/src/d_iwad.h
@@ -45,6 +45,7 @@
 char *D_FindWADByName(char *filename);
 char *D_TryFindWADByName(char *filename);
 char *D_FindIWAD(int mask, GameMission_t *mission);
+iwad_t **D_FindAllIWADs(int mask);
 
 #endif
 
--- a/src/setup/mainmenu.c
+++ b/src/setup/mainmenu.c
@@ -173,7 +173,6 @@
 
 static void InitConfig(void)
 {
-    SetupMission();
     InitBindings();
 
     SetChatMacroDefaults();
@@ -240,15 +239,19 @@
 
     TXT_SetDesktopTitle(PACKAGE_NAME " Setup ver " PACKAGE_VERSION);
     SetIcon();
-    
-    MainMenu();
 
     TXT_GUIMainLoop();
 }
 
-void D_DoomMain(void)
+static void MissionSet(void)
 {
     InitConfig();
+    MainMenu();
+}
+
+void D_DoomMain(void)
+{
+    SetupMission(MissionSet);
     RunGUI();
 }
 
--- a/src/setup/mode.c
+++ b/src/setup/mode.c
@@ -22,9 +22,11 @@
 #include <string.h>
 
 #include "config.h"
+#include "textscreen.h"
 
 #include "doomtype.h"
 #include "d_mode.h"
+#include "d_iwad.h"
 #include "i_system.h"
 #include "m_argv.h"
 #include "m_config.h"
@@ -44,19 +46,48 @@
 
 typedef struct
 {
+    char *label;
     GameMission_t mission;
+    int mask;
     char *name;
     char *config_file;
     char *extra_config_file;
 } mission_config_t;
 
-static mission_config_t config_files[] =
+// Default mission to fall back on, if no IWADs are found at all:
+
+#define DEFAULT_MISSION (&mission_configs[0])
+
+static mission_config_t mission_configs[] =
 {
-    { doom,     "doom",    "default.cfg", PROGRAM_PREFIX "doom.cfg" },
-    { heretic,  "heretic", "heretic.cfg", PROGRAM_PREFIX "heretic.cfg" },
-    { hexen,    "hexen",   "hexen.cfg",   PROGRAM_PREFIX "hexen.cfg" },
+    {
+        "Doom",
+        doom,
+        IWAD_MASK_DOOM,
+        "doom",
+        "default.cfg",
+        PROGRAM_PREFIX "doom.cfg"
+    },
+    {
+        "Heretic",
+        heretic,
+        IWAD_MASK_HERETIC,
+        "heretic",
+        "heretic.cfg",
+        PROGRAM_PREFIX "heretic.cfg"
+    },
+    {
+        "Hexen",
+        hexen,
+        IWAD_MASK_HEXEN,
+        "hexen",
+        "hexen.cfg",
+        PROGRAM_PREFIX "hexen.cfg"
+    }
 };
 
+static GameSelectCallback game_selected_callback;
+
 // Miscellaneous variables that aren't used in setup.
 
 static int showMessages = 1;
@@ -123,11 +154,11 @@
 {
     int i;
 
-    for (i=0; i<arrlen(config_files); ++i)
+    for (i=0; i<arrlen(mission_configs); ++i)
     {
-        if (!strcmp(config_files[i].name, name))
+        if (!strcmp(mission_configs[i].name, name))
         {
-            return &config_files[i];
+            return &mission_configs[i];
         }
     }
 
@@ -134,8 +165,75 @@
     return NULL;
 }
 
-void SetupMission(void)
+static void GameSelected(TXT_UNCAST_ARG(widget), TXT_UNCAST_ARG(config))
 {
+    TXT_CAST_ARG(mission_config_t, config);
+
+    SetMission(config);
+    game_selected_callback();
+}
+
+static void OpenGameSelectDialog(GameSelectCallback callback)
+{
+    mission_config_t *mission;
+    txt_window_t *window;
+    iwad_t **iwads;
+    int num_games;
+    int i;
+
+    window = TXT_NewWindow("Select game");
+
+    TXT_AddWidget(window, TXT_NewLabel("Select a game to configure:\n"));
+    num_games = 0;
+
+    // Add a button for each game.
+
+    for (i=0; i<arrlen(mission_configs); ++i)
+    {
+        // Do we have any IWADs for this game installed?
+        // If so, add a button.
+
+        iwads = D_FindAllIWADs(mission_configs[i].mask);
+
+        if (iwads[0] != NULL)
+        {
+            mission = &mission_configs[i];
+            TXT_AddWidget(window, TXT_NewButton2(mission_configs[i].label,
+                                                 GameSelected,
+                                                 &mission_configs[i]));
+            ++num_games;
+        }
+
+        free(iwads);
+    }
+
+    TXT_AddWidget(window, TXT_NewStrut(0, 1));
+
+    // No IWADs found at all?  Fall back to doom, then.
+
+    if (num_games == 0)
+    {
+        TXT_CloseWindow(window);
+        SetMission(DEFAULT_MISSION);
+        callback();
+        return;
+    }
+
+    // Only one game? Use that game, and don't bother with a dialog.
+
+    if (num_games == 1)
+    {
+        TXT_CloseWindow(window);
+        SetMission(mission);
+        callback();
+        return;
+    }
+
+    game_selected_callback = callback;
+}
+
+void SetupMission(GameSelectCallback callback)
+{
     mission_config_t *config;
     char *mission_name;
     int p;
@@ -149,22 +247,23 @@
 
     p = M_CheckParm("-game");
 
-    if (p > 0) 
+    if (p > 0)
     {
         mission_name = myargv[p + 1];
+
+        config = GetMissionForName(mission_name);
+
+        if (config == NULL)
+        {
+            I_Error("Invalid parameter - '%s'", mission_name);
+        }
+
+        SetMission(config);
+        callback();
     }
     else
     {
-        mission_name = "doom";
+        OpenGameSelectDialog(callback);
     }
-
-    config = GetMissionForName(mission_name);
-
-    if (config == NULL)
-    {
-        I_Error("Invalid parameter - '%s'", mission_name);
-    }
-
-    SetMission(config);
 }
 
--- a/src/setup/mode.h
+++ b/src/setup/mode.h
@@ -24,9 +24,10 @@
 
 #include "d_mode.h"
 
+typedef void (*GameSelectCallback)(void);
 extern GameMission_t gamemission;
 
-void SetupMission(void);
+void SetupMission(GameSelectCallback callback);
 void InitBindings(void);
 
 #endif /* #ifndef SETUP_MODE_H */