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 */