Various pointer changes
This commit is contained in:
20
external/parallel-rdp/ParallelRDPWrapper.cpp
vendored
20
external/parallel-rdp/ParallelRDPWrapper.cpp
vendored
@@ -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,7 +71,7 @@ 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()) {
|
||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
10
external/parallel-rdp/ParallelRDPWrapper.hpp
vendored
10
external/parallel-rdp/ParallelRDPWrapper.hpp
vendored
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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(regs.cop0.llbit) {
|
||||||
|
regs.cop0.llbit = false;
|
||||||
|
|
||||||
if (check_address_error(0b11, address)) {
|
if (check_address_error(0b11, address)) {
|
||||||
|
regs.gpr[RT(instr)] = 0;
|
||||||
|
regs.cop0.HandleTLBException(address);
|
||||||
regs.cop0.FireException(ExceptionCode::AddressErrorStore, 0, regs.oldPC);
|
regs.cop0.FireException(ExceptionCode::AddressErrorStore, 0, regs.oldPC);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(regs.cop0.llbit) {
|
|
||||||
regs.cop0.llbit = false;
|
|
||||||
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(regs.cop0.llbit) {
|
||||||
|
regs.cop0.llbit = false;
|
||||||
|
|
||||||
if (check_address_error(0b111, address)) {
|
if (check_address_error(0b111, address)) {
|
||||||
|
regs.gpr[RT(instr)] = 0;
|
||||||
regs.cop0.HandleTLBException(address);
|
regs.cop0.HandleTLBException(address);
|
||||||
regs.cop0.FireException(ExceptionCode::AddressErrorStore, 0, regs.oldPC);
|
regs.cop0.FireException(ExceptionCode::AddressErrorStore, 0, regs.oldPC);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(regs.cop0.llbit) {
|
|
||||||
regs.cop0.llbit = false;
|
|
||||||
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 {
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
gotten = SDL_AudioStreamGet(audioDevice->GetStream(), stream, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (audioDevice) {
|
|
||||||
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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{};
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -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,9 +60,13 @@ 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 {
|
||||||
|
if(emuThread) {
|
||||||
|
emuThread->SetRender(false);
|
||||||
emuThread->Stop();
|
emuThread->Stop();
|
||||||
}
|
}
|
||||||
|
QApplication::quit();
|
||||||
|
}
|
||||||
|
|
||||||
void KaizenQt::LoadTAS(const QString& fileName) noexcept {
|
void KaizenQt::LoadTAS(const QString& fileName) noexcept {
|
||||||
emuThread->core.LoadTAS(fileName.toStdString());
|
emuThread->core.LoadTAS(fileName.toStdString());
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user