Ryzee119 / usb64

usb64 - A project developed to use USB controllers on the Nintendo 64 console :tv: :video_game:
MIT License
149 stars 15 forks source link

Nintendo Switch Online N64 Controller + 8bitdo Adapter = Wrong/Missing Button Mappings #57

Open SubElement opened 2 years ago

SubElement commented 2 years ago

Hello,

I'm suing a USB64 (Latest build-202110290732) with the 8bitdo Adapter (Latest firmware, v2.02) with the Nintendo Switch Online N64 Controller. It mostly works okay, but some of the button mappings are incorrect. This is tested on an N64 with Controller Test Tool by sanni.

Here's what works correctly:

D-Pad (Up, Down, Left and Right) Analogue Stick Start Button L Button R Button

Important buttons that don't work work or have no mapping

B - Mapped as Z A - Mapped as Z C-Left - Mapped as B C-Down - Mapped as A C-Right - No Mapping C-Up - No Mapping Z-Trigger - No Mapping

Non-important buttons

ZR - No Mapping Screenshot Button - No Mapping Home Button - No Mapping

Is there anyway this can be corrected?

Please let me know if you need any more information or if I can help fix this in any way.

Thank you!

Ryzee119 commented 2 years ago

Thanks for raising this usse. It definitely can be corrected. Could you just try this build quickly? Its from https://github.com/Ryzee119/usb64/actions/runs/1769804523 and based on current master which has alot of changes from that release build. If the issue is still present we'll go from there

~test-firmware-teensy41.zip~ Disregard that. I tested it myself and its not working, Ill have to investigate a bit

Ryzee119 commented 2 years ago

Are you able to compile the code yourself?

The mapping is here: https://github.com/Ryzee119/usb64/blob/c3dae9b3f241df2a100d2c1e24575c3715a98418/src/input.cpp#L280-L325

It might need a bit of trial and error to get it correct

SubElement commented 2 years ago

Uhh, I’ve never compiled code of any variety I’m sorry. 😅

I assume it wouldn’t be noob friendly to do?

SubElement commented 2 years ago

Okay here is an update. With the 8bitdo adapter plugged in to my PC, I can map the buttons are in relation to an Xbox 360 controller if that's helpful:

N64                        X-Box 360
-----------------------------------------
D-Pad Up                   D-Pad Up
D-Pad Down                 D-Pad Down
D-Pad Left                 D-Pad Left
D-Pad Right                D-Pad Right
Analogue Stick             Analogue Stick
Start Button               Start Button
L Button                   L Button
R Button                   R Button
B                          Left Trigger
A                          Right Trigger
C-Left                     X
C-Down                     A
C-Right                    B
C-Up                       Y
Z-Trigger                  Back
Ryzee119 commented 2 years ago

That is helpful thanks. No wonder its being wacky... why tf did 8bitdo decide on that mapping 🤔

I should be able to have a look tomorrow (late here)

SubElement commented 2 years ago

Yeah, I have NFI why they chose that combination?

By the way I downloaded the code and visual studio to try and compile myself but I don't quite understand the code to button correlation... I tried! XD

Either way, I appreciate your help!

Ryzee119 commented 2 years ago

I've added this conditional to the mapping based on your handy table. Please test and let me know how it goes! usb64_8bitdo_n64fix.zip

The biggest problem is that this will replace the mapping for the 8bitdov2 adaptor for ALL controllers not just the n64 switch controller. The mapping does make some sense as I am looking at it more but not very intuitive if using other controllers now. Im not sure it is possible to determine if the connected controller is a n64 switch controller or not through the 8bitdo adaptor. That will need investigating.

if (joy->idVendor() == 0x2dc8 && joy->idProduct() == 0x3106)
{
    if (_buttons & (1 << 0))  state->dButtons |= N64_DU;  //DUP
    if (_buttons & (1 << 1))  state->dButtons |= N64_DD;  //DDOWN
    if (_buttons & (1 << 2))  state->dButtons |= N64_DL;  //DLEFT
    if (_buttons & (1 << 3))  state->dButtons |= N64_DR;  //DRIGHT

    //Analog stick (Normalise 0 to +/-100)
    state->x_axis = _axis[0] * 100 / 32768;
    state->y_axis = _axis[1] * 100 / 32768;

    if (_buttons & (1 << 4))  state->dButtons |= N64_ST;  //START
    if (_buttons & (1 << 8))  state->dButtons |= N64_LB;  //LB
    if (_buttons & (1 << 9))  state->dButtons |= N64_RB;  //RB

    if (_buttons & (1 << 6))  state->dButtons |= N64_B;   //LS
    if (_buttons & (1 << 7))  state->dButtons |= N64_A;   //RS

    if (_axis[4] > 10) state->dButtons |= N64_B; //LT
    if (_axis[5] > 10) state->dButtons |= N64_A; //RT

    if (_buttons & (1 << 12)) state->dButtons |= N64_CD;  //A
    if (_buttons & (1 << 13)) state->dButtons |= N64_CR;  //B
    if (_buttons & (1 << 14)) state->dButtons |= N64_CL;  //X
    if (_buttons & (1 << 15)) state->dButtons |= N64_CU;  //Y

    if (_buttons & (1 << 5))  state->dButtons |= N64_Z;  //BACK
    break;
}
SubElement commented 2 years ago

Hey! Thanks, so I just tried this before leaving for work and it's weirdly made no difference at all? The buttons seem to be working as before.

Unsure whats going on, and pretty sure it's flashed correctly.

Thoughts?

Edit: Oh, as perhaps as a solution to the exclusive mapping. Maybe have an option in a menu, or a key combo to enable NSO N64 more or something? Unsure how complicated something like that would be?

Ryzee119 commented 2 years ago

Can you confirm the device PID/VID? do they match joy->idVendor() == 0x2dc8 && joy->idProduct() == 0x3106)

SubElement commented 2 years ago

Hello! I plugged the 8bitdo Receiver into my MacBook Air to get a PID and VID in the same format as yours and they appear to be different.

PID = 0x028e VID = 0x045e

Screen Shot 2022-03-22 at 6 50 18 pm

Ryzee119 commented 2 years ago

Try this one. My mistake, I thought you had the 8bitdo adaptor V2, but its V1 with V2 firmware :)

usb64_n64switch_fix.zip

SubElement commented 2 years ago

Try this one. My mistake, I thought you had the 8bitdo adaptor V2, but its V1 with V2 firmware :)

Haha, no worries, easy mistake to make.

I just have it a try and all buttons work as expected, thank you! I greatly appreciate it.

Now, is there any chance I could use this mapping while also having other controllers plugged in?

Ryzee119 commented 2 years ago

Yea thanks for confirming the mapping. Ill add some kind of button combo to switch the layout as you suggested.

SubElement commented 2 years ago

Yea thanks for confirming the mapping. Ill add some kind of button combo to switch the layout as you suggested.

Legend, thanks!

Edit: Just a thought, it would have to be a button combo that is accessible to the limited buttons available before the fix.

IonBlade2K commented 2 months ago

@Ryzee119 is there any chance you still have a working buildchain?

I've got the 8bitdo N64 modkit to make my OEM controllers Bluetooth + hall effect sticks.

The modkit has practically the same behavior as documented above when used with the 8bitdo v1 adapter on the 2.05 firmware, except that:

Flashing the build in https://github.com/Ryzee119/usb64/issues/57#issuecomment-1075979608 above works perfect for this controller, therefore, except that there's no way to switch away from the default rumble pak to memory pak / virtual pak / transfer pack, or flush to SD, because the code seems to have stripped out the " if (combo_pressed) *combo_pressed = " line.

Since there's an extra button "ZR" on the memory pak, I'd wanted to customize a build for the modkit being used with the 8bitdo v1 receiver on v2 firmware, as you did above, as follows:

    if (_buttons & (1 << 0))  state->dButtons |= N64_DU;  //DUP
    if (_buttons & (1 << 1))  state->dButtons |= N64_DD;  //DDOWN
    if (_buttons & (1 << 2))  state->dButtons |= N64_DL;  //DLEFT
    if (_buttons & (1 << 3))  state->dButtons |= N64_DR;  //DRIGHT

    //Analog stick (Normalise 0 to +/-100)
    state->x_axis = _axis[0] * 100 / 32768;
    state->y_axis = _axis[1] * 100 / 32768;

    if (_buttons & (1 << 4))  state->dButtons |= N64_ST;  //START
    if (_buttons & (1 << 8))  state->dButtons |= N64_LB;  //LB
    if (_buttons & (1 << 9))  state->dButtons |= N64_RB;  //RB

    if (_axis[4] > 10) state->dButtons |= N64_B; //LT
    if (_axis[5] > 10) state->dButtons |= N64_A; //RT

    if (_buttons & (1 << 12)) state->dButtons |= N64_CD;  //A
    if (_buttons & (1 << 13)) state->dButtons |= N64_CR;  //B
    if (_buttons & (1 << 14)) state->dButtons |= N64_CL;  //X
    if (_buttons & (1 << 15)) state->dButtons |= N64_CU;  //Y

    if (_buttons & (1 << 5))  state->dButtons |= N64_Z;  //BACK

    // Button to hold for 'combos'
    if (combo_pressed) *combo_pressed = (_buttons & (1 << 6)); //LS ("ZR" button on modkit's pak)
    break;

I've spent 10 hours now trying to get the code to compile like it did a few years ago, but it seems like the dependency on teensy 4.13.1 means it no longer compiles unless you have it cached locally, because the platformio repository has removed that version.

I tried to change the platformio.ini to "platform = https://github.com/platformio/platform-teensy.git#v4.13.1" to get around this, but that in turn depends on framework-arduinoteensy 1.54, which has also been removed from the platformio repository.

I then tried to download 1.54 of framework-arduinoteensy from github and then add a platorm_packages reference for framework-arduinoteensy @ file://path to resolve that. I then get an error about not being able to find other source files.

GPT has led me around in circles all day, and I'm at my wit's end not knowing enough about platformio to sort out the broken repo dependencies to compile it myself. I'm hoping you might still have the toolchain to be able to throw the above in place of the same spot you threw the code for https://github.com/Ryzee119/usb64/issues/57#issuecomment-1075979608 so I could use these modkit controllers with the USB64 fully, while still being able to trigger pak swaps.

Even blueretro can't handle rumble on the real system with these like the USB64 can, and these modkits support decent Hall effect sticks, so getting a way to swap paks as above into USB64 would make USB64 + these the best OEM-feeling wireless setup for wireless N64 use!

Willing to throw some cash your way for the time!

supavgx commented 2 months ago

Im also willing to pitch in some cash to help fix this and also the nso n64 controller id like rumble and be able to switch paks i prefer this over bkueretro

IonBlade2K commented 2 months ago

@supavgx Think I got it, by using an older firmware as a base for the customizations.

If (and only if) you use the 8bitdo modkit with 8bitdo v1 receivers on the latest firmware, try the USB64 firmware in the zip below for full functionality (Rumble, all buttons, and all features but dual analog... since there's only one analog stick :) ).

8bitdomodkit-build-202109040414-base.hex.zip

Note: it uses new hotkey mappings for easier reachability. See below.

I've been using it the last hour with my 8bitdo modkit on a v1 8bitdo receiver on the latest 2.05 firmware, and everything seems to work great!

Controller Compatibility

Button mapping changes

Since the button on the modkit's controller pak is in a funky spot compared to "back" on 360 controllers, I redid the mappings to be more reachable by the right thumb while you use your index finger to reach for the ZR button, without having to change your left hand between prongs on the controller.

New mappings with this firmware are all triggered via the ZR (far right button on the transfer pak) of the 8bitdo modkit:

Note: uses a slightly older firmware as base

I've also attached the source containing the changes I made from the 202109040414 version for Ryzee's benefit, in case they are able to build the same build on the newer versions as a base. I couldn't get the newer bases to compile because of the dependencies that are no longer available. All changes were made in main.cpp and input.cpp, using the 202109040414 build as a basis.

Source-Based-On-202109040414.zip

Ryzee119 commented 2 months ago

is there any chance you still have a working buildchain?

@IonBlade2K this gets it compiling for me although I'm unable to test

-platform = teensy@~4.13.1
+platform = teensy@~5.0.0
IonBlade2K commented 2 months ago

Thanks! Tried it with teensy 5.0.0 earlier today, but the LCD screen just shows up as blinding white. (Interestingly enough, got the same with a newer 4.x).

On the bright side, I was able to get it working by modifying the older 202109040414 build, so it's at least working well enough for my needs now. :)

Ryzee119 commented 2 months ago

okay no worries, ill investigate it tomorrow

Ryzee119 commented 2 months ago

Can you try this? I don't immediately have my N64 handy but I was able to replicate the white screen and it appears fixed now

firmwareteensy50.zip

Changes: https://github.com/Ryzee119/usb64/tree/buildfix

Can build yourself with

git clone https://github.com/Ryzee119/usb64.git
cd usb64
git checkout buildifx
git submodule init
git submodule update

Then build as per normal.

supavgx commented 1 month ago

@supavgx Think I got it, by using an older firmware as a base for the customizations.

If (and only if) you use the 8bitdo modkit with 8bitdo v1 receivers on the latest firmware, try the USB64 firmware in the zip below for full functionality (Rumble, all buttons, and all features but dual analog... since there's only one analog stick :) ).

8bitdomodkit-build-202109040414-base.hex.zip

Note: it uses new hotkey mappings for easier reachability. See below.

I've been using it the last hour with my 8bitdo modkit on a v1 8bitdo receiver on the latest 2.05 firmware, and everything seems to work great!

Controller Compatibility

  • This custom version is intended only for users of the 8bitdo modkit with 8bitdo hardware 1 receivers on the latest firmware.
  • It might also work on N64 Online controllers with the same 8bitdo hardware 1 receiver on the latest firmware, but no guarantees - When using this firmware, ALL Xbox 360 controllers (even if not behind an 8bitdo adapter) and all controllers behind an 8bitdo v1 adapter will use the remappings intended for 8bitdo N64 modkit controllers, so you'll want to use this only if you exclusively use the 8bitdo modkit controllers on 8bitdo v1 adapters. It also strips out the dual analog button mapping, so it's not intended for non-N64 controllers' cases.

Button mapping changes

Since the button on the modkit's controller pak is in a funky spot compared to "back" on 360 controllers, I redid the mappings to be more reachable by the right thumb while you use your index finger to reach for the ZR button, without having to change your left hand between prongs on the controller.

New mappings with this firmware are all triggered via the ZR (far right button on the transfer pak) of the 8bitdo modkit:

  • ZR + C-buttons - memory pak 1-4
  • ZR + R - Transfer pak
  • ZR + A - Rumble pak
  • ZR + B - Virtual pak
  • ZR + Start - Backup buffered memory to SD card

Note: uses a slightly older firmware as base

  • I had to use the older https://github.com/Ryzee119/usb64/releases/tag/build-202109040414 version as the basis - that is missing a few upgrades to SD compatibility / bugfixes in output that Ryzee had mentioned in newer releases. The older version I had to use is the newest whose dependencies are still available so I could compile it.

I've also attached the source containing the changes I made from the 202109040414 version for Ryzee's benefit, in case they are able to build the same build on the newer versions as a base. I couldn't get the newer bases to compile because of the dependencies that are no longer available. All changes were made in main.cpp and input.cpp, using the 202109040414 build as a basis.

Source-Based-On-202109040414.zip

thanks ill give it a try

IonBlade2K commented 1 month ago

Thank you Ryzee! Was able to compile a new fork on 5.0 perfectly with that fix that works perfectly, just sent a donation over your way.

This makes USB64 + the 8bitdo modkit the first way I know of to support near perfect to original accuracy, original OEM construction, rumble, mempaks (through USB64), wireless, and Hall effect sticks that won't wear out over time.

Image attached of the controller test on the 8bitdo modkit with the Hall Effect stick installed, with virtual pak settings set to:

Near perfect to original OEM, and should last ages!

image

I've uploaded the fork with the button mappings for the 8bitdo (and probably the switch online controller. Don't have one to test) based on this over at https://github.com/IonBlade2K/usb64/tree/buildfix. I'll have to see if I can find some time to make some enhancements to allow SD card-based custom mappings before I make a pull request, as this build does overwrite default xbox 360 button behavior to be right for the 8bitdo. Going to take a while to digest the code in full to implement something like that, so no promises, but will be a fun weekend or two project when I can find some free weekends. :)

@supavgx, attached is a version based on the latest USB 64 build, and updated to Teensy 5.0 firmware. Ignore what I said in the last one about remapping the combo buttons. This build uses the stock USB64 combos (d-pad = mempak, L = rumble, start = virtual pak, etc.) for functionality, and just uses the ZR button on the pak for the 8bitdo as the "hotkey".

usb64-teensy5.0-8bitdomodkit.hex.zip

Ryzee119 commented 1 month ago

Thanks for testing it out. Amazing job on the button mapping fix If you want absolute perfection you can tweak this to adjust the magnitude at the 45degree segments. Maybe it could be tweaked up a bit based on your screenshot

I've merged the teensy 5 fix into master branch

https://github.com/Ryzee119/usb64/blob/61153f4a6460ac3999420088cc43a3ff9ed7406a/src/usb64_conf.h#L74

Really appreciate your donation too

IonBlade2K commented 1 month ago

TY! Setting that to 1.15 got me to where I’m ant about perfect overlap with the OEM graph! I do have one small issue left, but it’s nothing I can’t work around by plugging the adapters in one by one. I’ll open an issue in case you’re interested, but honesty it’s not worth the time to solve. 😀

Thank you again!