Move the new incomplete command line parser to Core

This commit is contained in:
Henrik Rydgård committed 2026-07-20 12:02:07 +02:00
1 parent a886cfb5ab
commit 29836ea74e
10 files changed
+141 -117

No files matched your search

+2
View File
@@ -2142,6 +2142,8 @@ endif()
add_library(${CoreLibName} ${CoreLinkType}
${CoreExtra}
${CommonJIT}
Core/CmdLine.cpp
Core/CmdLine.h
Core/Config.cpp
Core/Config.h
Core/ConfigSettings.cpp
+94
View File
@@ -0,0 +1,94 @@
#include "Core/Config.h"
#include "Core/CmdLine.h"
#include "Common/StringUtils.h"
void CommandLineOptions::Parse(int argc, const char *argv[]) {
constexpr std::string_view gpuBackendStr = "--graphics=";
constexpr std::string_view configOption = "--config=";
constexpr std::string_view controlsOption = "--controlconfig=";
#ifdef _DEBUG
enableLogging = true;
#endif
// The rest is handled in NativeInit().
for (size_t i = 1; i < argc; ++i) {
const size_t len = strlen(argv[i]);
if (argv[i][0] != '-' || len < 2) {
continue;
}
// single char commands, like -l, -s, -d
if (len == 2) {
switch (argv[i][1]) {
case 'l':
showLogWindow = true;
enableLogging = true;
break;
case 's':
optionS = true;
break;
case 'd':
debugLogLevel = true;
break;
}
}
// Simple bool commands
// NOTE: We need to parse --fullscreen early, before we create the window.
if (equals(argv[i], "--fullscreen")) {
fullscreen = true;
} else if (equals(argv[i], "--windowed")) {
fullscreen = false;
}
// Commands with parameters. TODO: Should support both space and equals, like --config=foo.ini and --config foo.ini
if (startsWith(argv[i], gpuBackendStr)) {
const std::string_view restOfOption = argv[i] + gpuBackendStr.size();
// Force software rendering off, as picking gles implies HW acceleration.
// We could add more options for software such as "software-gles",
// "software-vulkan" and "software-d3d11", or something similar.
// For now, software rendering force-activates OpenGL.
if (restOfOption == "directx11" || restOfOption == "d3d11") {
gpuBackend = GPUBackend::DIRECT3D11;
softwareRendering = false;
} else if (restOfOption == "gles") {
gpuBackend = GPUBackend::OPENGL;
softwareRendering = false;
} else if (restOfOption == "vulkan") {
gpuBackend = GPUBackend::VULKAN;
softwareRendering = false;
} else if (restOfOption == "software") {
gpuBackend = GPUBackend::OPENGL;
softwareRendering = true;
}
} else if (startsWith(argv[i], configOption)) {
configFilename = std::string(argv[i] + configOption.size());
} else if (startsWith(argv[i], controlsOption)) {
controlsConfigFilename = std::string(argv[i] + controlsOption.size());
}
}
}
void CommandLineOptions::ApplyToConfig() const {
if (fullscreen.has_value()) {
g_Config.bFullScreen = fullscreen.value();
g_Config.DoNotSaveSetting(&g_Config.bFullScreen);
}
if (gpuBackend.has_value()) {
g_Config.iGPUBackend = (int)gpuBackend.value();
g_Config.DoNotSaveSetting(&g_Config.iGPUBackend);
}
if (softwareRendering.has_value()) {
g_Config.bSoftwareRendering = softwareRendering.value();
g_Config.DoNotSaveSetting(&g_Config.bSoftwareRendering);
}
if (enableLogging.has_value()) {
g_Config.bEnableLogging = enableLogging.value();
g_Config.DoNotSaveSetting(&g_Config.bEnableLogging);
}
if (optionS) {
g_Config.bAutoRun = false;
g_Config.bSaveSettings = false;
}
}
+26
View File
@@ -0,0 +1,26 @@
#pragma once
#include <optional>
#include "Core/ConfigValues.h"
// We collect command line options in this struct, then we apply it to the config after it's been loaded.
struct CommandLineOptions {
std::optional<bool> fullscreen;
std::optional<GPUBackend> gpuBackend;
std::optional<bool> softwareRendering;
std::optional<bool> enableLogging;
#ifndef _DEBUG
bool showLogWindow = false;
#else
bool showLogWindow = true;
#endif
bool debugLogLevel = false;
std::string configFilename = "";
std::string controlsConfigFilename = "";
bool optionS = true; // a legacy option
void Parse(int argc, const char *argv[]);
void ApplyToConfig() const;
};
+2
View File
@@ -437,6 +437,7 @@
<ClCompile Include="..\ext\udis86\syn-intel.c" />
<ClCompile Include="..\ext\udis86\syn.c" />
<ClCompile Include="..\ext\udis86\udis86.c" />
<ClCompile Include="CmdLine.cpp" />
<ClCompile Include="ConfigSettings.cpp" />
<ClCompile Include="ControlMapper.cpp" />
<ClCompile Include="AVIDump.cpp" />
@@ -971,6 +972,7 @@
<ClInclude Include="..\ext\udis86\types.h" />
<ClInclude Include="..\ext\udis86\udint.h" />
<ClInclude Include="..\ext\udis86\udis86.h" />
<ClInclude Include="CmdLine.h" />
<ClInclude Include="ConfigSettings.h" />
<ClInclude Include="ControlMapper.h" />
<ClInclude Include="AVIDump.h" />
+6
View File
@@ -1390,6 +1390,9 @@
<ClCompile Include="Util\VideoPlayer.cpp">
<Filter>Util</Filter>
</ClCompile>
<ClCompile Include="CmdLine.cpp">
<Filter>Core</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ELF\ElfReader.h">
@@ -2250,6 +2253,9 @@
<ClInclude Include="Util\VideoPlayer.h">
<Filter>Util</Filter>
</ClInclude>
<ClInclude Include="CmdLine.h">
<Filter>Core</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\LICENSE.TXT" />
+5 -4
View File
@@ -619,19 +619,19 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch
break;
case 'j':
g_Config.iCpuCore = (int)CPUCore::JIT;
g_Config.bSaveSettings = false;
g_Config.DoNotSaveSetting(&g_Config.iCpuCore);
break;
case 'i':
g_Config.iCpuCore = (int)CPUCore::INTERPRETER;
g_Config.bSaveSettings = false;
g_Config.DoNotSaveSetting(&g_Config.iCpuCore);
break;
case 'r':
g_Config.iCpuCore = (int)CPUCore::IR_INTERPRETER;
g_Config.bSaveSettings = false;
g_Config.DoNotSaveSetting(&g_Config.iCpuCore);
break;
case 'J':
g_Config.iCpuCore = (int)CPUCore::JIT_IR;
g_Config.bSaveSettings = false;
g_Config.DoNotSaveSetting(&g_Config.iCpuCore);
break;
case '-':
if (!strncmp(argv[i], "--loglevel=", strlen("--loglevel=")) && strlen(argv[i]) > strlen("--loglevel="))
@@ -649,6 +649,7 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch
g_Config.bFullScreen = true;
}
if (!strncmp(argv[i], "--root=", strlen("--root=")) && strlen(argv[i]) > strlen("--root=")) {
g_Config.DoNotSaveSetting(&g_Config.mountRoot);
g_Config.mountRoot = Path(argv[i] + strlen("--root="));
}
if (!strcmp(argv[i], "--windowed")) {
+2
View File
@@ -86,6 +86,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\Core\AVIDump.h" />
<ClInclude Include="..\..\Core\CmdLine.h" />
<ClInclude Include="..\..\Core\Compatibility.h" />
<ClInclude Include="..\..\Core\Config.h" />
<ClInclude Include="..\..\Core\ConfigSettings.h" />
@@ -359,6 +360,7 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\Core\AVIDump.cpp" />
<ClCompile Include="..\..\Core\CmdLine.cpp" />
<ClCompile Include="..\..\Core\Compatibility.cpp" />
<ClCompile Include="..\..\Core\Config.cpp" />
<ClCompile Include="..\..\Core\ConfigSettings.cpp" />
+2
View File
@@ -411,6 +411,7 @@
<ClCompile Include="..\..\Core\Util\PathUtil.cpp" />
<ClCompile Include="..\..\Core\SaveStateRewind.cpp" />
<ClCompile Include="..\..\Core\Util\VideoPlayer.cpp" />
<ClCompile Include="..\..\Core\CmdLine.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\Core\AVIDump.h" />
@@ -684,6 +685,7 @@
<ClInclude Include="..\..\Core\Util\PathUtil.h" />
<ClInclude Include="..\..\Core\SaveStateRewind.h" />
<ClInclude Include="..\..\Core\Util\VideoPlayer.h" />
<ClInclude Include="..\..\Core\CmdLine.h" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\ext\gason\LICENSE" />
+1 -113
View File
@@ -50,6 +50,7 @@
#include "Core/Config.h"
#include "Core/ConfigValues.h"
#include "Core/CmdLine.h"
#include "Core/SaveState.h"
#include "Core/Instance.h"
#include "Core/HLE/Plugins.h"
@@ -1022,119 +1023,6 @@ static void WinMainCleanup() {
}
}
struct CommandLineOptions {
std::optional<bool> fullscreen;
std::optional<GPUBackend> gpuBackend;
std::optional<bool> softwareRendering;
std::optional<bool> enableLogging;
#ifndef _DEBUG
bool showLogWindow = false;
#else
bool showLogWindow = true;
#endif
bool debugLogLevel = false;
std::string configFilename = "";
std::string controlsConfigFilename = "";
bool optionS = true; // a legacy option
void Parse(int argc, const char *argv[]);
void ApplyToConfig() const;
};
void CommandLineOptions::Parse(int argc, const char *argv[]) {
constexpr std::string_view gpuBackendStr = "--graphics=";
constexpr std::string_view configOption = "--config=";
constexpr std::string_view controlsOption = "--controlconfig=";
#ifdef _DEBUG
enableLogging = true;
#endif
// The rest is handled in NativeInit().
for (size_t i = 1; i < argc; ++i) {
const size_t len = strlen(argv[i]);
if (argv[i][0] != '-' || len < 2) {
continue;
}
// single char commands, like -l, -s, -d
if (len == 2) {
switch (argv[i][1]) {
case 'l':
showLogWindow = true;
enableLogging = true;
break;
case 's':
optionS = true;
break;
case 'd':
debugLogLevel = true;
break;
}
}
// Simple bool commands
// NOTE: We need to parse --fullscreen early, before we create the window.
if (equals(argv[i], "--fullscreen")) {
fullscreen = true;
} else if (equals(argv[i], "--windowed")) {
fullscreen = false;
}
// Commands with parameters. TODO: Should support both space and equals, like --config=foo.ini and --config foo.ini
if (startsWith(argv[i], gpuBackendStr)) {
const std::string_view restOfOption = argv[i] + gpuBackendStr.size();
// Force software rendering off, as picking gles implies HW acceleration.
// We could add more options for software such as "software-gles",
// "software-vulkan" and "software-d3d11", or something similar.
// For now, software rendering force-activates OpenGL.
if (restOfOption == "directx11" || restOfOption == "d3d11") {
gpuBackend = GPUBackend::DIRECT3D11;
softwareRendering = false;
} else if (restOfOption == "gles") {
gpuBackend = GPUBackend::OPENGL;
softwareRendering = false;
} else if (restOfOption == "vulkan") {
gpuBackend = GPUBackend::VULKAN;
softwareRendering = false;
} else if (restOfOption == "software") {
gpuBackend = GPUBackend::OPENGL;
softwareRendering = true;
}
} else if (startsWith(argv[i], configOption)) {
configFilename = std::string(argv[i] + configOption.size());
} else if (startsWith(argv[i], controlsOption)) {
controlsConfigFilename = std::string(argv[i] + controlsOption.size());
}
}
}
void CommandLineOptions::ApplyToConfig() const {
if (fullscreen.has_value()) {
g_Config.bFullScreen = fullscreen.value();
g_Config.DoNotSaveSetting(&g_Config.bFullScreen);
}
if (gpuBackend.has_value()) {
g_Config.iGPUBackend = (int)gpuBackend.value();
g_Config.DoNotSaveSetting(&g_Config.iGPUBackend);
}
if (softwareRendering.has_value()) {
g_Config.bSoftwareRendering = softwareRendering.value();
g_Config.DoNotSaveSetting(&g_Config.bSoftwareRendering);
}
if (enableLogging.has_value()) {
g_Config.bEnableLogging = enableLogging.value();
g_Config.DoNotSaveSetting(&g_Config.bEnableLogging);
}
if (optionS) {
g_Config.bAutoRun = false;
g_Config.bSaveSettings = false;
}
}
int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow) {
const std::vector<std::wstring> wideArgs = GetWideCmdLine();
// Check for the Vulkan workaround before any serious init.
+1
View File
@@ -608,6 +608,7 @@ EXEC_AND_LIB_FILES := \
$(SRC)/Core/ControlMapper.cpp \
$(SRC)/Core/Core.cpp \
$(SRC)/Core/Compatibility.cpp \
$(SRC)/Core/CmdLine.cpp \
$(SRC)/Core/Config.cpp \
$(SRC)/Core/ConfigSettings.cpp \
$(SRC)/Core/CoreTiming.cpp \