155 lines
4.2 KiB
C++
155 lines
4.2 KiB
C++
#include <InputSettings.hpp>
|
|
#include <log.hpp>
|
|
#include <SDL3/SDL.h>
|
|
|
|
bool QueryDevices(void *userdata, SDL_Event *event);
|
|
bool PollGamepad(void *userdata, SDL_Event *event);
|
|
|
|
InputSettings::InputSettings(nlohmann::json &settings) : settings(settings) {
|
|
int i = 0;
|
|
for(auto& kb : kbButtons) {
|
|
auto field = JSONGetField<std::string>(settings, "input", kb.getName());
|
|
kb.setLabel(field != "" ? field : "##unsetButton" + std::to_string(i++));
|
|
}
|
|
|
|
devices.addItem({"Keyboard/Mouse"});
|
|
SDL_InitSubSystem(SDL_INIT_GAMEPAD);
|
|
SDL_AddEventWatch(QueryDevices, this);
|
|
SDL_AddEventWatch(PollGamepad, this);
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
if((i % 2 == 0) || i == 0) // only go down every 2 buttons... just... i like it this way
|
|
ImGui::SameLine();
|
|
|
|
i++;
|
|
}
|
|
|
|
return modified;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
bool QueryDevices(void *userdata, SDL_Event *event) {
|
|
auto _this = (InputSettings*)userdata;
|
|
if (!_this->devices.isEnabled())
|
|
return false;
|
|
|
|
switch (event->type) {
|
|
case SDL_EVENT_GAMEPAD_ADDED:
|
|
{
|
|
const auto index = event->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 (!_this->gamepadIndexes.contains(index)) {
|
|
_this->gamepadIndexes[index] = name;
|
|
}
|
|
_this->devices.addItem({name});
|
|
} else if (serial) {
|
|
if (!_this->gamepadIndexes.contains(index)) {
|
|
_this->gamepadIndexes[index] = serial;
|
|
}
|
|
_this->devices.addItem({serial});
|
|
} else if (path) {
|
|
if (!_this->gamepadIndexes.contains(index)) {
|
|
_this->gamepadIndexes[index] = path;
|
|
}
|
|
_this->devices.addItem({path});
|
|
}
|
|
|
|
SDL_CloseGamepad(gamepad);
|
|
}
|
|
return true;
|
|
case SDL_EVENT_GAMEPAD_REMOVED:
|
|
{
|
|
const auto index = event->gdevice.which;
|
|
|
|
if (_this->gamepadIndexes.contains(index))
|
|
_this->devices.removeItem(_this->gamepadIndexes[index]);
|
|
}
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool PollGamepad(void *userdata, SDL_Event *event) {
|
|
auto _this = (InputSettings*)userdata;
|
|
switch (event->type) {
|
|
case SDL_EVENT_GAMEPAD_BUTTON_DOWN:
|
|
{
|
|
if (!_this->selectedDeviceIsNotKeyboard)
|
|
return false;
|
|
|
|
const auto k = SDL_GetGamepadStringForButton(static_cast<SDL_GamepadButton>(event->gbutton.button));
|
|
JSONSetField<std::string>(_this->settings, "input", _this->kbButtons[_this->whichGrabbing].getName(), k);
|
|
_this->kbButtons[_this->whichGrabbing].setLabel(k);
|
|
_this->devices.setEnabled(true);
|
|
for (auto &kbButton : _this->kbButtons) {
|
|
kbButton.setEnabled(true);
|
|
}
|
|
|
|
_this->grabbing = false;
|
|
_this->whichGrabbing = -1;
|
|
|
|
_this->modified = true;
|
|
}
|
|
return true;
|
|
case SDL_EVENT_KEY_DOWN:
|
|
{
|
|
if (_this->selectedDeviceIsNotKeyboard)
|
|
return false;
|
|
|
|
const auto k = SDL_GetKeyName(event->key.key);
|
|
JSONSetField<std::string>(_this->settings, "input", _this->kbButtons[_this->whichGrabbing].getName(), k);
|
|
_this->kbButtons[_this->whichGrabbing].setLabel(k);
|
|
_this->devices.setEnabled(true);
|
|
for (auto &kbButton : _this->kbButtons) {
|
|
kbButton.setEnabled(true);
|
|
}
|
|
|
|
_this->grabbing = false;
|
|
_this->whichGrabbing = -1;
|
|
|
|
_this->modified = true;
|
|
}
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|