Better separation of concerns. Relegates `ControllerInterface` to
enumerating input controls, and the new `ControlReference` deals with
combining inputs and configuration expression parsing.
ControllerEmu is a massive class with a lot of nested public classes.
The only reason these are nested is because the outer class acts as a
namespace. There's no reason to keep these classes nested just for that.
Keeping these classes nested makes it impossible to forward declare them, which leads to quite a few includes in other headers, making compilation take
longer.
This moves the source files to their own directory so classes can be
separated as necessary to their own source files, and be namespaced under the
ControllerEmu namespace.
libusb on Windows is limited to only a single context. Trying to open
more than one can cause device enumerations to fail randomly.
libusb is thread-safe and we don't use the manual polling support (with
`poll()`) so this should be safe.
GetName() creates a new evdev device which calls tons of ioctls. But the
main culprit is close() which for input devices appears to be a slow
path in the kernel.
This commit reduces PopulateDevices() by 50% on my laptop, but ~730 ms
is still ridiculously slow for something that isn't needed right away.
The SDL backend crashes when you close a joystick after SDL_Quit has
been called. Some backends don't need to be shutdown and
re-initialized everytime, we can just ask to enumerate devices again.
Removed the unecessary forced tabbed layout, removed the layout part of the constructor and remade some method in preparation for tabbed styled input dialog such as the new hotkey configuration one. It breaks every inputconfigDialog, but this will get fixed in the next commits.
Also moved to a folder since there will be many more files created in the next commits so it gives better separation.
For hotkeys, changed HotkeyManager to allow to get and make partial groups of hotkeys.
Also preserved the old configuration naming scheme for the ini, this is done to preserve compatibility with the older groups structure.
Add the ability to get GCPad control groups
Used like the HotkeyManager methods, this is used for the new GCPad configuration dialog.
Add the ability to get groups of Keyboard input
Same reasons as the previous ones.
Add ability to get groups of Wiimote input
Add the ability to get extensions group
This needed to pass to 3 classes. Will be used for their respective dialogs.
This adds a recenter control binding which allows recentering the
cursor when relative input is enabled.
(EnableSettingControl is renamed to avoid confusions.)
This adds an option to enable relative input for the Wiimote IR
as described in issue 9014.
Enabling it will result in the pointer not going back to the centre
and the inputs will control the direction, not the absolute position.
Also adds a Dead Zone setting which is really needed when relative
input is enabled to prevent the cursor from slowly drifting on
most controllers. (Note: the Deadzone setting has no effect when
relative input is disabled)
Rewrite GetXInputGUIDS to use SetupAPI instead of WMI Queries. When
using a language pack where the system language and user/program
language differ, Windows starts taking a VERY long time (10+ seconds)
to complete Queries for Win32_PNPEntity objects (it's probably
translating every single string since it transfers every single one
from the WMI server into memory in the program).
Fixes Issue 9744.
There is no reason to prevent the user from closing the config dialog
if the device is not found. It's not very good UX…
Also fixes ExpressionParser to return NO_DEVICE if the device doesn't
exist instead of SUCCESS.
This adds hotplugging support to the evdev input backend. We use
libudev to monitor changes to input devices in a separate thread.
Removed devices are removed from the devices list, and new devices
are added to the list.
The effect is that controllers are usable immediately after plugging
them without having to manually refresh devices (if they were
configured to be used, of course).
Changes UpdateInput() to skip if we can't lock the mutex, instead of
potentially blocking the CPU thread and causing a short but noticeable
frame drop.
This adds RemoveDevice() to ControllerInterface, fixes ExpressionParser
and some other code to support device removals without crashing,
and adds an IsValid() method to Device, to prepare for hotplugging.
This adds RegisterHotplugCallback() to register a callback which will
be invoked by the input backends' hotplug threads when there is a new
device, so that Core (GCKeyboard, GCPad, Wiimote, Hotkey) can reload
the configuration without adding a dependency to Core from InputCommon.
This fixes warnings in:
- Source/Core/InputCommon/ControllerEmu.h: avoid shadowing other
variables (my fault)
- Source/Core/Core/IPC_HLE/WII_IPC_HLE.h: made
SDIO_EventNotify_CPUThread static as it's not used anywhere else
This makes the device ID assigning code common to all backends, by
moving it to AddDevice() instead of copy-pasting or replicating
the logic in the backends.
Also, to prepare for hotplugging, instead of relying on a name usage
count, the new ID assigning system always starts from ID 0 and tries
to assign the first ID that is not used.
The Setting class was used for both numeric values and booleans, and
other parts of the code had hacks to make it work with booleans.
By splitting Setting into NumericSetting and BooleanSetting, it is
clear which settings are numeric, and which are boolean, so there is
no need to guess by checking the default values or anything like that.
Also, booleans are stored as booleans in config files, instead of 1.0.
The values are expected to be in the 0.0-1.0 range (as indicated by the
comment), and other parts of Dolphin also expect it to be in that range
since the "full" axis has a -1.0 to 1.0 range. However, this is not
always the case and fvalue can end up being outside of the range. This
clamps fvalue to always be in the 0.0 and 1.0 range.
Small cleanup by using std::shared_ptr and getting rid of
ciface.Devices() which just returned the m_devices (which defeats the
point of making m_devices protected).
Incidentally, this should make the code safer when we have
different threads accessing devices in the future (for hotplug?).
A lot of code use Device references directly so there is
no easy way to remove FindDevice() and make those unique_ptrs.
Previously, the devices vector would be passed to all backends. They
would then manually push_back to it to add new devices. This was fine
but caused issues when trying to add synchronisation.
Instead, backends now call AddDevice() to fill m_devices so that it is
not accessible from the outside.
make sure Reset() can’t be run concurrently with AddGCAdapter() or
ResetRumble() (which is called on other threads) which can cause
crashes (issue #9462)
Disclaimer: I can't test if this works on xbox one controllers, i don't have one. But i have conformed that this UpdateMotors() is related to rumble for emulated wiimotes.
This partially reverts commit "XInput: Apply immediately as well" (1958a10b6f) from pr # https://github.com/dolphin-emu/dolphin/pull/1560
Hopefully this fixes the xbox one controller rumble issue:
https://bugs.dolphin-emu.org/issues/9071
And in theory it might reduce the used usb bandwidth, as it was originally intended before pr 1560.
@JMC47: Please do a good amount of testing, to see if this breaks rumble for wiimotes or gamecube controllers emulated with xinput devices.
Under failure conditions of the GC Adapter, When interface count is zero and we can't open the device.
Then there were race conditions on shutdown of the threads which could result in crashing.
Make adapter opening more robust like the Mayflash DolphinBar.
Make shutdown more robust by making the read thread control the write thread.
Make sure that there is actual data to be written when kicking the write thread. So it doesn't attempt a write a shutdown.
Make a toast on screen to tell the user that the adapter needs to be unplugged and plugged back in again for it to work.
Previously we would iterate through every GC adapter plugged in to the PC and steal ownership of it.
This causes issues all over the place in the implementation if this happens.
Break on the first adapter we can get access to.
No way to properly enable it from an end user perspective yet.
Doesn't require root.
This same sort of system can be used for the Dolphinbar in the future for real wiimote support.
The Wii U Gamecube controller adapter setup has always been a bit weird. It tries to be as automatic as possible to make the user experience as easy
as possible.
The problem with this approach is that it brings a large disconnect in the user experience because you have the Gamecube controller setup with regular
gamepads and then for some reason below that you have a "direct connect" option which will cause the Gamecube Adapter to overwrite the regular inputs
if something was connected.
While this works and allows the user to only click one checkbox to get the device working, it breaks the user's experience because they don't really
know what "direct connect" means and won't look it up to figure out what it is. Just expecting the device to work (At least one occurence of this in
the IRC channel in the last week).
This way around also had the terrible nature of making the code more filthy than it needed to be. The GCAdapter namespace was parasitic and hooked in
to the regular GC Controller SI class to overwrite the data that it was getting from the default configuration.
Now instead we have a specific SIDevice class for the Wii U Gamecube adapter. This class is fairly simple and is a child of the regular SI Gamecube
Pad device and only reimplements what it needs to.
This also gives the ability to configure controllers individually, which allows the user to configure rumble individually per pad input.
Overall the code is cleaner, and it fits more in line with how the rest of Dolphin works.
Lets the user set the following in intervals of 10 between 10 and 100;
- Stick/Radius (default 100,000000)
- Triggers/Threshold (default 90,000000)
- Tilt/Modifier/Range (default 50,000000) + mapped Tilt/Modifier button
to the configurations for wiimotes & nunchuks
If there were two commands in the buffer at once, it would only run the
first because of an error in UpdateInput.
If you sent the command "SET C" it would segfault because of a logic
issue in ParseCommand.
Currently only works on unix, but can be extended to other systems. Can
also be extended to do wiimotes.
Searches the Pipes folder for readable named pipes and creates a dolphin
input device out of them. Send controller inputs to the game by writing
to the file. Commands are described in Pipes.h.
Main Stick is changed to Control Stick and C-Stick is changed to C Stick.
A new ui_name variable is added to ControlGroup so that the UI strings
in DolphinWX can be updated without breaking backwards compatibility
with config INIs and other things that use names as IDs.
Previously, MacOpenFile only overrode anything on OS X; otherwise it was
just a useless method, which is presumably why it wasn't marked override
in the first place. Address this more sanely by wrapping it in #ifdef
__APPLE__.
Using SDL_INIT_JOYSTICK implies SDL_INIT_EVENTS which installs a signal
handler for SIGINT and SIGTERM. There will be a way to prevent this in
2.0.4 but for now we'll need to handle SDL_QUIT.
- Simplified the locking mechanism when controllers were updated
- Reloaded the config of the controls instead of re-initialising the control plugins
- Fixed controls being unresponsive after the Refresh button was pressed
- Disables the hotkeys while the controller config is open
My keyboard layout does not have Alt_R but ISO_Level3_Shift. As a
consequence any control expression containing Alt_R fails to evaluate
completely and is unusable. This modification replace the missing term
of the expression by a dummy expression which always evaluate to
0. This way, the keybinding can work even if some keys are not
available.
We can compile with haptic support, and then not initialize due to haptics not being available.
So if we are compiling with haptics, test initializing with haptics and if that fails attempt to initialize without haptics before bailing out.
I'm not sure when this nonsense of forcing locking the mutex when it's
already taken should have ever taken effect, but let's be thankful it
isn't now. That was a badly worded sentence.
This is good hygiene, and also happens to be required to build Dolphin
using Clang modules.
(Under this setup, each header file becomes a module, and each #include
is automatically translated to a module import. Recursive includes
still leak through (by default), but modules are compiled independently,
and can't depend on defines or types having previously been set up. The
main reason to retrofit it onto Dolphin is compilation performance - no
more textual includes whatsoever, rather than putting a few blessed
common headers into a PCH. Unfortunately, I found multiple Clang bugs
while trying to build Dolphin this way, so it's not ready yet, but I can
start with this prerequisite.)
Initialize now just takes the handle directly. Reinitialize is added because it is much more straightforward in comparison to doing the Shutdown-Initialize manually.
Added the option to handle whether the user wants to iterate through the
assignment of button mappings or assign them one at a time.
fixed formatting issues and code style.
I excluded this option from the config file. This stopped the check box value and the boolean from becoming offset. Since the option should always start as false.
This still causes an issue with the Wiimote input, since the class variable that keeps the state will be wiped, but the check box value will stay the same after closing/reopening without closing the entire Wiimote configuration. I am looking for a way to resolve this.
I also reduced wait time to 2.5 seconds vs. the 5 seconds previously. Seemed to be a little long.
These changes apparently did not go through.
This should fix the Wiimote issue.
strictStrings is not supported by debug libraries, and indeed breaks the build.
Drop wbemidl.h (incompatible with strictStrings) dependency by using SDL-style search for XInput GUIDs.
Yes, this is a fancy new feature, but our Wayland support was
particularly bitrotten, and ideally this would be handled by a platform
layer like SDL. If not, we can always add this back in when GLInterface
has caught up. We might be able to even support wxWidgets and GL
together with subsurfaces!
It was broken by e15ec56bf0 because it wasn't deemed important. However chances are people will eventually start using Dolphin on that configuration, so we shouldn't frivolously drop compatibility without good reason.
It was only used for Windows XP and lower.
This also bumps the _WIN32_WINNT define in the stdafx precompiled headers to set the minimum version as Windows Vista.
We can't use RendererHasFocus for this purpose because of some issues
with exclusive fullscreen, and the new RendererHasFocus implementation
didn't work for non-Render to Main Window cases, since the renderer
window wasn't managed by wx.
This will allow us to simplify the checks for background input and push
them further down into the architecture, into the ControllerEmu layer.
The new setting isn't actually used yet, though.
Do the scaling in the code that interprets the results.
This also removes the templatization of things and changes the interface
to always take a double.
This does add a bit more code to the users of GetState, especially when
having to deal with focus management, but this will be cleaned up very
soon, as focus and focus-related options will be centralized inside the
input platforms themselves, rather than spread out across all the input
plugins.