WORKS
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
#include <Core.hpp>
|
#include <Core.hpp>
|
||||||
#include <Scheduler.hpp>
|
#include <Scheduler.hpp>
|
||||||
#include <ParallelRDPWrapper.hpp>
|
#include <ParallelRDPWrapper.hpp>
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
namespace n64 {
|
namespace n64 {
|
||||||
u32 extraCycles = 0;
|
u32 extraCycles = 0;
|
||||||
@@ -16,15 +17,16 @@ u32 PopStalledCycles() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Core::Core() {
|
Core::Core() {
|
||||||
|
SDL_Init(SDL_INIT_EVERYTHING);
|
||||||
if(SDL_GameControllerAddMappingsFromFile("resources/gamecontrollerdb.txt") < 0) {
|
if(SDL_GameControllerAddMappingsFromFile("resources/gamecontrollerdb.txt") < 0) {
|
||||||
Util::warn("Failed to load game controller DB");
|
Util::warn("Failed to load game controller DB");
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu = std::make_unique<Interpreter>();
|
cpu = std::make_unique<Interpreter>();
|
||||||
LoadParallelRDP(cpu->mem.GetRDRAM());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::Stop() {
|
void Core::Stop() {
|
||||||
|
render = false;
|
||||||
pause = true;
|
pause = true;
|
||||||
romLoaded = false;
|
romLoaded = false;
|
||||||
cpu->Reset();
|
cpu->Reset();
|
||||||
@@ -54,6 +56,7 @@ void Core::LoadROM(const std::string& rom_) {
|
|||||||
cpu->mem.LoadSRAM(cpu->mem.saveType, rom);
|
cpu->mem.LoadSRAM(cpu->mem.saveType, rom);
|
||||||
PIF::ExecutePIF(cpu->mem, cpu->regs);
|
PIF::ExecutePIF(cpu->mem, cpu->regs);
|
||||||
pause = false;
|
pause = false;
|
||||||
|
render = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::Run(float volumeL, float volumeR) {
|
void Core::Run(float volumeL, float volumeR) {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ struct Core {
|
|||||||
u32 breakpoint = 0;
|
u32 breakpoint = 0;
|
||||||
|
|
||||||
bool pause = true;
|
bool pause = true;
|
||||||
bool render = true;
|
bool render = false;
|
||||||
u32 cycles = 0;
|
u32 cycles = 0;
|
||||||
bool romLoaded = false;
|
bool romLoaded = false;
|
||||||
std::string rom;
|
std::string rom;
|
||||||
|
|||||||
@@ -1,11 +1,23 @@
|
|||||||
|
#include <ParallelRDPWrapper.hpp>
|
||||||
#include <EmuThread.hpp>
|
#include <EmuThread.hpp>
|
||||||
|
#include <RenderWidget.hpp>
|
||||||
|
|
||||||
EmuThread::EmuThread(QObject* parent_object) noexcept : QThread(parent_object) {}
|
EmuThread::EmuThread(std::unique_ptr<QtInstanceFactory>&& instance, std::unique_ptr<Vulkan::WSIPlatform>&& wsiPlatform, std::unique_ptr<ParallelRdpWindowInfo>&& windowInfo, QObject* parent_object) noexcept
|
||||||
|
: QThread(parent_object), instance(std::move(instance)), wsiPlatform(std::move(wsiPlatform)), windowInfo(std::move(windowInfo)) {}
|
||||||
|
|
||||||
[[noreturn]] void EmuThread::run() noexcept {
|
[[noreturn]] void EmuThread::run() noexcept {
|
||||||
|
LoadWSIPlatform(instance.get(), std::move(wsiPlatform), std::move(windowInfo));
|
||||||
|
LoadParallelRDP(core.cpu->mem.GetRDRAM());
|
||||||
while (true) {
|
while (true) {
|
||||||
if (!core.pause) {
|
if (!core.pause) {
|
||||||
core.Run(0.5, 0.5);
|
core.Run(0.5, 0.5);
|
||||||
|
if(core.render) {
|
||||||
|
UpdateScreenParallelRdp(core, core.cpu->mem.mmio.vi);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(core.render) {
|
||||||
|
UpdateScreenParallelRdpNoGame(core);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,12 +2,20 @@
|
|||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <Core.hpp>
|
#include <Core.hpp>
|
||||||
|
|
||||||
|
struct QtInstanceFactory;
|
||||||
|
struct ParallelRdpWindowInfo;
|
||||||
|
namespace Vulkan {
|
||||||
|
struct WSIPlatform;
|
||||||
|
}
|
||||||
|
|
||||||
class EmuThread : public QThread
|
class EmuThread : public QThread
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
std::unique_ptr<QtInstanceFactory> instance;
|
||||||
|
std::unique_ptr<Vulkan::WSIPlatform> wsiPlatform;
|
||||||
|
std::unique_ptr<ParallelRdpWindowInfo> windowInfo;
|
||||||
public:
|
public:
|
||||||
explicit EmuThread(QObject* parent_object) noexcept;
|
explicit EmuThread(std::unique_ptr<QtInstanceFactory>&& instance, std::unique_ptr<Vulkan::WSIPlatform>&& wsiPlatform, std::unique_ptr<ParallelRdpWindowInfo>&& windowInfo, QObject* parent_object) noexcept;
|
||||||
|
|
||||||
[[noreturn]] void run() noexcept override;
|
[[noreturn]] void run() noexcept override;
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,16 @@
|
|||||||
#include <KaizenQt.hpp>
|
#include <KaizenQt.hpp>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
|
KaizenQt::KaizenQt() noexcept {
|
||||||
|
mainWindow = new MainWindowController();
|
||||||
|
emuThread = new EmuThread(
|
||||||
|
std::move(mainWindow->view.vulkanWidget->instance),
|
||||||
|
std::move(mainWindow->view.vulkanWidget->wsiPlatform),
|
||||||
|
std::move(mainWindow->view.vulkanWidget->windowInfo),
|
||||||
|
mainWindow);
|
||||||
|
|
||||||
KaizenQt::KaizenQt() noexcept : mainWindow(new MainWindowController), emuThread(new EmuThread(mainWindow)) {
|
|
||||||
ConnectMainWindowSignalsToSlots();
|
ConnectMainWindowSignalsToSlots();
|
||||||
|
|
||||||
mainWindow->show();
|
mainWindow->show();
|
||||||
@@ -19,6 +27,6 @@ void KaizenQt::ConnectMainWindowSignalsToSlots() noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void KaizenQt::LoadROM(const QString& file_name) noexcept {
|
void KaizenQt::LoadROM(const QString& file_name) noexcept {
|
||||||
emuThread->core.LoadROM(file_name.toStdString());
|
|
||||||
emuThread->start();
|
emuThread->start();
|
||||||
|
emuThread->core.LoadROM(file_name.toStdString());
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <MainWindow.hpp>
|
#include <MainWindow.hpp>
|
||||||
|
|
||||||
MainWindowController::MainWindowController() noexcept : vulkanWidget(new RenderWidget(this)) {
|
MainWindowController::MainWindowController() noexcept {
|
||||||
view.setupUi(this);
|
view.setupUi(this);
|
||||||
ConnectSignalsToSlots();
|
ConnectSignalsToSlots();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,11 +11,10 @@ class MainWindowController : public QMainWindow
|
|||||||
public:
|
public:
|
||||||
MainWindowController() noexcept;
|
MainWindowController() noexcept;
|
||||||
|
|
||||||
|
Ui::MainWindow view;
|
||||||
private:
|
private:
|
||||||
void ConnectSignalsToSlots() noexcept;
|
void ConnectSignalsToSlots() noexcept;
|
||||||
|
|
||||||
Ui::MainWindow view;
|
|
||||||
RenderWidget *vulkanWidget;
|
|
||||||
bool textPauseToggle = false;
|
bool textPauseToggle = false;
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
|
|||||||
@@ -19,11 +19,10 @@ RenderWidget::RenderWidget(QWidget* parent) : QWidget(parent) {
|
|||||||
Util::panic("Could not initialize Vulkan ICD");
|
Util::panic("Could not initialize Vulkan ICD");
|
||||||
}
|
}
|
||||||
|
|
||||||
windowHandle()->setVulkanInstance(&instance.get_qvkinstance());
|
instance = std::make_unique<QtInstanceFactory>();
|
||||||
|
windowHandle()->setVulkanInstance(&instance->qVkInstance);
|
||||||
windowHandle()->create();
|
windowHandle()->create();
|
||||||
|
|
||||||
wsiPlatform = std::make_unique<QtWSIPlatform>(windowHandle());
|
wsiPlatform = std::make_unique<QtWSIPlatform>(windowHandle());
|
||||||
windowInfo = std::make_unique<QtParallelRdpWindowInfo>(windowHandle());
|
windowInfo = std::make_unique<QtParallelRdpWindowInfo>(windowHandle());
|
||||||
|
|
||||||
LoadWSIPlatform(&instance, std::move(wsiPlatform), std::move(windowInfo));
|
|
||||||
}
|
}
|
||||||
@@ -4,10 +4,11 @@
|
|||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QWindow>
|
#include <QWindow>
|
||||||
#include <QVulkanInstance>
|
#include <QVulkanInstance>
|
||||||
|
#include <QVulkanWindow>
|
||||||
|
|
||||||
struct QtInstanceFactory : Vulkan::InstanceFactory {
|
struct QtInstanceFactory : Vulkan::InstanceFactory {
|
||||||
VkInstance create_instance(const VkInstanceCreateInfo *info) override {
|
VkInstance create_instance(const VkInstanceCreateInfo *info) override {
|
||||||
instance.setApiVersion({1,3,0});
|
qVkInstance.setApiVersion({1,3,0});
|
||||||
QByteArrayList exts;
|
QByteArrayList exts;
|
||||||
for(int i = 0; i < info->enabledExtensionCount; i++) {
|
for(int i = 0; i < info->enabledExtensionCount; i++) {
|
||||||
exts.push_back(QByteArray::fromStdString(info->ppEnabledExtensionNames[i]));
|
exts.push_back(QByteArray::fromStdString(info->ppEnabledExtensionNames[i]));
|
||||||
@@ -16,17 +17,15 @@ struct QtInstanceFactory : Vulkan::InstanceFactory {
|
|||||||
for(int i = 0; i < info->enabledLayerCount; i++) {
|
for(int i = 0; i < info->enabledLayerCount; i++) {
|
||||||
layers.push_back(QByteArray::fromStdString(info->ppEnabledLayerNames[i]));
|
layers.push_back(QByteArray::fromStdString(info->ppEnabledLayerNames[i]));
|
||||||
}
|
}
|
||||||
instance.setExtensions(exts);
|
qVkInstance.setExtensions(exts);
|
||||||
instance.setLayers(layers);
|
qVkInstance.setLayers(layers);
|
||||||
instance.setApiVersion({1,3,0});
|
qVkInstance.setApiVersion({1,3,0});
|
||||||
instance.create();
|
qVkInstance.create();
|
||||||
|
|
||||||
return instance.vkInstance();
|
return qVkInstance.vkInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVulkanInstance& get_qvkinstance() { return instance; }
|
QVulkanInstance qVkInstance;
|
||||||
private:
|
|
||||||
QVulkanInstance instance;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class QtParallelRdpWindowInfo : public ParallelRdpWindowInfo {
|
class QtParallelRdpWindowInfo : public ParallelRdpWindowInfo {
|
||||||
@@ -58,6 +57,8 @@ public:
|
|||||||
return QVulkanInstance::surfaceForWindow(window);
|
return QVulkanInstance::surfaceForWindow(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void destroy_surface(VkInstance instance, VkSurfaceKHR surface) override { }
|
||||||
|
|
||||||
uint32_t get_surface_width() override {
|
uint32_t get_surface_width() override {
|
||||||
return 640;
|
return 640;
|
||||||
}
|
}
|
||||||
@@ -70,7 +71,9 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void poll_input() override { }
|
void poll_input() override {
|
||||||
|
SDL_PumpEvents();
|
||||||
|
}
|
||||||
|
|
||||||
void event_frame_tick(double frame, double elapsed) override { }
|
void event_frame_tick(double frame, double elapsed) override { }
|
||||||
|
|
||||||
@@ -93,8 +96,8 @@ public:
|
|||||||
[[nodiscard]] QPaintEngine* paintEngine() const override {
|
[[nodiscard]] QPaintEngine* paintEngine() const override {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
std::unique_ptr<ParallelRdpWindowInfo> windowInfo;
|
std::unique_ptr<ParallelRdpWindowInfo> windowInfo;
|
||||||
std::unique_ptr<Vulkan::WSIPlatform> wsiPlatform;
|
std::unique_ptr<Vulkan::WSIPlatform> wsiPlatform;
|
||||||
QtInstanceFactory instance;
|
std::unique_ptr<QtInstanceFactory> instance;
|
||||||
};
|
};
|
||||||
@@ -30,6 +30,9 @@
|
|||||||
<property name="bottomMargin">
|
<property name="bottomMargin">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="RenderWidget" name="vulkanWidget"/>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenuBar" name="menubar">
|
<widget class="QMenuBar" name="menubar">
|
||||||
@@ -119,6 +122,13 @@
|
|||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>RenderWidget</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header>RenderWidget.hpp</header>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
|||||||
Reference in New Issue
Block a user