separate emu thread
This commit is contained in:
+3
-1
@@ -173,7 +173,9 @@ qt_add_executable(kaizen
|
|||||||
src/utils/Options.cpp
|
src/utils/Options.cpp
|
||||||
src/utils/File.cpp
|
src/utils/File.cpp
|
||||||
src/frontend/RomsList.hpp
|
src/frontend/RomsList.hpp
|
||||||
src/frontend/RomsList.cpp)
|
src/frontend/RomsList.cpp
|
||||||
|
src/frontend/EmuThread.hpp
|
||||||
|
src/frontend/EmuThread.cpp)
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
set(MIO_LIB mio::mio_full_winapi)
|
set(MIO_LIB mio::mio_full_winapi)
|
||||||
|
|||||||
@@ -1462,7 +1462,7 @@ Helper::BatchComposer::BatchComposer()
|
|||||||
|
|
||||||
void Helper::BatchComposer::begin_batch()
|
void Helper::BatchComposer::begin_batch()
|
||||||
{
|
{
|
||||||
if (!waits[submit_index].empty() || !cmds[submit_index].empty() || !signals[submit_index].empty())
|
if (!waits[submit_index].empty() || !cmds[submit_index].empty() || !signals_[submit_index].empty())
|
||||||
{
|
{
|
||||||
submit_index = submits.size();
|
submit_index = submits.size();
|
||||||
submits.emplace_back();
|
submits.emplace_back();
|
||||||
@@ -1491,8 +1491,8 @@ Helper::BatchComposer::bake(int profiling_iteration)
|
|||||||
submit = { VK_STRUCTURE_TYPE_SUBMIT_INFO_2 };
|
submit = { VK_STRUCTURE_TYPE_SUBMIT_INFO_2 };
|
||||||
submit.commandBufferInfoCount = uint32_t(cmds[i].size());
|
submit.commandBufferInfoCount = uint32_t(cmds[i].size());
|
||||||
submit.pCommandBufferInfos = cmds[i].data();
|
submit.pCommandBufferInfos = cmds[i].data();
|
||||||
submit.signalSemaphoreInfoCount = uint32_t(signals[i].size());
|
submit.signalSemaphoreInfoCount = uint32_t(signals_[i].size());
|
||||||
submit.pSignalSemaphoreInfos = signals[i].data();
|
submit.pSignalSemaphoreInfos = signals_[i].data();
|
||||||
submit.waitSemaphoreInfoCount = uint32_t(waits[i].size());
|
submit.waitSemaphoreInfoCount = uint32_t(waits[i].size());
|
||||||
submit.pWaitSemaphoreInfos = waits[i].data();
|
submit.pWaitSemaphoreInfos = waits[i].data();
|
||||||
|
|
||||||
@@ -1523,7 +1523,7 @@ Helper::BatchComposer::bake(int profiling_iteration)
|
|||||||
|
|
||||||
void Helper::BatchComposer::add_command_buffer(VkCommandBuffer cmd)
|
void Helper::BatchComposer::add_command_buffer(VkCommandBuffer cmd)
|
||||||
{
|
{
|
||||||
if (!signals[submit_index].empty())
|
if (!signals_[submit_index].empty())
|
||||||
begin_batch();
|
begin_batch();
|
||||||
|
|
||||||
VkCommandBufferSubmitInfo info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO };
|
VkCommandBufferSubmitInfo info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO };
|
||||||
@@ -1537,12 +1537,12 @@ void Helper::BatchComposer::add_signal_semaphore(VkSemaphore sem, VkPipelineStag
|
|||||||
info.semaphore = sem;
|
info.semaphore = sem;
|
||||||
info.stageMask = stages;
|
info.stageMask = stages;
|
||||||
info.value = timeline;
|
info.value = timeline;
|
||||||
signals[submit_index].push_back(info);
|
signals_[submit_index].push_back(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Helper::BatchComposer::add_wait_semaphore(SemaphoreHolder &sem, VkPipelineStageFlags2 stage)
|
void Helper::BatchComposer::add_wait_semaphore(SemaphoreHolder &sem, VkPipelineStageFlags2 stage)
|
||||||
{
|
{
|
||||||
if (!cmds[submit_index].empty() || !signals[submit_index].empty())
|
if (!cmds[submit_index].empty() || !signals_[submit_index].empty())
|
||||||
begin_batch();
|
begin_batch();
|
||||||
|
|
||||||
bool is_timeline = sem.get_semaphore_type() == VK_SEMAPHORE_TYPE_TIMELINE;
|
bool is_timeline = sem.get_semaphore_type() == VK_SEMAPHORE_TYPE_TIMELINE;
|
||||||
@@ -1556,7 +1556,7 @@ void Helper::BatchComposer::add_wait_semaphore(SemaphoreHolder &sem, VkPipelineS
|
|||||||
|
|
||||||
void Helper::BatchComposer::add_wait_semaphore(VkSemaphore sem, VkPipelineStageFlags2 stage)
|
void Helper::BatchComposer::add_wait_semaphore(VkSemaphore sem, VkPipelineStageFlags2 stage)
|
||||||
{
|
{
|
||||||
if (!cmds[submit_index].empty() || !signals[submit_index].empty())
|
if (!cmds[submit_index].empty() || !signals_[submit_index].empty())
|
||||||
begin_batch();
|
begin_batch();
|
||||||
|
|
||||||
VkSemaphoreSubmitInfo info = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO };
|
VkSemaphoreSubmitInfo info = { VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO };
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ private:
|
|||||||
VkPerformanceQuerySubmitInfoKHR profiling_infos[Helper::BatchComposer::MaxSubmissions];
|
VkPerformanceQuerySubmitInfoKHR profiling_infos[Helper::BatchComposer::MaxSubmissions];
|
||||||
|
|
||||||
Util::SmallVector<VkSemaphoreSubmitInfo> waits[MaxSubmissions];
|
Util::SmallVector<VkSemaphoreSubmitInfo> waits[MaxSubmissions];
|
||||||
Util::SmallVector<VkSemaphoreSubmitInfo> signals[MaxSubmissions];
|
Util::SmallVector<VkSemaphoreSubmitInfo> signals_[MaxSubmissions];
|
||||||
Util::SmallVector<VkCommandBufferSubmitInfo> cmds[MaxSubmissions];
|
Util::SmallVector<VkCommandBufferSubmitInfo> cmds[MaxSubmissions];
|
||||||
|
|
||||||
unsigned submit_index = 0;
|
unsigned submit_index = 0;
|
||||||
|
|||||||
@@ -0,0 +1,126 @@
|
|||||||
|
#include <EmuThread.hpp>
|
||||||
|
|
||||||
|
void EmuThread::run() {
|
||||||
|
core.parallel.Init(vulkanWidget->wsiPlatform, vulkanWidget->windowInfo, vulkanWidget->qtVkInstanceFactory.get(),
|
||||||
|
core.GetMem().GetRDRAMPtr());
|
||||||
|
while (!isInterruptionRequested()) {
|
||||||
|
if (!core.romLoaded || core.pause)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
SDL_Event e;
|
||||||
|
while (SDL_PollEvent(&e)) {
|
||||||
|
if (e.type == SDL_EVENT_GAMEPAD_ADDED) {
|
||||||
|
if (!gamepad) {
|
||||||
|
const auto index = e.gdevice.which;
|
||||||
|
|
||||||
|
gamepad = SDL_OpenGamepad(index);
|
||||||
|
warn("Found controller!");
|
||||||
|
warn("Name: {}", SDL_GetGamepadName(gamepad));
|
||||||
|
warn("Vendor: {}", SDL_GetGamepadVendor(gamepad));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.type == SDL_EVENT_GAMEPAD_REMOVED) {
|
||||||
|
if (gamepad) {
|
||||||
|
SDL_CloseGamepad(gamepad);
|
||||||
|
gamepad = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateKeys();
|
||||||
|
updateAxis();
|
||||||
|
|
||||||
|
core.parallel.SetFramerateUnlocked(unlockFrameratePressed);
|
||||||
|
|
||||||
|
auto timeStart = SDL_GetTicks();
|
||||||
|
core.Run();
|
||||||
|
core.parallel.UpdateScreen();
|
||||||
|
elapsed = SDL_GetTicks() - timeStart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmuThread::updateKeys() {
|
||||||
|
auto &pif = core.mem->mmio.si.pif;
|
||||||
|
if (gamepad) {
|
||||||
|
pif.UpdateButton(0, n64::Controller::Z,
|
||||||
|
SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_LEFT_TRIGGER) == SDL_JOYSTICK_AXIS_MAX);
|
||||||
|
pif.UpdateButton(0, n64::Controller::A, SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_SOUTH));
|
||||||
|
pif.UpdateButton(0, n64::Controller::B, SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_WEST));
|
||||||
|
pif.UpdateButton(0, n64::Controller::LT, SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER));
|
||||||
|
pif.UpdateButton(0, n64::Controller::RT, SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER));
|
||||||
|
pif.UpdateButton(0, n64::Controller::Start, SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_START));
|
||||||
|
pif.UpdateButton(0, n64::Controller::DUp, SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_DPAD_UP));
|
||||||
|
pif.UpdateButton(0, n64::Controller::DDown, SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_DPAD_DOWN));
|
||||||
|
pif.UpdateButton(0, n64::Controller::DLeft, SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_DPAD_LEFT));
|
||||||
|
pif.UpdateButton(0, n64::Controller::DRight, SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_DPAD_RIGHT));
|
||||||
|
pif.UpdateButton(0, n64::Controller::CUp,
|
||||||
|
SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTY) == SDL_JOYSTICK_AXIS_MIN);
|
||||||
|
pif.UpdateButton(0, n64::Controller::CDown,
|
||||||
|
SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTY) == SDL_JOYSTICK_AXIS_MAX);
|
||||||
|
pif.UpdateButton(0, n64::Controller::CLeft,
|
||||||
|
SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTX) == SDL_JOYSTICK_AXIS_MIN);
|
||||||
|
pif.UpdateButton(0, n64::Controller::CRight,
|
||||||
|
SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTX) == SDL_JOYSTICK_AXIS_MAX);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pif.UpdateButton(0, n64::Controller::Z, pressedKeys.test(0));
|
||||||
|
pif.UpdateButton(0, n64::Controller::A, pressedKeys.test(1));
|
||||||
|
pif.UpdateButton(0, n64::Controller::B, pressedKeys.test(2));
|
||||||
|
pif.UpdateButton(0, n64::Controller::LT, pressedKeys.test(3));
|
||||||
|
pif.UpdateButton(0, n64::Controller::RT, pressedKeys.test(4));
|
||||||
|
pif.UpdateButton(0, n64::Controller::Start, pressedKeys.test(5));
|
||||||
|
pif.UpdateButton(0, n64::Controller::DUp, pressedKeys.test(6));
|
||||||
|
pif.UpdateButton(0, n64::Controller::DDown, pressedKeys.test(7));
|
||||||
|
pif.UpdateButton(0, n64::Controller::DLeft, pressedKeys.test(8));
|
||||||
|
pif.UpdateButton(0, n64::Controller::DRight, pressedKeys.test(9));
|
||||||
|
pif.UpdateButton(0, n64::Controller::CUp, pressedKeys.test(10));
|
||||||
|
pif.UpdateButton(0, n64::Controller::CDown, pressedKeys.test(11));
|
||||||
|
pif.UpdateButton(0, n64::Controller::CLeft, pressedKeys.test(12));
|
||||||
|
pif.UpdateButton(0, n64::Controller::CRight, pressedKeys.test(13));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmuThread::updateAxis() {
|
||||||
|
auto &pif = core.mem->mmio.si.pif;
|
||||||
|
|
||||||
|
if (gamepad) {
|
||||||
|
float xclamped = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_LEFTX);
|
||||||
|
if (xclamped < 0) {
|
||||||
|
xclamped /= static_cast<float>(std::abs(SDL_JOYSTICK_AXIS_MAX));
|
||||||
|
} else {
|
||||||
|
xclamped /= SDL_JOYSTICK_AXIS_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
xclamped *= 86;
|
||||||
|
|
||||||
|
float yclamped = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_LEFTY);
|
||||||
|
if (yclamped < 0) {
|
||||||
|
yclamped /= static_cast<float>(std::abs(SDL_JOYSTICK_AXIS_MIN));
|
||||||
|
} else {
|
||||||
|
yclamped /= SDL_JOYSTICK_AXIS_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
yclamped *= 86;
|
||||||
|
|
||||||
|
pif.UpdateAxis(0, n64::Controller::Axis::Y, static_cast<s8>(-yclamped));
|
||||||
|
pif.UpdateAxis(0, n64::Controller::Axis::X, static_cast<s8>(xclamped));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
s16 x = 0, y = 0;
|
||||||
|
if (pressedKeys.test(14)) // up
|
||||||
|
y += 86;
|
||||||
|
|
||||||
|
if (pressedKeys.test(15)) // down
|
||||||
|
y -= 86;
|
||||||
|
|
||||||
|
if (pressedKeys.test(16)) // left
|
||||||
|
x -= 86;
|
||||||
|
|
||||||
|
if (pressedKeys.test(17)) // right
|
||||||
|
x += 86;
|
||||||
|
|
||||||
|
core.mem->mmio.si.pif.UpdateAxis(0, n64::Controller::X, x);
|
||||||
|
core.mem->mmio.si.pif.UpdateAxis(0, n64::Controller::Y, y);
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <QThread>
|
||||||
|
#include <RenderWidget.hpp>
|
||||||
|
#include <Core.hpp>
|
||||||
|
#include <bitset>
|
||||||
|
|
||||||
|
class EmuThread : public QThread {
|
||||||
|
Q_OBJECT
|
||||||
|
RenderWidget *vulkanWidget;
|
||||||
|
n64::Core &core = n64::Core::GetInstance();
|
||||||
|
void updateAxis();
|
||||||
|
void updateKeys();
|
||||||
|
|
||||||
|
public:
|
||||||
|
EmuThread(RenderWidget *rw) : vulkanWidget(rw) {}
|
||||||
|
void run() override;
|
||||||
|
std::bitset<18> pressedKeys{};
|
||||||
|
std::atomic_bool unlockFrameratePressed = false;
|
||||||
|
float elapsed = 0.f;
|
||||||
|
SDL_Gamepad *gamepad = nullptr;
|
||||||
|
};
|
||||||
+6
-135
@@ -82,39 +82,12 @@ KaizenGui::KaizenGui() noexcept : QMainWindow(nullptr), settings(QSettings::User
|
|||||||
|
|
||||||
setAcceptDrops(true);
|
setAcceptDrops(true);
|
||||||
|
|
||||||
SDLeventsTimer = new QTimer();
|
|
||||||
SDLeventsTimer->setInterval(1);
|
|
||||||
statusBarTimer = new QTimer();
|
statusBarTimer = new QTimer();
|
||||||
statusBarTimer->setInterval(500);
|
statusBarTimer->setInterval(500);
|
||||||
|
|
||||||
connect(SDLeventsTimer, &QTimer::timeout, this, [&] {
|
|
||||||
SDL_Event e;
|
|
||||||
while (SDL_PollEvent(&e)) {
|
|
||||||
if (e.type == SDL_EVENT_GAMEPAD_ADDED) {
|
|
||||||
if (!gamepad) {
|
|
||||||
const auto index = e.gdevice.which;
|
|
||||||
|
|
||||||
gamepad = SDL_OpenGamepad(index);
|
|
||||||
warn("Found controller!");
|
|
||||||
warn("Name: {}", SDL_GetGamepadName(gamepad));
|
|
||||||
warn("Vendor: {}", SDL_GetGamepadVendor(gamepad));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.type == SDL_EVENT_GAMEPAD_REMOVED) {
|
|
||||||
if (gamepad) {
|
|
||||||
SDL_CloseGamepad(gamepad);
|
|
||||||
gamepad = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
SDLeventsTimer->start();
|
|
||||||
|
|
||||||
connect(statusBarTimer, &QTimer::timeout, this, [&] {
|
connect(statusBarTimer, &QTimer::timeout, this, [&] {
|
||||||
pause->setText("Pause");
|
pause->setText("Pause");
|
||||||
fpsLabel->setText(std::format("FPS: {:.2f}", 1000.f / elapsed).c_str());
|
fpsLabel->setText(std::format("FPS: {:.2f}", 1000.f / emuThread->elapsed).c_str());
|
||||||
if (core.pause) {
|
if (core.pause) {
|
||||||
pause->setText("Resume");
|
pause->setText("Resume");
|
||||||
fpsLabel->setText("Paused");
|
fpsLabel->setText("Paused");
|
||||||
@@ -168,7 +141,8 @@ KaizenGui::KaizenGui() noexcept : QMainWindow(nullptr), settings(QSettings::User
|
|||||||
auto unlockFramerate = emulationMenu->addAction("Unlock framerate");
|
auto unlockFramerate = emulationMenu->addAction("Unlock framerate");
|
||||||
unlockFramerate->setCheckable(true);
|
unlockFramerate->setCheckable(true);
|
||||||
|
|
||||||
connect(unlockFramerate, &QAction::triggered, this, [&](bool checked) { unlockFrameratePressed = checked; });
|
connect(unlockFramerate, &QAction::triggered, this,
|
||||||
|
[&](bool checked) { emuThread->unlockFrameratePressed = checked; });
|
||||||
|
|
||||||
pause->setDisabled(true);
|
pause->setDisabled(true);
|
||||||
pause->setShortcut(QKeyCombination(Qt::CTRL, Qt::Key_P));
|
pause->setShortcut(QKeyCombination(Qt::CTRL, Qt::Key_P));
|
||||||
@@ -212,115 +186,12 @@ KaizenGui::KaizenGui() noexcept : QMainWindow(nullptr), settings(QSettings::User
|
|||||||
|
|
||||||
show();
|
show();
|
||||||
|
|
||||||
emuThread = QThread::create([&] {
|
emuThread = new EmuThread(vulkanWidget);
|
||||||
core.parallel.Init(vulkanWidget->wsiPlatform, vulkanWidget->windowInfo, vulkanWidget->qtVkInstanceFactory.get(),
|
|
||||||
core.GetMem().GetRDRAMPtr());
|
|
||||||
while (!emuThread->isInterruptionRequested()) {
|
|
||||||
if (!core.romLoaded || core.pause)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
updateKeys();
|
|
||||||
updateAxis();
|
|
||||||
|
|
||||||
core.parallel.SetFramerateUnlocked(unlockFrameratePressed);
|
|
||||||
|
|
||||||
auto timeStart = SDL_GetTicks();
|
|
||||||
core.Run();
|
|
||||||
core.parallel.UpdateScreen();
|
|
||||||
elapsed = SDL_GetTicks() - timeStart;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
emuThread->start();
|
emuThread->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
KaizenGui::~KaizenGui() { cleanup(); }
|
KaizenGui::~KaizenGui() { cleanup(); }
|
||||||
|
|
||||||
void KaizenGui::updateKeys() {
|
|
||||||
auto &pif = core.mem->mmio.si.pif;
|
|
||||||
if (gamepad) {
|
|
||||||
pif.UpdateButton(0, n64::Controller::Z,
|
|
||||||
SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_LEFT_TRIGGER) == SDL_JOYSTICK_AXIS_MAX);
|
|
||||||
pif.UpdateButton(0, n64::Controller::A, SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_SOUTH));
|
|
||||||
pif.UpdateButton(0, n64::Controller::B, SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_WEST));
|
|
||||||
pif.UpdateButton(0, n64::Controller::LT, SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER));
|
|
||||||
pif.UpdateButton(0, n64::Controller::RT, SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER));
|
|
||||||
pif.UpdateButton(0, n64::Controller::Start, SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_START));
|
|
||||||
pif.UpdateButton(0, n64::Controller::DUp, SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_DPAD_UP));
|
|
||||||
pif.UpdateButton(0, n64::Controller::DDown, SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_DPAD_DOWN));
|
|
||||||
pif.UpdateButton(0, n64::Controller::DLeft, SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_DPAD_LEFT));
|
|
||||||
pif.UpdateButton(0, n64::Controller::DRight, SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_DPAD_RIGHT));
|
|
||||||
pif.UpdateButton(0, n64::Controller::CUp,
|
|
||||||
SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTY) == SDL_JOYSTICK_AXIS_MIN);
|
|
||||||
pif.UpdateButton(0, n64::Controller::CDown,
|
|
||||||
SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTY) == SDL_JOYSTICK_AXIS_MAX);
|
|
||||||
pif.UpdateButton(0, n64::Controller::CLeft,
|
|
||||||
SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTX) == SDL_JOYSTICK_AXIS_MIN);
|
|
||||||
pif.UpdateButton(0, n64::Controller::CRight,
|
|
||||||
SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTX) == SDL_JOYSTICK_AXIS_MAX);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pif.UpdateButton(0, n64::Controller::Z, pressedKeys.test(0));
|
|
||||||
pif.UpdateButton(0, n64::Controller::A, pressedKeys.test(1));
|
|
||||||
pif.UpdateButton(0, n64::Controller::B, pressedKeys.test(2));
|
|
||||||
pif.UpdateButton(0, n64::Controller::LT, pressedKeys.test(3));
|
|
||||||
pif.UpdateButton(0, n64::Controller::RT, pressedKeys.test(4));
|
|
||||||
pif.UpdateButton(0, n64::Controller::Start, pressedKeys.test(5));
|
|
||||||
pif.UpdateButton(0, n64::Controller::DUp, pressedKeys.test(6));
|
|
||||||
pif.UpdateButton(0, n64::Controller::DDown, pressedKeys.test(7));
|
|
||||||
pif.UpdateButton(0, n64::Controller::DLeft, pressedKeys.test(8));
|
|
||||||
pif.UpdateButton(0, n64::Controller::DRight, pressedKeys.test(9));
|
|
||||||
pif.UpdateButton(0, n64::Controller::CUp, pressedKeys.test(10));
|
|
||||||
pif.UpdateButton(0, n64::Controller::CDown, pressedKeys.test(11));
|
|
||||||
pif.UpdateButton(0, n64::Controller::CLeft, pressedKeys.test(12));
|
|
||||||
pif.UpdateButton(0, n64::Controller::CRight, pressedKeys.test(13));
|
|
||||||
}
|
|
||||||
|
|
||||||
void KaizenGui::updateAxis() {
|
|
||||||
auto &pif = core.mem->mmio.si.pif;
|
|
||||||
|
|
||||||
if (gamepad) {
|
|
||||||
float xclamped = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_LEFTX);
|
|
||||||
if (xclamped < 0) {
|
|
||||||
xclamped /= static_cast<float>(std::abs(SDL_JOYSTICK_AXIS_MAX));
|
|
||||||
} else {
|
|
||||||
xclamped /= SDL_JOYSTICK_AXIS_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
xclamped *= 86;
|
|
||||||
|
|
||||||
float yclamped = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_LEFTY);
|
|
||||||
if (yclamped < 0) {
|
|
||||||
yclamped /= static_cast<float>(std::abs(SDL_JOYSTICK_AXIS_MIN));
|
|
||||||
} else {
|
|
||||||
yclamped /= SDL_JOYSTICK_AXIS_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
yclamped *= 86;
|
|
||||||
|
|
||||||
pif.UpdateAxis(0, n64::Controller::Axis::Y, static_cast<s8>(-yclamped));
|
|
||||||
pif.UpdateAxis(0, n64::Controller::Axis::X, static_cast<s8>(xclamped));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
s16 x = 0, y = 0;
|
|
||||||
if (pressedKeys.test(14)) // up
|
|
||||||
y += 86;
|
|
||||||
|
|
||||||
if (pressedKeys.test(15)) // down
|
|
||||||
y -= 86;
|
|
||||||
|
|
||||||
if (pressedKeys.test(16)) // left
|
|
||||||
x -= 86;
|
|
||||||
|
|
||||||
if (pressedKeys.test(17)) // right
|
|
||||||
x += 86;
|
|
||||||
|
|
||||||
core.mem->mmio.si.pif.UpdateAxis(0, n64::Controller::X, x);
|
|
||||||
core.mem->mmio.si.pif.UpdateAxis(0, n64::Controller::Y, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void KaizenGui::LoadROM(const std::string &path) noexcept {
|
void KaizenGui::LoadROM(const std::string &path) noexcept {
|
||||||
core.LoadROM(path);
|
core.LoadROM(path);
|
||||||
pause->setEnabled(true);
|
pause->setEnabled(true);
|
||||||
@@ -360,14 +231,14 @@ void KaizenGui::dragEnterEvent(QDragEnterEvent *event) {
|
|||||||
void KaizenGui::keyPressEvent(QKeyEvent *event) {
|
void KaizenGui::keyPressEvent(QKeyEvent *event) {
|
||||||
for (int i = 0; i < settingsWindow->input->mapping.size(); i++) {
|
for (int i = 0; i < settingsWindow->input->mapping.size(); i++) {
|
||||||
if (settingsWindow->input->mapping[i] == event->key())
|
if (settingsWindow->input->mapping[i] == event->key())
|
||||||
pressedKeys.set(i);
|
emuThread->pressedKeys.set(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KaizenGui::keyReleaseEvent(QKeyEvent *event) {
|
void KaizenGui::keyReleaseEvent(QKeyEvent *event) {
|
||||||
for (int i = 0; i < settingsWindow->input->mapping.size(); i++) {
|
for (int i = 0; i < settingsWindow->input->mapping.size(); i++) {
|
||||||
if (settingsWindow->input->mapping[i] == event->key())
|
if (settingsWindow->input->mapping[i] == event->key())
|
||||||
pressedKeys.reset(i);
|
emuThread->pressedKeys.reset(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#include <QDragEnterEvent>
|
#include <QDragEnterEvent>
|
||||||
#include <RomsList.hpp>
|
#include <RomsList.hpp>
|
||||||
#include <Core.hpp>
|
#include <Core.hpp>
|
||||||
#include <bitset>
|
#include <EmuThread.hpp>
|
||||||
|
|
||||||
class KaizenGui final : QMainWindow {
|
class KaizenGui final : QMainWindow {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -19,22 +19,16 @@ class KaizenGui final : QMainWindow {
|
|||||||
bool fastForward = false;
|
bool fastForward = false;
|
||||||
bool minimized = false;
|
bool minimized = false;
|
||||||
|
|
||||||
SDL_Gamepad *gamepad = nullptr;
|
|
||||||
bool gamepadConnected;
|
|
||||||
float elapsed = 0.f;
|
|
||||||
n64::Core &core = n64::Core::GetInstance();
|
n64::Core &core = n64::Core::GetInstance();
|
||||||
std::bitset<18> pressedKeys{};
|
|
||||||
std::atomic_bool unlockFrameratePressed = false;
|
|
||||||
|
|
||||||
QWidget *currentHomeWidget;
|
|
||||||
QLabel *romPathNotSet = new QLabel(R"(Kaizen could not find any ROMs. Set the path in "Settings -> General")");
|
QLabel *romPathNotSet = new QLabel(R"(Kaizen could not find any ROMs. Set the path in "Settings -> General")");
|
||||||
RomsListTable *romsListTable;
|
RomsListTable *romsListTable;
|
||||||
QStackedWidget *centralWidget = new QStackedWidget();
|
QStackedWidget *centralWidget = new QStackedWidget();
|
||||||
SettingsWindow *settingsWindow;
|
SettingsWindow *settingsWindow;
|
||||||
RenderWidget *vulkanWidget;
|
RenderWidget *vulkanWidget;
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
QThread *emuThread;
|
EmuThread *emuThread;
|
||||||
QTimer *statusBarTimer, *SDLeventsTimer;
|
QTimer *statusBarTimer;
|
||||||
QLabel *fpsLabel;
|
QLabel *fpsLabel;
|
||||||
QLabel *cpuTypeLabel;
|
QLabel *cpuTypeLabel;
|
||||||
QLabel *idleSkipLabel;
|
QLabel *idleSkipLabel;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#undef signals
|
|
||||||
#include <ParallelRDPWrapper.hpp>
|
#include <ParallelRDPWrapper.hpp>
|
||||||
#include <QVulkanWindow>
|
#include <QVulkanWindow>
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
|
|||||||
Reference in New Issue
Block a user