nsyshid: add backends for cross platform USB passthrough support #950

Merged
ssievert42 merged 3 commits from nsyshid_backends into main 2023-09-18 20:27:40 -03:00
ssievert42 commented 2023-08-26 14:38:54 -04:00 (Migrated from github.com)

This introduces the concept of backends for nsyshid that implement USB functionality.

Backends can be attached / detached at runtime. It is possible for more than one backend to be active at the same time, for example one backend could provide real USB devices, while another provides emulated devices.

There are two backends included already: one using libusb and one using the native Windows HID API.

Note that I am not experienced at all when it comes to working with USB devices or libusb. Feedback and suggestions how to improve this are very welcome :)

This also adds a whitelist feature, to only expose devices that the emulated Wii U needs to know about. That whitelist stuff could absolutely be expanded to be user configurable, but for now the whitelist is just populated with some known devices.

The libusb backend works nicely on Linux with the Lego Dimensions portal :)
That is the only configuration I can test though.
Libusb is fetched with vcpkg and statically linked into the final binary - hopefully that isn't an issue, but it seems like mentioning libusb in the about dialog (where it automagically appears), should suffice.
On macOS the libusb backend is compiled in by default and may or may not work.
Currently there are still unimplemented methods in the libusb backend: setProtocol and setReport, but the Lego Dimensions portal seems to work fine without them. And I have no idea how they could be implemented.
One neat thing that is included in the libusb backend as well is hotplug support - having to restart the game because of a flaky USB connection drove me mad enough to add this.
For hotplug support there needs to be someone that regularily calls libusb_handle_events_completed. I did this with a separate thread. Sadly it seems like libusb doesn't support hotplug on Windows.

On Linux, to be able to use a device, one needs to add some udev rules. Running lsusb spits out all connected devices as well as their vendorId and productId. For example to use the Lego Dimensions portal, you'd need to create a file /etc/udev/rules.d/99-lego-dimensions-portal.rules with the following contents:

# allow applications to talk to the lego dimensions portal
# place this file in '/etc/udev/rules.d/'
# after that you need to reboot or run 'sudo udevadm control --reload' and replug the device for the rules to apply
SUBSYSTEM=="usb", ATTRS{idVendor}=="0e6f", ATTRS{idProduct}=="0241", MODE="0666"

The Windows HID backend is entirely untested, but should ideally work 🤞

Those backends can be enabled / disabled with the CMake flags:

  • ENABLE_NSYSHID_LIBUSB - enable libusb backend; default "on" and not specifiable if the Windows HID backend is enabled
  • ENABLE_NSYSHID_WINDOWS_HID - enable Windows HID backend; default "on" on Windows

So to use the libusb backend on Windows you'd need to pass -DENABLE_NSYSHID_WINDOWS_HID=OFF -DENABLE_NSYSHID_LIBUSB=ON to cmake. (Only disabling the Windows HID backend is enough as well.)

Ideally closes #275, but, as I said above, I can only test this myself with the Lego Dimensions portal on Linux.

Supersedes #946

@deReeperJosh what do you think, could you use this as a base for emulated devices? And should the libusb backend even be enabled on macOS?

Things that should be done before this can be merged, that I can't do myself (any help is greatly appreciated!):

  • test with more devices (do we need to add more to the whitelist?)
  • test on Windows with the Windows HID backend (there shouldn't be a noticable difference to before)
  • test on Windows with the libusb backend (may require the zadig drivers as mentioned here)
  • test on macOS
This introduces the concept of backends for nsyshid that implement USB functionality. Backends can be attached / detached at runtime. It is possible for more than one backend to be active at the same time, for example one backend could provide real USB devices, while another provides emulated devices. There are two backends included already: one using libusb and one using the native Windows HID API. Note that I am not experienced at all when it comes to working with USB devices or libusb. Feedback and suggestions how to improve this are very welcome :) This also adds a whitelist feature, to only expose devices that the emulated Wii U needs to know about. That whitelist stuff could absolutely be expanded to be user configurable, but for now the whitelist is just populated with some known devices. The libusb backend works nicely on Linux with the Lego Dimensions portal :) That is the only configuration I can test though. Libusb is fetched with vcpkg and statically linked into the final binary - hopefully that isn't an issue, but it seems like mentioning libusb in the about dialog (where it automagically appears), should suffice. On macOS the libusb backend is compiled in by default and may or may not work. Currently there are still unimplemented methods in the libusb backend: `setProtocol` and `setReport`, but the Lego Dimensions portal seems to work fine without them. And I have no idea how they could be implemented. One neat thing that is included in the libusb backend as well is hotplug support - having to restart the game because of a flaky USB connection drove me mad enough to add this. For hotplug support there needs to be someone that regularily calls libusb_handle_events_completed. I did this with a separate thread. Sadly it seems like libusb doesn't support hotplug on Windows. On Linux, to be able to use a device, one needs to add some udev rules. Running `lsusb` spits out all connected devices as well as their vendorId and productId. For example to use the Lego Dimensions portal, you'd need to create a file /etc/udev/rules.d/99-lego-dimensions-portal.rules with the following contents: ``` # allow applications to talk to the lego dimensions portal # place this file in '/etc/udev/rules.d/' # after that you need to reboot or run 'sudo udevadm control --reload' and replug the device for the rules to apply SUBSYSTEM=="usb", ATTRS{idVendor}=="0e6f", ATTRS{idProduct}=="0241", MODE="0666" ``` The Windows HID backend is entirely untested, but should ideally work :crossed_fingers: Those backends can be enabled / disabled with the CMake flags: - `ENABLE_NSYSHID_LIBUSB` - enable libusb backend; default "on" and not specifiable if the Windows HID backend is enabled - `ENABLE_NSYSHID_WINDOWS_HID` - enable Windows HID backend; default "on" on Windows So to use the libusb backend on Windows you'd need to pass `-DENABLE_NSYSHID_WINDOWS_HID=OFF -DENABLE_NSYSHID_LIBUSB=ON` to cmake. (Only disabling the Windows HID backend is enough as well.) Ideally closes #275, but, as I said above, I can only test this myself with the Lego Dimensions portal on Linux. Supersedes #946 @deReeperJosh what do you think, could you use this as a base for emulated devices? And should the libusb backend even be enabled on macOS? Things that should be done before this can be merged, that I can't do myself (any help is greatly appreciated!): - [ ] test with more devices (do we need to add more to the whitelist?) - [ ] test on Windows with the Windows HID backend (there shouldn't be a noticable difference to before) - [ ] test on Windows with the libusb backend (may require the zadig drivers as mentioned [here](https://github.com/cemu-project/Cemu/pull/946#issuecomment-1691555362)) - [ ] test on macOS
deReeperJosh commented 2023-08-26 15:07:04 -04:00 (Migrated from github.com)

I think this should definitely be enabled for MacOS as well, libUSB works there as well (provided the device you want to use has a driver, otherwise the MacOS kernel claims it unless run with sudo)

I can help test on MacOS, and can eventually test the Skylanders Portal and the Disney Infinity Base

I think this should definitely be enabled for MacOS as well, libUSB works there as well (provided the device you want to use has a driver, otherwise the MacOS kernel claims it unless run with sudo) I can help test on MacOS, and can eventually test the Skylanders Portal and the Disney Infinity Base
ssievert42 commented 2023-08-29 15:03:53 -04:00 (Migrated from github.com)

The Windows build should be fixed now, at least Cemu builds and starts in my VM. On Windows, both the native Windows HID API backend and the libusb backend seem to work! 🎉
At least the Lego Dimensions portal lights up when using either of them, before Cemu crashes due to running in a VM with no proper OpenGL support.
The macOS build on the other hand... CI seems to fail somewhere in the process of vcpkg pulling in libusb and trying to build it, but without the logs that were written to some file on the runner (more specifically /Users/runner/work/Cemu/Cemu/dependencies/vcpkg/buildtrees/libusb/autoconf-x64-osx-err.log) it's really hard to tell where. I've disabled the libusb backend on macOS and made libusb only a dependency if we are not on osx for now.

The Windows build should be fixed now, at least Cemu builds and starts in my VM. On Windows, both the native Windows HID API backend and the libusb backend seem to work! :tada: At least the Lego Dimensions portal lights up when using either of them, before Cemu crashes due to running in a VM with no proper OpenGL support. The macOS build on the other hand... CI seems to fail somewhere in the process of vcpkg pulling in libusb and trying to build it, but without the logs that were written to some file on the runner (more specifically `/Users/runner/work/Cemu/Cemu/dependencies/vcpkg/buildtrees/libusb/autoconf-x64-osx-err.log`) it's really hard to tell where. I've disabled the libusb backend on macOS and made libusb only a dependency if we are not on osx for now.
ssievert42 (Migrated from github.com) reviewed 2023-08-29 15:08:17 -04:00
@ -4,2 +4,4 @@
#include <SetupAPI.h>
#pragma comment(lib, "Setupapi.lib")
#pragma comment(lib, "hid.lib")
ssievert42 (Migrated from github.com) commented 2023-08-29 15:08:17 -04:00

Otherwise the linker complains about undefined symbols, like for example HidD_GetAttributes.
Weirdly enough if I put those #pragma statements back in nsyshid.cpp everything links fine, but having them here seems like a cleaner solution.

Otherwise the linker complains about undefined symbols, like for example `HidD_GetAttributes`. Weirdly enough if I put those `#pragma` statements back in `nsyshid.cpp` everything links fine, but having them here seems like a cleaner solution.
ssievert42 commented 2023-08-31 07:58:48 -04:00 (Migrated from github.com)

Turns out to build libusb, you need to have autoconf automake libtool and m4 installed. Adding automake and libtool (which depend on autoconf and m4 respectively) allows the macOS build to succeed: https://github.com/ssievert42/Cemu/actions/runs/6035539753.

The AppImage that was generated by CI works nicely on Steam Deck with the Lego Dimensions portal, provided the udev rules I mentioned above are present :)

Something that puzzles me is that the Windows build doesn't need the zadig drivers for the libusb backend to work - at least in my VM.

Turns out to build libusb, you need to have `autoconf` `automake` `libtool` and `m4` installed. Adding `automake` and `libtool` (which depend on `autoconf` and `m4` respectively) allows the macOS build to succeed: https://github.com/ssievert42/Cemu/actions/runs/6035539753. The AppImage that was generated by CI works nicely on Steam Deck with the Lego Dimensions portal, provided the udev rules I mentioned above are present :) Something that puzzles me is that the Windows build doesn't need the zadig drivers for the libusb backend to work - at least in my VM.
ssievert42 commented 2023-09-02 05:37:00 -04:00 (Migrated from github.com)

Just tried to build the Flatpak and it fails :(
Since the Flatpak doesn't use vcpkg there is no libusb package that CMake can find - replacing:
dff33b36c7/src/Cafe/CMakeLists.txt (L533-L537)
with:

if (ENABLE_NSYSHID_LIBUSB)
    if (ENABLE_VCPKG)
        find_package(libusb CONFIG REQUIRED)
        target_include_directories(CemuCafe PRIVATE ${LIBUSB_INCLUDE_DIRS})
        target_link_libraries(CemuCafe PRIVATE ${LIBUSB_LIBRARIES})
    else ()
        target_link_libraries(CemuCafe PRIVATE usb-1.0)
    endif ()
endif ()

produces a working Flaptak; although hotplug seems to not work.

Would that change be enough to properly support building without vcpkg?

Just tried to build the Flatpak and it fails :( Since the Flatpak doesn't use vcpkg there is no `libusb` package that CMake can find - replacing: https://github.com/cemu-project/Cemu/blob/dff33b36c72ac05f0f609be65887699b5a73b662/src/Cafe/CMakeLists.txt#L533-L537 with: ```cmake if (ENABLE_NSYSHID_LIBUSB) if (ENABLE_VCPKG) find_package(libusb CONFIG REQUIRED) target_include_directories(CemuCafe PRIVATE ${LIBUSB_INCLUDE_DIRS}) target_link_libraries(CemuCafe PRIVATE ${LIBUSB_LIBRARIES}) else () target_link_libraries(CemuCafe PRIVATE usb-1.0) endif () endif () ``` produces a working Flaptak; although hotplug seems to not work. Would that change be enough to properly support building without vcpkg?
capitalistspz commented 2023-09-04 06:06:32 -03:00 (Migrated from github.com)

Just tried to build the Flatpak and it fails :( Since the Flatpak doesn't use vcpkg there is no libusb package that CMake can find - replacing:

I suggest using a cmake module to support building without vcpkg. To build without vcpkg on my machine, I created Findlibusb.cmake in the cmake folder

# SPDX-FileCopyrightText: 2022 Andrea Pappacoda <andrea@pappacoda.it>
# SPDX-License-Identifier: ISC

find_package(libusb CONFIG)
if (NOT libusb_FOUND)
    find_package(PkgConfig)
    if (PKG_CONFIG_FOUND)
        pkg_search_module(libusb IMPORTED_TARGET GLOBAL libusb-1.0 libusb)
        if (libusb_FOUND)
            add_library(libusb::libusb ALIAS PkgConfig::libusb)
        endif()
    endif()
endif()

find_package_handle_standard_args(libusb
        REQUIRED_VARS
        libusb_LINK_LIBRARIES
        libusb_FOUND
        VERSION_VAR libusb_VERSION
)

and changed dff33b36c7/src/Cafe/CMakeLists.txt (L533-L537) to

if (ENABLE_NSYSHID_LIBUSB)
	find_package(libusb MODULE REQUIRED)
	target_link_libraries(CemuCafe PRIVATE libusb::libusb)
endif ()
> Just tried to build the Flatpak and it fails :( Since the Flatpak doesn't use vcpkg there is no `libusb` package that CMake can find - replacing: I suggest using a cmake module to support building without vcpkg. To build without vcpkg on my machine, I created `Findlibusb.cmake` in the `cmake` folder ```cmake # SPDX-FileCopyrightText: 2022 Andrea Pappacoda <andrea@pappacoda.it> # SPDX-License-Identifier: ISC find_package(libusb CONFIG) if (NOT libusb_FOUND) find_package(PkgConfig) if (PKG_CONFIG_FOUND) pkg_search_module(libusb IMPORTED_TARGET GLOBAL libusb-1.0 libusb) if (libusb_FOUND) add_library(libusb::libusb ALIAS PkgConfig::libusb) endif() endif() endif() find_package_handle_standard_args(libusb REQUIRED_VARS libusb_LINK_LIBRARIES libusb_FOUND VERSION_VAR libusb_VERSION ) ``` and changed https://github.com/cemu-project/Cemu/blob/dff33b36c72ac05f0f609be65887699b5a73b662/src/Cafe/CMakeLists.txt#L533-L537 to ```cmake if (ENABLE_NSYSHID_LIBUSB) find_package(libusb MODULE REQUIRED) target_link_libraries(CemuCafe PRIVATE libusb::libusb) endif () ```
ssievert42 commented 2023-09-05 15:05:04 -03:00 (Migrated from github.com)

Thanks!
That looks a lot cleaner, and I like that it fails early at the cmake stage if libusb is not installed.
But I had to keep the if (ENABLE_VCPKG) ..., because otherwise building with vcpkg doesn't work on my computer.

Just pushed that cmake change along with some threading fixes (you could call me paranoid).

Thanks! That looks a lot cleaner, and I like that it fails early at the cmake stage if libusb is not installed. But I had to keep the `if (ENABLE_VCPKG) ...`, because otherwise building _with_ vcpkg doesn't work on my computer. Just pushed that cmake change along with some threading fixes (you could call me paranoid).
ssievert42 commented 2023-09-06 05:09:28 -03:00 (Migrated from github.com)

On the topic of threading: Turns out I was being a bit eager when it comes to locking in nsyshid.cpp, which could in theory result in an application locking up 😅
I redid that locking stuff, and tried to keep the sections where a mutex is held as short and simple as possible.

On the topic of threading: Turns out I was being a bit eager when it comes to locking in nsyshid.cpp, which could in theory result in an application locking up :sweat_smile: I redid that locking stuff, and tried to keep the sections where a mutex is held as short and simple as possible.
ssievert42 commented 2023-09-16 06:52:37 -03:00 (Migrated from github.com)

Just rebased on main, ran ClangFormat and tried to stick to the newly added coding style guidelines.

Just rebased on main, ran ClangFormat and tried to stick to the newly added coding style guidelines.
Exzap commented 2023-09-18 09:25:53 -03:00 (Migrated from github.com)

Looks good to me. Thanks!
If you need help fixing the Windows compilation error let me know. After resolving it we can merge this.

Looks good to me. Thanks! If you need help fixing the Windows compilation error let me know. After resolving it we can merge this.
ssievert42 commented 2023-09-18 11:06:37 -03:00 (Migrated from github.com)

Cool, thanks!
The Windows build should be fixed now :)

Cool, thanks! The Windows build should be fixed now :)
deReeperJosh commented 2023-09-19 14:07:34 -03:00 (Migrated from github.com)

I think this PR may have broken the Skylanders games on Windows and Mac, maybe linux too. When launching on my Mac, the game instantly crashes, and I am not sure if the compile definitions for libusb have worked because I get no log messages being printed out before the crash. Had a friend test on Windows and that also instantly crashed too

I think this PR may have broken the Skylanders games on Windows and Mac, maybe linux too. When launching on my Mac, the game instantly crashes, and I am not sure if the compile definitions for libusb have worked because I get no log messages being printed out before the crash. Had a friend test on Windows and that also instantly crashed too
deReeperJosh commented 2023-09-19 14:47:33 -03:00 (Migrated from github.com)

Ignore me, looks like the bug is only present when compiling from the repo rather than in the release version itself. Looks like the games still crash on windows though

Ignore me, looks like the bug is only present when compiling from the repo rather than in the release version itself. Looks like the games still crash on windows though
ssievert42 commented 2023-09-19 15:09:37 -03:00 (Migrated from github.com)

Welp, that's unfortunate :(
Maybe a clean rebuild could do the trick in your case then?
So with the release version, the Skylanders portal now works on macOS?
On Windows there shouldn't be a noticable difference to before these changes and after, but I guess I must have messed something up along the way when copy pasting the Windows HID code to the BackendWindowsHID class.

Welp, that's unfortunate :( Maybe a clean rebuild could do the trick in your case then? So with the release version, the Skylanders portal now works on macOS? On Windows there shouldn't be a noticable difference to before these changes and after, but I guess I must have messed something up along the way when copy pasting the Windows HID code to the `BackendWindowsHID` class.
deReeperJosh commented 2023-09-19 15:14:53 -03:00 (Migrated from github.com)

I haven't been able to test the Skylanders games out (still have no portal with me), but it won't work without an implementation of HIDRead and HIDSetReport. HIDRead needs to use the libusb interrupt transfer, and set report needs to use libusb control transfers

I haven't been able to test the Skylanders games out (still have no portal with me), but it won't work without an implementation of HIDRead and HIDSetReport. HIDRead needs to use the libusb interrupt transfer, and set report needs to use libusb control transfers
ssievert42 commented 2023-09-19 17:52:25 -03:00 (Migrated from github.com)

For what it's worth: The Lego Dimensions portal doesn't seem to care whether bulk transfers or interrupt transfers are used to talk to it; after swapping libusb_bulk_transfer for libusb_interrupt_transfer in the Read and Write methods, it still functions correctly.
Maybe something like the code below could be used for SetReport?

bool DeviceLibusb::SetReport(uint8* reportData, sint32 length, uint8* originalData, sint32 originalLength)
{
	auto handleLock = AquireHandleLock();
	if (!handleLock->IsValid())
	{
		cemuLog_logDebug(LogType::Force, "nsyshid::DeviceLibusb::SetReport(): device is not opened");
		return false;
	}

	int ret = 0;
	sint32 retryCount = 0;
	do
	{
		ret = libusb_control_transfer(handleLock->GetHandle(),
									  LIBUSB_RECIPIENT_INTERFACE | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_ENDPOINT_OUT,
									  LIBUSB_REQUEST_SET_CONFIGURATION,
									  (LIBUSB_DT_CONFIG << 8) | reportData[0],
									  0,
									  reportData,
									  length,
									  50);
		if (ret != 0)
		{
			retryCount++;
		}
	}
	while (ret != 0 && retryCount < 20);
	if (ret != 0)
	{
		cemuLog_logDebug(LogType::Force, "nsyshid::DeviceLibusb::SetReport(): control transfer failed with error code: {}", ret);
		return false;
	}
	return true;
}

Again, there's no way for me to test that, as I don't own any skylanders games.

On a side note, the flatpak built by flathub seems to have working hotplug support, while the one I built myself does not. No idea why that is the case, but if it works, it works ¯\_(ツ)_/¯

For what it's worth: The Lego Dimensions portal doesn't seem to care whether bulk transfers or interrupt transfers are used to talk to it; after swapping `libusb_bulk_transfer` for `libusb_interrupt_transfer` in the `Read` and `Write` methods, it still functions correctly. Maybe something like the code below could be used for `SetReport`? ```c++ bool DeviceLibusb::SetReport(uint8* reportData, sint32 length, uint8* originalData, sint32 originalLength) { auto handleLock = AquireHandleLock(); if (!handleLock->IsValid()) { cemuLog_logDebug(LogType::Force, "nsyshid::DeviceLibusb::SetReport(): device is not opened"); return false; } int ret = 0; sint32 retryCount = 0; do { ret = libusb_control_transfer(handleLock->GetHandle(), LIBUSB_RECIPIENT_INTERFACE | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_ENDPOINT_OUT, LIBUSB_REQUEST_SET_CONFIGURATION, (LIBUSB_DT_CONFIG << 8) | reportData[0], 0, reportData, length, 50); if (ret != 0) { retryCount++; } } while (ret != 0 && retryCount < 20); if (ret != 0) { cemuLog_logDebug(LogType::Force, "nsyshid::DeviceLibusb::SetReport(): control transfer failed with error code: {}", ret); return false; } return true; } ``` Again, there's no way for me to test that, as I don't own any skylanders games. On a side note, the flatpak built by flathub seems to have working hotplug support, while the one I built myself does not. No idea why that is the case, but if it works, it works ¯\\\_(ツ)_/¯
deReeperJosh commented 2023-09-19 19:21:03 -03:00 (Migrated from github.com)

Yeah, once I get my Portal back I'll try it out with bulk transfers, and try to confirm if that control transfer method works too. Side note, your changes have made it heaps easier for me to add an emulated Skylander Portal and I've got that working, just need to test a few more games before I make a PR :~)

Yeah, once I get my Portal back I'll try it out with bulk transfers, and try to confirm if that control transfer method works too. Side note, your changes have made it heaps easier for me to add an emulated Skylander Portal and I've got that working, just need to test a few more games before I make a PR :~)
andygrillo commented 2023-09-20 11:24:31 -03:00 (Migrated from github.com)

Hi can i help test this? I have a portal and skylanders games.

I tried with the latest appimage but the usb portal isnt detected. Is there something else I need to do?

Hi can i help test this? I have a portal and skylanders games. I tried with the latest appimage but the usb portal isnt detected. Is there something else I need to do?
ssievert42 commented 2023-09-20 13:13:13 -03:00 (Migrated from github.com)

Hi @andygrillo, that'd be cool!

If you haven't already, you need to create a udev rule to allow Cemu to talk to the portal, as described in the first comment.
Probably something like this for Skylanders:
SUBSYSTEM=="usb", ATTRS{idVendor}=="1430", ATTRS{idProduct}=="0150", MODE="0666"

The implementation is quite noisy when it comes to logging, especially if errors occur. Definitely have a look at lines containing "nsyshid" in log.txt.

This is a shot in the dark, but maybe the code I posted above for SetReport is enough to make the portal work (if it currently doesn't). If you don't want to compile yourself, you could use the AppImage generated here. (And check the commits that I added to my main branch beforehand, to make sure that I'm not including anything shady. (I obviously didn't include any shady stuff (as far as I know), but I just don't want to normalize people suggesting to download and run random executables.))

Hi @andygrillo, that'd be cool! If you haven't already, you need to create a udev rule to allow Cemu to talk to the portal, as described in the first comment. Probably something like this for Skylanders: `SUBSYSTEM=="usb", ATTRS{idVendor}=="1430", ATTRS{idProduct}=="0150", MODE="0666"` The implementation is quite noisy when it comes to logging, especially if errors occur. Definitely have a look at lines containing "nsyshid" in `log.txt`. This is a shot in the dark, but maybe the code I posted above for `SetReport` is enough to make the portal work (if it currently doesn't). If you don't want to compile yourself, you could use the AppImage generated [here](https://github.com/ssievert42/Cemu/actions/runs/6251171195). (And check the commits that I added to my main branch beforehand, to make sure that I'm not including anything shady. (I obviously didn't include any shady stuff (as far as I know), but I just don't want to normalize people suggesting to download and run random executables.))
andygrillo commented 2023-09-21 23:49:47 -03:00 (Migrated from github.com)

Hi @ssievert42 thanks for the guidance.

I confirm the portal I have, which works with windows cemu, according to lsusb does indeed as you suggest require udev rules with these params:

Bus 001 Device 006: ID 1430:0150 RedOctane wireless receiver for skylanders wii

so I created the udev rule 51-gcadapter.rules as follows:

SUBSYSTEM=="usb", ATTRS{idVendor}=="1430", ATTRS{idProduct}=="0150", MODE="0666"

I ran sudo udevadm control --reload then to enable the rule.

I took the appimage from the link you provided and booted up skylanders trap team, a game that works with my portal on windows cemu, and for the first time I got confirmation that a portal was connected, just not the right one:

image
cemu recognizes when I unplug it as it then says no portal connected.

What do you suggest I can try next?

Hi @ssievert42 thanks for the guidance. I confirm the portal I have, which works with windows cemu, according to lsusb does indeed as you suggest require udev rules with these params: ``` Bus 001 Device 006: ID 1430:0150 RedOctane wireless receiver for skylanders wii ``` so I created the udev rule `51-gcadapter.rules ` as follows: ``` SUBSYSTEM=="usb", ATTRS{idVendor}=="1430", ATTRS{idProduct}=="0150", MODE="0666" ``` I ran `sudo udevadm control --reload` then to enable the rule. I took the appimage from the link you provided and booted up skylanders trap team, a game that works with my portal on windows cemu, and for the first time I got confirmation that a portal was connected, just not the right one: ![image](https://github.com/cemu-project/Cemu/assets/6279965/85e6923b-3c9e-4481-850c-30e42d589775) cemu recognizes when I unplug it as it then says no portal connected. What do you suggest I can try next?
andygrillo commented 2023-09-22 00:24:35 -03:00 (Migrated from github.com)

ok in the logs i see this

[22:13:22.690] nsyshid::BackendLibusb: device not on whitelist: 1d6b:0003
[22:13:22.691] nsyshid::BackendLibusb: device not on whitelist: 1d6b:0002
[22:13:22.691] nsyshid::BackendLibusb: device not on whitelist: 1d6b:0003
[22:13:22.691] nsyshid::BackendLibusb: device not on whitelist: 8087:0aa7
[22:13:22.691] nsyshid::BackendLibusb: device not on whitelist: 048d:5702
[22:13:22.691] nsyshid::BackendLibusb: device not on whitelist: 046d:c52b
[22:13:22.691] nsyshid::BackendLibusb: device not on whitelist: 1d6b:0002

am I doing the udev rules incorrectly ? seems that the portal is missing from the list.

ok in the logs i see this ``` [22:13:22.690] nsyshid::BackendLibusb: device not on whitelist: 1d6b:0003 [22:13:22.691] nsyshid::BackendLibusb: device not on whitelist: 1d6b:0002 [22:13:22.691] nsyshid::BackendLibusb: device not on whitelist: 1d6b:0003 [22:13:22.691] nsyshid::BackendLibusb: device not on whitelist: 8087:0aa7 [22:13:22.691] nsyshid::BackendLibusb: device not on whitelist: 048d:5702 [22:13:22.691] nsyshid::BackendLibusb: device not on whitelist: 046d:c52b [22:13:22.691] nsyshid::BackendLibusb: device not on whitelist: 1d6b:0002 ``` am I doing the udev rules incorrectly ? seems that the portal is missing from the list.
deReeperJosh commented 2023-09-22 03:24:11 -03:00 (Migrated from github.com)

@andygrillo that looks like it worked, but Cemu hasn't completely added support for the Skylander portal yet. The game recognises it as a portal which is the important part! @ssievert42 I believe once the Report methods use control transfers that should fix skylanders. Will look in to getting a portal as soon as I can!

@andygrillo that looks like it worked, but Cemu hasn't completely added support for the Skylander portal yet. The game recognises it as a portal which is the important part! @ssievert42 I believe once the Report methods use control transfers that should fix skylanders. Will look in to getting a portal as soon as I can!
ssievert42 commented 2023-09-22 05:11:34 -03:00 (Migrated from github.com)

@andygrillo thanks for trying that out!

The udev stuff should be correct - the device not on whitelist bit in the logs is just telling you about other devices that are connected to your computer, but not whitelisted by Cemu. If the game sees a device, that means that it is on the whitelist 👍
I guess you have unplugged and replugged the portal, since you added the udev rule, a bunch of times by now, but for the udev rule to apply the device needs to be plugged in after the rule was created. I lost at least an hour to that when hacking on this PR.

There should be some more lines in the log that contain "nsyshid". If not, the game doesn't even try to talk to the portal, which would be really strange.

Could you please post the output of lsusb -v -d 1430:0150 while the skylanders portal is plugged in? That should list all descriptors of the device. My suspicion is, that my logic for figuring out from which endpoint can be read, and to which endpoint can be written, might be wrong.

What might actually work is applying this change on top. Cemu pads the data that is passed to SetReport and then should be sent to the portal; that change switches to using the original, unpadded data. Build here.

@deReeperJosh I'm actually cooking something that uses control transfers in SetReport on my main branch (seemed like the easiest way to trigger actions runs), but I'm not sure at all that the way I'm doing that is correct 😅

@andygrillo thanks for trying that out! The udev stuff should be correct - the `device not on whitelist` bit in the logs is just telling you about other devices that are connected to your computer, but not whitelisted by Cemu. If the game sees a device, that means that it is on the whitelist :+1: I guess you have unplugged and replugged the portal, since you added the udev rule, a bunch of times by now, but for the udev rule to apply the device needs to be plugged in after the rule was created. I lost at least an hour to that when hacking on this PR. There should be some more lines in the log that contain "nsyshid". If not, the game doesn't even try to talk to the portal, which would be really strange. Could you please post the output of `lsusb -v -d 1430:0150` while the skylanders portal is plugged in? That should list all descriptors of the device. My suspicion is, that my logic for figuring out from which endpoint can be read, and to which endpoint can be written, might be wrong. What might actually work is applying [this change](https://github.com/ssievert42/Cemu/commit/cee96af158b43f097fa3ad6279929a00fa9d1e31) on top. Cemu pads the data that is passed to `SetReport` and then should be sent to the portal; that change switches to using the original, unpadded data. Build [here](https://github.com/ssievert42/Cemu/actions/runs/6271501677). @deReeperJosh I'm actually cooking something that uses control transfers in `SetReport` on my [main branch](https://github.com/ssievert42/Cemu) (seemed like the easiest way to trigger actions runs), but I'm not sure at all that the way I'm doing that is correct :sweat_smile:
deReeperJosh commented 2023-09-22 05:13:59 -03:00 (Migrated from github.com)

Oh awesome! The only examples off the top of my head that use libusb that you could compare with are RPCS3 and Dolphin, so maybe check there to see if there's anything you can apply here too

Oh awesome! The only examples off the top of my head that use libusb that you could compare with are RPCS3 and Dolphin, so maybe check there to see if there's anything you can apply here too
andygrillo commented 2023-09-22 14:07:10 -03:00 (Migrated from github.com)

here is the output from lsusb -v -d 1430:

[gamer@chimeraos ~]$ lsusb -v -d 1430:0150

Bus 001 Device 006: ID 1430:0150 RedOctane wireless receiver for skylanders wii
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x1430 RedOctane
  idProduct          0x0150 wireless receiver for skylanders wii
  bcdDevice            1.00
  iManufacturer           1 Activision
  iProduct                2 Spyro Porta
  iSerial                 0 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x0029
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              500mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      29
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               1
Device Status:     0x0000
  (Bus Powered)
here is the output from `lsusb -v -d 1430`: ``` [gamer@chimeraos ~]$ lsusb -v -d 1430:0150 Bus 001 Device 006: ID 1430:0150 RedOctane wireless receiver for skylanders wii Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x1430 RedOctane idProduct 0x0150 wireless receiver for skylanders wii bcdDevice 1.00 iManufacturer 1 Activision iProduct 2 Spyro Porta iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 0x0029 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 500mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 0 bInterfaceProtocol 0 iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.11 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 29 Report Descriptors: ** UNAVAILABLE ** Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 1 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 1 Device Status: 0x0000 (Bus Powered) ```
andygrillo commented 2023-09-22 14:09:55 -03:00 (Migrated from github.com)

I tried your new build @ssievert42 but same issue, cemu says incompatible portal.

I tried your new build @ssievert42 but same issue, cemu says incompatible portal.
andygrillo commented 2023-09-22 14:12:00 -03:00 (Migrated from github.com)

here is the whole log.txt from the recent cemu attempt:

[12:08:19.915] ------- Init Cemu 2.0-cee96af (experimental) -------
[12:08:19.916] Init Wii U memory space (base: 0x00007f66b8000000)
[12:08:19.918] mlc01 path: /home/gamer/.local/share/Cemu/mlc01
[12:08:19.918] CPU: AMD Ryzen 5 5600X 6-Core Processor             
[12:08:19.918] RAM: 15913MB
[12:08:19.918] Platform: Linux (AppImage)
[12:08:19.918] Used CPU extensions: SSSE3, SSE4.1, AVX, AVX2, LZCNT, MOVBE, BMI2, AES-NI, INVARIANT-TSC
[12:08:19.921] IOSU_CRYPTO: No otp.bin found. Online mode cannot be used
[12:08:19.921] IOSU_CRYPTO: No Seeprom.bin found. Online mode cannot be used
[12:08:19.932] Failed to read valid PlayDiary header
[12:08:21.284] Mounting title 000500001017c600
[12:08:21.284] Base: /run/media/sda1/ROMS/Wii U/Skylanders Trap Team [Game] [000500001017c600] [Folder]
[12:08:21.284] Update: Not present
[12:08:21.284] DLC: Not present
[12:08:21.323] COS: System fonts found. Generated shareddata (26609KB)
[12:08:21.329] Recompiler initialized
[12:08:21.509] ------- Init Vulkan graphics backend -------
[12:08:21.528] Vulkan instance version: 1.3
[12:08:21.533] Using GPU: AMD Radeon RX 6600 (RADV NAVI23)
[12:08:21.533] Driver version: Mesa 23.1.3
[12:08:21.533] VulkanLimits: UBAlignment 4 nonCoherentAtomSize 64
[12:08:21.540] Using available debug function: vkCreateDebugUtilsMessengerEXT()
[12:08:21.540] Vulkan device memory info:
[12:08:21.540] Heap 0 - Size 7936MB Flags 0x00000001
[12:08:21.540] Heap 1 - Size 7956MB Flags 0x00000000
[12:08:21.540] Heap 2 - Size 256MB Flags 0x00000001
[12:08:21.540] Memory 0 - HeapIndex 0 Flags 0x00000001
[12:08:21.540] Memory 1 - HeapIndex 0 Flags 0x00000001
[12:08:21.540] Memory 2 - HeapIndex 1 Flags 0x00000006
[12:08:21.540] Memory 3 - HeapIndex 2 Flags 0x00000007
[12:08:21.540] Memory 4 - HeapIndex 2 Flags 0x00000007
[12:08:21.540] Memory 5 - HeapIndex 1 Flags 0x0000000e
[12:08:21.540] Memory 6 - HeapIndex 1 Flags 0x0000000e
[12:08:21.540] Memory 7 - HeapIndex 0 Flags 0x000000c1
[12:08:21.540] Memory 8 - HeapIndex 1 Flags 0x000000c6
[12:08:21.540] Memory 9 - HeapIndex 2 Flags 0x000000c7
[12:08:21.540] Memory 10 - HeapIndex 1 Flags 0x000000ce
[12:08:21.540] VK_FORMAT_D24_UNORM_S8_UINT not supported
[12:08:21.540] VK_FORMAT_R4G4_UNORM_PACK8 not supported
[12:08:22.569] ------- Loaded title -------
[12:08:22.569] TitleId: 00050000-1017c600
[12:08:22.569] TitleVersion: v1
[12:08:22.569] TitleRegion: US
[12:08:22.569] Save path:   /home/gamer/.local/share/Cemu/mlc01/usr/save/00050000/1017C600/user/ (not present)
[12:08:22.569] Shader cache file: shaderCache/transferable/000500001017c600.bin
[12:08:22.569] gameprofile path: gameProfiles/000500001017c600.ini
[12:08:22.569] RPX hash (updated): 24e28517
[12:08:22.569] RPX hash (base): 24e28517
[12:08:22.576] nsyshid::BackendLibusb: device not on whitelist: 1d6b:0003
[12:08:22.576] nsyshid::BackendLibusb: device not on whitelist: 1d6b:0002
[12:08:22.577] nsyshid::BackendLibusb: device not on whitelist: 1d6b:0003
[12:08:22.577] nsyshid::BackendLibusb: device not on whitelist: 8087:0aa7
[12:08:22.577] nsyshid::BackendLibusb: device not on whitelist: 048d:5702
[12:08:22.577] nsyshid::BackendLibusb: device not on whitelist: 046d:c52b
[12:08:22.577] nsyshid::BackendLibusb: device not on whitelist: 1d6b:0002
[12:08:22.616] Loaded module 'tfbgame_cafe' with checksum 0x321d97f0
[12:08:22.616] RPL link time: 39ms
[12:08:22.638] HLE scan time: 22ms
[12:08:22.638] ------- Active settings -------
[12:08:22.638] CPU-Mode: Multi-core recompiler (gameprofile)
[12:08:22.638] Load shared libraries: true (gameprofile)
[12:08:22.638] Use precompiled shaders: auto (gameprofile)
[12:08:22.638] Full sync at GX2DrawDone: true
[12:08:22.638] Strict shader mul: true
[12:08:22.638] Async compile: true
[12:08:22.638] Console language: English
[12:08:22.720] ------- Activate graphic packs -------
[12:08:22.720] Set vsync frequency to 120 (graphic pack Skylanders Trap Team/Mods/FPS)
[12:08:22.720] Activate graphic pack: Skylanders Trap Team/Mods/FPS [Presets: 60 FPS]
[12:08:22.722] Activate graphic pack: Skylanders Trap Team/Graphics [Presets: 1920x1080,Medium (100%, Default)]
[12:08:22.722] ------- Init Audio backend -------
[12:08:22.722] DirectSound: not supported
[12:08:22.722] XAudio 2.8: not supported
[12:08:22.722] XAudio 2.7: not supported
[12:08:22.722] Cubeb: available
[12:08:22.722] ------- Init Audio input backend -------
[12:08:22.722] Cubeb: available
[12:08:22.722] ------- Run title -------
[12:08:22.852] IOSU_ACT: using account default in first slot
[12:08:22.947] Game attempting to re-initialize existing thread
[12:08:22.947] Calling OSCreateThread() on thread which is still active (Thread exited without detached flag). Forcing OSDetachThread()...
[12:09:07.022] nsyshid.HIDRead(): Unable to find device with hid handle 2```
here is the whole log.txt from the recent cemu attempt: ``` [12:08:19.915] ------- Init Cemu 2.0-cee96af (experimental) ------- [12:08:19.916] Init Wii U memory space (base: 0x00007f66b8000000) [12:08:19.918] mlc01 path: /home/gamer/.local/share/Cemu/mlc01 [12:08:19.918] CPU: AMD Ryzen 5 5600X 6-Core Processor [12:08:19.918] RAM: 15913MB [12:08:19.918] Platform: Linux (AppImage) [12:08:19.918] Used CPU extensions: SSSE3, SSE4.1, AVX, AVX2, LZCNT, MOVBE, BMI2, AES-NI, INVARIANT-TSC [12:08:19.921] IOSU_CRYPTO: No otp.bin found. Online mode cannot be used [12:08:19.921] IOSU_CRYPTO: No Seeprom.bin found. Online mode cannot be used [12:08:19.932] Failed to read valid PlayDiary header [12:08:21.284] Mounting title 000500001017c600 [12:08:21.284] Base: /run/media/sda1/ROMS/Wii U/Skylanders Trap Team [Game] [000500001017c600] [Folder] [12:08:21.284] Update: Not present [12:08:21.284] DLC: Not present [12:08:21.323] COS: System fonts found. Generated shareddata (26609KB) [12:08:21.329] Recompiler initialized [12:08:21.509] ------- Init Vulkan graphics backend ------- [12:08:21.528] Vulkan instance version: 1.3 [12:08:21.533] Using GPU: AMD Radeon RX 6600 (RADV NAVI23) [12:08:21.533] Driver version: Mesa 23.1.3 [12:08:21.533] VulkanLimits: UBAlignment 4 nonCoherentAtomSize 64 [12:08:21.540] Using available debug function: vkCreateDebugUtilsMessengerEXT() [12:08:21.540] Vulkan device memory info: [12:08:21.540] Heap 0 - Size 7936MB Flags 0x00000001 [12:08:21.540] Heap 1 - Size 7956MB Flags 0x00000000 [12:08:21.540] Heap 2 - Size 256MB Flags 0x00000001 [12:08:21.540] Memory 0 - HeapIndex 0 Flags 0x00000001 [12:08:21.540] Memory 1 - HeapIndex 0 Flags 0x00000001 [12:08:21.540] Memory 2 - HeapIndex 1 Flags 0x00000006 [12:08:21.540] Memory 3 - HeapIndex 2 Flags 0x00000007 [12:08:21.540] Memory 4 - HeapIndex 2 Flags 0x00000007 [12:08:21.540] Memory 5 - HeapIndex 1 Flags 0x0000000e [12:08:21.540] Memory 6 - HeapIndex 1 Flags 0x0000000e [12:08:21.540] Memory 7 - HeapIndex 0 Flags 0x000000c1 [12:08:21.540] Memory 8 - HeapIndex 1 Flags 0x000000c6 [12:08:21.540] Memory 9 - HeapIndex 2 Flags 0x000000c7 [12:08:21.540] Memory 10 - HeapIndex 1 Flags 0x000000ce [12:08:21.540] VK_FORMAT_D24_UNORM_S8_UINT not supported [12:08:21.540] VK_FORMAT_R4G4_UNORM_PACK8 not supported [12:08:22.569] ------- Loaded title ------- [12:08:22.569] TitleId: 00050000-1017c600 [12:08:22.569] TitleVersion: v1 [12:08:22.569] TitleRegion: US [12:08:22.569] Save path: /home/gamer/.local/share/Cemu/mlc01/usr/save/00050000/1017C600/user/ (not present) [12:08:22.569] Shader cache file: shaderCache/transferable/000500001017c600.bin [12:08:22.569] gameprofile path: gameProfiles/000500001017c600.ini [12:08:22.569] RPX hash (updated): 24e28517 [12:08:22.569] RPX hash (base): 24e28517 [12:08:22.576] nsyshid::BackendLibusb: device not on whitelist: 1d6b:0003 [12:08:22.576] nsyshid::BackendLibusb: device not on whitelist: 1d6b:0002 [12:08:22.577] nsyshid::BackendLibusb: device not on whitelist: 1d6b:0003 [12:08:22.577] nsyshid::BackendLibusb: device not on whitelist: 8087:0aa7 [12:08:22.577] nsyshid::BackendLibusb: device not on whitelist: 048d:5702 [12:08:22.577] nsyshid::BackendLibusb: device not on whitelist: 046d:c52b [12:08:22.577] nsyshid::BackendLibusb: device not on whitelist: 1d6b:0002 [12:08:22.616] Loaded module 'tfbgame_cafe' with checksum 0x321d97f0 [12:08:22.616] RPL link time: 39ms [12:08:22.638] HLE scan time: 22ms [12:08:22.638] ------- Active settings ------- [12:08:22.638] CPU-Mode: Multi-core recompiler (gameprofile) [12:08:22.638] Load shared libraries: true (gameprofile) [12:08:22.638] Use precompiled shaders: auto (gameprofile) [12:08:22.638] Full sync at GX2DrawDone: true [12:08:22.638] Strict shader mul: true [12:08:22.638] Async compile: true [12:08:22.638] Console language: English [12:08:22.720] ------- Activate graphic packs ------- [12:08:22.720] Set vsync frequency to 120 (graphic pack Skylanders Trap Team/Mods/FPS) [12:08:22.720] Activate graphic pack: Skylanders Trap Team/Mods/FPS [Presets: 60 FPS] [12:08:22.722] Activate graphic pack: Skylanders Trap Team/Graphics [Presets: 1920x1080,Medium (100%, Default)] [12:08:22.722] ------- Init Audio backend ------- [12:08:22.722] DirectSound: not supported [12:08:22.722] XAudio 2.8: not supported [12:08:22.722] XAudio 2.7: not supported [12:08:22.722] Cubeb: available [12:08:22.722] ------- Init Audio input backend ------- [12:08:22.722] Cubeb: available [12:08:22.722] ------- Run title ------- [12:08:22.852] IOSU_ACT: using account default in first slot [12:08:22.947] Game attempting to re-initialize existing thread [12:08:22.947] Calling OSCreateThread() on thread which is still active (Thread exited without detached flag). Forcing OSDetachThread()... [12:09:07.022] nsyshid.HIDRead(): Unable to find device with hid handle 2```
andygrillo commented 2023-09-22 14:19:23 -03:00 (Migrated from github.com)

just checking I understood this comment @ssievert42 - "for the udev rule to apply the device needs to be plugged in after the rule was created"...

I had the portal plugged in when creating the rule, then when enabling the rule with sudo udevadm control --reload, then unplugged and replugged before starting the game.

I also recently rebooted the device.

just checking I understood this comment @ssievert42 - "for the udev rule to apply the device needs to be plugged in after the rule was created"... I had the portal plugged in when creating the rule, then when enabling the rule with `sudo udevadm control --reload`, then unplugged and replugged before starting the game. I also recently rebooted the device.
ssievert42 commented 2023-09-23 05:24:16 -03:00 (Migrated from github.com)

The lsusb output looks pretty similar to the Lego Dimensions portal, and since the device only has two endpoints and one configuration, my default endpoint discovery logic shouldn't be at fault here.

I had the portal plugged in when creating the rule, then when enabling the rule with sudo udevadm control --reload, then unplugged and replugged before starting the game.

Everything should be fine in that regard, then 👍

I totally forgot that the excessive logging only happens in debug builds. This change also logs a lot of stuff in a release build and might provide some more insight into what is going wrong. (Build here)

[12:09:07.022] nsyshid.HIDRead(): Unable to find device with hid handle 2

This could be one of two things: either the device left, and the game tried to read from it using the now invalid hid handle, or it is impossible to open the device. The build with more logging should help to differentiate between the two.
Weirdly enough, I could only get the Unable to find device with hid handle ... message with Lego Dimensions, when I removed my udev rule file /etc/udev/rules.d/99-lego-dimensions-portal.rules.

The `lsusb` output looks pretty similar to the Lego Dimensions portal, and since the device only has two endpoints and one configuration, my default endpoint discovery logic shouldn't be at fault here. > I had the portal plugged in when creating the rule, then when enabling the rule with sudo udevadm control --reload, then unplugged and replugged before starting the game. Everything should be fine in that regard, then :+1: I totally forgot that the excessive logging only happens in debug builds. [This change](https://github.com/ssievert42/Cemu/commit/fd44367fe8d9b85e9f80bcd6f732c636fff6fcfb) also logs a lot of stuff in a release build and might provide some more insight into what is going wrong. (Build [here](https://github.com/ssievert42/Cemu/actions/runs/6282613020)) > `[12:09:07.022] nsyshid.HIDRead(): Unable to find device with hid handle 2` This could be one of two things: either the device left, and the game tried to read from it using the now invalid hid handle, or it is impossible to open the device. The build with more logging should help to differentiate between the two. Weirdly enough, I could only get the `Unable to find device with hid handle ...` message with Lego Dimensions, when I removed my udev rule file `/etc/udev/rules.d/99-lego-dimensions-portal.rules`.
andygrillo commented 2023-09-23 13:41:36 -03:00 (Migrated from github.com)

here is the full log using the debugging build. please note once I got to the incompatible portal screen I tried disconnecting and reconnecting the portal.
log.txt

here is the full log using the debugging build. please note once I got to the incompatible portal screen I tried disconnecting and reconnecting the portal. [log.txt](https://github.com/cemu-project/Cemu/files/12706911/log.txt)
andygrillo commented 2023-09-27 20:33:29 -03:00 (Migrated from github.com)

Hi @ssievert42 , did my log help in anyway ? I wish I could be more help but I don't know how to interact with libusb...

Hi @ssievert42 , did my log help in anyway ? I wish I could be more help but I don't know how to interact with libusb...
ssievert42 commented 2023-09-28 11:42:04 -03:00 (Migrated from github.com)

Hi @andygrillo the log definitely helped!
That makes two of us :)
Reading data from the portal seems to work, but writing does not:
nsyshid::DeviceLibusb::SetReport(): control transfer failed with error code: 2
Since error code 2 means LIBUSB_ERROR_INVALID_PARAM I must have supplied an invalid parameter to libusb_control_transfer. I'm honestly starting to run out of ideas, and trying to develop for a device without having access to such a device is just no fun.
RPCS3 and Dolphin seem to use libusb's async api, but from a quick glance I can't figure out what the equivalent arguments for the synchronous api would be.
There is however a project that manages to talk to a Skylanders portal only using libusb_interrupt_transfer like this.
If this change (build here) doesn't work, then I guess it's up to someone other than me to get the Skylanders portal to work.

Hi @andygrillo the log definitely helped! That makes two of us :) Reading data from the portal seems to work, but writing does not: `nsyshid::DeviceLibusb::SetReport(): control transfer failed with error code: 2` Since error code 2 means `LIBUSB_ERROR_INVALID_PARAM` I must have supplied an invalid parameter to `libusb_control_transfer`. I'm honestly starting to run out of ideas, and trying to develop for a device without having access to such a device is just no fun. RPCS3 and Dolphin seem to use libusb's async api, but from a quick glance I can't figure out what the equivalent arguments for the synchronous api would be. There is however a project that manages to talk to a Skylanders portal only using `libusb_interrupt_transfer` [like this](https://github.com/silicontrip/SkyReader/blob/76ae573aca0801888b7b8ccee9cc437af978039e/portalio_libusb.cpp#L146). If [this change](https://github.com/ssievert42/Cemu/commit/f8c0ecb5d67eba183b63ef971e8f99abd35b4557) (build [here](https://github.com/ssievert42/Cemu/actions/runs/6340378915)) doesn't work, then I guess it's up to someone other than me to get the Skylanders portal to work.
andygrillo commented 2023-09-28 15:12:58 -03:00 (Migrated from github.com)

thanks very much, unfortuantely this doesn't work. Thanks for the many attempts!

thanks very much, unfortuantely this doesn't work. Thanks for the many attempts!
deReeperJosh commented 2023-11-21 11:59:23 -03:00 (Migrated from github.com)

I think I have made some progress here (in terms of getting the Skylander portal working) - the set protocol method is quite important, because it tells us what interface and configuration to claim via libusb, so what I have done locally is use the SetProtocol method to release all current interfaces, then set the configuration to the one provided in the setprotocol method, then detach kernel drivers and claim all interfaces for that config.

When the SetReport method is called, I use the libusb_control_transfer method, and I am now in game with giants! I will keep trying out things, but I am currently hardcoding values to ones I have seen in Dolphin (bmRequestType, bmRequest, wIndex and wValue), but this seems to be working okay for now.

I think I have made some progress here (in terms of getting the Skylander portal working) - the set protocol method is quite important, because it tells us what interface and configuration to claim via libusb, so what I have done locally is use the SetProtocol method to release all current interfaces, then set the configuration to the one provided in the setprotocol method, then detach kernel drivers and claim all interfaces for that config. When the SetReport method is called, I use the libusb_control_transfer method, and I am now in game with giants! I will keep trying out things, but I am currently hardcoding values to ones I have seen in Dolphin (bmRequestType, bmRequest, wIndex and wValue), but this seems to be working okay for now.
deReeperJosh commented 2023-11-21 17:47:13 -03:00 (Migrated from github.com)

@andygrillo if you want to help test, I have opened https://github.com/cemu-project/Cemu/pull/1027 which should hopefully fix Skylanders on linux

@andygrillo if you want to help test, I have opened https://github.com/cemu-project/Cemu/pull/1027 which should hopefully fix Skylanders on linux
Sign in to join this conversation.
No reviewers
No Label
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: cemu-project_Mirror/Cemu-2024-03-05#950
No description provided.