Files

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

247 lines
5.3 KiB
C++
Raw Permalink Normal View History

// Copyright 2008 Dolphin Emulator Project
2015-05-18 01:08:10 +02:00
// Licensed under GPLv2+
// Refer to the license.txt file included.
2018-10-24 15:50:54 +10:00
#include "DolphinNoGUI/Platform.h"
#include <OptionParser.h>
2014-02-22 23:36:30 +01:00
#include <cstddef>
2014-02-17 05:18:15 -05:00
#include <cstdio>
2014-02-22 23:36:30 +01:00
#include <cstring>
#include <signal.h>
2014-03-12 15:33:41 -04:00
#include <string>
2018-10-24 15:50:54 +10:00
#ifndef _WIN32
2015-09-04 02:14:10 -04:00
#include <unistd.h>
2019-11-26 15:25:19 +11:00
#else
#include <Windows.h>
2018-10-24 15:50:54 +10:00
#endif
2009-05-15 08:55:46 +00:00
2019-11-26 15:25:19 +11:00
#include "Common/StringUtil.h"
2016-06-18 02:43:59 +02:00
#include "Core/Analytics.h"
2017-05-27 15:43:40 +02:00
#include "Core/Boot/Boot.h"
#include "Core/BootManager.h"
#include "Core/Core.h"
#include "Core/Host.h"
#include "UICommon/CommandLineParse.h"
2018-06-08 15:56:11 -05:00
#ifdef USE_DISCORD_PRESENCE
#include "UICommon/DiscordPresence.h"
#endif
2014-10-04 15:12:15 -04:00
#include "UICommon/UICommon.h"
#include "VideoCommon/RenderBase.h"
#include "VideoCommon/VideoBackendBase.h"
2018-10-24 15:50:54 +10:00
static std::unique_ptr<Platform> s_platform;
static void signal_handler(int)
{
const char message[] = "A signal was received. A second signal will force Dolphin to stop.\n";
2018-10-24 15:50:54 +10:00
#ifdef _WIN32
puts(message);
#else
if (write(STDERR_FILENO, message, sizeof(message)) < 0)
{
}
2018-10-24 15:50:54 +10:00
#endif
s_platform->RequestShutdown();
}
2011-02-08 15:36:15 +00:00
void Host_NotifyMapLoaded()
{
}
void Host_RefreshDSPDebuggerWindow()
{
}
2019-03-18 17:30:33 +01:00
bool Host_UIBlocksControllerState()
{
return false;
}
2018-10-24 15:50:54 +10:00
static Common::Event s_update_main_frame_event;
void Host_Message(HostMessageID id)
2010-03-16 13:18:52 +00:00
{
if (id == HostMessageID::WMUserStop)
2018-10-24 15:50:54 +10:00
s_platform->Stop();
2010-03-16 13:18:52 +00:00
}
void Host_UpdateTitle(const std::string& title)
{
2018-10-24 15:50:54 +10:00
s_platform->SetTitle(title);
}
2010-04-19 03:06:18 +00:00
void Host_UpdateDisasmDialog()
{
}
2008-09-07 21:06:55 +00:00
void Host_UpdateMainFrame()
{
2018-10-24 15:50:54 +10:00
s_update_main_frame_event.Set();
2008-09-07 21:06:55 +00:00
}
void Host_RequestRenderWindowSize(int width, int height)
{
}
bool Host_RendererHasFocus()
{
2018-10-24 15:50:54 +10:00
return s_platform->IsWindowFocused();
}
2015-01-04 17:09:56 +01:00
bool Host_RendererIsFullscreen()
{
2018-10-24 15:50:54 +10:00
return s_platform->IsWindowFullscreen();
2015-01-04 17:09:56 +01:00
}
void Host_YieldToUI()
{
}
void Host_UpdateProgressDialog(const char* caption, int position, int total)
{
}
void Host_TitleChanged()
{
#ifdef USE_DISCORD_PRESENCE
Discord::UpdateDiscordPresence();
#endif
}
2018-10-24 15:50:54 +10:00
static std::unique_ptr<Platform> GetPlatform(const optparse::Values& options)
{
std::string platform_name = static_cast<const char*>(options.get("platform"));
#if HAVE_X11
2018-10-24 15:50:54 +10:00
if (platform_name == "x11" || platform_name.empty())
return Platform::CreateX11Platform();
#endif
2019-04-10 14:44:21 +00:00
#ifdef __linux__
if (platform_name == "fbdev" || platform_name.empty())
return Platform::CreateFBDevPlatform();
#endif
2019-11-26 15:25:19 +11:00
#ifdef _WIN32
if (platform_name == "win32" || platform_name.empty())
return Platform::CreateWin32Platform();
#endif
2018-10-24 15:50:54 +10:00
if (platform_name == "headless" || platform_name.empty())
return Platform::CreateHeadlessPlatform();
return nullptr;
}
int main(int argc, char* argv[])
{
auto parser = CommandLineParse::CreateParser(CommandLineParse::ParserOptions::OmitGUIOptions);
2018-10-24 15:50:54 +10:00
parser->add_option("-p", "--platform")
.action("store")
.help("Window platform to use [%choices]")
.choices({
"headless"
2019-04-10 14:44:21 +00:00
#ifdef __linux__
,
"fbdev"
#endif
2018-10-24 15:50:54 +10:00
#if HAVE_X11
,
"x11"
2019-11-26 15:25:19 +11:00
#endif
#ifdef _WIN32
,
"win32"
2018-10-24 15:50:54 +10:00
#endif
});
optparse::Values& options = CommandLineParse::ParseArguments(parser.get(), argc, argv);
std::vector<std::string> args = parser->args();
std::unique_ptr<BootParameters> boot;
if (options.is_set("exec"))
2014-02-16 23:51:41 -05:00
{
2018-11-05 19:20:45 +01:00
const std::list<std::string> paths_list = options.all("exec");
const std::vector<std::string> paths{std::make_move_iterator(std::begin(paths_list)),
std::make_move_iterator(std::end(paths_list))};
boot = BootParameters::GenerateFromFile(paths);
}
else if (options.is_set("nand_title"))
{
const std::string hex_string = static_cast<const char*>(options.get("nand_title"));
if (hex_string.length() != 16)
{
fprintf(stderr, "Invalid title ID\n");
parser->print_help();
return 1;
}
const u64 title_id = std::stoull(hex_string, nullptr, 16);
boot = std::make_unique<BootParameters>(BootParameters::NANDTitle{title_id});
}
else if (args.size())
2014-02-16 23:51:41 -05:00
{
boot = BootParameters::GenerateFromFile(args.front());
args.erase(args.begin());
}
else
{
parser->print_help();
return 0;
}
2017-02-28 11:36:11 -08:00
std::string user_directory;
if (options.is_set("user"))
user_directory = static_cast<const char*>(options.get("user"));
2017-02-28 11:36:11 -08:00
UICommon::SetUserDirectory(user_directory);
2014-10-04 15:12:15 -04:00
UICommon::Init();
2009-05-15 08:55:46 +00:00
2018-10-24 15:50:54 +10:00
s_platform = GetPlatform(options);
if (!s_platform || !s_platform->Init())
{
fprintf(stderr, "No platform found, or failed to initialize.\n");
return 1;
}
Core::SetOnStateChangedCallback([](Core::State state) {
if (state == Core::State::Uninitialized)
2018-10-24 15:50:54 +10:00
s_platform->Stop();
});
2019-11-26 15:25:19 +11:00
#ifdef _WIN32
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
#else
// Shut down cleanly on SIGINT and SIGTERM
struct sigaction sa;
sa.sa_handler = signal_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESETHAND;
sigaction(SIGINT, &sa, nullptr);
sigaction(SIGTERM, &sa, nullptr);
2019-11-26 15:25:19 +11:00
#endif
DolphinAnalytics::Instance().ReportDolphinStart("nogui");
2016-06-18 02:43:59 +02:00
2018-10-24 15:50:54 +10:00
if (!BootManager::BootCore(std::move(boot), s_platform->GetWindowSystemInfo()))
2008-09-07 21:06:55 +00:00
{
fprintf(stderr, "Could not boot the specified file\n");
return 1;
2008-09-07 21:06:55 +00:00
}
2018-06-08 15:56:11 -05:00
#ifdef USE_DISCORD_PRESENCE
Discord::UpdateDiscordPresence();
#endif
2018-10-24 15:50:54 +10:00
s_platform->MainLoop();
Core::Stop();
Core::Shutdown();
2018-10-24 15:50:54 +10:00
s_platform.reset();
2014-10-04 15:12:15 -04:00
UICommon::Shutdown();
return 0;
}