diff --git a/src/hooks_textures.cpp b/src/hooks_textures.cpp index 7ce094e..bbda9c7 100644 --- a/src/hooks_textures.cpp +++ b/src/hooks_textures.cpp @@ -593,14 +593,6 @@ class TextureReplacement : public Hook } }; - inline static const char* padTypes[] = // Must match the Game::GamepadType enum! - { - "PC", - "Xbox", - "PlayStation", - "Switch" - }; - inline static const char* padType = nullptr; static void HandleTexture(void** ppSrcData, UINT* pSrcDataSize, std::filesystem::path texturePackName, bool isUITexture) @@ -632,9 +624,11 @@ class TextureReplacement : public Hook { // TODO: switching textures during gameplay (eg. from Xbox -> PC due to controller disconnect) will cause corruption ;_; // instead we'll have to track the first pad-type we switched to, and always use that for the session - if (Game::PadType != Game::GamepadType::PC && padType == nullptr) [[unlikely]] + if (padType == nullptr && (Game::CurrentPadType != Game::GamepadType::None || Game::ForcedPadType != Game::GamepadType::None)) { - padType = padTypes[int(Game::PadType)]; + auto type = (Game::ForcedPadType != Game::GamepadType::None) ? Game::ForcedPadType : Game::CurrentPadType; + if (type != Game::GamepadType::PC) + padType = Game::PadTypes[int(type)]; } usePadDirectory = padType != nullptr; @@ -652,6 +646,10 @@ class TextureReplacement : public Hook path_load = XmtLoadPath / texturePackName.filename().stem() / padType / ddsNameIndexed; if (!FileSystem.exists(path_load)) path_load = XmtLoadPath / texturePackName.filename().stem() / padType / ddsName; + if (!FileSystem.exists(path_load)) + path_load = XmtLoadPath / padType / texturePackName.filename().stem() / ddsNameIndexed; + if (!FileSystem.exists(path_load)) + path_load = XmtLoadPath / padType / texturePackName.filename().stem() / ddsName; if (!FileSystem.exists(path_load)) path_load = XmtLoadPath / padType / ddsNameIndexed; if (!FileSystem.exists(path_load)) diff --git a/src/input_manager.cpp b/src/input_manager.cpp index 5fbf3e3..113a543 100644 --- a/src/input_manager.cpp +++ b/src/input_manager.cpp @@ -269,6 +269,19 @@ class InputManager return controllers[primaryControllerIndex]; } + void set_primary_gamepad(int index) + { + if (index < 0 || index >= controllers.size()) + primaryControllerIndex = -1; + else + primaryControllerIndex = index; + + spdlog::debug("InputManager::primaryControllerIndex = {}", primaryControllerIndex); + + if (auto* pad = primary_gamepad()) + setupGamepad(pad); + } + void init(HWND hwnd) { SDL_SetHint(SDL_HINT_JOYSTICK_RAWINPUT, "0"); @@ -376,20 +389,20 @@ class InputManager void setupGamepad(SDL_Gamepad* controller) { - Game::PadType = Game::GamepadType::Xbox; + Game::CurrentPadType = Game::GamepadType::Xbox; auto type = SDL_GetGamepadType(controller); switch (type) { case SDL_GAMEPAD_TYPE_PS3: case SDL_GAMEPAD_TYPE_PS4: case SDL_GAMEPAD_TYPE_PS5: - Game::PadType = Game::GamepadType::PS; + Game::CurrentPadType = Game::GamepadType::PS; break; case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_LEFT: case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT: case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_JOYCON_PAIR: case SDL_GAMEPAD_TYPE_NINTENDO_SWITCH_PRO: - Game::PadType = Game::GamepadType::Switch; + Game::CurrentPadType = Game::GamepadType::Switch; break; }; } @@ -417,12 +430,9 @@ class InputManager controllers.push_back(controller); + // If we don't have primary already, set it as this if (primaryControllerIndex == -1) - { - primaryControllerIndex = controllers.size() - 1; - spdlog::debug("InputManager::primaryControllerIndex = {}", primaryControllerIndex); - setupGamepad(controller); // Bind inputs to the new primary controller - } + set_primary_gamepad(controllers.size() - 1); } void onControllerRemoved(SDL_JoystickID instanceId) @@ -438,7 +448,7 @@ class InputManager if (it != controllers.end()) { - Game::PadType = Game::GamepadType::PC; + Game::CurrentPadType = Game::GamepadType::PC; SDL_CloseGamepad(*it); controllers.erase(it); @@ -446,16 +456,7 @@ class InputManager spdlog::debug(__FUNCTION__ "(instance {}): removed instance", instanceId); if (primaryControllerIndex >= controllers.size()) - { - if (controllers.empty()) - primaryControllerIndex = -1; - else - { - primaryControllerIndex = 0; - setupGamepad(controllers[primaryControllerIndex]); // Rebind inputs to next available controller - } - spdlog::debug("InputManager::primaryControllerIndex = {}", primaryControllerIndex); - } + set_primary_gamepad(controllers.empty() ? -1 : 0); } } @@ -872,10 +873,7 @@ class InputManager std::string name = SDL_GetGamepadName(controller); if(ImGui::Button(name.c_str())) - { - primaryControllerIndex = i; - setupGamepad(controller); - } + set_primary_gamepad(i); ImGui::TableNextColumn(); @@ -890,7 +888,6 @@ class InputManager ImGui::Separator(); - // Analog Controls Table if (ImGui::CollapsingHeader("Controls", ImGuiTreeNodeFlags_DefaultOpen)) { if (ImGui::BeginTable("VolumeBindings", 3, ImGuiTableFlags_Borders)) @@ -1016,6 +1013,7 @@ class InputManager { SwitchId switchId = SwitchId(i); + // TODO: scan through games SwitchOn/SwitchNow calls and see if these are ever used if (switchId == SwitchId::Unknown0x100 || switchId == SwitchId::Unknown0x200 || switchId == SwitchId::Unknown0x10000 || switchId == SwitchId::Unknown0x20000) { diff --git a/src/plugin.hpp b/src/plugin.hpp index 9d9868f..2d4ae5f 100644 --- a/src/plugin.hpp +++ b/src/plugin.hpp @@ -49,18 +49,29 @@ namespace Game { enum class GamepadType { + None, PC, Xbox, PS, Switch }; + inline static const char* PadTypes[] = + { + "None", + "PC", + "Xbox", + "PlayStation", + "Switch" + }; + inline std::chrono::system_clock::time_point StartupTime; inline float DeltaTime = (1.f / 60.f); inline bool DrawDistanceDebugEnabled = false; - inline GamepadType PadType = GamepadType::PC; + inline GamepadType CurrentPadType = GamepadType::PC; + inline GamepadType ForcedPadType = GamepadType::None; }; namespace Settings