From 607a43620a64bd8f78eb9aa0e082b5d9ebc6dccd Mon Sep 17 00:00:00 2001 From: Simone Date: Thu, 18 Jan 2024 17:12:23 +0100 Subject: [PATCH] Okokokokokokokok --- src/frontend/CMakeLists.txt | 2 + src/frontend/KaizenQt.cpp | 13 ++---- src/frontend/KaizenQt.hpp | 22 +++++++++- src/frontend/MainWindow.cpp | 21 +++++----- src/frontend/MainWindow.hpp | 5 ++- src/frontend/RenderWidget.cpp | 31 +++++++++++++++ src/frontend/RenderWidget.hpp | 75 +++++++++++++++++++++++++++++++++++ src/frontend/main.cpp | 2 +- src/frontend/mainwindow.ui | 10 +++++ 9 files changed, 156 insertions(+), 25 deletions(-) create mode 100644 src/frontend/RenderWidget.cpp create mode 100644 src/frontend/RenderWidget.hpp diff --git a/src/frontend/CMakeLists.txt b/src/frontend/CMakeLists.txt index 4b112510..6d9491ea 100644 --- a/src/frontend/CMakeLists.txt +++ b/src/frontend/CMakeLists.txt @@ -53,6 +53,8 @@ add_executable(kaizen-qt main.cpp KaizenQt.hpp KaizenQt.cpp + RenderWidget.cpp + RenderWidget.hpp EmuThread.hpp EmuThread.cpp mainwindow.ui diff --git a/src/frontend/KaizenQt.cpp b/src/frontend/KaizenQt.cpp index 23485f27..9a4be5c2 100644 --- a/src/frontend/KaizenQt.cpp +++ b/src/frontend/KaizenQt.cpp @@ -2,17 +2,13 @@ #include #include -KaizenQt::KaizenQt() noexcept - : mainWindow(new MainWindowController), - emuThread(new EmuThread(mainWindow)) -{ +KaizenQt::KaizenQt() noexcept : mainWindow(new MainWindowController), emuThread(new EmuThread(mainWindow)) { ConnectMainWindowSignalsToSlots(); mainWindow->show(); } -void KaizenQt::ConnectMainWindowSignalsToSlots() noexcept -{ +void KaizenQt::ConnectMainWindowSignalsToSlots() noexcept { connect(mainWindow, &MainWindowController::OpenROM, this, &KaizenQt::LoadROM); connect(mainWindow, &MainWindowController::Exit, this, []() { QApplication::quit(); @@ -22,8 +18,7 @@ void KaizenQt::ConnectMainWindowSignalsToSlots() noexcept connect(mainWindow, &MainWindowController::Pause, emuThread, &EmuThread::TogglePause); } -void KaizenQt::LoadROM(const QString& file_name) noexcept -{ +void KaizenQt::LoadROM(const QString& file_name) noexcept { emuThread->core.LoadROM(file_name.toStdString()); emuThread->start(); -} +} \ No newline at end of file diff --git a/src/frontend/KaizenQt.hpp b/src/frontend/KaizenQt.hpp index 9d622a02..20e1bc92 100644 --- a/src/frontend/KaizenQt.hpp +++ b/src/frontend/KaizenQt.hpp @@ -1,6 +1,26 @@ #pragma once -#include #include +#include + +enum class CompositorCategory { + Windows, MacOS, XCB, Wayland +}; + +static inline CompositorCategory GetOSCompositorCategory() { + const QString platform_name = QGuiApplication::platformName(); + if (platform_name == QStringLiteral("windows")) + return CompositorCategory::Windows; + else if (platform_name == QStringLiteral("xcb")) + return CompositorCategory::XCB; + else if (platform_name == QStringLiteral("wayland") || + platform_name == QStringLiteral("wayland-egl")) + return CompositorCategory::Wayland; + else if (platform_name == QStringLiteral("cocoa") || platform_name == QStringLiteral("ios")) + return CompositorCategory::MacOS; + + Util::error("Unknown Qt platform!"); + return CompositorCategory::Windows; +} class KaizenQt : public QObject { Q_OBJECT diff --git a/src/frontend/MainWindow.cpp b/src/frontend/MainWindow.cpp index 678a0338..bb4fdbc7 100644 --- a/src/frontend/MainWindow.cpp +++ b/src/frontend/MainWindow.cpp @@ -1,20 +1,17 @@ -#include #include #include +#include -MainWindowController::MainWindowController() noexcept -{ +MainWindowController::MainWindowController() noexcept { view.setupUi(this); ConnectSignalsToSlots(); } -void MainWindowController::ConnectSignalsToSlots() noexcept -{ +void MainWindowController::ConnectSignalsToSlots() noexcept { connect(view.actionOpen, &QAction::triggered, this, [this]() { QString file_name = QFileDialog::getOpenFileName(this); - if (!file_name.isEmpty()) - { + if (!file_name.isEmpty()) { view.actionPause->setEnabled(true); view.actionReset->setEnabled(true); view.actionStop->setEnabled(true); @@ -24,24 +21,24 @@ void MainWindowController::ConnectSignalsToSlots() noexcept connect(view.actionExit, &QAction::triggered, this, [this]() { emit Exit(); - }); + }); connect(view.actionReset, &QAction::triggered, this, [this]() { emit Reset(); - }); + }); connect(view.actionStop, &QAction::triggered, this, [this]() { view.actionPause->setDisabled(true); view.actionReset->setDisabled(true); view.actionStop->setDisabled(true); emit Stop(); - }); + }); connect(view.actionPause, &QAction::triggered, this, [this]() { textPauseToggle = !textPauseToggle; view.actionPause->setText(textPauseToggle ? "Resume" : "Pause"); emit Pause(); - }); + }); connect(view.actionAbout, &QAction::triggered, this, [this]() { QMessageBox::about( @@ -50,5 +47,5 @@ void MainWindowController::ConnectSignalsToSlots() noexcept "experience and great compatibility.\n" "sliice is licensed under the BSD 3-clause license.\n" "Nintendo 64 is a registered trademarks of Nintendo Co., Ltd.")); - }); + }); } \ No newline at end of file diff --git a/src/frontend/MainWindow.hpp b/src/frontend/MainWindow.hpp index a8695200..a00f1d1b 100644 --- a/src/frontend/MainWindow.hpp +++ b/src/frontend/MainWindow.hpp @@ -1,6 +1,7 @@ #pragma once -#include #include "ui_mainwindow.h" +#include +#include class MainWindowController : public QMainWindow { @@ -15,7 +16,7 @@ private: Ui::MainWindow view; bool textPauseToggle = false; -signals: +Q_SIGNALS: void OpenROM(const QString& rom_file); void Exit(); void Reset(); diff --git a/src/frontend/RenderWidget.cpp b/src/frontend/RenderWidget.cpp new file mode 100644 index 00000000..97e4d6e3 --- /dev/null +++ b/src/frontend/RenderWidget.cpp @@ -0,0 +1,31 @@ +#include +#include + +RenderWidget::RenderWidget(QWidget* parent) : QWidget(parent) { + if (volkInitialize() != VK_SUCCESS) { + Util::panic("Could not initialize Vulkan loader!"); + } + + create(); + + setAttribute(Qt::WA_NativeWindow); + setAttribute(Qt::WA_PaintOnScreen); + if (GetOSCompositorCategory() == CompositorCategory::Wayland) { + setAttribute(Qt::WA_DontCreateNativeAncestors); + } + + if (GetOSCompositorCategory() == CompositorCategory::MacOS) { + windowHandle()->setSurfaceType(QWindow::MetalSurface); + } + else { + windowHandle()->setSurfaceType(QWindow::VulkanSurface); + } + + instance.create(); + windowHandle()->setVulkanInstance(&instance); + + wsiPlatform = new QtWSIPlatform(windowHandle()); + windowInfo = std::make_unique(windowHandle()); + + LoadWSIPlatform(wsiPlatform, std::move(windowInfo)); +} \ No newline at end of file diff --git a/src/frontend/RenderWidget.hpp b/src/frontend/RenderWidget.hpp new file mode 100644 index 00000000..262bbf4f --- /dev/null +++ b/src/frontend/RenderWidget.hpp @@ -0,0 +1,75 @@ +#pragma once +#undef signals +#include +#include +#include +#include + +class QtParallelRdpWindowInfo : public ParallelRdpWindowInfo { +public: + QtParallelRdpWindowInfo(QWindow* window) : window(window) {} + CoordinatePair get_window_size() { + CoordinatePair{ static_cast(window->width()), static_cast(window->height()) }; + } +private: + QWindow* window; +}; + +class QtWSIPlatform final : public Vulkan::WSIPlatform { +public: + QtWSIPlatform(QWindow* window) : window(window) {} + + std::vector get_instance_extensions() override { + auto vec = std::vector(); + + for (const auto& ext : window->vulkanInstance()->extensions()) { + vec.push_back(ext); + } + + return vec; + } + + VkSurfaceKHR create_surface(VkInstance, VkPhysicalDevice) override { + return QVulkanInstance::surfaceForWindow(window); + } + + uint32_t get_surface_width() override { + return 640; + } + + uint32_t get_surface_height() override { + return 480; + } + + bool alive(Vulkan::WSI&) override { + return true; + } + + void poll_input() override { } + + void event_frame_tick(double frame, double elapsed) override { } + + const VkApplicationInfo* get_application_info() override { + return &appInfo; + } + + VkApplicationInfo appInfo{ + .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, + .apiVersion = VK_API_VERSION_1_3 + }; +private: + QWindow* window; +}; + +class RenderWidget : public QWidget { +public: + explicit RenderWidget(QWidget* parent); + + QPaintEngine* paintEngine() const override { + return nullptr; + } +private: + std::unique_ptr windowInfo; + QtWSIPlatform* wsiPlatform; + QVulkanInstance instance; +}; \ No newline at end of file diff --git a/src/frontend/main.cpp b/src/frontend/main.cpp index a8d34e1d..4380075a 100644 --- a/src/frontend/main.cpp +++ b/src/frontend/main.cpp @@ -1,7 +1,7 @@ +#include #include #include #include -#include int main(int argc, char** argv) { QApplication app(argc, argv); diff --git a/src/frontend/mainwindow.ui b/src/frontend/mainwindow.ui index 1c8fc3a4..5c9cb14e 100644 --- a/src/frontend/mainwindow.ui +++ b/src/frontend/mainwindow.ui @@ -30,6 +30,9 @@ 0 + + + @@ -119,6 +122,13 @@ + + + Renderer + QWidget +
RenderWidget.hpp
+
+