[SDL] Log controller GUIDs and their mapping
This commit is contained in:
parent
61ea486481
commit
6e13258ad4
|
@ -94,3 +94,6 @@
|
||||||
[submodule "third_party/tabulate"]
|
[submodule "third_party/tabulate"]
|
||||||
path = third_party/tabulate
|
path = third_party/tabulate
|
||||||
url = https://github.com/p-ranav/tabulate.git
|
url = https://github.com/p-ranav/tabulate.git
|
||||||
|
[submodule "third_party/rapidcsv"]
|
||||||
|
path = third_party/rapidcsv
|
||||||
|
url = https://github.com/d99kris/rapidcsv
|
||||||
|
|
|
@ -111,36 +111,87 @@ X_STATUS SDLInputDriver::Setup() {
|
||||||
if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) < 0) {
|
if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sdl_gamecontroller_initialized_ = true;
|
sdl_gamecontroller_initialized_ = true;
|
||||||
|
|
||||||
if (!cvars::mappings_file.empty()) {
|
LoadGameControllerDB();
|
||||||
if (!std::filesystem::exists(cvars::mappings_file)) {
|
|
||||||
XELOGW("SDL GameControllerDB: file '{}' does not exist.",
|
|
||||||
xe::path_to_utf8(cvars::mappings_file));
|
|
||||||
} else {
|
|
||||||
auto mappings_file = filesystem::OpenFile(cvars::mappings_file, "rb");
|
|
||||||
if (!mappings_file) {
|
|
||||||
XELOGE("SDL GameControllerDB: failed to open file '{}'.",
|
|
||||||
xe::path_to_utf8(cvars::mappings_file));
|
|
||||||
} else {
|
|
||||||
auto mappings_result = SDL_GameControllerAddMappingsFromRW(
|
|
||||||
SDL_RWFromFP(mappings_file, SDL_TRUE), 1);
|
|
||||||
if (mappings_result < 0) {
|
|
||||||
XELOGE("SDL GameControllerDB: error loading file '{}': {}.",
|
|
||||||
xe::path_to_utf8(cvars::mappings_file), mappings_result);
|
|
||||||
} else {
|
|
||||||
XELOGI("SDL GameControllerDB: loaded {} mappings.",
|
|
||||||
mappings_result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return (sdl_events_initialized_ && sdl_gamecontroller_initialized_)
|
return (sdl_events_initialized_ && sdl_gamecontroller_initialized_)
|
||||||
? X_STATUS_SUCCESS
|
? X_STATUS_SUCCESS
|
||||||
: X_STATUS_UNSUCCESSFUL;
|
: X_STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SDLInputDriver::LoadGameControllerDB() {
|
||||||
|
if (cvars::mappings_file.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!std::filesystem::exists(cvars::mappings_file)) {
|
||||||
|
XELOGW("SDL GameControllerDB: file '{}' does not exist.",
|
||||||
|
xe::path_to_utf8(cvars::mappings_file));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
XELOGI("SDL GameControllerDB: Loading {}",
|
||||||
|
xe::path_to_utf8(cvars::mappings_file));
|
||||||
|
|
||||||
|
uint32_t updated_mappings = 0;
|
||||||
|
uint32_t added_mappings = 0;
|
||||||
|
|
||||||
|
rapidcsv::Document mappings(
|
||||||
|
xe::path_to_utf8(cvars::mappings_file), rapidcsv::LabelParams(-1, -1),
|
||||||
|
rapidcsv::SeparatorParams(), rapidcsv::ConverterParams(),
|
||||||
|
rapidcsv::LineReaderParams(true /* pSkipCommentLines */,
|
||||||
|
'#' /* pCommentPrefix */,
|
||||||
|
true /* pSkipEmptyLines */));
|
||||||
|
|
||||||
|
for (size_t i = 0; i < mappings.GetRowCount(); i++) {
|
||||||
|
std::vector<std::string> row = mappings.GetRow<std::string>(i);
|
||||||
|
|
||||||
|
if (row.size() < 2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string guid = row[0];
|
||||||
|
std::string controller_name = row[1];
|
||||||
|
|
||||||
|
auto format = [](std::string& ss, std::string& s) {
|
||||||
|
return ss.empty() ? s : ss + "," + s;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string mapping_str =
|
||||||
|
std::accumulate(row.begin(), row.end(), std::string{}, format);
|
||||||
|
|
||||||
|
int updated = SDL_GameControllerAddMapping(mapping_str.c_str());
|
||||||
|
|
||||||
|
switch (updated) {
|
||||||
|
case 0: {
|
||||||
|
XELOGI("SDL GameControllerDB: Updated {}, {}", controller_name, guid);
|
||||||
|
updated_mappings++;
|
||||||
|
} break;
|
||||||
|
case 1: {
|
||||||
|
added_mappings++;
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
|
XELOGW("SDL GameControllerDB: error loading mapping '{}'", mapping_str);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < HID_SDL_USER_COUNT; i++) {
|
||||||
|
auto controller = GetControllerState(i);
|
||||||
|
|
||||||
|
if (controller) {
|
||||||
|
XELOGI("SDL Controller {}: {}", i,
|
||||||
|
SDL_GameControllerMapping(controller->sdl));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
XELOGI("SDL GameControllerDB: Updated {} mappings.", updated_mappings);
|
||||||
|
XELOGI("SDL GameControllerDB: Added {} mappings.", added_mappings);
|
||||||
|
}
|
||||||
|
|
||||||
X_RESULT SDLInputDriver::GetCapabilities(uint32_t user_index, uint32_t flags,
|
X_RESULT SDLInputDriver::GetCapabilities(uint32_t user_index, uint32_t flags,
|
||||||
X_INPUT_CAPABILITIES* out_caps) {
|
X_INPUT_CAPABILITIES* out_caps) {
|
||||||
assert(sdl_events_initialized_ && sdl_gamecontroller_initialized_);
|
assert(sdl_events_initialized_ && sdl_gamecontroller_initialized_);
|
||||||
|
@ -419,12 +470,20 @@ void SDLInputDriver::OnControllerDeviceAdded(const SDL_Event& event) {
|
||||||
assert_always();
|
assert_always();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char guid_str[33];
|
||||||
|
|
||||||
|
SDL_JoystickGetGUIDString(
|
||||||
|
SDL_JoystickGetGUID(SDL_GameControllerGetJoystick(controller)), guid_str,
|
||||||
|
33);
|
||||||
|
|
||||||
XELOGI(
|
XELOGI(
|
||||||
"SDL OnControllerDeviceAdded: \"{}\", "
|
"SDL OnControllerDeviceAdded: \"{}\", "
|
||||||
"JoystickType({}), "
|
"JoystickType({}), "
|
||||||
"GameControllerType({}), "
|
"GameControllerType({}), "
|
||||||
"VendorID(0x{:04X}), "
|
"VendorID(0x{:04X}), "
|
||||||
"ProductID(0x{:04X})",
|
"ProductID(0x{:04X}), "
|
||||||
|
"GUID({})",
|
||||||
SDL_GameControllerName(controller),
|
SDL_GameControllerName(controller),
|
||||||
SDL_JoystickGetType(SDL_GameControllerGetJoystick(controller)),
|
SDL_JoystickGetType(SDL_GameControllerGetJoystick(controller)),
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 12)
|
#if SDL_VERSION_ATLEAST(2, 0, 12)
|
||||||
|
@ -434,10 +493,11 @@ void SDLInputDriver::OnControllerDeviceAdded(const SDL_Event& event) {
|
||||||
#endif
|
#endif
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 6)
|
#if SDL_VERSION_ATLEAST(2, 0, 6)
|
||||||
SDL_GameControllerGetVendor(controller),
|
SDL_GameControllerGetVendor(controller),
|
||||||
SDL_GameControllerGetProduct(controller));
|
SDL_GameControllerGetProduct(controller),
|
||||||
#else
|
#else
|
||||||
"?", "?");
|
"?", "?",
|
||||||
#endif
|
#endif
|
||||||
|
guid_str);
|
||||||
int user_id = -1;
|
int user_id = -1;
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 9)
|
#if SDL_VERSION_ATLEAST(2, 0, 9)
|
||||||
// Check if the controller has a player index LED.
|
// Check if the controller has a player index LED.
|
||||||
|
@ -468,6 +528,8 @@ void SDLInputDriver::OnControllerDeviceAdded(const SDL_Event& event) {
|
||||||
UpdateXCapabilities(state);
|
UpdateXCapabilities(state);
|
||||||
|
|
||||||
XELOGI("SDL OnControllerDeviceAdded: Added at index {}.", user_id);
|
XELOGI("SDL OnControllerDeviceAdded: Added at index {}.", user_id);
|
||||||
|
XELOGI("SDL Controller {}: {}", user_id,
|
||||||
|
SDL_GameControllerMapping(controller));
|
||||||
} else {
|
} else {
|
||||||
// No more controllers needed, close it.
|
// No more controllers needed, close it.
|
||||||
SDL_GameControllerClose(controller);
|
SDL_GameControllerClose(controller);
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
|
#include "third_party/rapidcsv/src/rapidcsv.h"
|
||||||
#include "xenia/hid/input_driver.h"
|
#include "xenia/hid/input_driver.h"
|
||||||
|
|
||||||
#define HID_SDL_USER_COUNT 4
|
#define HID_SDL_USER_COUNT 4
|
||||||
|
@ -35,6 +36,8 @@ class SDLInputDriver final : public InputDriver {
|
||||||
|
|
||||||
X_STATUS Setup() override;
|
X_STATUS Setup() override;
|
||||||
|
|
||||||
|
void LoadGameControllerDB();
|
||||||
|
|
||||||
X_RESULT GetCapabilities(uint32_t user_index, uint32_t flags,
|
X_RESULT GetCapabilities(uint32_t user_index, uint32_t flags,
|
||||||
X_INPUT_CAPABILITIES* out_caps) override;
|
X_INPUT_CAPABILITIES* out_caps) override;
|
||||||
X_RESULT GetState(uint32_t user_index, X_INPUT_STATE* out_state) override;
|
X_RESULT GetState(uint32_t user_index, X_INPUT_STATE* out_state) override;
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 7e87d8cac42a03c323d06c8414d2afddd21788f2
|
Loading…
Reference in New Issue