mirror of
https://github.com/obhq/obliteration.git
synced 2024-10-06 16:03:22 +00:00
Adds an option to start VMM immediately (#1019)
This commit is contained in:
parent
ff0163e303
commit
802de64433
1
.vscode/launch.json
vendored
1
.vscode/launch.json
vendored
@ -23,6 +23,7 @@
|
||||
"name": "Kernel",
|
||||
"type": "lldb",
|
||||
"request": "custom",
|
||||
"preLaunchTask": "Launch VMM (Debug)",
|
||||
"initCommands": [
|
||||
"platform select remote-gdb-server",
|
||||
"platform connect connect://localhost:1234"
|
||||
|
32
.vscode/tasks.json
vendored
Normal file
32
.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "Launch VMM (Debug)",
|
||||
"detail": "Launch the GUI then start the VMM in debug mode",
|
||||
"type": "process",
|
||||
"isBackground": true,
|
||||
"runOptions": {
|
||||
"instanceLimit": 1
|
||||
},
|
||||
"linux": {
|
||||
"command": "${workspaceFolder}/build/gui/obliteration"
|
||||
},
|
||||
"osx": {
|
||||
"command": "${workspaceFolder}/build/gui/obliteration.app/Contents/MacOS/obliteration"
|
||||
},
|
||||
"windows": {
|
||||
"command": "${workspaceFolder}/build/gui/Obliteration.exe",
|
||||
"options": {
|
||||
"env": {
|
||||
"Path": "${env:Path};${env:CMAKE_PREFIX_PATH}\\bin"
|
||||
}
|
||||
}
|
||||
},
|
||||
"args": [
|
||||
"--debug",
|
||||
"127.0.0.1:1234"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
22
gui/main.cpp
22
gui/main.cpp
@ -7,6 +7,7 @@
|
||||
#endif
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCommandLineParser>
|
||||
#include <QList>
|
||||
#include <QMessageBox>
|
||||
#include <QMetaObject>
|
||||
@ -57,6 +58,14 @@ int main(int argc, char *argv[])
|
||||
|
||||
QGuiApplication::setWindowIcon(QIcon(":/resources/obliteration-icon.png"));
|
||||
|
||||
// Parse arguments.
|
||||
QCommandLineParser args;
|
||||
|
||||
args.setApplicationDescription("Virtualization stack for Obliteration");
|
||||
args.addHelpOption();
|
||||
args.addOption(Args::debug);
|
||||
args.process(app);
|
||||
|
||||
// Hook Rust panic.
|
||||
QObject panic;
|
||||
|
||||
@ -199,11 +208,11 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
// Run main window.
|
||||
// Setup main window.
|
||||
#ifdef __APPLE__
|
||||
MainWindow win;
|
||||
MainWindow win(args);
|
||||
#else
|
||||
MainWindow win(&vulkan, std::move(vkDevices));
|
||||
MainWindow win(args, &vulkan, std::move(vkDevices));
|
||||
#endif
|
||||
|
||||
if (!win.loadProfiles() || !win.loadGames()) {
|
||||
@ -212,5 +221,12 @@ int main(int argc, char *argv[])
|
||||
|
||||
win.restoreGeometry();
|
||||
|
||||
// Run main window.
|
||||
auto debug = args.value(Args::debug);
|
||||
|
||||
if (!debug.isEmpty()) {
|
||||
win.startVmm(debug);
|
||||
}
|
||||
|
||||
return QApplication::exec();
|
||||
}
|
||||
|
@ -14,6 +14,8 @@
|
||||
#include <QAction>
|
||||
#include <QApplication>
|
||||
#include <QCloseEvent>
|
||||
#include <QCommandLineOption>
|
||||
#include <QCommandLineParser>
|
||||
#include <QDesktopServices>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
@ -35,11 +37,19 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
namespace Args {
|
||||
const QCommandLineOption debug("debug", "Immediate launch the VMM in debug mode.", "addr", "127.0.0.1:1234");
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
MainWindow::MainWindow() :
|
||||
MainWindow::MainWindow(const QCommandLineParser &args) :
|
||||
#else
|
||||
MainWindow::MainWindow(QVulkanInstance *vulkan, QList<VkPhysicalDevice> &&vkDevices) :
|
||||
MainWindow::MainWindow(
|
||||
const QCommandLineParser &args,
|
||||
QVulkanInstance *vulkan,
|
||||
QList<VkPhysicalDevice> &&vkDevices) :
|
||||
#endif
|
||||
m_args(args),
|
||||
m_main(nullptr),
|
||||
m_profiles(nullptr),
|
||||
m_games(nullptr),
|
||||
@ -341,95 +351,6 @@ void MainWindow::saveProfile(Profile *p)
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::startVmm(const QString &debugAddr)
|
||||
{
|
||||
// Get full path to kernel binary.
|
||||
std::string kernel;
|
||||
|
||||
if (QFile::exists(".obliteration-development")) {
|
||||
auto b = std::filesystem::current_path();
|
||||
#ifdef _WIN32
|
||||
auto target = L"x86_64-unknown-none";
|
||||
#elif defined(__aarch64__)
|
||||
auto target = "aarch64-unknown-none-softfloat";
|
||||
#else
|
||||
auto target = "x86_64-unknown-none";
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && defined(NDEBUG)
|
||||
kernel = (b / L"target" / target / L"release" / L"obkrnl").u8string();
|
||||
#elif defined(_WIN32) && !defined(NDEBUG)
|
||||
kernel = (b / L"target" / target / L"debug" / L"obkrnl").u8string();
|
||||
#elif defined(NDEBUG)
|
||||
kernel = (b / "target" / target / "release" / "obkrnl").u8string();
|
||||
#else
|
||||
kernel = (b / "target" / target / "debug" / "obkrnl").u8string();
|
||||
#endif
|
||||
} else {
|
||||
#ifdef _WIN32
|
||||
std::filesystem::path b(QCoreApplication::applicationDirPath().toStdString(), std::filesystem::path::native_format);
|
||||
b /= L"share";
|
||||
b /= L"obkrnl";
|
||||
kernel = b.u8string();
|
||||
#else
|
||||
auto b = std::filesystem::path(QCoreApplication::applicationDirPath().toStdString(), std::filesystem::path::native_format).parent_path();
|
||||
#ifdef __APPLE__
|
||||
b /= "Resources";
|
||||
#else
|
||||
b /= "share";
|
||||
#endif
|
||||
b /= "obkrnl";
|
||||
kernel = b.u8string();
|
||||
#endif
|
||||
}
|
||||
|
||||
// Swap launch settings with the screen before getting a Vulkan surface otherwise it will fail.
|
||||
m_main->setCurrentIndex(1);
|
||||
|
||||
// Run.
|
||||
auto debug = debugAddr.toStdString();
|
||||
VmmScreen screen;
|
||||
Rust<RustError> error;
|
||||
Rust<Vmm> vmm;
|
||||
|
||||
memset(&screen, 0, sizeof(screen));
|
||||
|
||||
#ifdef __APPLE__
|
||||
screen.view = m_screen->winId();
|
||||
#else
|
||||
screen.vk_instance = reinterpret_cast<size_t>(m_screen->vulkanInstance()->vkInstance());
|
||||
screen.vk_device = reinterpret_cast<size_t>(m_launch->currentDisplayDevice()->handle());
|
||||
screen.vk_surface = reinterpret_cast<size_t>(QVulkanInstance::surfaceForWindow(m_screen));
|
||||
|
||||
if (!screen.vk_surface) {
|
||||
m_main->setCurrentIndex(0);
|
||||
QMessageBox::critical(this, "Error", "Couldn't create VkSurfaceKHR.");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
vmm = vmm_run(
|
||||
kernel.c_str(),
|
||||
&screen,
|
||||
m_launch->currentProfile(),
|
||||
debug.empty() ? nullptr : debug.c_str(),
|
||||
MainWindow::vmmHandler,
|
||||
this,
|
||||
&error);
|
||||
|
||||
if (!vmm) {
|
||||
m_main->setCurrentIndex(0);
|
||||
QMessageBox::critical(
|
||||
this,
|
||||
"Error",
|
||||
QString("Couldn't run %1: %2").arg(kernel.c_str()).arg(error_message(error)));
|
||||
return;
|
||||
}
|
||||
|
||||
m_vmm = std::move(vmm);
|
||||
m_screen->requestUpdate();
|
||||
}
|
||||
|
||||
void MainWindow::updateScreen()
|
||||
{
|
||||
// Do nothing if the VMM is not running.
|
||||
@ -462,15 +383,21 @@ void MainWindow::vmmError(const QString &msg)
|
||||
|
||||
QMessageBox::critical(this, "Error", msg);
|
||||
|
||||
m_main->setCurrentIndex(0);
|
||||
if (m_args.isSet(Args::debug)) {
|
||||
close();
|
||||
} else {
|
||||
m_main->setCurrentIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::waitingDebugger(const QString &addr)
|
||||
{
|
||||
QMessageBox::information(
|
||||
this,
|
||||
"Debug",
|
||||
QString("The VMM are waiting for a debugger at %1.").arg(addr));
|
||||
if (!m_args.isSet(Args::debug)) {
|
||||
QMessageBox::information(
|
||||
this,
|
||||
"Debug",
|
||||
QString("The VMM are waiting for a debugger at %1.").arg(addr));
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::waitKernelExit(bool success)
|
||||
@ -564,6 +491,95 @@ void MainWindow::restoreGeometry()
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::startVmm(const QString &debugAddr)
|
||||
{
|
||||
// Get full path to kernel binary.
|
||||
std::string kernel;
|
||||
|
||||
if (QFile::exists(".obliteration-development")) {
|
||||
auto b = std::filesystem::current_path();
|
||||
#ifdef _WIN32
|
||||
auto target = L"x86_64-unknown-none";
|
||||
#elif defined(__aarch64__)
|
||||
auto target = "aarch64-unknown-none-softfloat";
|
||||
#else
|
||||
auto target = "x86_64-unknown-none";
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && defined(NDEBUG)
|
||||
kernel = (b / L"target" / target / L"release" / L"obkrnl").u8string();
|
||||
#elif defined(_WIN32) && !defined(NDEBUG)
|
||||
kernel = (b / L"target" / target / L"debug" / L"obkrnl").u8string();
|
||||
#elif defined(NDEBUG)
|
||||
kernel = (b / "target" / target / "release" / "obkrnl").u8string();
|
||||
#else
|
||||
kernel = (b / "target" / target / "debug" / "obkrnl").u8string();
|
||||
#endif
|
||||
} else {
|
||||
#ifdef _WIN32
|
||||
std::filesystem::path b(QCoreApplication::applicationDirPath().toStdString(), std::filesystem::path::native_format);
|
||||
b /= L"share";
|
||||
b /= L"obkrnl";
|
||||
kernel = b.u8string();
|
||||
#else
|
||||
auto b = std::filesystem::path(QCoreApplication::applicationDirPath().toStdString(), std::filesystem::path::native_format).parent_path();
|
||||
#ifdef __APPLE__
|
||||
b /= "Resources";
|
||||
#else
|
||||
b /= "share";
|
||||
#endif
|
||||
b /= "obkrnl";
|
||||
kernel = b.u8string();
|
||||
#endif
|
||||
}
|
||||
|
||||
// Swap launch settings with the screen before getting a Vulkan surface otherwise it will fail.
|
||||
m_main->setCurrentIndex(1);
|
||||
|
||||
// Run.
|
||||
auto debug = debugAddr.toStdString();
|
||||
VmmScreen screen;
|
||||
Rust<RustError> error;
|
||||
Rust<Vmm> vmm;
|
||||
|
||||
memset(&screen, 0, sizeof(screen));
|
||||
|
||||
#ifdef __APPLE__
|
||||
screen.view = m_screen->winId();
|
||||
#else
|
||||
screen.vk_instance = reinterpret_cast<size_t>(m_screen->vulkanInstance()->vkInstance());
|
||||
screen.vk_device = reinterpret_cast<size_t>(m_launch->currentDisplayDevice()->handle());
|
||||
screen.vk_surface = reinterpret_cast<size_t>(QVulkanInstance::surfaceForWindow(m_screen));
|
||||
|
||||
if (!screen.vk_surface) {
|
||||
m_main->setCurrentIndex(0);
|
||||
QMessageBox::critical(this, "Error", "Couldn't create VkSurfaceKHR.");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
vmm = vmm_run(
|
||||
kernel.c_str(),
|
||||
&screen,
|
||||
m_launch->currentProfile(),
|
||||
debug.empty() ? nullptr : debug.c_str(),
|
||||
MainWindow::vmmHandler,
|
||||
this,
|
||||
&error);
|
||||
|
||||
if (!vmm) {
|
||||
m_main->setCurrentIndex(0);
|
||||
QMessageBox::critical(
|
||||
this,
|
||||
"Error",
|
||||
QString("Couldn't run %1: %2").arg(kernel.c_str()).arg(error_message(error)));
|
||||
return;
|
||||
}
|
||||
|
||||
m_vmm = std::move(vmm);
|
||||
m_screen->requestUpdate();
|
||||
}
|
||||
|
||||
bool MainWindow::requireVmmStopped()
|
||||
{
|
||||
if (m_vmm) {
|
||||
|
@ -13,21 +13,27 @@ class GameListModel;
|
||||
class LaunchSettings;
|
||||
class LogsViewer;
|
||||
class ProfileList;
|
||||
class QCommandLineOption;
|
||||
class QCommandLineParser;
|
||||
class QStackedWidget;
|
||||
class Screen;
|
||||
|
||||
class MainWindow final : public QMainWindow {
|
||||
public:
|
||||
#ifdef __APPLE__
|
||||
MainWindow();
|
||||
MainWindow(const QCommandLineParser &args);
|
||||
#else
|
||||
MainWindow(QVulkanInstance *vulkan, QList<VkPhysicalDevice> &&vkDevices);
|
||||
MainWindow(
|
||||
const QCommandLineParser &args,
|
||||
QVulkanInstance *vulkan,
|
||||
QList<VkPhysicalDevice> &&vkDevices);
|
||||
#endif
|
||||
~MainWindow() override;
|
||||
|
||||
bool loadProfiles();
|
||||
bool loadGames();
|
||||
void restoreGeometry();
|
||||
void startVmm(const QString &debugAddr);
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
|
||||
@ -38,7 +44,6 @@ private slots:
|
||||
void reportIssue();
|
||||
void aboutObliteration();
|
||||
void saveProfile(Profile *p);
|
||||
void startVmm(const QString &debugAddr);
|
||||
void updateScreen();
|
||||
private:
|
||||
void vmmError(const QString &msg);
|
||||
@ -50,6 +55,7 @@ private:
|
||||
|
||||
static void vmmHandler(const VmmEvent *ev, void *cx);
|
||||
|
||||
const QCommandLineParser &m_args;
|
||||
QStackedWidget *m_main;
|
||||
ProfileList *m_profiles;
|
||||
GameListModel *m_games;
|
||||
@ -58,3 +64,7 @@ private:
|
||||
QPointer<LogsViewer> m_logs;
|
||||
Rust<Vmm> m_vmm; // Destroy first.
|
||||
};
|
||||
|
||||
namespace Args {
|
||||
extern const QCommandLineOption debug;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user