Next step is actually using the user config for input

This commit is contained in:
SimoZ64
2025-06-02 20:07:06 +02:00
parent efe6a2fcb8
commit 891c722b33
6 changed files with 103 additions and 7 deletions

View File

@@ -71,6 +71,7 @@ struct Combobox {
bool isEnabled() { return enabled; } bool isEnabled() { return enabled; }
const std::string& getCurrentlySelected() { return items[current_index].getLabel(); } const std::string& getCurrentlySelected() { return items[current_index].getLabel(); }
const int& getCurrentlySelectedIndex() { return current_index; }
void setCurrentIndex(int v) { current_index = v; } void setCurrentIndex(int v) { current_index = v; }
int getCurrentIndex() { return current_index; } int getCurrentIndex() { return current_index; }

View File

@@ -29,8 +29,9 @@ void InputSettings::UnregisterEventWatchers() {
bool InputSettings::render() { bool InputSettings::render() {
if(devices.render()) { if(devices.render()) {
auto currentlySelectedDevice = devices.getCurrentlySelected(); auto currentlySelectedDevice = devices.getCurrentlySelected();
currentlySelectedDeviceIndex = devices.getCurrentlySelectedIndex();
JSONSetField<std::string>(settings, "input", "Device", currentlySelectedDevice); JSONSetField<std::string>(settings, "input", "Device", currentlySelectedDevice);
selectedDeviceIsNotKeyboard = currentlySelectedDevice == "Keyboard/Mouse"; selectedDeviceIsNotKeyboard = currentlySelectedDevice != "Keyboard/Mouse";
modified = true; modified = true;
} }
@@ -76,12 +77,13 @@ bool QueryDevices(void *userdata, SDL_Event *event) {
{ {
const auto index = event->gdevice.which; const auto index = event->gdevice.which;
const auto gamepad = SDL_OpenGamepad(index); auto gamepad = SDL_OpenGamepad(index);
Util::info("Found controller!"); Util::info("Found controller!");
const auto serial = SDL_GetGamepadSerial(gamepad); const auto serial = SDL_GetGamepadSerial(gamepad);
const auto name = SDL_GetGamepadName(gamepad); const auto name = SDL_GetGamepadName(gamepad);
const auto path = SDL_GetGamepadPath(gamepad); const auto path = SDL_GetGamepadPath(gamepad);
_this->gamepads[index] = gamepad;
if (name) { if (name) {
if (!_this->gamepadIndexes.contains(index)) { if (!_this->gamepadIndexes.contains(index)) {
_this->gamepadIndexes[index] = name; _this->gamepadIndexes[index] = name;
@@ -98,16 +100,16 @@ bool QueryDevices(void *userdata, SDL_Event *event) {
} }
_this->devices.addItem({path}); _this->devices.addItem({path});
} }
SDL_CloseGamepad(gamepad);
} }
return true; return true;
case SDL_EVENT_GAMEPAD_REMOVED: case SDL_EVENT_GAMEPAD_REMOVED:
{ {
const auto index = event->gdevice.which; const auto index = event->gdevice.which;
if (_this->gamepadIndexes.contains(index)) if (_this->gamepadIndexes.contains(index)) {
_this->devices.removeItem(_this->gamepadIndexes[index]); _this->devices.removeItem(_this->gamepadIndexes[index]);
SDL_CloseGamepad(_this->gamepads[index]);
}
} }
return true; return true;
default: default:

View File

@@ -7,8 +7,10 @@
class InputSettings final { class InputSettings final {
public: public:
std::unordered_map<u32, SDL_Gamepad*> gamepads{};
bool grabbing = false; bool grabbing = false;
int whichGrabbing = -1; int whichGrabbing = -1;
int currentlySelectedDeviceIndex = -1;
std::unordered_map<u32, std::string> gamepadIndexes{}; std::unordered_map<u32, std::string> gamepadIndexes{};
std::array<gui::PushButton, 18> kbButtons = { std::array<gui::PushButton, 18> kbButtons = {

View File

@@ -4,8 +4,12 @@
#include <ImGuiImpl/StatusBar.hpp> #include <ImGuiImpl/StatusBar.hpp>
#include <ImGuiImpl/GUI.hpp> #include <ImGuiImpl/GUI.hpp>
bool HandleInput(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) { 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()); gui::Initialize(core->parallel.wsi, window.getHandle());
SDL_AddEventWatch(HandleInput, this);
actionPause.setFunc([&]() { actionPause.setFunc([&]() {
if(ImGui::IsItemClicked()) { if(ImGui::IsItemClicked()) {
@@ -82,6 +86,94 @@ KaizenGui::KaizenGui() noexcept : window("Kaizen", 800, 600), core(std::make_sha
KaizenGui::~KaizenGui() { KaizenGui::~KaizenGui() {
gui::Cleanup(); gui::Cleanup();
SDL_RemoveEventWatch(HandleInput, this);
SDL_Quit();
}
bool HandleInput(void *userdata, SDL_Event *event) {
auto _this = (KaizenGui*)userdata;
InputSettings& inputSettings = _this->settingsWindow.inputSettings;
n64::PIF &pif = _this->core->cpu->GetMem().mmio.si.pif;
switch(event->type) {
case SDL_EVENT_GAMEPAD_AXIS_MOTION:
if(!inputSettings.selectedDeviceIsNotKeyboard)
return false;
{
_this->core->pause = true;
pif.UpdateButton(0, n64::Controller::Key::Z, SDL_GetGamepadAxis(inputSettings.gamepads[inputSettings.currentlySelectedDeviceIndex], SDL_GAMEPAD_AXIS_LEFT_TRIGGER) == SDL_JOYSTICK_AXIS_MAX);
pif.UpdateButton(0, n64::Controller::Key::CUp, SDL_GetGamepadAxis(inputSettings.gamepads[inputSettings.currentlySelectedDeviceIndex], SDL_GAMEPAD_AXIS_RIGHTY) <= -127);
pif.UpdateButton(0, n64::Controller::Key::CDown, SDL_GetGamepadAxis(inputSettings.gamepads[inputSettings.currentlySelectedDeviceIndex], SDL_GAMEPAD_AXIS_RIGHTY) >= 127);
pif.UpdateButton(0, n64::Controller::Key::CLeft, SDL_GetGamepadAxis(inputSettings.gamepads[inputSettings.currentlySelectedDeviceIndex], SDL_GAMEPAD_AXIS_RIGHTX) <= -127);
pif.UpdateButton(0, n64::Controller::Key::CRight, SDL_GetGamepadAxis(inputSettings.gamepads[inputSettings.currentlySelectedDeviceIndex], SDL_GAMEPAD_AXIS_RIGHTX) >= 127);
float xclamped = SDL_GetGamepadAxis(inputSettings.gamepads[inputSettings.currentlySelectedDeviceIndex], SDL_GAMEPAD_AXIS_LEFTX);
if (xclamped < 0) {
xclamped /= float(std::abs(SDL_JOYSTICK_AXIS_MAX));
} else {
xclamped /= SDL_JOYSTICK_AXIS_MAX;
}
xclamped *= 86;
float yclamped = SDL_GetGamepadAxis(inputSettings.gamepads[inputSettings.currentlySelectedDeviceIndex], SDL_GAMEPAD_AXIS_LEFTY);
if (yclamped < 0) {
yclamped /= float(std::abs(SDL_JOYSTICK_AXIS_MIN));
} else {
yclamped /= SDL_JOYSTICK_AXIS_MAX;
}
yclamped *= 86;
pif.UpdateAxis(0, n64::Controller::Axis::Y, -yclamped);
pif.UpdateAxis(0, n64::Controller::Axis::X, xclamped);
_this->core->pause = false;
}
return true;
case SDL_EVENT_GAMEPAD_BUTTON_DOWN:
if(!inputSettings.selectedDeviceIsNotKeyboard)
return false;
{
_this->core->pause = true;
pif.UpdateButton(0, n64::Controller::Key::A, SDL_GetGamepadButton(inputSettings.gamepads[inputSettings.currentlySelectedDeviceIndex], SDL_GAMEPAD_BUTTON_SOUTH));
pif.UpdateButton(0, n64::Controller::Key::B, SDL_GetGamepadButton(inputSettings.gamepads[inputSettings.currentlySelectedDeviceIndex], SDL_GAMEPAD_BUTTON_WEST));
pif.UpdateButton(0, n64::Controller::Key::Start, SDL_GetGamepadButton(inputSettings.gamepads[inputSettings.currentlySelectedDeviceIndex], SDL_GAMEPAD_BUTTON_START));
pif.UpdateButton(0, n64::Controller::Key::DUp, SDL_GetGamepadButton(inputSettings.gamepads[inputSettings.currentlySelectedDeviceIndex], SDL_GAMEPAD_BUTTON_DPAD_UP));
pif.UpdateButton(0, n64::Controller::Key::DDown, SDL_GetGamepadButton(inputSettings.gamepads[inputSettings.currentlySelectedDeviceIndex], SDL_GAMEPAD_BUTTON_DPAD_DOWN));
pif.UpdateButton(0, n64::Controller::Key::DLeft, SDL_GetGamepadButton(inputSettings.gamepads[inputSettings.currentlySelectedDeviceIndex], SDL_GAMEPAD_BUTTON_DPAD_LEFT));
pif.UpdateButton(0, n64::Controller::Key::DRight, SDL_GetGamepadButton(inputSettings.gamepads[inputSettings.currentlySelectedDeviceIndex], SDL_GAMEPAD_BUTTON_DPAD_RIGHT));
pif.UpdateButton(0, n64::Controller::Key::LT, SDL_GetGamepadButton(inputSettings.gamepads[inputSettings.currentlySelectedDeviceIndex], SDL_GAMEPAD_BUTTON_LEFT_SHOULDER));
pif.UpdateButton(0, n64::Controller::Key::RT, SDL_GetGamepadButton(inputSettings.gamepads[inputSettings.currentlySelectedDeviceIndex], SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER));
_this->core->pause = false;
}
return true;
case SDL_EVENT_KEY_DOWN:
case SDL_EVENT_KEY_UP:
if(inputSettings.selectedDeviceIsNotKeyboard)
return false;
{
_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]);
pif.UpdateButton(0, n64::Controller::Key::CDown, keys[SDL_SCANCODE_END]);
pif.UpdateButton(0, n64::Controller::Key::CLeft, keys[SDL_SCANCODE_DELETE]);
pif.UpdateButton(0, n64::Controller::Key::CRight, keys[SDL_SCANCODE_PAGEDOWN]);
pif.UpdateButton(0, n64::Controller::Key::A, keys[SDL_SCANCODE_X]);
pif.UpdateButton(0, n64::Controller::Key::B, keys[SDL_SCANCODE_C]);
pif.UpdateButton(0, n64::Controller::Key::Start, keys[SDL_SCANCODE_RETURN]);
pif.UpdateButton(0, n64::Controller::Key::DUp, keys[SDL_SCANCODE_I]);
pif.UpdateButton(0, n64::Controller::Key::DDown, keys[SDL_SCANCODE_K]);
pif.UpdateButton(0, n64::Controller::Key::DLeft, keys[SDL_SCANCODE_J]);
pif.UpdateButton(0, n64::Controller::Key::DRight, keys[SDL_SCANCODE_L]);
pif.UpdateButton(0, n64::Controller::Key::LT, keys[SDL_SCANCODE_A]);
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;
}
} }
void KaizenGui::RenderUI() { void KaizenGui::RenderUI() {

View File

@@ -27,7 +27,6 @@ public:
void LoadROM(const std::string &path) noexcept; void LoadROM(const std::string &path) noexcept;
private: private:
bool quit = false; bool quit = false;
void handleEvents();
std::function<void()> emuExitFunc; std::function<void()> emuExitFunc;
void RenderUI(); void RenderUI();
}; };

View File

@@ -12,8 +12,8 @@ class SettingsWindow final {
nlohmann::json settings; nlohmann::json settings;
CPUSettings cpuSettings{settings}; CPUSettings cpuSettings{settings};
AudioSettings audioSettings{settings}; AudioSettings audioSettings{settings};
InputSettings inputSettings{settings};
public: public:
InputSettings inputSettings{settings};
gui::PopupWindow popup{"Emulator Settings"}; gui::PopupWindow popup{"Emulator Settings"};
bool render(); bool render();
SettingsWindow(); SettingsWindow();