gamepad works now finally. Ready for merge in dev

This commit is contained in:
SimoZ64
2025-06-27 12:18:44 +02:00
parent 7ca337ca48
commit 1be357e607
6 changed files with 73 additions and 91 deletions

View File

@@ -21,7 +21,6 @@ public:
void Init(const std::shared_ptr<Vulkan::WSIPlatform> &,
const std::shared_ptr<WindowInfo> &, const u8 *);
ParallelRDP() = default;
void UpdateScreen(n64::Core &, bool = true) const;
void EnqueueCommand(int, const u32 *) const;

View File

@@ -8,13 +8,6 @@ namespace n64 {
#define SYSTEM_SAMPLE_SIZE 4
#define BYTES_PER_HALF_SECOND (((float)AUDIO_SAMPLE_RATE / 2) * SYSTEM_SAMPLE_SIZE)
AudioDevice::~AudioDevice() {
LockMutex();
SDL_DestroyAudioStream(GetStream());
UnlockMutex();
SDL_DestroyMutex(audioStreamMutex);
}
AudioDevice::AudioDevice() {
audioStreamMutex = SDL_CreateMutex();
if (!audioStreamMutex) {

View File

@@ -5,7 +5,6 @@
namespace n64 {
struct AudioDevice {
AudioDevice();
~AudioDevice();
void Reset() { running = false; }

View File

@@ -5,15 +5,11 @@
#include <ImGuiImpl/GUI.hpp>
#include <resources/gamecontrollerdb.h>
bool HandleInput(void *userdata, SDL_Event *event);
bool QueryDevices(void *userdata, SDL_Event *event);
KaizenGui::KaizenGui() noexcept : window("Kaizen", 800, 600), core(std::make_shared<n64::Core>()), vulkanWidget(core, window.getHandle()), emuThread(core, fpsCounter, vulkanWidget, settingsWindow) {
gui::Initialize(core->parallel.wsi, window.getHandle());
SDL_InitSubSystem(SDL_INIT_GAMEPAD);
SDL_AddGamepadMapping(gamecontrollerdb_str);
SDL_AddEventWatch(HandleInput, this);
SDL_AddEventWatch(QueryDevices, this);
actionPause.setFunc([&]() {
if(ImGui::IsItemClicked()) {
@@ -43,8 +39,11 @@ KaizenGui::KaizenGui() noexcept : window("Kaizen", 800, 600), core(std::make_sha
});
statusBar.setFunc([&]() {
/* TODO: for when I'll separate the GUI and the Core in two threads again
ImGui::Text("GUI FPS: %.2f, Emulation FPS: %s", ImGui::GetIO().Framerate,
fmt::format(fpsCounter > 0 ? fmt::runtime("{0:.2f}") : fmt::runtime("{1}"), fpsCounter, "Not playing").c_str());
*/
ImGui::Text("FPS: %.2f", ImGui::GetIO().Framerate);
});
menuBar.addMenu({"File",
@@ -91,51 +90,40 @@ KaizenGui::KaizenGui() noexcept : window("Kaizen", 800, 600), core(std::make_sha
KaizenGui::~KaizenGui() {
gui::Cleanup();
SDL_RemoveEventWatch(HandleInput, this);
SDL_RemoveEventWatch(QueryDevices, this);
SDL_Quit();
}
bool QueryDevices(void *userdata, SDL_Event *event) {
auto _this = (KaizenGui*)userdata;
switch (event->type) {
void KaizenGui::QueryDevices(SDL_Event event) {
switch (event.type) {
case SDL_EVENT_GAMEPAD_ADDED:
{
const auto index = event->gdevice.which;
const auto index = event.gdevice.which;
auto gamepad = SDL_OpenGamepad(index);
gamepad = SDL_OpenGamepad(index);
Util::info("Found controller!");
const auto serial = SDL_GetGamepadSerial(gamepad);
const auto name = SDL_GetGamepadName(gamepad);
const auto path = SDL_GetGamepadPath(gamepad);
_this->gamepad = gamepad;
}
return true;
break;
case SDL_EVENT_GAMEPAD_REMOVED:
SDL_CloseGamepad(_this->gamepad);
return true;
default:
return false;
SDL_CloseGamepad(gamepad);
break;
default: break;
}
}
bool HandleInput(void *userdata, SDL_Event *event) {
auto _this = (KaizenGui*)userdata;
n64::PIF &pif = _this->core->cpu->GetMem().mmio.si.pif;
switch(event->type) {
void KaizenGui::HandleInput(SDL_Event event) {
n64::PIF &pif = core->cpu->GetMem().mmio.si.pif;
switch(event.type) {
case SDL_EVENT_GAMEPAD_AXIS_MOTION:
if(!_this->gamepad)
return false;
if(!gamepad)
break;
{
_this->core->pause = true;
pif.UpdateButton(0, n64::Controller::Key::Z, SDL_GetGamepadAxis(_this->gamepad, SDL_GAMEPAD_AXIS_LEFT_TRIGGER) == SDL_JOYSTICK_AXIS_MAX);
pif.UpdateButton(0, n64::Controller::Key::CUp, SDL_GetGamepadAxis(_this->gamepad, SDL_GAMEPAD_AXIS_RIGHTY) <= -127);
pif.UpdateButton(0, n64::Controller::Key::CDown, SDL_GetGamepadAxis(_this->gamepad, SDL_GAMEPAD_AXIS_RIGHTY) >= 127);
pif.UpdateButton(0, n64::Controller::Key::CLeft, SDL_GetGamepadAxis(_this->gamepad, SDL_GAMEPAD_AXIS_RIGHTX) <= -127);
pif.UpdateButton(0, n64::Controller::Key::CRight, SDL_GetGamepadAxis(_this->gamepad, SDL_GAMEPAD_AXIS_RIGHTX) >= 127);
pif.UpdateButton(0, n64::Controller::Key::Z, SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_LEFT_TRIGGER) == SDL_JOYSTICK_AXIS_MAX);
pif.UpdateButton(0, n64::Controller::Key::CUp, SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTY) <= -127);
pif.UpdateButton(0, n64::Controller::Key::CDown, SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTY) >= 127);
pif.UpdateButton(0, n64::Controller::Key::CLeft, SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTX) <= -127);
pif.UpdateButton(0, n64::Controller::Key::CRight, SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTX) >= 127);
float xclamped = SDL_GetGamepadAxis(_this->gamepad, SDL_GAMEPAD_AXIS_LEFTX);
float xclamped = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_LEFTX);
if (xclamped < 0) {
xclamped /= float(std::abs(SDL_JOYSTICK_AXIS_MAX));
} else {
@@ -144,7 +132,7 @@ bool HandleInput(void *userdata, SDL_Event *event) {
xclamped *= 86;
float yclamped = SDL_GetGamepadAxis(_this->gamepad, SDL_GAMEPAD_AXIS_LEFTY);
float yclamped = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_LEFTY);
if (yclamped < 0) {
yclamped /= float(std::abs(SDL_JOYSTICK_AXIS_MIN));
} else {
@@ -155,32 +143,28 @@ bool HandleInput(void *userdata, SDL_Event *event) {
pif.UpdateAxis(0, n64::Controller::Axis::Y, -yclamped);
pif.UpdateAxis(0, n64::Controller::Axis::X, xclamped);
_this->core->pause = false;
}
return true;
break;
case SDL_EVENT_GAMEPAD_BUTTON_DOWN:
if(!_this->gamepad)
return false;
{
_this->core->pause = true;
pif.UpdateButton(0, n64::Controller::Key::A, SDL_GetGamepadButton(_this->gamepad, SDL_GAMEPAD_BUTTON_SOUTH));
pif.UpdateButton(0, n64::Controller::Key::B, SDL_GetGamepadButton(_this->gamepad, SDL_GAMEPAD_BUTTON_WEST));
pif.UpdateButton(0, n64::Controller::Key::Start, SDL_GetGamepadButton(_this->gamepad, SDL_GAMEPAD_BUTTON_START));
pif.UpdateButton(0, n64::Controller::Key::DUp, SDL_GetGamepadButton(_this->gamepad, SDL_GAMEPAD_BUTTON_DPAD_UP));
pif.UpdateButton(0, n64::Controller::Key::DDown, SDL_GetGamepadButton(_this->gamepad, SDL_GAMEPAD_BUTTON_DPAD_DOWN));
pif.UpdateButton(0, n64::Controller::Key::DLeft, SDL_GetGamepadButton(_this->gamepad, SDL_GAMEPAD_BUTTON_DPAD_LEFT));
pif.UpdateButton(0, n64::Controller::Key::DRight, SDL_GetGamepadButton(_this->gamepad, SDL_GAMEPAD_BUTTON_DPAD_RIGHT));
pif.UpdateButton(0, n64::Controller::Key::LT, SDL_GetGamepadButton(_this->gamepad, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER));
pif.UpdateButton(0, n64::Controller::Key::RT, SDL_GetGamepadButton(_this->gamepad, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER));
_this->core->pause = false;
}
return true;
case SDL_EVENT_GAMEPAD_BUTTON_UP:
if(!gamepad)
break;
pif.UpdateButton(0, n64::Controller::Key::A, SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_SOUTH));
pif.UpdateButton(0, n64::Controller::Key::B, SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_WEST));
pif.UpdateButton(0, n64::Controller::Key::Start, SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_START));
pif.UpdateButton(0, n64::Controller::Key::DUp, SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_DPAD_UP));
pif.UpdateButton(0, n64::Controller::Key::DDown, SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_DPAD_DOWN));
pif.UpdateButton(0, n64::Controller::Key::DLeft, SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_DPAD_LEFT));
pif.UpdateButton(0, n64::Controller::Key::DRight, SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_DPAD_RIGHT));
pif.UpdateButton(0, n64::Controller::Key::LT, SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER));
pif.UpdateButton(0, n64::Controller::Key::RT, SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER));
break;
case SDL_EVENT_KEY_DOWN:
case SDL_EVENT_KEY_UP:
if(_this->gamepad)
return false;
if(gamepad)
break;
{
_this->core->pause = true;
auto keys = SDL_GetKeyboardState(nullptr);
pif.UpdateButton(0, n64::Controller::Key::Z, keys[SDL_SCANCODE_Z]);
pif.UpdateButton(0, n64::Controller::Key::CUp, keys[SDL_SCANCODE_HOME]);
@@ -198,10 +182,9 @@ bool HandleInput(void *userdata, SDL_Event *event) {
pif.UpdateButton(0, n64::Controller::Key::RT, keys[SDL_SCANCODE_S]);
pif.UpdateAxis(0, n64::Controller::Axis::Y, keys[SDL_SCANCODE_UP] ? 86 : keys[SDL_SCANCODE_DOWN] ? -86 : 0);
pif.UpdateAxis(0, n64::Controller::Axis::X, keys[SDL_SCANCODE_LEFT] ? -86 : keys[SDL_SCANCODE_RIGHT] ? 86 : 0);
_this->core->pause = false;
}
return true;
default: return false;
break;
default: break;
}
}
@@ -217,7 +200,7 @@ void KaizenGui::RenderUI() {
ImGui::RenderPlatformWindowsDefault();
}
if(!core->pause) {
if(!core->pause && core->romLoaded) {
core->parallel.UpdateScreen(*core.get());
return;
}
@@ -245,6 +228,8 @@ void KaizenGui::run() {
emuThread.Stop();
break;
}
QueryDevices(e);
HandleInput(e);
}
emuThread.run();

View File

@@ -13,15 +13,19 @@ class KaizenGui final {
public:
explicit KaizenGui() noexcept;
~KaizenGui();
double fpsCounter = -1.0;
gui::MenuBar<true> menuBar;
gui::MenuItem actionPause{"Pause", nullptr, false}, actionStop{"Stop", nullptr, false}, actionReset{"Reset", nullptr, false};
SettingsWindow settingsWindow;
std::shared_ptr<n64::Core> core;
RenderWidget vulkanWidget;
EmuThread emuThread;
gui::PopupWindow about{"About Kaizen"};
gui::StatusBar statusBar{};
std::shared_ptr<n64::Core> core;
RenderWidget vulkanWidget;
SettingsWindow settingsWindow;
EmuThread emuThread;
SDL_Gamepad* gamepad = nullptr;
void run();
@@ -31,4 +35,6 @@ private:
bool quit = false;
std::function<void()> emuExitFunc;
void RenderUI();
void HandleInput(SDL_Event event);
void QueryDevices(SDL_Event event);
};