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