Files
kaizen/src/frontend/InputSettings.cpp
2025-05-22 00:30:33 +02:00

153 lines
3.7 KiB
C++

#include <InputSettings.hpp>
#include <log.hpp>
#include <SDL3/SDL.h>
InputSettings::InputSettings(nlohmann::json &settings) : settings(settings) {
for(auto& kb : kbButtons) {
kb.setLabel(JSONGetField<std::string>(settings, "input", kb.getName()));
}
devices.addItem({"Keyboard/Mouse"});
SDL_InitSubSystem(SDL_INIT_GAMEPAD);
}
bool InputSettings::render() {
if(devices.render()) {
auto currentlySelectedDevice = devices.getCurrentlySelected();
JSONSetField<std::string>(settings, "input", "Device", currentlySelectedDevice);
selectedDeviceIsNotKeyboard = currentlySelectedDevice == "Keyboard/Mouse";
modified = true;
}
int i = 0;
for(auto& kb : kbButtons) {
if(kb.render()) {
devices.setEnabled(false);
for (auto &otherKb : kbButtons) {
otherKb.setEnabled(false);
}
whichGrabbing = i;
}
QueryDevices();
PollGamepad();
if(i % 2 != 0) // only go down every 2 buttons... just... i like it this way
ImGui::SameLine();
i++;
}
return true;
}
std::array<SDL_Keycode, 18> InputSettings::GetMappedKeys() {
std::array<SDL_Keycode, 18> ret{};
int i = 0;
for (auto& kb : kbButtons) {
ret[i++] = SDL_GetKeyFromName(kb.getLabel().c_str());
}
return ret;
}
void InputSettings::QueryDevices() noexcept {
if (!devices.isEnabled())
return;
SDL_Event e;
while (SDL_PollEvent(&e)) {
switch (e.type) {
case SDL_EVENT_GAMEPAD_ADDED:
{
const auto index = e.gdevice.which;
const auto 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);
if (name) {
if (!gamepadIndexes.contains(index)) {
gamepadIndexes[index] = name;
}
devices.addItem({name});
} else if (serial) {
if (!gamepadIndexes.contains(index)) {
gamepadIndexes[index] = serial;
}
devices.addItem({serial});
} else if (path) {
if (!gamepadIndexes.contains(index)) {
gamepadIndexes[index] = path;
}
devices.addItem({path});
}
SDL_CloseGamepad(gamepad);
}
break;
case SDL_EVENT_GAMEPAD_REMOVED:
{
const auto index = e.gdevice.which;
if (gamepadIndexes.contains(index))
devices.removeItem(gamepadIndexes[index]);
}
break;
}
}
}
void InputSettings::PollGamepad() noexcept {
SDL_Event e;
while (SDL_PollEvent(&e)) {
switch (e.type) {
case SDL_EVENT_GAMEPAD_BUTTON_DOWN:
{
if (!selectedDeviceIsNotKeyboard)
return;
const auto k = SDL_GetGamepadStringForButton(static_cast<SDL_GamepadButton>(e.gbutton.button));
JSONSetField<std::string>(settings, "input", kbButtons[whichGrabbing].getName(), k);
kbButtons[whichGrabbing].setLabel(k);
devices.setEnabled(true);
for (auto &kbButton : kbButtons) {
kbButton.setEnabled(true);
}
grabbing = false;
whichGrabbing = -1;
modified = true;
}
break;
case SDL_EVENT_KEY_DOWN:
{
if (selectedDeviceIsNotKeyboard)
return;
const auto k = SDL_GetKeyName(e.key.key);
JSONSetField<std::string>(settings, "input", kbButtons[whichGrabbing].getName(), k);
kbButtons[whichGrabbing].setLabel(k);
devices.setEnabled(true);
for (auto &kbButton : kbButtons) {
kbButton.setEnabled(true);
}
grabbing = false;
whichGrabbing = -1;
modified = true;
}
break;
default:
break;
}
}
}