Refactor Parallel RDP wrapper

This commit is contained in:
Simone
2024-05-14 12:15:27 +02:00
parent 5f2dc06236
commit 02d1f888d8
16 changed files with 171 additions and 137 deletions

View File

@@ -6,14 +6,11 @@
using namespace Vulkan; using namespace Vulkan;
using namespace RDP; using namespace RDP;
static CommandProcessor* command_processor; bool ParallelRDP::IsFramerateUnlocked() {
static std::unique_ptr<ParallelRdpWindowInfo> windowInfo;
bool IsFramerateUnlocked() {
return wsi->get_present_mode() != PresentMode::SyncToVBlank; return wsi->get_present_mode() != PresentMode::SyncToVBlank;
} }
void SetFramerateUnlocked(bool unlocked) { void ParallelRDP::SetFramerateUnlocked(bool unlocked) {
if (unlocked) { if (unlocked) {
wsi->set_present_mode(PresentMode::UnlockedForceTearing); wsi->set_present_mode(PresentMode::UnlockedForceTearing);
} else { } else {
@@ -23,7 +20,7 @@ void SetFramerateUnlocked(bool unlocked) {
Program* fullscreen_quad_program; Program* fullscreen_quad_program;
WSI* LoadWSIPlatform(Vulkan::InstanceFactory* instanceFactory, std::unique_ptr<Vulkan::WSIPlatform>&& wsi_platform, std::unique_ptr<ParallelRdpWindowInfo>&& newWindowInfo) { void ParallelRDP::LoadWSIPlatform(Vulkan::InstanceFactory* instanceFactory, std::unique_ptr<Vulkan::WSIPlatform>&& wsi_platform, std::unique_ptr<ParallelRDP::WindowInfo>&& newWindowInfo) {
wsi = new WSI(); wsi = new WSI();
wsi->set_backbuffer_srgb(false); wsi->set_backbuffer_srgb(false);
wsi->set_platform(wsi_platform.get()); wsi->set_platform(wsi_platform.get());
@@ -34,10 +31,9 @@ WSI* LoadWSIPlatform(Vulkan::InstanceFactory* instanceFactory, std::unique_ptr<V
} }
windowInfo = std::move(newWindowInfo); windowInfo = std::move(newWindowInfo);
return wsi;
} }
void LoadParallelRDP(const u8* rdram) { void ParallelRDP::Init(const u8* rdram) {
ResourceLayout vertLayout; ResourceLayout vertLayout;
ResourceLayout fragLayout; ResourceLayout fragLayout;
@@ -74,7 +70,7 @@ void LoadParallelRDP(const u8* rdram) {
CommandProcessorFlags flags = 0; CommandProcessorFlags flags = 0;
command_processor = new CommandProcessor(wsi->get_device(), reinterpret_cast<void *>(aligned_rdram), command_processor = new CommandProcessor(wsi->get_device(), reinterpret_cast<void*>(aligned_rdram),
offset, 8 * 1024 * 1024, 4 * 1024 * 1024, flags); offset, 8 * 1024 * 1024, 4 * 1024 * 1024, flags);
if (!command_processor->device_is_supported()) { if (!command_processor->device_is_supported()) {
@@ -82,7 +78,11 @@ void LoadParallelRDP(const u8* rdram) {
} }
} }
void DrawFullscreenTexturedQuad(Util::IntrusivePtr<Image> image, Util::IntrusivePtr<CommandBuffer> cmd) { ParallelRDP::ParallelRDP(Vulkan::InstanceFactory* factory, std::unique_ptr<Vulkan::WSIPlatform>&& wsi_platform, std::unique_ptr<WindowInfo>&& newWindowInfo) {
LoadWSIPlatform(factory, std::move(wsi_platform), std::move(newWindowInfo));
}
void ParallelRDP::DrawFullscreenTexturedQuad(Util::IntrusivePtr<Image> image, Util::IntrusivePtr<CommandBuffer> cmd) {
cmd->set_texture(0, 0, image->get_view(), Vulkan::StockSampler::LinearClamp); cmd->set_texture(0, 0, image->get_view(), Vulkan::StockSampler::LinearClamp);
cmd->set_program(fullscreen_quad_program); cmd->set_program(fullscreen_quad_program);
cmd->set_quad_state(); cmd->set_quad_state();
@@ -118,7 +118,7 @@ void DrawFullscreenTexturedQuad(Util::IntrusivePtr<Image> image, Util::Intrusive
cmd->draw(3, 1); cmd->draw(3, 1);
} }
void UpdateScreen(Util::IntrusivePtr<Image> image) { void ParallelRDP::UpdateScreen(Util::IntrusivePtr<Image> image) {
wsi->begin_frame(); wsi->begin_frame();
if (!image) { if (!image) {
@@ -153,7 +153,7 @@ void UpdateScreen(Util::IntrusivePtr<Image> image) {
wsi->end_frame(); wsi->end_frame();
} }
void UpdateScreenParallelRdp(n64::VI& vi) { void ParallelRDP::UpdateScreen(n64::VI& vi, bool noGame) {
command_processor->set_vi_register(VIRegister::Control, vi.status.raw); command_processor->set_vi_register(VIRegister::Control, vi.status.raw);
command_processor->set_vi_register(VIRegister::Origin, vi.origin); command_processor->set_vi_register(VIRegister::Origin, vi.origin);
command_processor->set_vi_register(VIRegister::Width, vi.width); command_processor->set_vi_register(VIRegister::Width, vi.width);
@@ -168,7 +168,7 @@ void UpdateScreenParallelRdp(n64::VI& vi) {
command_processor->set_vi_register(VIRegister::VBurst, vi.vburst); command_processor->set_vi_register(VIRegister::VBurst, vi.vburst);
command_processor->set_vi_register(VIRegister::XScale, vi.xscale.raw); command_processor->set_vi_register(VIRegister::XScale, vi.xscale.raw);
command_processor->set_vi_register(VIRegister::YScale, vi.yscale.raw); command_processor->set_vi_register(VIRegister::YScale, vi.yscale.raw);
if (!noGame) {
RDP::ScanoutOptions opts; RDP::ScanoutOptions opts;
opts.persist_frame_on_invalid_input = true; opts.persist_frame_on_invalid_input = true;
opts.vi.aa = true; opts.vi.aa = true;
@@ -181,16 +181,17 @@ void UpdateScreenParallelRdp(n64::VI& vi) {
Util::IntrusivePtr<Image> image = command_processor->scanout(opts); Util::IntrusivePtr<Image> image = command_processor->scanout(opts);
UpdateScreen(image); UpdateScreen(image);
command_processor->begin_frame_context(); command_processor->begin_frame_context();
} }
else {
void UpdateScreenParallelRdpNoGame() {
UpdateScreen(static_cast<Util::IntrusivePtr<Image>>(nullptr)); UpdateScreen(static_cast<Util::IntrusivePtr<Image>>(nullptr));
command_processor->begin_frame_context();
}
} }
void ParallelRdpEnqueueCommand(int command_length, u32* buffer) { void ParallelRDP::EnqueueCommand(int command_length, u32* buffer) {
command_processor->enqueue_command(command_length, buffer); command_processor->enqueue_command(command_length, buffer);
} }
void ParallelRdpOnFullSync() { void ParallelRDP::OnFullSync() {
command_processor->wait_for_timeline(command_processor->signal_timeline()); command_processor->wait_for_timeline(command_processor->signal_timeline());
} }

View File

@@ -1,24 +1,38 @@
#pragma once #pragma once
#include <backend/Core.hpp> #include <backend/Core.hpp>
#include <wsi.hpp> #include <wsi.hpp>
#include <rdp_device.hpp>
class ParallelRdpWindowInfo { class ParallelRDP {
public: public:
class WindowInfo {
public:
struct CoordinatePair { struct CoordinatePair {
float x; float x;
float y; float y;
}; };
virtual CoordinatePair get_window_size() = 0; virtual CoordinatePair get_window_size() = 0;
virtual ~ParallelRdpWindowInfo() = default; virtual ~WindowInfo() = default;
};
void Init(const u8*);
ParallelRDP(Vulkan::InstanceFactory*, std::unique_ptr<Vulkan::WSIPlatform>&&, std::unique_ptr<WindowInfo>&&);
~ParallelRDP() {
delete wsi;
delete command_processor;
}
void UpdateScreen(n64::VI&, bool = false);
void EnqueueCommand(int, u32*);
void OnFullSync();
bool IsFramerateUnlocked();
void SetFramerateUnlocked(bool);
private:
void LoadWSIPlatform(Vulkan::InstanceFactory*, std::unique_ptr<Vulkan::WSIPlatform>&&, std::unique_ptr<WindowInfo>&&);
void DrawFullscreenTexturedQuad(Util::IntrusivePtr<Vulkan::Image>, Util::IntrusivePtr<Vulkan::CommandBuffer>);
void UpdateScreen(Util::IntrusivePtr<Vulkan::Image>);
Vulkan::WSI* wsi = nullptr;
RDP::CommandProcessor* command_processor;
std::unique_ptr<WindowInfo> windowInfo;
}; };
static Vulkan::WSI* wsi;
void LoadParallelRDP(const u8* rdram);
Vulkan::WSI* LoadWSIPlatform(Vulkan::InstanceFactory*, std::unique_ptr<Vulkan::WSIPlatform>&& wsi_platform, std::unique_ptr<ParallelRdpWindowInfo>&& newWindowInfo);
void UpdateScreenParallelRdp(n64::VI& vi);
void ParallelRdpEnqueueCommand(int command_length, u32* buffer);
void ParallelRdpOnFullSync();
void UpdateScreenParallelRdpNoGame();
bool IsFramerateUnlocked();
void SetFramerateUnlocked(bool unlocked);

View File

@@ -3,18 +3,18 @@
#include <ParallelRDPWrapper.hpp> #include <ParallelRDPWrapper.hpp>
namespace n64 { namespace n64 {
Core::Core() : cpu(std::make_unique<Interpreter>()) {} Core::Core(ParallelRDP& parallel) : cpu(std::make_unique<Interpreter>(parallel)) {}
void Core::Stop() { void Core::Stop() {
render = false; render = false;
pause = true; pause = true;
romLoaded = false; romLoaded = false;
cpu->Reset(); cpu->Reset();
cpu->mem.Reset(); cpu->GetMem().Reset();
} }
bool Core::LoadTAS(const fs::path &path) { bool Core::LoadTAS(const fs::path &path) {
return cpu->mem.mmio.si.pif.movie.Load(path); return cpu->GetMem().mmio.si.pif.movie.Load(path);
} }
void Core::LoadROM(const std::string& rom_) { void Core::LoadROM(const std::string& rom_) {
@@ -30,23 +30,23 @@ void Core::LoadROM(const std::string& rom_) {
return e == extension; return e == extension;
}); });
cpu->mem.LoadROM(isArchive, rom); cpu->GetMem().LoadROM(isArchive, rom);
GameDB::match(cpu->mem); GameDB::match(cpu->GetMem());
cpu->mem.mmio.vi.isPal = cpu->mem.IsROMPAL(); cpu->GetMem().mmio.vi.isPal = cpu->GetMem().IsROMPAL();
cpu->mem.mmio.si.pif.InitDevices(cpu->mem.saveType); cpu->GetMem().mmio.si.pif.InitDevices(cpu->GetMem().saveType);
cpu->mem.mmio.si.pif.mempakPath = rom; cpu->GetMem().mmio.si.pif.mempakPath = rom;
cpu->mem.mmio.si.pif.LoadEeprom(cpu->mem.saveType, rom); cpu->GetMem().mmio.si.pif.LoadEeprom(cpu->GetMem().saveType, rom);
cpu->mem.flash.Load(cpu->mem.saveType, rom); cpu->GetMem().flash.Load(cpu->GetMem().saveType, rom);
cpu->mem.LoadSRAM(cpu->mem.saveType, rom); cpu->GetMem().LoadSRAM(cpu->GetMem().saveType, rom);
cpu->mem.mmio.si.pif.Execute(); cpu->GetMem().mmio.si.pif.Execute();
pause = false; pause = false;
render = true; render = true;
} }
void Core::Run(float volumeL, float volumeR) { void Core::Run(float volumeL, float volumeR) {
Mem& mem = cpu->mem; Mem& mem = cpu->GetMem();
MMIO& mmio = mem.mmio; MMIO& mmio = mem.mmio;
Registers& regs = cpu->regs; Registers& regs = cpu->GetRegs();
for (int field = 0; field < mmio.vi.numFields; field++) { for (int field = 0; field < mmio.vi.numFields; field++) {
u32 frameCycles = 0; u32 frameCycles = 0;
@@ -95,7 +95,7 @@ void Core::Run(float volumeL, float volumeR) {
} }
void Core::Serialize() { void Core::Serialize() {
auto sMEM = cpu->mem.Serialize(); auto sMEM = cpu->GetMem().Serialize();
auto sCPU = cpu->Serialize(); auto sCPU = cpu->Serialize();
auto sVER = std::vector<u8>{KAIZEN_VERSION >> 8, KAIZEN_VERSION >> 4, KAIZEN_VERSION & 0xFF}; auto sVER = std::vector<u8>{KAIZEN_VERSION >> 8, KAIZEN_VERSION >> 4, KAIZEN_VERSION & 0xFF};
memSize = sMEM.size(); memSize = sMEM.size();
@@ -114,7 +114,7 @@ void Core::Deserialize() {
Util::panic("PROBLEMI!"); Util::panic("PROBLEMI!");
} }
cpu->mem.Deserialize(std::vector<u8>(serialized[slot].begin() + verSize, serialized[slot].begin() + verSize + memSize)); cpu->GetMem().Deserialize(std::vector<u8>(serialized[slot].begin() + verSize, serialized[slot].begin() + verSize + memSize));
cpu->Deserialize(std::vector<u8>(serialized[slot].begin() + verSize + memSize, serialized[slot].begin() + verSize + memSize + cpuSize)); cpu->Deserialize(std::vector<u8>(serialized[slot].begin() + verSize + memSize, serialized[slot].begin() + verSize + memSize + cpuSize));
serialized[slot].erase(serialized[slot].begin(), serialized[slot].end()); serialized[slot].erase(serialized[slot].begin(), serialized[slot].end());
} }

View File

@@ -8,7 +8,7 @@ struct Event;
namespace n64 { namespace n64 {
struct Core { struct Core {
~Core() { Stop(); } ~Core() { Stop(); }
Core(); Core(ParallelRDP&);
void Stop(); void Stop();
void LoadROM(const std::string&); void LoadROM(const std::string&);
bool LoadTAS(const fs::path&); bool LoadTAS(const fs::path&);
@@ -16,7 +16,7 @@ struct Core {
void Serialize(); void Serialize();
void Deserialize(); void Deserialize();
void TogglePause() { pause = !pause; } void TogglePause() { pause = !pause; }
[[nodiscard]] VI& GetVI() const { return cpu->mem.mmio.vi; } [[nodiscard]] VI& GetVI() const { return cpu->GetMem().mmio.vi; }
u32 breakpoint = 0; u32 breakpoint = 0;

View File

@@ -6,15 +6,12 @@ namespace n64 {
struct BaseCPU { struct BaseCPU {
virtual ~BaseCPU() = default; virtual ~BaseCPU() = default;
virtual int Step() = 0; virtual int Step() = 0;
virtual void Reset() { virtual void Reset() = 0;
regs.Reset();
mem.Reset();
}
virtual bool ShouldServiceInterrupt() = 0; virtual bool ShouldServiceInterrupt() = 0;
virtual void CheckCompareInterrupt() = 0; virtual void CheckCompareInterrupt() = 0;
virtual std::vector<u8> Serialize() = 0; virtual std::vector<u8> Serialize() = 0;
virtual void Deserialize(const std::vector<u8>&) = 0; virtual void Deserialize(const std::vector<u8>&) = 0;
Registers regs; virtual Mem& GetMem() = 0;
Mem mem{regs}; virtual Registers& GetRegs() = 0;
}; };
} }

View File

@@ -1,6 +1,7 @@
#include <Core.hpp> #include <Core.hpp>
namespace n64 { namespace n64 {
Interpreter::Interpreter(ParallelRDP& parallel) : mem(regs, parallel) { }
bool Interpreter::ShouldServiceInterrupt() { bool Interpreter::ShouldServiceInterrupt() {
bool interrupts_pending = (regs.cop0.status.im & regs.cop0.cause.interruptPending) != 0; bool interrupts_pending = (regs.cop0.status.im & regs.cop0.cause.interruptPending) != 0;

View File

@@ -5,11 +5,25 @@
namespace n64 { namespace n64 {
struct Core; struct Core;
struct Interpreter : BaseCPU { struct Interpreter final : BaseCPU {
Interpreter() = default; explicit Interpreter(ParallelRDP&);
~Interpreter() override = default; ~Interpreter() override = default;
int Step() override; int Step() override;
void Reset() override {
regs.Reset();
mem.Reset();
}
Mem& GetMem() override {
return mem;
}
Registers& GetRegs() override {
return regs;
}
private: private:
Registers regs;
Mem mem;
u64 cop2Latch{}; u64 cop2Latch{};
friend struct Cop1; friend struct Cop1;
#define check_address_error(mask, vaddr) (((!regs.cop0.is64BitAddressing) && (s32)(vaddr) != (vaddr)) || (((vaddr) & (mask)) != 0)) #define check_address_error(mask, vaddr) (((!regs.cop0.is64BitAddressing) && (s32)(vaddr) != (vaddr)) || (((vaddr) & (mask)) != 0))

View File

@@ -8,12 +8,14 @@
#include <core/RSP.hpp> #include <core/RSP.hpp>
#include <core/RDP.hpp> #include <core/RDP.hpp>
class ParallelRDP;
namespace n64 { namespace n64 {
struct Mem; struct Mem;
struct Registers; struct Registers;
struct MMIO { struct MMIO {
MMIO(Mem& mem, Registers& regs) : vi(mem, regs), mi(regs), ai(mem, regs), pi(mem, regs), si(mem, regs), rsp(mem, regs), rdp(mem, regs) {} MMIO(Mem& mem, Registers& regs, ParallelRDP& parallel) : vi(mem, regs), mi(regs), ai(mem, regs), pi(mem, regs), si(mem, regs), rsp(mem, regs), rdp(mem, regs, parallel) {}
void Reset(); void Reset();
VI vi; VI vi;

View File

@@ -8,7 +8,7 @@
#include <cassert> #include <cassert>
namespace n64 { namespace n64 {
Mem::Mem(Registers& regs) : flash(saveData), mmio(*this, regs) { Mem::Mem(Registers& regs, ParallelRDP& parallel) : flash(saveData), mmio(*this, regs, parallel) {
memset(readPages, 0, PAGE_COUNT); memset(readPages, 0, PAGE_COUNT);
memset(writePages, 0, PAGE_COUNT); memset(writePages, 0, PAGE_COUNT);

View File

@@ -81,7 +81,7 @@ struct Flash {
struct Mem { struct Mem {
~Mem() = default; ~Mem() = default;
Mem(Registers&); Mem(Registers&, ParallelRDP&);
void Reset(); void Reset();
void LoadSRAM(SaveType, fs::path); void LoadSRAM(SaveType, fs::path);
static std::vector<u8> OpenROM(const std::string&, size_t&); static std::vector<u8> OpenROM(const std::string&, size_t&);

View File

@@ -5,7 +5,7 @@
#include <core/mmio/Interrupt.hpp> #include <core/mmio/Interrupt.hpp>
namespace n64 { namespace n64 {
RDP::RDP(Mem& mem, Registers& regs) : mem(mem), regs(regs) { RDP::RDP(Mem& mem, Registers& regs, ParallelRDP& parallel) : mem(mem), regs(regs), parallel(parallel) {
rdram.resize(RDRAM_SIZE); rdram.resize(RDRAM_SIZE);
memset(cmd_buf, 0, 0x100000); memset(cmd_buf, 0, 0x100000);
dpc.status.raw = 0x80; dpc.status.raw = 0x80;
@@ -177,7 +177,7 @@ void RDP::RunCommand() {
} }
if (cmd >= 8) { if (cmd >= 8) {
ParallelRdpEnqueueCommand(cmd_len, &cmd_buf[buf_index]); parallel.EnqueueCommand(cmd_len, &cmd_buf[buf_index]);
} }
if (cmd == 0x29) { if (cmd == 0x29) {
@@ -199,7 +199,7 @@ void RDP::RunCommand() {
} }
void RDP::OnFullSync() { void RDP::OnFullSync() {
ParallelRdpOnFullSync(); parallel.OnFullSync();
dpc.status.pipeBusy = false; dpc.status.pipeBusy = false;
dpc.status.startGclk = false; dpc.status.startGclk = false;

View File

@@ -2,6 +2,8 @@
#include <common.hpp> #include <common.hpp>
#include <vector> #include <vector>
class ParallelRDP;
namespace n64 { namespace n64 {
struct RSP; struct RSP;
@@ -54,7 +56,7 @@ struct RDP {
DPC dpc{}; DPC dpc{};
u32 cmd_buf[0xFFFFF]{}; u32 cmd_buf[0xFFFFF]{};
RDP(Mem&, Registers&); RDP(Mem&, Registers&, ParallelRDP&);
void Reset(); void Reset();
std::vector<u8> rdram{}; std::vector<u8> rdram{};
@@ -82,5 +84,6 @@ struct RDP {
private: private:
Mem& mem; Mem& mem;
Registers& regs; Registers& regs;
ParallelRDP& parallel;
}; };
} // backend } // backend

View File

@@ -1,24 +1,21 @@
#include <ParallelRDPWrapper.hpp>
#include <EmuThread.hpp> #include <EmuThread.hpp>
#include <RenderWidget.hpp> #include <RenderWidget.hpp>
#include <ParallelRDPWrapper.hpp>
#include "Audio.hpp" #include "Audio.hpp"
EmuThread::EmuThread(std::unique_ptr<QtInstanceFactory>&& instance, std::unique_ptr<Vulkan::WSIPlatform>&& wsiPlatform, std::unique_ptr<ParallelRdpWindowInfo>&& windowInfo, QObject* parent_object) noexcept EmuThread::EmuThread(std::unique_ptr<QtInstanceFactory>&& instance_, std::unique_ptr<Vulkan::WSIPlatform>&& wsiPlatform_, std::unique_ptr<ParallelRDP::WindowInfo>&& windowInfo_, QObject* parent_object) noexcept
: QThread(parent_object), instance(std::move(instance)), wsiPlatform(std::move(wsiPlatform)), windowInfo(std::move(windowInfo)) {} : QThread(parent_object), instance(std::move(instance_)), wsiPlatform(std::move(wsiPlatform_)), windowInfo(std::move(windowInfo_)), parallel(instance.get(), std::move(wsiPlatform), 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.GetRDRAMPtr());
while (true) { while (true) {
if (!core->pause) { if (!core->pause) {
core->Run(settings->getVolumeL(), settings->getVolumeR()); core->Run(settings->getVolumeL(), settings->getVolumeR());
if(core->render) { if(core->render) {
UpdateScreenParallelRdp(core->cpu->mem.mmio.vi); parallel.UpdateScreen(core->cpu->GetMem().mmio.vi);
} }
} else { } else {
if(core->render) { if(core->render) {
UpdateScreenParallelRdpNoGame(); parallel.UpdateScreen(core->cpu->GetMem().mmio.vi, true);
} }
} }
} }

View File

@@ -1,25 +1,29 @@
#pragma once #pragma once
#undef signals
#include <ParallelRDPWrapper.hpp>
#include <QThread> #include <QThread>
#include <Core.hpp> #include <Core.hpp>
#include <SettingsWindow.hpp> #include <SettingsWindow.hpp>
#include <memory>
struct QtInstanceFactory; struct QtInstanceFactory;
class ParallelRdpWindowInfo;
namespace Vulkan {
class WSIPlatform;
}
class EmuThread : public QThread class EmuThread : public QThread
{ {
Q_OBJECT Q_OBJECT
std::unique_ptr<QtInstanceFactory> instance; std::unique_ptr<QtInstanceFactory> instance;
std::unique_ptr<Vulkan::WSIPlatform> wsiPlatform; std::unique_ptr<Vulkan::WSIPlatform> wsiPlatform;
std::unique_ptr<ParallelRdpWindowInfo> windowInfo; std::unique_ptr<ParallelRDP::WindowInfo> windowInfo;
public: public:
explicit EmuThread(std::unique_ptr<QtInstanceFactory>&& instance, std::unique_ptr<Vulkan::WSIPlatform>&& wsiPlatform, std::unique_ptr<ParallelRdpWindowInfo>&& windowInfo, QObject* parent_object) noexcept; explicit EmuThread(std::unique_ptr<QtInstanceFactory>&& instance, std::unique_ptr<Vulkan::WSIPlatform>&& wsiPlatform, std::unique_ptr<ParallelRDP::WindowInfo>&& windowInfo, QObject* parent_object) noexcept;
~EmuThread() {
delete core;
delete settings;
}
[[noreturn]] void run() noexcept override; [[noreturn]] void run() noexcept override;
ParallelRDP parallel;
n64::Core* core; n64::Core* core;
SettingsWindow* settings; SettingsWindow* settings;
bool running = false; bool running = false;

View File

@@ -14,6 +14,8 @@ KaizenQt::KaizenQt() noexcept : QWidget(nullptr) {
std::move(mainWindow->view.vulkanWidget->wsiPlatform), std::move(mainWindow->view.vulkanWidget->wsiPlatform),
std::move(mainWindow->view.vulkanWidget->windowInfo), std::move(mainWindow->view.vulkanWidget->windowInfo),
mainWindow); mainWindow);
emuThread->core = new n64::Core(emuThread->parallel);
emuThread->parallel.Init(emuThread->core->cpu->GetMem().GetRDRAMPtr());
ConnectMainWindowSignalsToSlots(); ConnectMainWindowSignalsToSlots();
@@ -27,7 +29,6 @@ KaizenQt::KaizenQt() noexcept : QWidget(nullptr) {
connect(settingsWindow, &SettingsWindow::regrabKeyboard, this, [&]() { connect(settingsWindow, &SettingsWindow::regrabKeyboard, this, [&]() {
grabKeyboard(); grabKeyboard();
}), }),
emuThread->core = new n64::Core();
emuThread->settings = settingsWindow; emuThread->settings = settingsWindow;
} }
@@ -67,24 +68,24 @@ void KaizenQt::LoadTAS(const QString& fileName) noexcept {
void KaizenQt::keyPressEvent(QKeyEvent *e) { void KaizenQt::keyPressEvent(QKeyEvent *e) {
emuThread->core->pause = true; emuThread->core->pause = true;
auto k = static_cast<Qt::Key>(e->key()); auto k = static_cast<Qt::Key>(e->key());
if(k == settingsWindow->keyMap[0]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::A, true); if(k == settingsWindow->keyMap[0]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::A, true);
if(k == settingsWindow->keyMap[1]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::B, true); if(k == settingsWindow->keyMap[1]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::B, true);
if(k == settingsWindow->keyMap[2]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::Z, true); if(k == settingsWindow->keyMap[2]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::Z, true);
if(k == settingsWindow->keyMap[3]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::Start, true); if(k == settingsWindow->keyMap[3]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::Start, true);
if(k == settingsWindow->keyMap[4]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::LT, true); if(k == settingsWindow->keyMap[4]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::LT, true);
if(k == settingsWindow->keyMap[5]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::RT, true); if(k == settingsWindow->keyMap[5]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::RT, true);
if(k == settingsWindow->keyMap[6]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::DUp, true); if(k == settingsWindow->keyMap[6]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::DUp, true);
if(k == settingsWindow->keyMap[7]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::DDown, true); if(k == settingsWindow->keyMap[7]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::DDown, true);
if(k == settingsWindow->keyMap[8]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::DLeft, true); if(k == settingsWindow->keyMap[8]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::DLeft, true);
if(k == settingsWindow->keyMap[9]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::DRight, true); if(k == settingsWindow->keyMap[9]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::DRight, true);
if(k == settingsWindow->keyMap[10]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::CUp, true); if(k == settingsWindow->keyMap[10]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::CUp, true);
if(k == settingsWindow->keyMap[11]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::CDown, true); if(k == settingsWindow->keyMap[11]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::CDown, true);
if(k == settingsWindow->keyMap[12]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::CLeft, true); if(k == settingsWindow->keyMap[12]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::CLeft, true);
if(k == settingsWindow->keyMap[13]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::CRight, true); if(k == settingsWindow->keyMap[13]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::CRight, true);
if(k == settingsWindow->keyMap[14]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateAxis(n64::Controller::Axis::Y, 86); if(k == settingsWindow->keyMap[14]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateAxis(n64::Controller::Axis::Y, 86);
if(k == settingsWindow->keyMap[15]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateAxis(n64::Controller::Axis::Y, -86); if(k == settingsWindow->keyMap[15]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateAxis(n64::Controller::Axis::Y, -86);
if(k == settingsWindow->keyMap[16]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateAxis(n64::Controller::Axis::X, -86); if(k == settingsWindow->keyMap[16]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateAxis(n64::Controller::Axis::X, -86);
if(k == settingsWindow->keyMap[17]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateAxis(n64::Controller::Axis::X, 86); if(k == settingsWindow->keyMap[17]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateAxis(n64::Controller::Axis::X, 86);
emuThread->core->pause = false; emuThread->core->pause = false;
QWidget::keyPressEvent(e); QWidget::keyPressEvent(e);
} }
@@ -92,24 +93,24 @@ void KaizenQt::keyPressEvent(QKeyEvent *e) {
void KaizenQt::keyReleaseEvent(QKeyEvent *e) { void KaizenQt::keyReleaseEvent(QKeyEvent *e) {
emuThread->core->pause = true; emuThread->core->pause = true;
auto k = static_cast<Qt::Key>(e->key()); auto k = static_cast<Qt::Key>(e->key());
if (k == settingsWindow->keyMap[0]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::A, false); if (k == settingsWindow->keyMap[0]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::A, false);
if (k == settingsWindow->keyMap[1]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::B, false); if (k == settingsWindow->keyMap[1]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::B, false);
if (k == settingsWindow->keyMap[2]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::Z, false); if (k == settingsWindow->keyMap[2]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::Z, false);
if (k == settingsWindow->keyMap[3]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::Start, false); if (k == settingsWindow->keyMap[3]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::Start, false);
if (k == settingsWindow->keyMap[4]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::LT, false); if (k == settingsWindow->keyMap[4]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::LT, false);
if (k == settingsWindow->keyMap[5]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::RT, false); if (k == settingsWindow->keyMap[5]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::RT, false);
if (k == settingsWindow->keyMap[6]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::DUp, false); if (k == settingsWindow->keyMap[6]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::DUp, false);
if (k == settingsWindow->keyMap[7]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::DDown, false); if (k == settingsWindow->keyMap[7]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::DDown, false);
if (k == settingsWindow->keyMap[8]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::DLeft, false); if (k == settingsWindow->keyMap[8]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::DLeft, false);
if (k == settingsWindow->keyMap[9]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::DRight, false); if (k == settingsWindow->keyMap[9]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::DRight, false);
if (k == settingsWindow->keyMap[10]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::CUp, false); if (k == settingsWindow->keyMap[10]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::CUp, false);
if (k == settingsWindow->keyMap[11]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::CDown, false); if (k == settingsWindow->keyMap[11]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::CDown, false);
if (k == settingsWindow->keyMap[12]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::CLeft, false); if (k == settingsWindow->keyMap[12]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::CLeft, false);
if (k == settingsWindow->keyMap[13]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::CRight, false); if (k == settingsWindow->keyMap[13]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateButton(n64::Controller::Key::CRight, false);
if (k == settingsWindow->keyMap[14]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateAxis(n64::Controller::Axis::Y, 0); if (k == settingsWindow->keyMap[14]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateAxis(n64::Controller::Axis::Y, 0);
if (k == settingsWindow->keyMap[15]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateAxis(n64::Controller::Axis::Y, 0); if (k == settingsWindow->keyMap[15]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateAxis(n64::Controller::Axis::Y, 0);
if (k == settingsWindow->keyMap[16]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateAxis(n64::Controller::Axis::X, 0); if (k == settingsWindow->keyMap[16]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateAxis(n64::Controller::Axis::X, 0);
if (k == settingsWindow->keyMap[17]) emuThread->core->cpu->mem.mmio.si.pif.joybusDevices[0].controller.UpdateAxis(n64::Controller::Axis::X, 0); if (k == settingsWindow->keyMap[17]) emuThread->core->cpu->GetMem().mmio.si.pif.joybusDevices[0].controller.UpdateAxis(n64::Controller::Axis::X, 0);
emuThread->core->pause = false; emuThread->core->pause = false;
QWidget::keyPressEvent(e); QWidget::keyPressEvent(e);
} }

View File

@@ -29,7 +29,7 @@ struct QtInstanceFactory : Vulkan::InstanceFactory {
QVulkanInstance qVkInstance; QVulkanInstance qVkInstance;
}; };
class QtParallelRdpWindowInfo : public ParallelRdpWindowInfo { class QtParallelRdpWindowInfo : public ParallelRDP::WindowInfo {
public: public:
explicit QtParallelRdpWindowInfo(QWindow* window) : window(window) {} explicit QtParallelRdpWindowInfo(QWindow* window) : window(window) {}
CoordinatePair get_window_size() override { CoordinatePair get_window_size() override {
@@ -96,7 +96,7 @@ public:
return nullptr; return nullptr;
} }
std::unique_ptr<ParallelRdpWindowInfo> windowInfo; std::unique_ptr<ParallelRDP::WindowInfo> windowInfo;
std::unique_ptr<Vulkan::WSIPlatform> wsiPlatform; std::unique_ptr<Vulkan::WSIPlatform> wsiPlatform;
std::unique_ptr<QtInstanceFactory> instance; std::unique_ptr<QtInstanceFactory> instance;
Q_SIGNALS: Q_SIGNALS: