Various pointer changes

This commit is contained in:
SimoneN64
2024-07-03 21:11:03 +02:00
parent 15838db5b6
commit d90e26ac0c
13 changed files with 144 additions and 150 deletions

View File

@@ -20,21 +20,21 @@ void ParallelRDP::SetFramerateUnlocked(bool unlocked) {
Program* fullscreen_quad_program; Program* fullscreen_quad_program;
void ParallelRDP::LoadWSIPlatform(Vulkan::InstanceFactory* instanceFactory, std::unique_ptr<Vulkan::WSIPlatform>&& wsi_platform, std::unique_ptr<ParallelRDP::WindowInfo>&& newWindowInfo) { void ParallelRDP::LoadWSIPlatform(const std::shared_ptr<Vulkan::InstanceFactory>& instanceFactory, const std::shared_ptr<Vulkan::WSIPlatform>& wsi_platform, const std::shared_ptr<ParallelRDP::WindowInfo>& newWindowInfo) {
wsi = std::make_unique<WSI>(); wsi = std::make_shared<WSI>();
wsi->set_backbuffer_srgb(false); wsi->set_backbuffer_srgb(false);
wsi->set_platform(wsi_platform.get()); wsi->set_platform(wsi_platform.get());
wsi->set_present_mode(PresentMode::SyncToVBlank); wsi->set_present_mode(PresentMode::SyncToVBlank);
Context::SystemHandles handles; Context::SystemHandles handles;
if (!wsi->init_simple(instanceFactory, 1, handles)) { if (!wsi->init_simple(instanceFactory.get(), 1, handles)) {
Util::panic("Failed to initialize WSI!"); Util::panic("Failed to initialize WSI!");
} }
windowInfo = std::move(newWindowInfo); windowInfo = newWindowInfo;
} }
void ParallelRDP::Init(Vulkan::InstanceFactory* factory, std::unique_ptr<Vulkan::WSIPlatform>&& wsiPlatform, std::unique_ptr<WindowInfo>&& newWindowInfo, const u8* rdram) { void ParallelRDP::Init(const std::shared_ptr<Vulkan::InstanceFactory>& factory, const std::shared_ptr<Vulkan::WSIPlatform>& wsiPlatform, const std::shared_ptr<WindowInfo>& newWindowInfo, const u8* rdram) {
LoadWSIPlatform(factory, std::move(wsiPlatform), std::move(newWindowInfo)); LoadWSIPlatform(factory, wsiPlatform, newWindowInfo);
ResourceLayout vertLayout; ResourceLayout vertLayout;
ResourceLayout fragLayout; ResourceLayout fragLayout;
@@ -63,8 +63,7 @@ void ParallelRDP::Init(Vulkan::InstanceFactory* factory, std::unique_ptr<Vulkan:
auto aligned_rdram = reinterpret_cast<uintptr_t>(rdram); auto aligned_rdram = reinterpret_cast<uintptr_t>(rdram);
uintptr_t offset = 0; uintptr_t offset = 0;
if (wsi->get_device().get_device_features().supports_external_memory_host) if (wsi->get_device().get_device_features().supports_external_memory_host) {
{
size_t align = wsi->get_device().get_device_features().host_memory_properties.minImportedHostPointerAlignment; size_t align = wsi->get_device().get_device_features().host_memory_properties.minImportedHostPointerAlignment;
offset = aligned_rdram & (align - 1); offset = aligned_rdram & (align - 1);
aligned_rdram -= offset; aligned_rdram -= offset;
@@ -72,8 +71,8 @@ void ParallelRDP::Init(Vulkan::InstanceFactory* factory, std::unique_ptr<Vulkan:
CommandProcessorFlags flags = 0; CommandProcessorFlags flags = 0;
command_processor = std::make_unique<CommandProcessor>(wsi->get_device(), reinterpret_cast<void*>(aligned_rdram), command_processor = std::make_shared<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()) {
Util::panic("This device probably does not support 8/16-bit storage. Make sure you're using up-to-date drivers!"); Util::panic("This device probably does not support 8/16-bit storage. Make sure you're using up-to-date drivers!");
@@ -101,11 +100,11 @@ void ParallelRDP::DrawFullscreenTexturedQuad(Util::IntrusivePtr<Image> image, Ut
float height = (wsi->get_platform().get_surface_height() / windowSize.y) * zoom; float height = (wsi->get_platform().get_surface_height() / windowSize.y) * zoom;
float uniform_data[] = { float uniform_data[] = {
// Size // Size
width, height, width, height,
// Offset // Offset
(1.0f - width) * 0.5f, (1.0f - width) * 0.5f,
(1.0f - height) * 0.5f}; (1.0f - height) * 0.5f};
cmd->push_constants(uniform_data, 0, sizeof(uniform_data)); cmd->push_constants(uniform_data, 0, sizeof(uniform_data));
@@ -122,7 +121,7 @@ void ParallelRDP::UpdateScreen(Util::IntrusivePtr<Image> image) {
if (!image) { if (!image) {
auto info = Vulkan::ImageCreateInfo::immutable_2d_image(800, 600, VK_FORMAT_R8G8B8A8_UNORM); auto info = Vulkan::ImageCreateInfo::immutable_2d_image(800, 600, VK_FORMAT_R8G8B8A8_UNORM);
info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | info.usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
VK_IMAGE_USAGE_TRANSFER_DST_BIT; VK_IMAGE_USAGE_TRANSFER_DST_BIT;
info.misc = IMAGE_MISC_MUTABLE_SRGB_BIT; info.misc = IMAGE_MISC_MUTABLE_SRGB_BIT;
info.initial_layout = VK_IMAGE_LAYOUT_UNDEFINED; info.initial_layout = VK_IMAGE_LAYOUT_UNDEFINED;
image = wsi->get_device().create_image(info); image = wsi->get_device().create_image(info);
@@ -179,8 +178,7 @@ void ParallelRDP::UpdateScreen(n64::VI& vi, bool noGame) {
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 {
else {
UpdateScreen(static_cast<Util::IntrusivePtr<Image>>(nullptr)); UpdateScreen(static_cast<Util::IntrusivePtr<Image>>(nullptr));
command_processor->begin_frame_context(); command_processor->begin_frame_context();
} }

View File

@@ -15,7 +15,7 @@ public:
virtual ~WindowInfo() = default; virtual ~WindowInfo() = default;
}; };
void Init(Vulkan::InstanceFactory*, std::unique_ptr<Vulkan::WSIPlatform>&&, std::unique_ptr<WindowInfo>&&, const u8*); void Init(const std::shared_ptr<Vulkan::InstanceFactory>&, const std::shared_ptr<Vulkan::WSIPlatform>&, const std::shared_ptr<WindowInfo>&, const u8*);
ParallelRDP() = default; ParallelRDP() = default;
void UpdateScreen(n64::VI&, bool = false); void UpdateScreen(n64::VI&, bool = false);
@@ -24,11 +24,11 @@ public:
bool IsFramerateUnlocked(); bool IsFramerateUnlocked();
void SetFramerateUnlocked(bool); void SetFramerateUnlocked(bool);
private: private:
void LoadWSIPlatform(Vulkan::InstanceFactory*, std::unique_ptr<Vulkan::WSIPlatform>&&, std::unique_ptr<WindowInfo>&&); void LoadWSIPlatform(const std::shared_ptr<Vulkan::InstanceFactory>&, const std::shared_ptr<Vulkan::WSIPlatform>&, const std::shared_ptr<WindowInfo>&);
void DrawFullscreenTexturedQuad(Util::IntrusivePtr<Vulkan::Image>, Util::IntrusivePtr<Vulkan::CommandBuffer>); void DrawFullscreenTexturedQuad(Util::IntrusivePtr<Vulkan::Image>, Util::IntrusivePtr<Vulkan::CommandBuffer>);
void UpdateScreen(Util::IntrusivePtr<Vulkan::Image>); void UpdateScreen(Util::IntrusivePtr<Vulkan::Image>);
std::unique_ptr<Vulkan::WSI> wsi; std::shared_ptr<Vulkan::WSI> wsi;
std::unique_ptr<RDP::CommandProcessor> command_processor; std::shared_ptr<RDP::CommandProcessor> command_processor;
std::unique_ptr<WindowInfo> windowInfo; std::shared_ptr<WindowInfo> windowInfo;
}; };

View File

@@ -48,6 +48,10 @@ int Interpreter::Step() {
return 1; return 1;
} }
if((u64)regs.pc == 0xFFFFFFFF8002070C) {
printf("\n");
}
regs.oldPC = regs.pc; regs.oldPC = regs.pc;
regs.pc = regs.nextPC; regs.pc = regs.nextPC;
regs.nextPC += 4; regs.nextPC += 4;

View File

@@ -337,6 +337,11 @@ template<> void Mem::Write<u8>(Registers& regs, u32 paddr, u32 val) {
const auto pointer = writePages[page]; const auto pointer = writePages[page];
SI& si = mmio.si; SI& si = mmio.si;
if(paddr == 0x0023e650) {
//DumpRDRAM();
//fmt::print("PC is 0x{:016X}: Writing 0x{:02X} -> 0x{:08X}\n", (u64)regs.oldPC, (u8)val, paddr);
}
if(pointer) { if(pointer) {
((u8*)pointer)[BYTE_ADDRESS(offset)] = val; ((u8*)pointer)[BYTE_ADDRESS(offset)] = val;
} else { } else {
@@ -382,6 +387,11 @@ template<> void Mem::Write<u16>(Registers& regs, u32 paddr, u32 val) {
const auto pointer = writePages[page]; const auto pointer = writePages[page];
SI& si = mmio.si; SI& si = mmio.si;
if(paddr == 0x0023e650) {
//DumpRDRAM();
//fmt::print("PC is 0x{:016X}: Writing 0x{:04X} -> 0x{:08X}\n", (u64) regs.oldPC, (u16) val, paddr);
}
if(pointer) { if(pointer) {
Util::WriteAccess<u16>((u8*)pointer, HALF_ADDRESS(offset), val); Util::WriteAccess<u16>((u8*)pointer, HALF_ADDRESS(offset), val);
} else { } else {
@@ -427,6 +437,11 @@ template<> void Mem::Write<u32>(Registers& regs, u32 paddr, u32 val) {
const auto pointer = writePages[page]; const auto pointer = writePages[page];
SI& si = mmio.si; SI& si = mmio.si;
if(paddr == 0x0023e650) {
//DumpRDRAM();
//fmt::print("PC is 0x{:016X}: Writing 0x{:08X} -> 0x{:08X}\n", (u64) regs.oldPC, val, paddr);
}
if(pointer) { if(pointer) {
Util::WriteAccess<u32>((u8*)pointer, offset, val); Util::WriteAccess<u32>((u8*)pointer, offset, val);
} else { } else {
@@ -466,6 +481,11 @@ void Mem::Write(Registers& regs, u32 paddr, u64 val) {
const auto pointer = writePages[page]; const auto pointer = writePages[page];
SI& si = mmio.si; SI& si = mmio.si;
if(paddr == 0x0023e650) {
//DumpRDRAM();
//fmt::print("PC is 0x{:016X}: Writing 0x{:016X} -> 0x{:08X}\n", (u64) regs.oldPC, val, paddr);
}
if(pointer) { if(pointer) {
Util::WriteAccess<u64>((u8*)pointer, offset, val); Util::WriteAccess<u64>((u8*)pointer, offset, val);
} else { } else {

View File

@@ -465,15 +465,19 @@ void Interpreter::sb(u32 instr) {
void Interpreter::sc(u32 instr) { void Interpreter::sc(u32 instr) {
u64 address = regs.gpr[RS(instr)] + (s16)instr; u64 address = regs.gpr[RS(instr)] + (s16)instr;
if (check_address_error(0b11, address)) {
regs.cop0.FireException(ExceptionCode::AddressErrorStore, 0, regs.oldPC);
return;
}
if(regs.cop0.llbit) { if(regs.cop0.llbit) {
regs.cop0.llbit = false; regs.cop0.llbit = false;
if (check_address_error(0b11, address)) {
regs.gpr[RT(instr)] = 0;
regs.cop0.HandleTLBException(address);
regs.cop0.FireException(ExceptionCode::AddressErrorStore, 0, regs.oldPC);
return;
}
u32 paddr = 0; u32 paddr = 0;
if(!regs.cop0.MapVAddr(Cop0::STORE, address, paddr)) { if(!regs.cop0.MapVAddr(Cop0::STORE, address, paddr)) {
regs.gpr[RT(instr)] = 0;
regs.cop0.HandleTLBException(address); regs.cop0.HandleTLBException(address);
regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC);
} else { } else {
@@ -496,16 +500,20 @@ void Interpreter::scd(u32 instr) {
} }
s64 address = regs.gpr[RS(instr)] + (s16)instr; s64 address = regs.gpr[RS(instr)] + (s16)instr;
if (check_address_error(0b111, address)) {
regs.cop0.HandleTLBException(address);
regs.cop0.FireException(ExceptionCode::AddressErrorStore, 0, regs.oldPC);
return;
}
if(regs.cop0.llbit) { if(regs.cop0.llbit) {
regs.cop0.llbit = false; regs.cop0.llbit = false;
if (check_address_error(0b111, address)) {
regs.gpr[RT(instr)] = 0;
regs.cop0.HandleTLBException(address);
regs.cop0.FireException(ExceptionCode::AddressErrorStore, 0, regs.oldPC);
return;
}
u32 paddr = 0; u32 paddr = 0;
if(!regs.cop0.MapVAddr(Cop0::STORE, address, paddr)) { if(!regs.cop0.MapVAddr(Cop0::STORE, address, paddr)) {
regs.gpr[RT(instr)] = 0;
regs.cop0.HandleTLBException(address); regs.cop0.HandleTLBException(address);
regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC);
} else { } else {

View File

@@ -11,19 +11,13 @@ namespace n64 {
void audioCallback(void* user, Uint8* stream, int length) { void audioCallback(void* user, Uint8* stream, int length) {
auto audioDevice = (AudioDevice*)user; auto audioDevice = (AudioDevice*)user;
int gotten = 0, available = 0; int gotten = 0, available = 0;
if (audioDevice) { if (audioDevice) {
audioDevice->LockMutex(); audioDevice->LockMutex();
} available = SDL_AudioStreamAvailable(audioDevice->GetStream());
if (available > 0) {
if (audioDevice) { gotten = SDL_AudioStreamGet(audioDevice->GetStream(), stream, length);
available = SDL_AudioStreamAvailable(audioDevice->GetStream().get()); }
}
if (available > 0 && audioDevice) {
gotten = SDL_AudioStreamGet(audioDevice->GetStream().get(), stream, length);
}
if (audioDevice) {
audioDevice->UnlockMutex(); audioDevice->UnlockMutex();
} }
@@ -37,11 +31,18 @@ void audioCallback(void* user, Uint8* stream, int length) {
} }
} }
AudioDevice::AudioDevice() : audioStream(SDL_NewAudioStream, SDL_FreeAudioStream, "audioStream", SYSTEM_SAMPLE_FORMAT, 2, AUDIO_SAMPLE_RATE, SYSTEM_SAMPLE_FORMAT, 2, AUDIO_SAMPLE_RATE), AudioDevice::~AudioDevice() {
audioStreamMutex(SDL_CreateMutex, SDL_DestroyMutex, "audioStreamMutex") { LockMutex();
SDL_FreeAudioStream(GetStream());
UnlockMutex();
SDL_DestroyMutex(audioStreamMutex);
}
AudioDevice::AudioDevice() : audioStream(SDL_NewAudioStream(SYSTEM_SAMPLE_FORMAT, 2, AUDIO_SAMPLE_RATE, SYSTEM_SAMPLE_FORMAT, 2, AUDIO_SAMPLE_RATE)),
audioStreamMutex(SDL_CreateMutex()) {
SDL_InitSubSystem(SDL_INIT_AUDIO); SDL_InitSubSystem(SDL_INIT_AUDIO);
if(!audioStreamMutex.get()) { if(!audioStreamMutex) {
Util::panic("Unable to initialize audio mutex: {}", SDL_GetError()); Util::panic("Unable to initialize audio mutex: {}", SDL_GetError());
} }
@@ -66,15 +67,16 @@ void AudioDevice::PushSample(float left, float volumeL, float right, float volum
float adjustedR = right * volumeR; float adjustedR = right * volumeR;
float samples[2]{ adjustedL, adjustedR }; float samples[2]{ adjustedL, adjustedR };
auto availableBytes = (float)SDL_AudioStreamAvailable(audioStream.get()); auto availableBytes = (float)SDL_AudioStreamAvailable(audioStream);
if(availableBytes <= BYTES_PER_HALF_SECOND) { if(availableBytes <= BYTES_PER_HALF_SECOND) {
SDL_AudioStreamPut(audioStream.get(), samples, 2 * sizeof(float)); SDL_AudioStreamPut(audioStream, samples, 2 * sizeof(float));
} }
} }
void AudioDevice::AdjustSampleRate(int sampleRate) { void AudioDevice::AdjustSampleRate(int sampleRate) {
LockMutex(); LockMutex();
audioStream.Construct(SDL_NewAudioStream, SYSTEM_SAMPLE_FORMAT, 2, sampleRate, SYSTEM_SAMPLE_FORMAT, 2, AUDIO_SAMPLE_RATE); SDL_FreeAudioStream(audioStream);
audioStream = SDL_NewAudioStream(SYSTEM_SAMPLE_FORMAT, 2, sampleRate, SYSTEM_SAMPLE_FORMAT, 2, AUDIO_SAMPLE_RATE);
UnlockMutex(); UnlockMutex();
} }
} }

View File

@@ -5,24 +5,23 @@
namespace n64 { namespace n64 {
struct AudioDevice { struct AudioDevice {
AudioDevice(); AudioDevice();
~AudioDevice();
void PushSample(float, float, float, float); void PushSample(float, float, float, float);
void AdjustSampleRate(int); void AdjustSampleRate(int);
void LockMutex() { void LockMutex() {
if(audioStreamMutex.get()) if(audioStreamMutex)
SDL_LockMutex(audioStreamMutex.get()); SDL_LockMutex(audioStreamMutex);
} }
void UnlockMutex() { void UnlockMutex() {
if (audioStreamMutex.get()) if (audioStreamMutex)
SDL_UnlockMutex(audioStreamMutex.get()); SDL_UnlockMutex(audioStreamMutex);
} }
Util::AutoRelease<SDL_AudioStream, const SDL_AudioFormat, const Uint8, const int, const SDL_AudioFormat, SDL_AudioStream* GetStream() { return audioStream; }
const Uint8, const int>& GetStream() { return audioStream; }
private: private:
Util::AutoRelease<SDL_AudioStream, const SDL_AudioFormat, const Uint8, const int, const SDL_AudioFormat, SDL_AudioStream* audioStream;
const Uint8, const int> audioStream; SDL_mutex* audioStreamMutex;
Util::AutoRelease<SDL_mutex> audioStreamMutex;
SDL_AudioSpec audioSpec{}; SDL_AudioSpec audioSpec{};
SDL_AudioSpec request{}; SDL_AudioSpec request{};
SDL_AudioDeviceID handle{}; SDL_AudioDeviceID handle{};

View File

@@ -1,17 +1,13 @@
#include <EmuThread.hpp> #include <EmuThread.hpp>
#include <RenderWidget.hpp>
#include <ParallelRDPWrapper.hpp>
#include "Audio.hpp"
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
EmuThread::EmuThread(std::unique_ptr<QtInstanceFactory>&& instance_, std::unique_ptr<Vulkan::WSIPlatform>&& wsiPlatform_, std::unique_ptr<ParallelRDP::WindowInfo>&& windowInfo_, SettingsWindow& settings) noexcept EmuThread::EmuThread(const std::shared_ptr<QtInstanceFactory>& instance_, const std::shared_ptr<Vulkan::WSIPlatform>& wsiPlatform_, const std::shared_ptr<ParallelRDP::WindowInfo>& windowInfo_, SettingsWindow& settings) noexcept
: instance(std::move(instance_)), wsiPlatform(std::move(wsiPlatform_)), : instance(instance_), wsiPlatform(wsiPlatform_),
windowInfo(std::move(windowInfo_)), windowInfo(windowInfo_),
controller(SDL_GameControllerClose, "GameController"),
core(parallel), settings(settings) {} core(parallel), settings(settings) {}
[[noreturn]] void EmuThread::run() noexcept { [[noreturn]] void EmuThread::run() noexcept {
parallel.Init(instance.get(), std::move(wsiPlatform), std::move(windowInfo), core.cpu->GetMem().GetRDRAMPtr()); parallel.Init(instance, wsiPlatform, windowInfo, core.cpu->GetMem().GetRDRAMPtr());
SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER); SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER);
bool controllerConnected = false; bool controllerConnected = false;
@@ -25,11 +21,11 @@ EmuThread::EmuThread(std::unique_ptr<QtInstanceFactory>&& instance_, std::unique
switch(e.type) { switch(e.type) {
case SDL_CONTROLLERDEVICEADDED: { case SDL_CONTROLLERDEVICEADDED: {
const int index = e.cdevice.which; const int index = e.cdevice.which;
controller.Construct(SDL_GameControllerOpen, index); controller = SDL_GameControllerOpen(index);
Util::info("Found controller!"); Util::info("Found controller!");
auto serial = SDL_GameControllerGetSerial(controller.get()); auto serial = SDL_GameControllerGetSerial(controller);
auto name = SDL_GameControllerName(controller.get()); auto name = SDL_GameControllerName(controller);
auto path = SDL_GameControllerPath(controller.get()); auto path = SDL_GameControllerPath(controller);
Util::info("\tName: {}", name ? name : "Not available"); Util::info("\tName: {}", name ? name : "Not available");
Util::info("\tSerial: {}", serial ? serial : "Not available"); Util::info("\tSerial: {}", serial ? serial : "Not available");
Util::info("\tPath: {}", path ? path : "Not available"); Util::info("\tPath: {}", path ? path : "Not available");
@@ -37,7 +33,7 @@ EmuThread::EmuThread(std::unique_ptr<QtInstanceFactory>&& instance_, std::unique
} break; } break;
case SDL_CONTROLLERDEVICEREMOVED: { case SDL_CONTROLLERDEVICEREMOVED: {
controllerConnected = false; controllerConnected = false;
controller.Destroy(); SDL_GameControllerClose(controller);
} break; } break;
} }
} }
@@ -59,22 +55,22 @@ EmuThread::EmuThread(std::unique_ptr<QtInstanceFactory>&& instance_, std::unique
if(controllerConnected) { if(controllerConnected) {
n64::PIF& pif = core.cpu->GetMem().mmio.si.pif; n64::PIF& pif = core.cpu->GetMem().mmio.si.pif;
pif.UpdateButton(0, n64::Controller::Key::A, SDL_GameControllerGetButton(controller.get(), SDL_CONTROLLER_BUTTON_A)); pif.UpdateButton(0, n64::Controller::Key::A, SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_A));
pif.UpdateButton(0, n64::Controller::Key::B, SDL_GameControllerGetButton(controller.get(), SDL_CONTROLLER_BUTTON_X)); pif.UpdateButton(0, n64::Controller::Key::B, SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_X));
pif.UpdateButton(0, n64::Controller::Key::Z, SDL_GameControllerGetAxis(controller.get(), SDL_CONTROLLER_AXIS_TRIGGERLEFT) == SDL_JOYSTICK_AXIS_MAX); pif.UpdateButton(0, n64::Controller::Key::Z, SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_TRIGGERLEFT) == SDL_JOYSTICK_AXIS_MAX);
pif.UpdateButton(0, n64::Controller::Key::Start, SDL_GameControllerGetButton(controller.get(), SDL_CONTROLLER_BUTTON_START)); pif.UpdateButton(0, n64::Controller::Key::Start, SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_START));
pif.UpdateButton(0, n64::Controller::Key::DUp, SDL_GameControllerGetButton(controller.get(), SDL_CONTROLLER_BUTTON_DPAD_UP)); pif.UpdateButton(0, n64::Controller::Key::DUp, SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_UP));
pif.UpdateButton(0, n64::Controller::Key::DDown, SDL_GameControllerGetButton(controller.get(), SDL_CONTROLLER_BUTTON_DPAD_DOWN)); pif.UpdateButton(0, n64::Controller::Key::DDown, SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_DOWN));
pif.UpdateButton(0, n64::Controller::Key::DLeft, SDL_GameControllerGetButton(controller.get(), SDL_CONTROLLER_BUTTON_DPAD_LEFT)); pif.UpdateButton(0, n64::Controller::Key::DLeft, SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_LEFT));
pif.UpdateButton(0, n64::Controller::Key::DRight, SDL_GameControllerGetButton(controller.get(), SDL_CONTROLLER_BUTTON_DPAD_RIGHT)); pif.UpdateButton(0, n64::Controller::Key::DRight, SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_DPAD_RIGHT));
pif.UpdateButton(0, n64::Controller::Key::LT, SDL_GameControllerGetButton(controller.get(), SDL_CONTROLLER_BUTTON_LEFTSHOULDER)); pif.UpdateButton(0, n64::Controller::Key::LT, SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_LEFTSHOULDER));
pif.UpdateButton(0, n64::Controller::Key::RT, SDL_GameControllerGetButton(controller.get(), SDL_CONTROLLER_BUTTON_RIGHTSHOULDER)); pif.UpdateButton(0, n64::Controller::Key::RT, SDL_GameControllerGetButton(controller, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER));
pif.UpdateButton(0, n64::Controller::Key::CUp, SDL_GameControllerGetAxis(controller.get(), SDL_CONTROLLER_AXIS_RIGHTY) <= -127); pif.UpdateButton(0, n64::Controller::Key::CUp, SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_RIGHTY) <= -127);
pif.UpdateButton(0, n64::Controller::Key::CDown, SDL_GameControllerGetAxis(controller.get(), SDL_CONTROLLER_AXIS_RIGHTY) >= 127); pif.UpdateButton(0, n64::Controller::Key::CDown, SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_RIGHTY) >= 127);
pif.UpdateButton(0, n64::Controller::Key::CLeft, SDL_GameControllerGetAxis(controller.get(), SDL_CONTROLLER_AXIS_RIGHTX) <= -127); pif.UpdateButton(0, n64::Controller::Key::CLeft, SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_RIGHTX) <= -127);
pif.UpdateButton(0, n64::Controller::Key::CRight, SDL_GameControllerGetAxis(controller.get(), SDL_CONTROLLER_AXIS_RIGHTX) >= 127); pif.UpdateButton(0, n64::Controller::Key::CRight, SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_RIGHTX) >= 127);
float xclamped = SDL_GameControllerGetAxis(controller.get(), SDL_CONTROLLER_AXIS_LEFTX); float xclamped = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTX);
if(xclamped < 0) { if(xclamped < 0) {
xclamped /= float(std::abs(SDL_JOYSTICK_AXIS_MIN)); xclamped /= float(std::abs(SDL_JOYSTICK_AXIS_MIN));
} else { } else {
@@ -83,7 +79,7 @@ EmuThread::EmuThread(std::unique_ptr<QtInstanceFactory>&& instance_, std::unique
xclamped *= 86; xclamped *= 86;
float yclamped = SDL_GameControllerGetAxis(controller.get(), SDL_CONTROLLER_AXIS_LEFTY); float yclamped = SDL_GameControllerGetAxis(controller, SDL_CONTROLLER_AXIS_LEFTY);
if(yclamped < 0) { if(yclamped < 0) {
yclamped /= float(std::abs(SDL_JOYSTICK_AXIS_MIN)); yclamped /= float(std::abs(SDL_JOYSTICK_AXIS_MIN));
} else { } else {

View File

@@ -9,37 +9,37 @@
class EmuThread : public QThread class EmuThread : public QThread
{ {
Q_OBJECT Q_OBJECT
std::unique_ptr<QtInstanceFactory> instance; std::shared_ptr<QtInstanceFactory> instance;
std::unique_ptr<Vulkan::WSIPlatform> wsiPlatform; std::shared_ptr<Vulkan::WSIPlatform> wsiPlatform;
std::unique_ptr<ParallelRDP::WindowInfo> windowInfo; std::shared_ptr<ParallelRDP::WindowInfo> windowInfo;
public: public:
explicit EmuThread(std::unique_ptr<QtInstanceFactory>&& instance, std::unique_ptr<Vulkan::WSIPlatform>&& wsiPlatform, std::unique_ptr<ParallelRDP::WindowInfo>&& windowInfo, SettingsWindow&) noexcept; explicit EmuThread(const std::shared_ptr<QtInstanceFactory>& instance, const std::shared_ptr<Vulkan::WSIPlatform>& wsiPlatform, const std::shared_ptr<ParallelRDP::WindowInfo>& windowInfo, SettingsWindow&) noexcept;
[[noreturn]] void run() noexcept override; [[noreturn]] void run() noexcept override;
Util::AutoRelease<SDL_GameController, int> controller; SDL_GameController* controller = nullptr;
ParallelRDP parallel; ParallelRDP parallel;
n64::Core core; n64::Core core;
SettingsWindow& settings; SettingsWindow& settings;
bool running = false;
void TogglePause() void TogglePause() {
{ core.pause = !core.pause;
running = !running;
} }
void Reset() void SetRender(bool v) {
{ core.render = v;
running = false; }
void Reset() {
core.pause = true;
core.Stop(); core.Stop();
core.LoadROM(core.rom); core.LoadROM(core.rom);
running = true; core.pause = false;
} }
void Stop() void Stop() {
{
core.rom = {}; core.rom = {};
running = false; core.pause = true;
core.Stop(); core.Stop();
} }
}; };

View File

@@ -28,14 +28,13 @@ KaizenQt::KaizenQt() noexcept : QWidget(nullptr) {
grabKeyboard(); grabKeyboard();
}); });
} }
void KaizenQt::ConnectMainWindowSignalsToSlots() noexcept { void KaizenQt::ConnectMainWindowSignalsToSlots() noexcept {
connect(mainWindow.get(), &MainWindowController::OpenSettings, this, [this]() { connect(mainWindow.get(), &MainWindowController::OpenSettings, this, [this]() {
settingsWindow->show(); settingsWindow->show();
}); });
connect(mainWindow.get(), &MainWindowController::OpenROM, this, &KaizenQt::LoadROM); connect(mainWindow.get(), &MainWindowController::OpenROM, this, &KaizenQt::LoadROM);
connect(mainWindow.get(), &MainWindowController::Exit, this, []() { connect(mainWindow.get(), &MainWindowController::Exit, this, &KaizenQt::Quit);
QApplication::quit();
});
connect(mainWindow.get(), &MainWindowController::Reset, emuThread.get(), &EmuThread::Reset); connect(mainWindow.get(), &MainWindowController::Reset, emuThread.get(), &EmuThread::Reset);
connect(mainWindow.get(), &MainWindowController::Stop, emuThread.get(), &EmuThread::Stop); connect(mainWindow.get(), &MainWindowController::Stop, emuThread.get(), &EmuThread::Stop);
connect(mainWindow.get(), &MainWindowController::Stop, this, [this]() { connect(mainWindow.get(), &MainWindowController::Stop, this, [this]() {
@@ -61,8 +60,12 @@ void KaizenQt::LoadROM(const QString& fileName) noexcept {
mainWindow->setWindowTitle(emuThread->core.cpu->GetMem().rom.gameNameDB.c_str()); mainWindow->setWindowTitle(emuThread->core.cpu->GetMem().rom.gameNameDB.c_str());
} }
void KaizenQt::closeEvent(QCloseEvent*) { void KaizenQt::Quit() noexcept {
emuThread->Stop(); if(emuThread) {
emuThread->SetRender(false);
emuThread->Stop();
}
QApplication::quit();
} }
void KaizenQt::LoadTAS(const QString& fileName) noexcept { void KaizenQt::LoadTAS(const QString& fileName) noexcept {

View File

@@ -33,8 +33,8 @@ public:
void dragEnterEvent(QDragEnterEvent*) override; void dragEnterEvent(QDragEnterEvent*) override;
void keyPressEvent(QKeyEvent*) override; void keyPressEvent(QKeyEvent*) override;
void keyReleaseEvent(QKeyEvent*) override; void keyReleaseEvent(QKeyEvent*) override;
void closeEvent(QCloseEvent*) override;
private: private:
void Quit() noexcept;
void ConnectMainWindowSignalsToSlots() noexcept; void ConnectMainWindowSignalsToSlots() noexcept;
std::unique_ptr<MainWindowController> mainWindow; std::unique_ptr<MainWindowController> mainWindow;
std::unique_ptr<SettingsWindow> settingsWindow; std::unique_ptr<SettingsWindow> settingsWindow;

View File

@@ -31,6 +31,10 @@ void MainWindowController::ConnectSignalsToSlots() noexcept {
emit Exit(); emit Exit();
}); });
connect(this, &MainWindowController::destroyed, this, [this]() {
emit Exit();
});
connect(view.actionReset, &QAction::triggered, this, [this]() { connect(view.actionReset, &QAction::triggered, this, [this]() {
emit Reset(); emit Reset();
}); });

View File

@@ -6,46 +6,6 @@
#include <functional> #include <functional>
namespace Util { namespace Util {
template <class T, typename... Args>
struct AutoRelease {
AutoRelease(void (*dtor)(T*), const char* name = "") : dtor(dtor), name(name) { }
AutoRelease(T* (*ctor)(Args...), void (*dtor)(T*), const char* name = "", Args... args) : dtor(dtor), name(name) {
thing = ctor(args...);
}
T* get() {
if (!thing) {
Util::panic("AutoRelease::{} is null!", name);
}
return thing;
}
void Construct(T* (*ctor)(Args...), Args... args) {
if(thing) {
dtor(thing);
}
thing = ctor(args...);
}
void Destroy() {
if(thing) {
dtor(thing);
}
}
~AutoRelease() {
if(thing) {
dtor(thing);
}
}
private:
const char* name = "";
T* thing = nullptr;
void (*dtor)(T*) = nullptr;
};
template<typename T> template<typename T>
static FORCE_INLINE T ReadAccess(const u8* data, u32 index) { static FORCE_INLINE T ReadAccess(const u8* data, u32 index) {
if constexpr (sizeof(T) == 8) { if constexpr (sizeof(T) == 8) {