Right, FMSelector is in the NewDark package, as an example of how to use the provided facilities to manage FMs. I believe that DarkLoader's current version is not fully compatible (from reading about the problems folk are having) and needs to be updated. The tools to do so are included in NewDark iuf anyone wants to take that on.
Quote:
An FM selector is a separate library (DLL) containing a utility, usually a UI based application, that lists
the available FMs and lets the user pick which one to run. A selector could range from a simple list box
with the FM names or a full blown manager with extended info, last played timestamps, sorting/filtering etc.
The default name for the selector is "FMSEL.DLL", but can be configured with the "fm_selector" cam_mod.ini var.
Exports
-------
The DLL only needs to have a single symbol exported "SelectFM", which is a function in the form of:
int __cdecl SelectFM(sFMSelectorData *data);
The following return values are defined:
0 = 'data->sName' is expected to contain the selected FM name, if string is empty it means no FM
1 = cancel and exit game
Any other value is interpreted as cancel-and-continue, the game will start using the cam_mod.ini based
active FM if defined, otherwise it will run without any FM.
Data types
----------
#pragma pack(4)
typedef struct sFMSelectorData
{
// sizeof(sFMSelectorData)
int nStructSize;
// game version string as returned by AppName() (ie. in the form "Thief 2 Final 1.19")
const char *sGameVersion;
// supplied initial FM root path (the FM selector may change this)
char *sRootPath;
int nMaxRootLen;
// buffer to copy the selected FM name
char *sName;
int nMaxNameLen;
// set to non-zero when selector is invoked after game exit (if requested during game start)
int bExitedGame;
// FM selector should set this to non-zero if it wants to be invoked after game exits (only done for FMs)
int bRunAfterGame;
// optional list of paths to exclude from mod_path/uber_mod_path in + separated format and like the config
// vars, or if "*" all mod paths are excluded (leave buffer empty for no excludes)
// the specified exclude paths work as if they had a "*\" wildcard prefix
char *sModExcludePaths;
int nMaxModExcludeLen;
// language setting for FM (set by the FM selector when an FM is selected), may be empty if FM has no
// language specific resources
// when 'bForceLanguage' is 0 this is used to ensure an FM runs correctly even if it doesn't support
// the game's current language setting (set by the "language" config var)
// when 'bForceLanguage' is 1 this is used to force a language (that must be supported by the FM) other
// than the game's current language
char *sLanguage;
int nLanguageLen;
int bForceLanguage;
} sFMSelectorData;
#pragma pack()
typedef enum eFMSelReturn
{
kSelFMRet_OK = 0, // run selected FM 'data->sName' (0-len string to run without an FM)
kSelFMRet_Cancel = -1, // cancel FM selection and start game as-is (no FM or if defined in cam_mod.ini use that)
kSelFMRet_ExitGame = 1 // abort and quit game
} eFMSelReturn;
typedef int (__cdecl *FMSelectorFunc)(sFMSelectorData*);
Sample implementation
---------------------
A minimal FM selector code sample is included. It simply displays a list of directories in the FM path, that the
user can select from.
The sample is based in part on the work of the FLTK project ((
http://www.fltk.org)).
Personally, I think the FMSelector provided with NewDark does a better job of segregating FMs and preventing corruption, but then again I've never gotten DarkLoader to work. FMSelector seems robust and stable, and more to the point for me, works.