New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor GCAdapter, part 1 #10604
Refactor GCAdapter, part 1 #10604
Conversation
|
I'm dropping b84b146, as it still causes issues with the freebsd builder. |
76a12e2
to
6f0d855
Compare
|
Working fine on macOS Catalina x86_64. |
6f0d855
to
f94d28b
Compare
|
tbh i think splicing 2 files into 1 with a bunch of #ifdefs is a step backward. |
|
I think the current 2-file version with large amounts of overlapping code is pretty bad, especially since the different files diverged for various bugfixes and other behaviors. But it would make sense to eventually split out the libusb and android code into other files, once everything else is merged nicely. Code like #ifndef ANDROID
if (s_handle == nullptr)
return;
#else
if (!s_detected || !s_fd)
return;
#endifis something that I wouldn't want to keep permanently, but is a bit awkward to merge together. (I'm also not sure what the deal is with |
f94d28b
to
18a743c
Compare
|
The Ideally I think we'd want an interface for the basic libusb functionality with Android/PC implementations. |
|
This fixes LibUSB issues on certain hardware, so we should probably get this cleaned up and reviewed. |
|
Tested on Windows with the Super Smash Bros. GameCube Adapter for Wii U and MAYFLASH 2 Ports Wii U GC GameCube Controller Adapter for Wii U/PC. Adapter was detected in settings and controller was working as intended. |
18a743c
to
e2cc950
Compare
|
I've got an adapter now and have done some testing, and things seem good on Windows at least. I still need to test on Android, though. |
|
Tested again on macOS Catalina. Adapter working as it should. |
e2cc950
to
2cc944d
Compare
|
I did some testing with the CI build on android, and it seems to work fine there too (although it was a debug build so performance wasn't great). This PR is ready for review. |
|
This build works fine for me on windows and Android, forgot to comment. |
|
Need to look over the exit-early commit some more, not super familiar with the input code but from what I could tell all seems like a solid refactor. |
|
That commit's easier to look at if you disable whitespace ( |
|
Ah neat, did not know that was a thing. That is much easier to read! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not done reviewing but wanted to make some comments in case I didn't finish. Mostly nitpicky except for casting the type byte for each controller.
| #ifndef ANDROID | ||
| #include <libusb.h> | ||
| #else | ||
| #include <jni.h> | ||
| #endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] I think if-else statements are slightly easier to follow when the condition is positive:
#ifdef ANDROID
#include <jni.h>
#else
#include <libusb.h>
#endif
There are a few similar occurrences I would swap, if I'm not missing a reason to do it this way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was mostly trying to put the non-android code on the top (though there isn't a strong reason for doing so). I could add a second define for using the libusb implementation instead, or I could just swap them. Do you have any preference between these?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Almost called this out as well. I agree about the positiveness being more readable though I also feel like if statements are easier to read if the smaller block is on top.
As for using a second define or swap them, I don't personally have a preference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the long run I don't think it really matters because the plan is to split the android USB code and the libusb code into separate files again in a later PR (leaving the common logic in GCAdapter), so it doesn't really matter which comes first. I'll swap them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... actually, while trying to swap them, I've found that there are a lot of cases where it's #ifndef ANDROID without a corresponding #else (at least initially), so a second define is probably better (otherwise it'll just end up being a mix of #ifdef ANDROID and #ifndef ANDROID which is much more confusing than almost entirely #ifndef ANDROID).
| int err = libusb_interrupt_transfer(s_handle, s_endpoint_in, s_controller_payload_swap, | ||
| int err = libusb_interrupt_transfer(s_handle, s_endpoint_in, s_controller_payload_swap.data(), | ||
| sizeof(s_controller_payload_swap), &payload_size, 16); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
err can be const.
[Opinion/Bikeshed] Not that I expect anyone to be confused by err, but in the spirit of updating unnecessarily abbreviated names from old code this could be error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. I've also added a new fmt::formatter that calls libusb_strerror and libusb_error_name to improve the related log messages.
| static u8 s_controller_payload[37]; | ||
| static u8 s_controller_payload_swap[37]; | ||
| static std::array<u8, 37> s_controller_payload; | ||
| static std::array<u8, 37> s_controller_payload_swap; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since _swap and _copy are defined to have the same size as _payload, would it make sense to make that explicit with std::array<u8, s_controller_payload.size()>?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll create constexpr size_t CONTROLER_PAYLOAD_SIZE = 37 instead.
| // TODO: What do the other bits here indicate? Does casting to an enum like this make sense? | ||
| const auto type = static_cast<ControllerType>(controller_payload_copy[1 + (9 * chan)] >> 4); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't seen any explicit documentation on the adapter's protocol, so flagging this for anybody who knows it better.
From what I can tell everything else assumes 0 <= type <= 2 which implies the top two bits are 0. If that's not necessarily the case we need to deal with that somehow.
b27075c
to
bcb5969
Compare
| @@ -87,10 +87,14 @@ static std::array<u8, SerialInterface::MAX_SI_CHANNELS> s_controller_type = { | |||
| ControllerTypes::CONTROLLER_NONE, ControllerTypes::CONTROLLER_NONE}; | |||
| static std::array<u8, SerialInterface::MAX_SI_CHANNELS> s_controller_rumble{}; | |||
|
|
|||
| constexpr size_t CONTROLER_INPUT_PAYLOAD_EXPECTED_SIZE = 37; | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it make sense to move these above their respective usages (at least until there are extra scenarios where they are used) so as to improve readability?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They're already used in several places (both for declaring the variables and when reading into them), and IMO it's better to have them all together to highlight that the sizes are different (and that different sizes are used for rumble and init).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Untested. LGTM
This is mostly a brainless merge, #ifdef-ing anything that doesn't match between the two while preserving common logic. I didn't rename any variables (although similar ones do exist), but I did change one log that was ERROR on android and NOTICE elsewhere to just always be NOTICE. Further merging will follow.
I believe the setting already existed in the UI; it just wasn't implemented in GCAdapter_Android.cpp.
This hack was added in 8f0cbef, and the part of it in SI_DeviceGCAdapter is present on Android already, so I don't see any reason why this part doesn't apply to Android.
It was removed for non-android in 56239d1, and android already uses a separate thread, so presumably this isn't needed anymore.
This is only so that indentation is consistent with the non-android code.
This was done for Android in 6cc40b1.
bcb5969
to
6823b4d
Compare
In particular, the android and non-android versions are now in a single file, with the parts where they differ separated using the preprocessor. I also removed some old special cases, which may or may not be relevant.
I don't own a GC adapter, so this PR has not been tested at all (and thus I'm submitting it as a draft). Further work will probably be done as a separate PR.