If libusb fails to initialize, an assertion fails, but if that happens before the main window is created, then Dolphin just dies. Now, the panic alert is properly shown and the user can ignore it.
SPDX standardizes how source code conveys its copyright and licensing
information. See https://spdx.github.io/spdx-spec/1-rationale/ . SPDX
tags are adopted in many large projects, including things like the Linux
kernel.
Unfortunately, it appears that using libusb's synchronous transfer API
from several threads causes nasty race conditions in event handling and
can lead to deadlocks, despite the fact that libusb's synchronous API
is documented to be perfectly fine to use from several threads (only
the manual polling functionality is supposed to require special
precautions).
Since usbdk was the only real reason for using a single libusb context
and since usbdk (currently) has so many issues with Dolphin, I think
dropping support for it in order to fix other backends is acceptable.
Avoids dragging in IniFile, EXI device and SI device headers in this header which is
quite widely used throughout the codebase.
This also uncovered a few cases where indirect inclusions were being
relied upon, which this also fixes.
If opening the adapter fails, report the libusb error message in the GUI
instead of “No Adapter Detected”.
The error condition is removed when the adapter is unplugged.
* Simplifies libusb context usage and allows us to set options for
all contexts easily. Notably, this lets us enable usbdk support
in libusb, which is now opt-in in the latest version.
* Moves the libusb config descriptor wrapper class to LibusbUtils too
since that could easily be reused.
* Moves device listing to LibusbUtils too and add a lock around it
as some libusb backends are not thread safe.
* Consequences: only a single context and a single event handling
thread is used now, which is more efficient.
This is only ever queried and not set outside of the Core.cpp, so this
should just be hidden internally and just have a function exposed that
allows querying it.
Places all of the SI code under the SerialInterface namespace instead of
only the main source file. This keeps all SI code under a common name,
as well as out of the global 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.
make sure Reset() can’t be run concurrently with AddGCAdapter() or
ResetRumble() (which is called on other threads) which can cause
crashes (issue #9462)
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.
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.