| 20 | #endif |
| 21 | |
| 22 | ControllerPtr ControllerFactory::CreateController(InputAPI::Type api, std::string_view uuid, |
| 23 | std::string_view display_name) |
| 24 | { |
| 25 | switch (api) |
| 26 | { |
| 27 | #if HAS_KEYBOARD |
| 28 | case InputAPI::Keyboard: |
| 29 | return std::make_shared<KeyboardController>(); |
| 30 | #endif |
| 31 | #if HAS_DIRECTINPUT |
| 32 | case InputAPI::DirectInput: |
| 33 | { |
| 34 | GUID guid; |
| 35 | // Workaround for mouse2joystick users, which has 0 as it's uuid in it's profile and counts on Cemu applying it to the first directinput controller. GUIDFromString also doesn't allow for invalid uuids either. |
| 36 | if (uuid == "0") |
| 37 | { |
| 38 | const auto provider = InputManager::instance().get_api_provider(InputAPI::DirectInput); |
| 39 | const auto controllers = provider->get_controllers(); |
| 40 | if (controllers.empty()) |
| 41 | throw std::invalid_argument(fmt::format( |
| 42 | "can't apply non-uuid-specific directinput profile when no controllers are available")); |
| 43 | if (!GUIDFromString(controllers.front()->uuid().c_str(), guid)) |
| 44 | throw std::invalid_argument(fmt::format("invalid guid format: {}", uuid)); |
| 45 | } |
| 46 | else |
| 47 | { |
| 48 | if (!GUIDFromString(uuid.data(), guid)) |
| 49 | throw std::invalid_argument(fmt::format("invalid guid format: {}", uuid)); |
| 50 | } |
| 51 | |
| 52 | return std::make_shared<DirectInputController>(guid); |
| 53 | } |
| 54 | #endif |
| 55 | #if HAS_XINPUT |
| 56 | case InputAPI::XInput: |
| 57 | { |
| 58 | const auto index = ConvertString<uint32>(uuid); |
| 59 | return std::make_shared<XInputController>(index); |
| 60 | } |
| 61 | #endif |
| 62 | #if HAS_SDL |
| 63 | case InputAPI::SDLController: |
| 64 | { |
| 65 | // diid_guid |
| 66 | const auto index = uuid.find_first_of('_'); |
| 67 | if (index == std::string_view::npos) |
| 68 | throw std::invalid_argument(fmt::format("invalid sdl uuid format: {}", uuid)); |
| 69 | |
| 70 | const auto guid_index = ConvertString<size_t>(uuid.substr(0, index)); |
| 71 | const auto guid = SDL_JoystickGetGUIDFromString(std::string{uuid.substr(index + 1)}.c_str()); |
| 72 | |
| 73 | if (display_name.empty()) |
| 74 | return std::make_shared<SDLController>(guid, guid_index); |
| 75 | else |
| 76 | return std::make_shared<SDLController>(guid, guid_index, display_name); |
| 77 | } |
| 78 | #endif |
| 79 | #if HAS_DSU |
nothing calls this directly
no test coverage detected