[SDL] Log controller GUIDs and their mapping
This commit is contained in:
parent
61ea486481
commit
6e13258ad4
|
@ -94,3 +94,6 @@
|
|||
[submodule "third_party/tabulate"]
|
||||
path = third_party/tabulate
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
|
||||
sdl_gamecontroller_initialized_ = true;
|
||||
|
||||
if (!cvars::mappings_file.empty()) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
LoadGameControllerDB();
|
||||
});
|
||||
|
||||
return (sdl_events_initialized_ && sdl_gamecontroller_initialized_)
|
||||
? X_STATUS_SUCCESS
|
||||
: 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_INPUT_CAPABILITIES* out_caps) {
|
||||
assert(sdl_events_initialized_ && sdl_gamecontroller_initialized_);
|
||||
|
@ -419,12 +470,20 @@ void SDLInputDriver::OnControllerDeviceAdded(const SDL_Event& event) {
|
|||
assert_always();
|
||||
return;
|
||||
}
|
||||
|
||||
char guid_str[33];
|
||||
|
||||
SDL_JoystickGetGUIDString(
|
||||
SDL_JoystickGetGUID(SDL_GameControllerGetJoystick(controller)), guid_str,
|
||||
33);
|
||||
|
||||
XELOGI(
|
||||
"SDL OnControllerDeviceAdded: \"{}\", "
|
||||
"JoystickType({}), "
|
||||
"GameControllerType({}), "
|
||||
"VendorID(0x{:04X}), "
|
||||
"ProductID(0x{:04X})",
|
||||
"ProductID(0x{:04X}), "
|
||||
"GUID({})",
|
||||
SDL_GameControllerName(controller),
|
||||
SDL_JoystickGetType(SDL_GameControllerGetJoystick(controller)),
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 12)
|
||||
|
@ -434,10 +493,11 @@ void SDLInputDriver::OnControllerDeviceAdded(const SDL_Event& event) {
|
|||
#endif
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 6)
|
||||
SDL_GameControllerGetVendor(controller),
|
||||
SDL_GameControllerGetProduct(controller));
|
||||
SDL_GameControllerGetProduct(controller),
|
||||
#else
|
||||
"?", "?");
|
||||
"?", "?",
|
||||
#endif
|
||||
guid_str);
|
||||
int user_id = -1;
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 9)
|
||||
// Check if the controller has a player index LED.
|
||||
|
@ -468,6 +528,8 @@ void SDLInputDriver::OnControllerDeviceAdded(const SDL_Event& event) {
|
|||
UpdateXCapabilities(state);
|
||||
|
||||
XELOGI("SDL OnControllerDeviceAdded: Added at index {}.", user_id);
|
||||
XELOGI("SDL Controller {}: {}", user_id,
|
||||
SDL_GameControllerMapping(controller));
|
||||
} else {
|
||||
// No more controllers needed, close it.
|
||||
SDL_GameControllerClose(controller);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <optional>
|
||||
|
||||
#include "SDL.h"
|
||||
#include "third_party/rapidcsv/src/rapidcsv.h"
|
||||
#include "xenia/hid/input_driver.h"
|
||||
|
||||
#define HID_SDL_USER_COUNT 4
|
||||
|
@ -35,6 +36,8 @@ class SDLInputDriver final : public InputDriver {
|
|||
|
||||
X_STATUS Setup() override;
|
||||
|
||||
void LoadGameControllerDB();
|
||||
|
||||
X_RESULT GetCapabilities(uint32_t user_index, uint32_t flags,
|
||||
X_INPUT_CAPABILITIES* out_caps) 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