mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2025-01-31 19:55:38 +00:00
143 lines
3.6 KiB
C++
143 lines
3.6 KiB
C++
#include "common/assert.h"
|
|
#include "common/file_system.h"
|
|
#include "common/log.h"
|
|
#include "common/string_util.h"
|
|
#include "core/system.h"
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <vector>
|
|
|
|
#ifdef WITH_VTY
|
|
#include "vty_host_interface.h"
|
|
#endif
|
|
|
|
#ifdef WITH_SDL2
|
|
#include "sdl_host_interface.h"
|
|
|
|
static bool IsSDLHostInterfaceAvailable()
|
|
{
|
|
#if defined(__linux__)
|
|
// Only available if we have a X11 or Wayland display.
|
|
if (std::getenv("DISPLAY") || std::getenv("WAYLAND_DISPLAY"))
|
|
return true;
|
|
else
|
|
return false;
|
|
#else
|
|
// Always available on Windows/Apple.
|
|
return true;
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
#ifdef _WIN32
|
|
#include "common/windows_headers.h"
|
|
#include "win32_host_interface.h"
|
|
#include <shellapi.h>
|
|
#endif
|
|
|
|
static std::unique_ptr<NoGUIHostInterface> CreateHostInterface()
|
|
{
|
|
const char* platform = std::getenv("DUCKSTATION_NOGUI_PLATFORM");
|
|
std::unique_ptr<NoGUIHostInterface> host_interface;
|
|
|
|
#ifdef WITH_SDL2
|
|
if (!host_interface && (!platform || StringUtil::Strcasecmp(platform, "sdl") == 0) && IsSDLHostInterfaceAvailable())
|
|
host_interface = SDLHostInterface::Create();
|
|
#endif
|
|
|
|
#ifdef WITH_VTY
|
|
if (!host_interface && (!platform || StringUtil::Strcasecmp(platform, "vty") == 0))
|
|
host_interface = VTYHostInterface::Create();
|
|
#endif
|
|
|
|
#ifdef _WIN32
|
|
if (!host_interface && (!platform || StringUtil::Strcasecmp(platform, "win32") == 0))
|
|
host_interface = Win32HostInterface::Create();
|
|
#endif
|
|
|
|
return host_interface;
|
|
}
|
|
|
|
static int Run(std::unique_ptr<NoGUIHostInterface> host_interface, std::unique_ptr<SystemBootParameters> boot_params)
|
|
{
|
|
if (!host_interface->Initialize())
|
|
{
|
|
host_interface->Shutdown();
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
if (boot_params)
|
|
host_interface->BootSystem(*boot_params);
|
|
|
|
int result;
|
|
if (System::IsValid() || !host_interface->InBatchMode())
|
|
{
|
|
host_interface->Run();
|
|
result = EXIT_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
host_interface->ReportError("No file specified, and we're in batch mode. Exiting.");
|
|
result = EXIT_FAILURE;
|
|
}
|
|
|
|
host_interface->Shutdown();
|
|
return result;
|
|
}
|
|
|
|
#ifdef _WIN32
|
|
|
|
int wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
|
|
{
|
|
std::unique_ptr<NoGUIHostInterface> host_interface = CreateHostInterface();
|
|
std::unique_ptr<SystemBootParameters> boot_params;
|
|
|
|
{
|
|
std::vector<std::string> argc_strings;
|
|
argc_strings.reserve(1);
|
|
|
|
// CommandLineToArgvW() only adds the program path if the command line is empty?!
|
|
argc_strings.push_back(FileSystem::GetProgramPath());
|
|
|
|
if (std::wcslen(lpCmdLine) > 0)
|
|
{
|
|
int argc;
|
|
LPWSTR* argv_wide = CommandLineToArgvW(lpCmdLine, &argc);
|
|
if (argv_wide)
|
|
{
|
|
for (int i = 0; i < argc; i++)
|
|
argc_strings.push_back(StringUtil::WideStringToUTF8String(argv_wide[i]));
|
|
|
|
LocalFree(argv_wide);
|
|
}
|
|
}
|
|
|
|
std::vector<char*> argc_pointers;
|
|
argc_pointers.reserve(argc_strings.size());
|
|
for (std::string& arg : argc_strings)
|
|
argc_pointers.push_back(arg.data());
|
|
|
|
if (!host_interface->ParseCommandLineParameters(static_cast<int>(argc_pointers.size()), argc_pointers.data(),
|
|
&boot_params))
|
|
{
|
|
return EXIT_FAILURE;
|
|
}
|
|
}
|
|
|
|
return Run(std::move(host_interface), std::move(boot_params));
|
|
}
|
|
|
|
#else
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
std::unique_ptr<NoGUIHostInterface> host_interface = CreateHostInterface();
|
|
std::unique_ptr<SystemBootParameters> boot_params;
|
|
if (!host_interface->ParseCommandLineParameters(argc, argv, &boot_params))
|
|
return EXIT_FAILURE;
|
|
|
|
return Run(std::move(host_interface), std::move(boot_params));
|
|
}
|
|
|
|
#endif |