CommandLineParse.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. // Copyright 2017 Dolphin Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "UICommon/CommandLineParse.h"
  4. #include <list>
  5. #include <optional>
  6. #include <sstream>
  7. #include <string>
  8. #include <tuple>
  9. #include <OptionParser.h>
  10. #include "Common/Config/Config.h"
  11. #include "Common/StringUtil.h"
  12. #include "Common/Version.h"
  13. #include "Core/Config/MainSettings.h"
  14. namespace CommandLineParse
  15. {
  16. class CommandLineConfigLayerLoader final : public Config::ConfigLayerLoader
  17. {
  18. public:
  19. CommandLineConfigLayerLoader(const std::list<std::string>& args, const std::string& video_backend,
  20. const std::string& audio_backend, bool batch, bool debugger)
  21. : ConfigLayerLoader(Config::LayerType::CommandLine)
  22. {
  23. if (!video_backend.empty())
  24. m_values.emplace_back(Config::MAIN_GFX_BACKEND.GetLocation(), video_backend);
  25. if (!audio_backend.empty())
  26. {
  27. m_values.emplace_back(Config::MAIN_DSP_HLE.GetLocation(),
  28. ValueToString(audio_backend == "HLE"));
  29. }
  30. // Batch mode hides the main window, and render to main hides the render window. To avoid a
  31. // situation where we would have no window at all, disable render to main when using batch mode.
  32. if (batch)
  33. m_values.emplace_back(Config::MAIN_RENDER_TO_MAIN.GetLocation(), ValueToString(false));
  34. if (debugger)
  35. m_values.emplace_back(Config::MAIN_ENABLE_DEBUGGING.GetLocation(), ValueToString(true));
  36. // Arguments are in the format of <System>.<Section>.<Key>=Value
  37. for (const auto& arg : args)
  38. {
  39. std::istringstream buffer(arg);
  40. std::string system_str, section, key, value;
  41. std::getline(buffer, system_str, '.');
  42. std::getline(buffer, section, '.');
  43. std::getline(buffer, key, '=');
  44. std::getline(buffer, value, '=');
  45. std::optional<Config::System> system = Config::GetSystemFromName(system_str);
  46. if (system)
  47. {
  48. m_values.emplace_back(
  49. Config::Location{std::move(*system), std::move(section), std::move(key)},
  50. std::move(value));
  51. }
  52. }
  53. }
  54. void Load(Config::Layer* layer) override
  55. {
  56. for (auto& value : m_values)
  57. {
  58. layer->Set(std::get<0>(value), std::get<1>(value));
  59. }
  60. }
  61. void Save(Config::Layer* layer) override
  62. {
  63. // Save Nothing
  64. }
  65. private:
  66. std::list<std::tuple<Config::Location, std::string>> m_values;
  67. };
  68. std::unique_ptr<optparse::OptionParser> CreateParser(ParserOptions options)
  69. {
  70. auto parser = std::make_unique<optparse::OptionParser>();
  71. parser->usage("usage: %prog [options]... [FILE]...").version(Common::GetScmRevStr());
  72. parser->add_option("-u", "--user").action("store").help("User folder path");
  73. parser->add_option("-m", "--movie").action("store").help("Play a movie file");
  74. parser->add_option("-e", "--exec")
  75. .action("append")
  76. .metavar("<file>")
  77. .type("string")
  78. .help("Load the specified file");
  79. parser->add_option("-n", "--nand_title")
  80. .action("store")
  81. .metavar("<16-character ASCII title ID>")
  82. .type("string")
  83. .help("Launch a NAND title");
  84. parser->add_option("-C", "--config")
  85. .action("append")
  86. .metavar("<System>.<Section>.<Key>=<Value>")
  87. .type("string")
  88. .help("Set a configuration option");
  89. parser->add_option("-s", "--save_state")
  90. .action("store")
  91. .metavar("<file>")
  92. .type("string")
  93. .help("Load the initial save state");
  94. if (options == ParserOptions::IncludeGUIOptions)
  95. {
  96. parser->add_option("-d", "--debugger")
  97. .action("store_true")
  98. .help("Show the debugger pane and additional View menu options");
  99. parser->add_option("-l", "--logger").action("store_true").help("Open the logger");
  100. parser->add_option("-b", "--batch")
  101. .action("store_true")
  102. .help("Run Dolphin without the user interface (Requires --exec or --nand-title)");
  103. parser->add_option("-c", "--confirm").action("store_true").help("Set Confirm on Stop");
  104. }
  105. parser->set_defaults("video_backend", "");
  106. parser->set_defaults("audio_emulation", "");
  107. parser->add_option("-v", "--video_backend").action("store").help("Specify a video backend");
  108. parser->add_option("-a", "--audio_emulation")
  109. .choices({"HLE", "LLE"})
  110. .help("Choose audio emulation from [%choices]");
  111. return parser;
  112. }
  113. static void AddConfigLayer(const optparse::Values& options)
  114. {
  115. std::list<std::string> config_args;
  116. if (options.is_set_by_user("config"))
  117. config_args = options.all("config");
  118. Config::AddLayer(std::make_unique<CommandLineConfigLayerLoader>(
  119. std::move(config_args), static_cast<const char*>(options.get("video_backend")),
  120. static_cast<const char*>(options.get("audio_emulation")),
  121. static_cast<bool>(options.get("batch")), static_cast<bool>(options.get("debugger"))));
  122. }
  123. optparse::Values& ParseArguments(optparse::OptionParser* parser, int argc, char** argv)
  124. {
  125. optparse::Values& options = parser->parse_args(argc, argv);
  126. AddConfigLayer(options);
  127. return options;
  128. }
  129. optparse::Values& ParseArguments(optparse::OptionParser* parser,
  130. const std::vector<std::string>& arguments)
  131. {
  132. optparse::Values& options = parser->parse_args(arguments);
  133. AddConfigLayer(options);
  134. return options;
  135. }
  136. } // namespace CommandLineParse