#include #include #include InputSettings::InputSettings(nlohmann::json &settings) : settings(settings) { for(auto& kb : kbButtons) { kb.setLabel(JSONGetField(settings, "input", kb.getName())); } devices.addItem({"Keyboard/Mouse"}); SDL_InitSubSystem(SDL_INIT_GAMEPAD); } bool InputSettings::render() { if(devices.render()) { auto currentlySelectedDevice = devices.getCurrentlySelected(); JSONSetField(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 InputSettings::GetMappedKeys() { std::array 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(e.gbutton.button)); JSONSetField(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(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; } } }