2006-03-20 17:12:09 +00:00
|
|
|
/*
|
2018-09-02 00:57:29 +00:00
|
|
|
* This file is part of the DXX-Rebirth project <https://www.dxx-rebirth.com/>.
|
2014-06-12 08:41:03 +00:00
|
|
|
* It is copyright by its individual contributors, as recorded in the
|
|
|
|
* project's Git history. See COPYING.txt at the top level for license
|
|
|
|
* terms and a link to the Git history.
|
|
|
|
*/
|
2006-03-20 17:12:09 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
* Functions for accessing arguments.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2013-11-10 00:41:38 +00:00
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
2006-03-20 17:12:09 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2013-06-30 02:22:56 +00:00
|
|
|
#include <SDL_stdinc.h>
|
2006-03-20 17:12:09 +00:00
|
|
|
#include "physfsx.h"
|
|
|
|
#include "args.h"
|
|
|
|
#include "u_mem.h"
|
|
|
|
#include "strutil.h"
|
2007-07-14 22:36:04 +00:00
|
|
|
#include "digi.h"
|
2007-10-13 23:52:17 +00:00
|
|
|
#include "game.h"
|
2008-04-06 20:23:28 +00:00
|
|
|
#include "console.h"
|
2016-10-08 23:24:22 +00:00
|
|
|
#include "mission.h"
|
2016-09-11 18:49:15 +00:00
|
|
|
#if DXX_USE_UDP
|
2011-06-30 23:00:59 +00:00
|
|
|
#include "net_udp.h"
|
|
|
|
#endif
|
2007-07-15 21:22:07 +00:00
|
|
|
|
2015-03-22 18:49:20 +00:00
|
|
|
#include "compiler-range_for.h"
|
|
|
|
#include "partial_range.h"
|
|
|
|
|
2016-01-29 04:05:47 +00:00
|
|
|
namespace dcx {
|
|
|
|
CArg CGameArg;
|
2006-03-20 17:12:09 +00:00
|
|
|
|
2016-03-04 04:12:35 +00:00
|
|
|
namespace {
|
|
|
|
|
2020-12-26 21:17:29 +00:00
|
|
|
constexpr std::integral_constant<std::size_t, 1000> MAX_ARGS{};
|
|
|
|
typedef std::vector<std::string> Arglist;
|
|
|
|
|
2015-03-22 18:49:21 +00:00
|
|
|
class ini_entry
|
|
|
|
{
|
|
|
|
public:
|
2020-04-26 17:26:23 +00:00
|
|
|
const std::string filename;
|
2015-03-22 18:49:21 +00:00
|
|
|
ini_entry(std::string &&f) :
|
2020-04-26 17:26:23 +00:00
|
|
|
filename(std::move(f))
|
2015-03-22 18:49:21 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef std::vector<ini_entry> Inilist;
|
2006-03-20 17:12:09 +00:00
|
|
|
|
2013-11-10 18:31:52 +00:00
|
|
|
class argument_exception
|
|
|
|
{
|
|
|
|
public:
|
2015-03-22 18:49:21 +00:00
|
|
|
const std::string arg;
|
|
|
|
argument_exception(std::string &&a) :
|
|
|
|
arg(std::move(a))
|
|
|
|
{
|
|
|
|
}
|
2013-11-10 18:31:52 +00:00
|
|
|
};
|
2007-07-14 20:33:42 +00:00
|
|
|
|
2013-11-10 18:31:52 +00:00
|
|
|
class missing_parameter : public argument_exception
|
2006-03-20 17:12:09 +00:00
|
|
|
{
|
2013-11-10 18:31:52 +00:00
|
|
|
public:
|
2020-04-26 17:26:23 +00:00
|
|
|
using argument_exception::argument_exception;
|
2013-11-10 18:31:52 +00:00
|
|
|
};
|
2006-03-20 17:12:09 +00:00
|
|
|
|
2013-11-10 18:31:52 +00:00
|
|
|
class unhandled_argument : public argument_exception
|
|
|
|
{
|
|
|
|
public:
|
2020-04-26 17:26:23 +00:00
|
|
|
using argument_exception::argument_exception;
|
2013-11-10 18:31:52 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class conversion_failure : public argument_exception
|
|
|
|
{
|
|
|
|
public:
|
2015-03-22 18:49:21 +00:00
|
|
|
const std::string value;
|
|
|
|
conversion_failure(std::string &&a, std::string &&v) :
|
|
|
|
argument_exception(std::move(a)), value(std::move(v))
|
|
|
|
{
|
|
|
|
}
|
2013-11-10 18:31:52 +00:00
|
|
|
};
|
|
|
|
|
2015-03-22 18:49:21 +00:00
|
|
|
class nesting_depth_exceeded
|
|
|
|
{
|
2013-11-10 18:31:52 +00:00
|
|
|
};
|
|
|
|
|
2015-03-22 18:49:21 +00:00
|
|
|
static void AppendIniArgs(const char *filename, Arglist &Args)
|
2007-07-14 20:33:42 +00:00
|
|
|
{
|
2021-07-25 23:00:56 +00:00
|
|
|
if (auto f = PHYSFSX_openReadBuffered(filename).first)
|
2015-01-17 18:31:42 +00:00
|
|
|
{
|
2014-09-07 19:48:10 +00:00
|
|
|
PHYSFSX_gets_line_t<1024> line;
|
2015-10-09 02:46:11 +00:00
|
|
|
while (Args.size() < MAX_ARGS && PHYSFSX_fgets(line, f))
|
2007-07-14 20:33:42 +00:00
|
|
|
{
|
2016-05-12 13:15:26 +00:00
|
|
|
const auto separator = " \t";
|
2013-08-03 15:50:56 +00:00
|
|
|
for(char *token = strtok(line, separator); token != NULL; token = strtok(NULL, separator))
|
2014-05-24 23:03:19 +00:00
|
|
|
{
|
|
|
|
if (*token == ';')
|
|
|
|
break;
|
2013-11-10 00:41:38 +00:00
|
|
|
Args.push_back(token);
|
2014-05-24 23:03:19 +00:00
|
|
|
}
|
2007-07-14 20:33:42 +00:00
|
|
|
}
|
|
|
|
}
|
2007-10-12 20:09:26 +00:00
|
|
|
}
|
|
|
|
|
2015-03-22 18:49:20 +00:00
|
|
|
static std::string &&arg_string(Arglist::iterator &pp, Arglist::const_iterator end)
|
2013-11-10 18:31:52 +00:00
|
|
|
{
|
2015-03-22 18:49:20 +00:00
|
|
|
auto arg = pp;
|
2013-11-10 18:31:52 +00:00
|
|
|
if (++pp == end)
|
2015-03-22 18:49:21 +00:00
|
|
|
throw missing_parameter(std::move(*arg));
|
2015-03-22 18:49:20 +00:00
|
|
|
return std::move(*pp);
|
2007-10-12 20:09:26 +00:00
|
|
|
}
|
2013-11-10 18:31:52 +00:00
|
|
|
|
2015-03-22 18:49:20 +00:00
|
|
|
static long arg_integer(Arglist::iterator &pp, Arglist::const_iterator end)
|
2013-11-10 18:31:52 +00:00
|
|
|
{
|
2015-03-22 18:49:20 +00:00
|
|
|
auto arg = pp;
|
|
|
|
auto &&value = arg_string(pp, end);
|
2013-11-10 18:31:52 +00:00
|
|
|
char *p;
|
2015-03-22 18:49:20 +00:00
|
|
|
auto i = strtol(value.c_str(), &p, 10);
|
2013-11-10 18:31:52 +00:00
|
|
|
if (*p)
|
2015-03-22 18:49:21 +00:00
|
|
|
throw conversion_failure(std::move(*arg), std::move(value));
|
2013-11-10 18:31:52 +00:00
|
|
|
return i;
|
2007-07-14 20:33:42 +00:00
|
|
|
}
|
|
|
|
|
2015-03-23 19:18:17 +00:00
|
|
|
template<typename E> E arg_enum(Arglist::iterator &pp, Arglist::const_iterator end)
|
2015-03-22 17:17:11 +00:00
|
|
|
{
|
|
|
|
return static_cast<E>(arg_integer(pp, end));
|
|
|
|
}
|
|
|
|
|
2016-10-31 10:21:59 +00:00
|
|
|
#if DXX_USE_UDP
|
2015-03-22 18:49:20 +00:00
|
|
|
static void arg_port_number(Arglist::iterator &pp, Arglist::const_iterator end, uint16_t &out, bool allow_privileged)
|
2015-01-24 19:16:35 +00:00
|
|
|
{
|
|
|
|
auto port = arg_integer(pp, end);
|
|
|
|
if (static_cast<uint16_t>(port) == port && (allow_privileged || port >= 1024))
|
|
|
|
out = port;
|
|
|
|
}
|
2016-10-31 10:21:59 +00:00
|
|
|
#endif
|
2015-01-24 19:16:35 +00:00
|
|
|
|
2015-03-22 18:49:21 +00:00
|
|
|
static void InitGameArg()
|
2007-07-14 20:33:42 +00:00
|
|
|
{
|
2015-11-24 04:05:35 +00:00
|
|
|
CGameArg.SysMaxFPS = MAXIMUM_FPS;
|
2016-09-11 18:49:15 +00:00
|
|
|
#if DXX_USE_UDP
|
2015-12-24 04:01:27 +00:00
|
|
|
CGameArg.MplUdpHostAddr = UDP_MANUAL_ADDR_DEFAULT;
|
2016-09-11 18:49:15 +00:00
|
|
|
#if DXX_USE_TRACKER
|
2015-12-24 04:01:29 +00:00
|
|
|
CGameArg.MplTrackerAddr = TRACKER_ADDR_DEFAULT;
|
2015-12-24 04:01:29 +00:00
|
|
|
CGameArg.MplTrackerPort = TRACKER_PORT_DEFAULT;
|
2013-11-10 18:31:52 +00:00
|
|
|
#endif
|
|
|
|
#endif
|
2015-10-18 21:01:21 +00:00
|
|
|
CGameArg.DbgVerbose = CON_NORMAL;
|
2015-12-18 04:08:23 +00:00
|
|
|
CGameArg.DbgBpp = 32;
|
2016-09-24 18:06:11 +00:00
|
|
|
#if DXX_USE_OGL
|
2015-12-24 04:01:27 +00:00
|
|
|
CGameArg.OglSyncMethod = OGL_SYNC_METHOD_DEFAULT;
|
2015-12-24 04:01:27 +00:00
|
|
|
CGameArg.OglSyncWait = OGL_SYNC_WAIT_DEFAULT;
|
2021-03-15 18:32:10 +00:00
|
|
|
CGameArg.OglStereo = false;
|
2015-12-18 04:08:23 +00:00
|
|
|
CGameArg.DbgGlIntensity4Ok = true;
|
2015-12-18 04:08:24 +00:00
|
|
|
CGameArg.DbgGlLuminance4Alpha4Ok = true;
|
2015-12-18 04:08:24 +00:00
|
|
|
CGameArg.DbgGlRGBA2Ok = true;
|
2015-12-18 04:08:24 +00:00
|
|
|
CGameArg.DbgGlReadPixelsOk = true;
|
2015-12-18 04:08:24 +00:00
|
|
|
CGameArg.DbgGlGetTexLevelParamOk = true;
|
2013-11-10 18:31:52 +00:00
|
|
|
#endif
|
2015-03-22 18:49:21 +00:00
|
|
|
}
|
|
|
|
|
2016-03-02 02:52:44 +00:00
|
|
|
}
|
|
|
|
|
2020-12-26 21:17:29 +00:00
|
|
|
}
|
|
|
|
|
2016-03-02 02:52:44 +00:00
|
|
|
namespace dsx {
|
|
|
|
|
|
|
|
Arg GameArg;
|
|
|
|
|
2020-12-26 21:17:29 +00:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
static void InitGameArg()
|
|
|
|
{
|
|
|
|
#if defined(DXX_BUILD_DESCENT_II)
|
|
|
|
GameArg.SndDigiSampleRate = SAMPLE_RATE_22K;
|
|
|
|
#endif
|
|
|
|
::dcx::InitGameArg();
|
|
|
|
}
|
|
|
|
|
2016-03-02 02:52:44 +00:00
|
|
|
static void ReadCmdArgs(Inilist &ini, Arglist &Args);
|
|
|
|
|
2015-03-22 18:49:21 +00:00
|
|
|
static void ReadIniArgs(Inilist &ini)
|
|
|
|
{
|
|
|
|
Arglist Args;
|
2020-04-26 17:26:23 +00:00
|
|
|
AppendIniArgs(ini.back().filename.c_str(), Args);
|
2015-03-22 18:49:21 +00:00
|
|
|
ReadCmdArgs(ini, Args);
|
2016-05-31 00:42:56 +00:00
|
|
|
ini.pop_back();
|
2015-03-22 18:49:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ReadCmdArgs(Inilist &ini, Arglist &Args)
|
|
|
|
{
|
2015-03-22 18:49:20 +00:00
|
|
|
for (Arglist::iterator pp = Args.begin(), end = Args.end(); pp != end; ++pp)
|
2013-11-10 18:31:52 +00:00
|
|
|
{
|
|
|
|
const char *p = pp->c_str();
|
2007-07-14 20:33:42 +00:00
|
|
|
// System Options
|
|
|
|
|
2013-11-10 18:31:52 +00:00
|
|
|
if (!d_stricmp(p, "-help") || !d_stricmp(p, "-h") || !d_stricmp(p, "-?") || !d_stricmp(p, "?"))
|
2015-11-24 04:05:35 +00:00
|
|
|
CGameArg.SysShowCmdHelp = true;
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-nonicefps"))
|
2015-12-24 04:01:26 +00:00
|
|
|
CGameArg.SysNoNiceFPS = true;
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-maxfps"))
|
2015-11-24 04:05:35 +00:00
|
|
|
CGameArg.SysMaxFPS = arg_integer(pp, end);
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-hogdir"))
|
2015-12-24 04:01:26 +00:00
|
|
|
CGameArg.SysHogDir = arg_string(pp, end);
|
2015-10-11 22:21:00 +00:00
|
|
|
#if PHYSFS_VER_MAJOR >= 2
|
|
|
|
else if (!d_stricmp(p, "-add-missions-dir"))
|
2015-11-24 04:05:35 +00:00
|
|
|
CGameArg.SysMissionDir = arg_string(pp, end);
|
2015-10-11 22:21:00 +00:00
|
|
|
#endif
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-nohogdir"))
|
2015-09-22 02:28:38 +00:00
|
|
|
{
|
2018-09-14 02:20:55 +00:00
|
|
|
/* No effect if no DXX_SHAREPATH. Ignore it so that players can
|
2015-09-22 02:28:38 +00:00
|
|
|
* pass it via a cross-platform ini.
|
|
|
|
*/
|
2018-09-14 02:20:55 +00:00
|
|
|
#if DXX_USE_SHAREPATH
|
2019-01-20 05:36:56 +00:00
|
|
|
GameArg.SysNoHogDir = true;
|
2015-09-22 02:28:38 +00:00
|
|
|
#endif
|
|
|
|
}
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-use_players_dir"))
|
2016-07-22 02:25:17 +00:00
|
|
|
CGameArg.SysUsePlayersDir = static_cast<int8_t>(- (sizeof(PLAYER_DIRECTORY_TEXT) - 1));
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-lowmem"))
|
2015-12-24 04:01:26 +00:00
|
|
|
CGameArg.SysLowMem = true;
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-pilot"))
|
2015-12-24 04:01:26 +00:00
|
|
|
CGameArg.SysPilot = arg_string(pp, end);
|
2015-02-28 19:36:02 +00:00
|
|
|
else if (!d_stricmp(p, "-record-demo-format"))
|
2015-12-24 04:01:26 +00:00
|
|
|
CGameArg.SysRecordDemoNameTemplate = arg_string(pp, end);
|
2015-02-28 19:36:02 +00:00
|
|
|
else if (!d_stricmp(p, "-auto-record-demo"))
|
2015-12-24 04:01:27 +00:00
|
|
|
CGameArg.SysAutoRecordDemo = true;
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-window"))
|
2015-12-24 04:01:27 +00:00
|
|
|
CGameArg.SysWindow = true;
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-noborders"))
|
2015-12-24 04:01:27 +00:00
|
|
|
CGameArg.SysNoBorders = true;
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-notitles"))
|
2015-12-24 04:01:27 +00:00
|
|
|
CGameArg.SysNoTitles = true;
|
2015-10-09 02:46:09 +00:00
|
|
|
#if defined(DXX_BUILD_DESCENT_II)
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-nomovies"))
|
|
|
|
GameArg.SysNoMovies = 1;
|
2013-03-03 01:03:33 +00:00
|
|
|
#endif
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-autodemo"))
|
2015-12-24 04:01:27 +00:00
|
|
|
CGameArg.SysAutoDemo = true;
|
2007-10-01 20:42:35 +00:00
|
|
|
|
2007-07-14 20:33:42 +00:00
|
|
|
// Control Options
|
|
|
|
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-nocursor"))
|
2015-07-18 21:01:56 +00:00
|
|
|
CGameArg.CtlNoCursor = true;
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-nomouse"))
|
2015-07-18 21:01:56 +00:00
|
|
|
CGameArg.CtlNoMouse = true;
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-nojoystick"))
|
2015-11-26 02:56:55 +00:00
|
|
|
{
|
2016-09-25 04:52:48 +00:00
|
|
|
#if DXX_MAX_JOYSTICKS
|
2015-11-26 02:56:55 +00:00
|
|
|
CGameArg.CtlNoJoystick = 1;
|
|
|
|
#endif
|
|
|
|
}
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-nostickykeys"))
|
2015-07-18 21:01:56 +00:00
|
|
|
CGameArg.CtlNoStickyKeys = true;
|
2007-07-14 22:36:04 +00:00
|
|
|
|
|
|
|
// Sound Options
|
|
|
|
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-nosound"))
|
2015-11-24 04:05:36 +00:00
|
|
|
CGameArg.SndNoSound = 1;
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-nomusic"))
|
2015-12-24 04:01:26 +00:00
|
|
|
CGameArg.SndNoMusic = true;
|
2013-03-03 01:03:33 +00:00
|
|
|
#if defined(DXX_BUILD_DESCENT_II)
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-sound11k"))
|
|
|
|
GameArg.SndDigiSampleRate = SAMPLE_RATE_11K;
|
2013-03-03 01:03:33 +00:00
|
|
|
#endif
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-nosdlmixer"))
|
2015-02-08 17:43:29 +00:00
|
|
|
{
|
2016-09-11 18:49:15 +00:00
|
|
|
#if DXX_USE_SDLMIXER
|
2015-11-24 04:05:36 +00:00
|
|
|
CGameArg.SndDisableSdlMixer = true;
|
2007-09-18 13:37:39 +00:00
|
|
|
#endif
|
2015-02-08 17:43:29 +00:00
|
|
|
}
|
2007-09-18 13:37:39 +00:00
|
|
|
|
2007-07-15 15:23:45 +00:00
|
|
|
// Graphics Options
|
|
|
|
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-lowresfont"))
|
2015-12-24 04:01:26 +00:00
|
|
|
CGameArg.GfxSkipHiresFNT = true;
|
2013-03-03 01:03:33 +00:00
|
|
|
#if defined(DXX_BUILD_DESCENT_II)
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-lowresgraphics"))
|
|
|
|
GameArg.GfxSkipHiresGFX = 1;
|
|
|
|
else if (!d_stricmp(p, "-lowresmovies"))
|
|
|
|
GameArg.GfxSkipHiresMovie = 1;
|
2013-03-03 01:03:33 +00:00
|
|
|
#endif
|
2016-09-24 18:06:11 +00:00
|
|
|
#if DXX_USE_OGL
|
2007-07-15 21:22:07 +00:00
|
|
|
// OpenGL Options
|
|
|
|
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-gl_fixedfont"))
|
2015-12-24 04:01:27 +00:00
|
|
|
CGameArg.OglFixedFont = true;
|
2015-03-22 17:17:11 +00:00
|
|
|
else if (!d_stricmp(p, "-gl_syncmethod"))
|
2015-12-24 04:01:27 +00:00
|
|
|
CGameArg.OglSyncMethod = arg_enum<SyncGLMethod>(pp, end);
|
2015-03-22 17:17:11 +00:00
|
|
|
else if (!d_stricmp(p, "-gl_syncwait"))
|
2015-12-24 04:01:27 +00:00
|
|
|
CGameArg.OglSyncWait = arg_integer(pp, end);
|
2016-08-29 15:07:30 +00:00
|
|
|
else if (!d_stricmp(p, "-gl_darkedges"))
|
|
|
|
CGameArg.OglDarkEdges = true;
|
2021-03-09 20:59:20 +00:00
|
|
|
else if (!d_stricmp(p, "-gl_stereo"))
|
|
|
|
CGameArg.OglStereo = true;
|
2021-03-12 18:07:45 +00:00
|
|
|
else if (!d_stricmp(p, "-gl_stereoview"))
|
|
|
|
CGameArg.OglStereoView = arg_integer(pp, end);
|
2007-07-15 21:22:07 +00:00
|
|
|
#endif
|
|
|
|
|
2007-07-16 02:34:51 +00:00
|
|
|
// Multiplayer Options
|
|
|
|
|
2016-09-11 18:49:15 +00:00
|
|
|
#if DXX_USE_UDP
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-udp_hostaddr"))
|
2015-12-24 04:01:27 +00:00
|
|
|
CGameArg.MplUdpHostAddr = arg_string(pp, end);
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-udp_hostport"))
|
2015-01-25 05:32:44 +00:00
|
|
|
/* Peers use -udp_myport to change, so peer cannot set a
|
|
|
|
* privileged port.
|
|
|
|
*/
|
2015-12-24 04:01:28 +00:00
|
|
|
arg_port_number(pp, end, CGameArg.MplUdpHostPort, false);
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-udp_myport"))
|
2014-09-17 02:16:33 +00:00
|
|
|
{
|
2015-12-24 04:01:29 +00:00
|
|
|
arg_port_number(pp, end, CGameArg.MplUdpMyPort, false);
|
2014-09-17 02:16:33 +00:00
|
|
|
}
|
2015-01-24 19:16:35 +00:00
|
|
|
else if (!d_stricmp(p, "-no-tracker"))
|
|
|
|
{
|
|
|
|
/* Always recognized. No-op if tracker support compiled
|
|
|
|
* out. */
|
2016-09-11 18:49:15 +00:00
|
|
|
#if DXX_USE_TRACKER
|
2015-12-24 04:01:29 +00:00
|
|
|
CGameArg.MplTrackerAddr.clear();
|
2015-01-24 19:16:35 +00:00
|
|
|
#endif
|
|
|
|
}
|
2016-09-11 18:49:15 +00:00
|
|
|
#if DXX_USE_TRACKER
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-tracker_hostaddr"))
|
2015-01-24 19:16:35 +00:00
|
|
|
{
|
2015-12-24 04:01:29 +00:00
|
|
|
CGameArg.MplTrackerAddr = arg_string(pp, end);
|
2015-01-24 19:16:35 +00:00
|
|
|
}
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-tracker_hostport"))
|
2015-12-24 04:01:29 +00:00
|
|
|
arg_port_number(pp, end, CGameArg.MplTrackerPort, true);
|
2011-06-30 23:00:59 +00:00
|
|
|
#endif
|
2011-04-05 00:24:34 +00:00
|
|
|
#endif
|
2007-07-16 02:34:51 +00:00
|
|
|
|
2013-03-03 01:03:33 +00:00
|
|
|
#if defined(DXX_BUILD_DESCENT_I)
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-nobm"))
|
|
|
|
GameArg.EdiNoBm = 1;
|
2013-03-03 01:03:33 +00:00
|
|
|
#elif defined(DXX_BUILD_DESCENT_II)
|
2016-09-11 18:49:16 +00:00
|
|
|
#if DXX_USE_EDITOR
|
2007-07-14 22:36:04 +00:00
|
|
|
// Editor Options
|
|
|
|
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-autoload"))
|
|
|
|
GameArg.EdiAutoLoad = arg_string(pp, end);
|
|
|
|
else if (!d_stricmp(p, "-macdata"))
|
|
|
|
GameArg.EdiMacData = 1;
|
|
|
|
else if (!d_stricmp(p, "-hoarddata"))
|
|
|
|
GameArg.EdiSaveHoardData = 1;
|
2013-03-03 01:03:33 +00:00
|
|
|
#endif
|
2007-07-15 21:22:07 +00:00
|
|
|
#endif
|
2007-07-18 20:13:17 +00:00
|
|
|
|
|
|
|
// Debug Options
|
|
|
|
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-debug"))
|
2022-05-16 08:03:34 +00:00
|
|
|
{
|
|
|
|
if (CGameArg.DbgVerbose < CON_DEBUG)
|
|
|
|
CGameArg.DbgVerbose = CON_DEBUG;
|
|
|
|
}
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-verbose"))
|
2022-05-16 08:03:34 +00:00
|
|
|
{
|
|
|
|
if (CGameArg.DbgVerbose < CON_VERBOSE)
|
|
|
|
CGameArg.DbgVerbose = CON_VERBOSE;
|
|
|
|
}
|
2013-11-10 18:31:52 +00:00
|
|
|
|
2012-06-10 22:26:20 +00:00
|
|
|
else if (!d_stricmp(p, "-no-grab"))
|
2015-07-18 21:01:56 +00:00
|
|
|
CGameArg.DbgForbidConsoleGrab = true;
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-safelog"))
|
2015-10-18 21:01:21 +00:00
|
|
|
CGameArg.DbgSafelog = true;
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-norun"))
|
2015-12-24 04:01:28 +00:00
|
|
|
CGameArg.DbgNoRun = true;
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-renderstats"))
|
2015-12-24 04:01:28 +00:00
|
|
|
CGameArg.DbgRenderStats = true;
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-text"))
|
2015-12-24 04:01:28 +00:00
|
|
|
CGameArg.DbgAltTex = arg_string(pp, end);
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-showmeminfo"))
|
2015-08-11 03:05:55 +00:00
|
|
|
CGameArg.DbgShowMemInfo = 1;
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-nodoublebuffer"))
|
2015-12-24 04:01:28 +00:00
|
|
|
CGameArg.DbgNoDoubleBuffer = true;
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-bigpig"))
|
2015-12-24 04:01:28 +00:00
|
|
|
CGameArg.DbgNoCompressPigBitmap = true;
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-16bpp"))
|
2015-12-18 04:08:23 +00:00
|
|
|
CGameArg.DbgBpp = 16;
|
2007-07-22 20:40:39 +00:00
|
|
|
|
2016-09-24 18:06:11 +00:00
|
|
|
#if DXX_USE_OGL
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-gl_oldtexmerge"))
|
2015-12-18 04:08:24 +00:00
|
|
|
CGameArg.DbgUseOldTextureMerge = true;
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-gl_intensity4_ok"))
|
2015-12-18 04:08:23 +00:00
|
|
|
CGameArg.DbgGlIntensity4Ok = arg_integer(pp, end);
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-gl_luminance4_alpha4_ok"))
|
2015-12-18 04:08:24 +00:00
|
|
|
CGameArg.DbgGlLuminance4Alpha4Ok = arg_integer(pp, end);
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-gl_rgba2_ok"))
|
2015-12-18 04:08:24 +00:00
|
|
|
CGameArg.DbgGlRGBA2Ok = arg_integer(pp, end);
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-gl_readpixels_ok"))
|
2015-12-18 04:08:24 +00:00
|
|
|
CGameArg.DbgGlReadPixelsOk = arg_integer(pp, end);
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-gl_gettexlevelparam_ok"))
|
2015-12-18 04:08:24 +00:00
|
|
|
CGameArg.DbgGlGetTexLevelParamOk = arg_integer(pp, end);
|
2007-07-23 18:13:49 +00:00
|
|
|
#else
|
2017-11-01 02:01:20 +00:00
|
|
|
else if (!d_stricmp(p, "-tmap"))
|
|
|
|
CGameArg.DbgTexMap = arg_string(pp, end);
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-hwsurface"))
|
2015-12-24 04:01:27 +00:00
|
|
|
CGameArg.DbgSdlHWSurface = true;
|
2013-11-10 18:31:52 +00:00
|
|
|
else if (!d_stricmp(p, "-asyncblit"))
|
2015-12-24 04:01:28 +00:00
|
|
|
CGameArg.DbgSdlASyncBlit = true;
|
2007-07-22 01:34:00 +00:00
|
|
|
#endif
|
2015-03-22 18:49:21 +00:00
|
|
|
else if (!d_stricmp(p, "-ini"))
|
|
|
|
{
|
|
|
|
ini.emplace_back(arg_string(pp, end));
|
|
|
|
if (ini.size() > 10)
|
|
|
|
throw nesting_depth_exceeded();
|
|
|
|
ReadIniArgs(ini);
|
|
|
|
}
|
2018-08-22 18:10:33 +00:00
|
|
|
#if defined(__APPLE__) && defined(__MACH__)
|
2018-08-21 19:04:21 +00:00
|
|
|
else if (!strncmp(p, "-psn", 4))
|
|
|
|
{
|
|
|
|
//do nothing/gobble it up
|
|
|
|
}
|
2018-08-22 18:10:33 +00:00
|
|
|
#endif
|
2013-11-10 18:31:52 +00:00
|
|
|
else
|
2015-03-22 18:49:21 +00:00
|
|
|
throw unhandled_argument(std::move(*pp));
|
2013-11-10 18:31:52 +00:00
|
|
|
}
|
2015-03-22 18:49:21 +00:00
|
|
|
}
|
2013-11-10 18:31:52 +00:00
|
|
|
|
2016-03-02 02:52:44 +00:00
|
|
|
}
|
|
|
|
|
2020-12-26 21:17:29 +00:00
|
|
|
}
|
|
|
|
|
2016-03-02 02:52:44 +00:00
|
|
|
namespace dcx {
|
|
|
|
|
2020-12-26 21:17:29 +00:00
|
|
|
namespace {
|
|
|
|
|
2015-03-22 18:49:21 +00:00
|
|
|
static void PostProcessGameArg()
|
|
|
|
{
|
2015-11-24 04:05:35 +00:00
|
|
|
if (CGameArg.SysMaxFPS < MINIMUM_FPS)
|
|
|
|
CGameArg.SysMaxFPS = MINIMUM_FPS;
|
|
|
|
else if (CGameArg.SysMaxFPS > MAXIMUM_FPS)
|
|
|
|
CGameArg.SysMaxFPS = MAXIMUM_FPS;
|
2015-10-11 22:21:00 +00:00
|
|
|
#if PHYSFS_VER_MAJOR >= 2
|
2015-11-24 04:05:35 +00:00
|
|
|
if (!CGameArg.SysMissionDir.empty())
|
|
|
|
PHYSFS_mount(CGameArg.SysMissionDir.c_str(), MISSION_DIR, 1);
|
2015-10-11 22:21:00 +00:00
|
|
|
#endif
|
2013-11-10 18:31:52 +00:00
|
|
|
|
2018-07-28 23:22:58 +00:00
|
|
|
#if SDL_MAJOR_VERSION == 1
|
2013-11-10 18:31:52 +00:00
|
|
|
static char sdl_disable_lock_keys[] = "SDL_DISABLE_LOCK_KEYS=0";
|
2015-07-18 21:01:56 +00:00
|
|
|
if (CGameArg.CtlNoStickyKeys) // Must happen before SDL_Init!
|
2016-09-05 09:31:22 +00:00
|
|
|
sdl_disable_lock_keys[sizeof(sdl_disable_lock_keys) - 2] = '1';
|
2013-11-10 18:31:52 +00:00
|
|
|
SDL_putenv(sdl_disable_lock_keys);
|
2018-07-28 23:22:58 +00:00
|
|
|
#endif
|
2007-07-14 20:33:42 +00:00
|
|
|
}
|
|
|
|
|
2015-03-22 18:49:21 +00:00
|
|
|
static std::string ConstructIniStackExplanation(const Inilist &ini)
|
2006-03-20 17:12:09 +00:00
|
|
|
{
|
2015-03-22 18:49:21 +00:00
|
|
|
Inilist::const_reverse_iterator i = ini.rbegin(), e = ini.rend();
|
|
|
|
if (i == e)
|
|
|
|
return " while processing <command line>";
|
|
|
|
std::string result;
|
|
|
|
result.reserve(ini.size() * 128);
|
|
|
|
result += " while processing \"";
|
|
|
|
for (;;)
|
|
|
|
{
|
2020-04-26 17:26:23 +00:00
|
|
|
result += i->filename;
|
2015-03-22 18:49:21 +00:00
|
|
|
if (++ i == e)
|
|
|
|
return result += "\"";
|
|
|
|
result += "\"\n included from \"";
|
|
|
|
}
|
2006-03-20 17:12:09 +00:00
|
|
|
}
|
|
|
|
|
2016-03-02 02:52:44 +00:00
|
|
|
}
|
|
|
|
|
2020-12-26 21:17:29 +00:00
|
|
|
}
|
|
|
|
|
2016-03-02 02:52:44 +00:00
|
|
|
namespace dsx {
|
|
|
|
|
2015-01-28 03:42:53 +00:00
|
|
|
bool InitArgs( int argc,char **argv )
|
2006-03-20 17:12:09 +00:00
|
|
|
{
|
2015-03-22 18:49:21 +00:00
|
|
|
InitGameArg();
|
2006-03-20 17:12:09 +00:00
|
|
|
|
2015-03-22 18:49:21 +00:00
|
|
|
Inilist ini;
|
2013-11-10 18:31:52 +00:00
|
|
|
try {
|
2015-03-22 18:49:21 +00:00
|
|
|
{
|
|
|
|
assert(ini.empty());
|
2016-03-02 02:52:44 +00:00
|
|
|
#if defined(DXX_BUILD_DESCENT_I)
|
|
|
|
const auto INI_FILENAME = "d1x.ini";
|
|
|
|
#elif defined(DXX_BUILD_DESCENT_II)
|
|
|
|
const auto INI_FILENAME = "d2x.ini";
|
|
|
|
#endif
|
2015-03-22 18:49:21 +00:00
|
|
|
ini.emplace_back(INI_FILENAME);
|
|
|
|
ReadIniArgs(ini);
|
|
|
|
}
|
2016-05-10 15:54:57 +00:00
|
|
|
{
|
|
|
|
Arglist Args;
|
|
|
|
Args.reserve(argc);
|
|
|
|
range_for (auto &i, unchecked_partial_range(argv, 1u, static_cast<unsigned>(argc)))
|
|
|
|
Args.push_back(i);
|
|
|
|
ReadCmdArgs(ini, Args);
|
|
|
|
}
|
2015-03-22 18:49:21 +00:00
|
|
|
PostProcessGameArg();
|
2015-01-28 03:42:53 +00:00
|
|
|
return true;
|
2013-11-10 18:31:52 +00:00
|
|
|
} catch(const missing_parameter& e) {
|
2015-06-16 03:15:40 +00:00
|
|
|
UserError("Missing parameter for argument \"%s\"%s", e.arg.c_str(), ConstructIniStackExplanation(ini).c_str());
|
2013-11-10 18:31:52 +00:00
|
|
|
} catch(const unhandled_argument& e) {
|
2015-06-16 03:15:40 +00:00
|
|
|
UserError("Unhandled argument \"%s\"%s", e.arg.c_str(), ConstructIniStackExplanation(ini).c_str());
|
2013-11-10 18:31:52 +00:00
|
|
|
} catch(const conversion_failure& e) {
|
2015-06-16 03:15:40 +00:00
|
|
|
UserError("Failed to convert argument \"%s\" parameter \"%s\"%s", e.arg.c_str(), e.value.c_str(), ConstructIniStackExplanation(ini).c_str());
|
2015-03-22 18:49:21 +00:00
|
|
|
} catch(const nesting_depth_exceeded &) {
|
2015-06-16 03:15:40 +00:00
|
|
|
UserError("Nesting depth exceeded%s", ConstructIniStackExplanation(ini).c_str());
|
2013-11-10 18:31:52 +00:00
|
|
|
}
|
2015-01-28 03:42:53 +00:00
|
|
|
return false;
|
2006-03-20 17:12:09 +00:00
|
|
|
}
|
2015-12-13 18:00:48 +00:00
|
|
|
|
|
|
|
}
|