mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2026-06-27 14:49:05 +00:00
Heyy everyone! Continuing my work on the input system overhaul, this PR is mainly focused around three new features : - Dynamic Input Swap - Device Profile Linking - Player Device Assignement What are these new features and why are they bundled in the same PR you might ask? - **Dynamic Input Swap** Is a new feature that, when enabled, allows the user to switch between multiple input devices, without having to return to the settings menu. This feature can be enabled at the bottom of the Input Settings menu, next to the "global input" checkbox. A nifty new tooltip has been added for clarity. - **Device Profile linking** : While working on Dynamic Input Swap, one issue arose, which was that Ryujinx would use that device’s Default profile, without the user being able to specify a specific profile to use on that specific device. This feature fixes that, by allowing the user to link a profile as the device’s Default. This means that this profile will be auto loaded when selecting that same device, both when connecting it to the emulator, and when using Dynamic Input Swap. This feature can be found next to the Device Profiles dropdown, and includes a nifty new tooltip. By default, the "default" profile is linked to any device. There also is a small icon to the right of the profile name’s Right to visualise which profile is linked. - **Player Device Assignement** : Another issue that arose while working on Dynamic Input Swap was that enabling the feature would render multi player configurations unusable. This new feature addresses this issue by adding a new menu, which allows the user to assign different Input Devices to different players. Inside this new menu, you also get the device’s linked profile and the list of which players are already assigned to which input device, below and to the right of the input device name, respectively. You also get an option to allow mapping the same input device to different players. ### Nerd Zone This PR adds a new player-level input routing layer on top of the existing `InputConfig` system. Previously, each player effectively had one active input config, tied to one device. Given Dynamic Input Swap needs more state than that, this PR introduces a persisted `PlayerInputAssignment` model, which stores the player index, whether Dynamic Input Swap is enabled or not, the list of assigned input devices and an optional profile name bound to each assigned device. The new assignment data lives coexists with the existing input configs instead of replacing them, which should keep the old single-device behavior intact when Dynamic Input Swap is disabled, while allowing dynamic players to own multiple devices. New configl types include: - `AssignedInputDevice` - `AssignedInputDeviceType` - `PlayerInputAssignment` - `PlayerInputAssignmentHelper` - `PlayerInputDeviceAssignmentItem` `PlayerInputAssignmentHelper` normalizes assignments, deduplicates device entries, preserves a primary device, and compares assignments for dirty-checking. On the runtime side, `NpadManager` now passes both the normal `InputConfig` and the player assignment to `NpadController`. When Dynamic Input Swap is disabled, Ryujinx switches to the old behavior : one player config opens one device. However, when it's enabled, `NpadController` opens every assigned keyboard/controller device it can resolve, tracks their state snapshots, and promotes the active source based on recent input. Dynamic swap currently follows a “last meaningful input wins” model (annotated in the code) : So if the keyboard produces new input, it becomes active; if an assigned controller produces new input, that controller becomes active; if the active device stops producing input and another assigned device is held/active, the active source can fall back; and if no device has produced input yet, the initial active source is chosen from the selected config and available assigned devices. Per-device profile binding is handled by storing the profile name on the assigned device entry. When a device is selected or resolved through Dynamic Input Swap, Ryujinx tries to load that bound profile for the matching device type. If the profile is missing, invalid, or explicitly `Default`, it falls back to the generated default config for that device type. The new restore-to-defaults behavior deliberately bypasses linked profiles. This means pressing the reset button loads the real generated Default profile for the currently selected device, not the profile linked to that device. The input settings UI now dirty-checks both the currently edited input config and the player input assignment state, meaning that assigning/unassigning devices, changing Dynamic Input Swap, or changing profile bindings correctly marks the page as modified -> in continuation of my previous efforts in #13 to clean up its behaviour. The Assigned Devices dialog is backed by the currently available keyboard/controller device list. It also checks other players’ persisted assignments so the UI can show which players already use a device. If duplicate assignment is disabled, devices already assigned to another dynamic-swap player are disabled for the current player. If no explicit player assignments exist yet, Ryujinx synthesizes a default assignment from the existing input config. Dynamic swap is disabled by default until the user enables it. ⚠️⚠️⚠️⚠️⚠️Caution : this PR is still a WIP; and while all features described above have been fully implemented, various issues still remain, notably inside the Player assignement menu, that are getting worked on. Additionally, little bug testing has been done across the emulator, so it is not guaranteed that this build will be bug free. Signed by : 🦫 With the very generous help and support from @neo 🤗 Reviewed-on: https://git.ryujinx.app/projects/Ryubing/pulls/125