mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-08-09 01:29:23 +00:00
input: add controller index to SDL controllers
This commit is contained in:
parent
84d2ad70e6
commit
b436d2a7f4
3 changed files with 83 additions and 10 deletions
|
@ -43,7 +43,7 @@ struct pad_list_entry
|
||||||
bool is_buddy_only = false;
|
bool is_buddy_only = false;
|
||||||
|
|
||||||
explicit pad_list_entry(std::string _name, bool _is_buddy_only)
|
explicit pad_list_entry(std::string _name, bool _is_buddy_only)
|
||||||
: name(_name), is_buddy_only(_is_buddy_only)
|
: name(std::move(_name)), is_buddy_only(_is_buddy_only)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -355,12 +355,67 @@ void sdl_pad_handler::enumerate_devices()
|
||||||
|
|
||||||
if (SDLDevice::sdl_info info = get_sdl_info(i); info.game_controller)
|
if (SDLDevice::sdl_info info = get_sdl_info(i); info.game_controller)
|
||||||
{
|
{
|
||||||
std::string name = info.name;
|
|
||||||
std::shared_ptr<SDLDevice> dev = std::make_shared<SDLDevice>();
|
std::shared_ptr<SDLDevice> dev = std::make_shared<SDLDevice>();
|
||||||
dev->sdl = std::move(info);
|
dev->sdl = std::move(info);
|
||||||
m_controllers[std::move(name)] = std::move(dev);
|
|
||||||
|
// Count existing real devices with the same name
|
||||||
|
u32 device_count = 1; // This device also counts
|
||||||
|
for (const auto& controller : m_controllers)
|
||||||
|
{
|
||||||
|
if (controller.second && !controller.second->sdl.is_virtual_device && controller.second->sdl.name == dev->sdl.name)
|
||||||
|
{
|
||||||
|
device_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add real device
|
||||||
|
const std::string device_name = fmt::format("%s %d", dev->sdl.name, device_count);
|
||||||
|
m_controllers[device_name] = std::move(dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<SDLDevice> sdl_pad_handler::get_device_by_game_controller(SDL_GameController* game_controller) const
|
||||||
|
{
|
||||||
|
if (!game_controller)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
const char* name = SDL_GameControllerName(game_controller);
|
||||||
|
const char* path = SDL_GameControllerPath(game_controller);
|
||||||
|
const char* serial = SDL_GameControllerGetSerial(game_controller);
|
||||||
|
|
||||||
|
// Try to find a real device
|
||||||
|
for (const auto& controller : m_controllers)
|
||||||
|
{
|
||||||
|
if (!controller.second || controller.second->sdl.is_virtual_device)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const auto is_same = [](const char* c, std::string_view s) -> bool
|
||||||
|
{
|
||||||
|
return c ? c == s : s.empty();
|
||||||
|
};
|
||||||
|
|
||||||
|
if (is_same(name, controller.second->sdl.name) &&
|
||||||
|
is_same(path, controller.second->sdl.path) &&
|
||||||
|
is_same(serial, controller.second->sdl.serial))
|
||||||
|
{
|
||||||
|
return controller.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to find a virtual device if we can't find a real device
|
||||||
|
for (const auto& controller : m_controllers)
|
||||||
|
{
|
||||||
|
if (!controller.second || !controller.second->sdl.is_virtual_device)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (name && controller.second->sdl.name.starts_with(name))
|
||||||
|
{
|
||||||
|
return controller.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<PadDevice> sdl_pad_handler::get_device(const std::string& device)
|
std::shared_ptr<PadDevice> sdl_pad_handler::get_device(const std::string& device)
|
||||||
|
@ -376,6 +431,7 @@ std::shared_ptr<PadDevice> sdl_pad_handler::get_device(const std::string& device
|
||||||
// Add a virtual controller until it is actually attached
|
// Add a virtual controller until it is actually attached
|
||||||
std::shared_ptr<SDLDevice> dev = std::make_unique<SDLDevice>();
|
std::shared_ptr<SDLDevice> dev = std::make_unique<SDLDevice>();
|
||||||
dev->sdl.name = device;
|
dev->sdl.name = device;
|
||||||
|
dev->sdl.is_virtual_device = true;
|
||||||
m_controllers.emplace(device, dev);
|
m_controllers.emplace(device, dev);
|
||||||
sdl_log.warning("Adding empty device: %s", device);
|
sdl_log.warning("Adding empty device: %s", device);
|
||||||
|
|
||||||
|
@ -418,9 +474,24 @@ PadHandlerBase::connection sdl_pad_handler::update_connection(const std::shared_
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const char* name = SDL_GameControllerNameForIndex(i))
|
// Get game controller
|
||||||
|
SDL_GameController* game_controller = SDL_GameControllerOpen(i);
|
||||||
|
if (!game_controller)
|
||||||
{
|
{
|
||||||
if (dev->sdl.name == name)
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find out if we already know this controller
|
||||||
|
std::shared_ptr<SDLDevice> sdl_device = get_device_by_game_controller(game_controller);
|
||||||
|
if (!sdl_device)
|
||||||
|
{
|
||||||
|
// Close the game controller if we don't know it.
|
||||||
|
SDL_GameControllerClose(game_controller);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-attach the controller if the device matches the current one
|
||||||
|
if (sdl_device.get() == dev)
|
||||||
{
|
{
|
||||||
if (SDLDevice::sdl_info info = get_sdl_info(i); info.game_controller)
|
if (SDLDevice::sdl_info info = get_sdl_info(i); info.game_controller)
|
||||||
{
|
{
|
||||||
|
@ -430,7 +501,6 @@ PadHandlerBase::connection sdl_pad_handler::update_connection(const std::shared_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return connection::disconnected;
|
return connection::disconnected;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,8 @@ public:
|
||||||
u16 product_version = 0;
|
u16 product_version = 0;
|
||||||
u16 firmware_version = 0;
|
u16 firmware_version = 0;
|
||||||
|
|
||||||
|
bool is_virtual_device = false;
|
||||||
|
|
||||||
bool has_led = false;
|
bool has_led = false;
|
||||||
bool has_rumble = false;
|
bool has_rumble = false;
|
||||||
bool has_rumble_triggers = false;
|
bool has_rumble_triggers = false;
|
||||||
|
@ -112,6 +114,7 @@ private:
|
||||||
std::map<std::string, std::shared_ptr<SDLDevice>> m_controllers;
|
std::map<std::string, std::shared_ptr<SDLDevice>> m_controllers;
|
||||||
|
|
||||||
void enumerate_devices();
|
void enumerate_devices();
|
||||||
|
std::shared_ptr<SDLDevice> get_device_by_game_controller(SDL_GameController* game_controller) const;
|
||||||
|
|
||||||
std::shared_ptr<PadDevice> get_device(const std::string& device) override;
|
std::shared_ptr<PadDevice> get_device(const std::string& device) override;
|
||||||
PadHandlerBase::connection update_connection(const std::shared_ptr<PadDevice>& device) override;
|
PadHandlerBase::connection update_connection(const std::shared_ptr<PadDevice>& device) override;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue