raphnet / gc_n64_usb-v3

Gamecube/N64 to USB adapter firmware (3rd generation)
http://www.raphnet.net/electronique/gcn64_usb_adapter_gen3/index_en.php
GNU General Public License v3.0
42 stars 10 forks source link

Feature request: retroarch mapping compatibility #10

Open vpelletier opened 2 years ago

vpelletier commented 2 years ago

I recently purchased this adapter, and was disappointed that it did not work out-of-the-box with retroarch: while 9 N64 buttons did get detected, 5 did not trigger any event.

I dug a bit, and the first level of this issue is that SDL2 lacks a profile for this controller, and the one it seems to internally auto-generate is incorrect (in my case, preventing L, R, Z, Cleft and Cright from being detected). I have not dug into SDL2's default mapping yet.

This can be worked around by the following controllermap line:

030000009b2800006000000001010000,raphnet technologies GC/N64 to USB v3.6,platform:Linux,a:b0,b:b1,start:b3,leftshoulder:b4,rightshoulder:b5,dpup:b10,dpdown:b11,dpleft:b12,dpright:b13,leftx:a0,lefty:a1,-rightx:b8,+rightx:b9,-righty:b6,+righty:b7,lefttrigger:b2,

~~and by setting the SDL_GAMECONTROLLERCONFIG_FILE environment variable to that file's path before running retroarch. I could then assign all the buttons:~~

$ cat ~/.config/retroarch/autoconfig/sdl2/raphnet\ technologies\ GC_N64\ to\ USB\ v3.6.cfg
input_driver = "sdl2"
input_device = "raphnet technologies GC/N64 to USB v3.6"
input_vendor_id = "10395"
input_product_id = "96"
input_a_btn = "0"
input_b_btn = "1"
input_l2_btn = "2"
input_start_btn = "6"
input_l_btn = "9"
input_r_btn = "10"
input_r_y_minus_btn = "6"
input_r_y_plus_btn = "7"
input_r_x_minus_btn = "8"
input_r_x_plus_btn = "9"
input_up_btn = "11"
input_down_btn = "12"
input_left_btn = "13"
input_right_btn = "14"
input_l_x_plus_axis = "+0"
input_l_x_minus_axis = "-0"
input_l_y_plus_axis = "+1"
input_l_y_minus_axis = "-1"
input_l2_axis = "+4"
input_r_x_plus_axis = "+2"
input_r_x_minus_axis = "-2"
input_r_y_plus_axis = "+3"
input_r_y_minus_axis = "-3"

The second level of this issue is that retroarch cannot provide a default mapping for this adapter, because they cannot distinguish between an N64 controller and a GC controller being plugged in, and both will report different events for the "same" button. This applies to the above SDL2 controllermap, which will likely only work for N64 controllers (I do not have a GC controller at the moment to confirm this, though).

Here is an idea I had: could the adapter change its descriptors based on what controller is plugged in ? I believe it could be:

I believe it should be possible for the device to disconnect itself from the bus and then to reconnect itself, in order to trigger a new enumeration, allowing the descriptor changes to be noticed by the host, but I have not checked its documentation (I know it is possible on the Cypress FX2 µC).

If this is done, then it becomes reliably possible to write:

vpelletier commented 2 years ago

it did not work out-of-the-box with retroarch

My apologies. It looks like I had a non-default setting (maybe I started retroarch long ago and forgot ?). Using X as input driver and udev as controller driver instead of SDL2 in both and every button works fine without remapping shenanigans.

Nevertheless, I think the suggestion of making the adapter identify itself differently based on what controller is plugged in may make sense regardless.

claabs commented 6 months ago

I'll add in that I'm also seeing this issue with SDL2 applications. It essentially nullifies the ability to use some buttons on the N64 side of the adapter, since the GC mapping is the default mapping in gamecontrollerdb

Comparing the two (formatted for convenience)

030000009b2800006000000000000000,Raphnet GC/N64 - GC ,a:b0,b:b7,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,lefttrigger:+a5,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:+a2,rightx:a3,            righty:a4,            start:b3,                x:b1,y:b8,platform:Windows,
030000009b2800006000000000000000,Raphnet GC/N64 - N64,a:b0,b:b1,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,                leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b2, +rightx:b9,-rightx:b8,+righty:b7,-righty:b6,start:b3,leftshoulder:b4,          platform:Windows,

I considered mapping the missing N64 b5, b6, and b9 to random SDL buttons, but I think issues would arise on the analog/digital input mapping, and it's not a great UX for N64 controller users to have a mixed up controller layout by default.

As mentioned by OP, it would be ideal to have a separate gamepad GUID for the N64 side of the adapter.