NicoHood / Nintendo

Use Nintendo Controllers with Arduino
http://www.nicohood.de
MIT License
278 stars 55 forks source link

Gamecube: Add support for Steering Wheel #6

Open Otamay opened 8 years ago

Otamay commented 8 years ago

In line 105 of Nintendo.cpp: uint8_t command[] = { 0x40, 0x03, rumble & 0x01 };

by changing it to: uint8_t command[] = { 0x30, 0x00, 0x00 };

This would enable reading from Nintendo Steering Wheel (buttons and wheel). First command byte should be dependant upon Gamecube device type, 0x900 for regular and 0x800 for steering wheel. Other devices not tested yet. What would be the right way of implementing it?

PD: keeping second command (0x03, polling for gamecube?) would cause steering wheel to turn right.

NicoHood commented 8 years ago

Thx for the note. I havent been working on this for quite some time. Doesnt mean I dont want to improve the project ;)

I recently pushed my (unfinished) work of the n64 implementation to the dev2 branch. https://github.com/NicoHood/Nintendo/tree/dev2

This should work for reading N64 controllers. I was about to enable the other way, to pretend the arduino to be a controller, so you can create a gamecube to n64 adapter etc.

Feel free to push any improvements to the dev2 branch then.

I think a good idea would be to add the wheel here, and in the examples as well: https://github.com/NicoHood/Nintendo/blob/dev2/src/Gamecube.h#L36

Does the wheel has the same output as a controller? (like this https://github.com/NicoHood/Nintendo/blob/dev2/src/Gamecube.h#L49-L92 ) If yes, then we could add this quite simple I think. Where did you get the information from? Which wheel exactly are you using? If I have more information I could add this more safe to the repo. I could also add links to the wiki, so people can also profit from this information.

Edit: It would be nice if you can test the dev2 branch, so I can merge it to master. I'll then just leave it "as it is". Then the library would at least appear in the library manager of the ide, n64 experimental.

Otamay commented 8 years ago

Hello, I've forked your project and created a pull request (sorry if I did something wrong, didn't have used git before).

Your dev2 branch seems to be better organized, I've made the proper changes for wheel support and tested the code, it works fine (tested only gamecube control input, I haven't tested other features like N64 support or working as a HID). However, regarding my changes, in read function inside Gamecube.cpp Device ID must be obtained somehow to choose the apropiate command to be sent, but I don't know another way for doing this than by adding the "status" parameter and directly read the Device ID.

Second and third values of the command sent are values for playing with the control's force-feedback. In this link there are some clues about how to implement it properly: https://forums.dolphin-emu.org/Thread-anybody-own-a-logitech-speed-force-racing-wheel-for-gamecube?pid=232321#pid232321

Regarding buttons, wheel has the same output as the controller, except that X stick values and c-stick X and Y values are read as 0. So aside of force-feedback, the steering wheel works as a normal gamecube controller.

NicoHood commented 8 years ago

This could lead us to call begin() automatically before we call read(). With a proper timeout we could detect if a device disconnects and begin() has to be called again. This would make it easier for the user to use this library and more save for the (untested) wireless controllers which require the begin() call.

Instead of passing the whole struct, I'd rather just pass the device id. But with the approach above we could avoid this.

I do not have the cables here till christmas, so I am not able to test this. I am willing to add wheel support then, but I'd like to improve the API some further (and also test write() and N64 at the same time.

I think you got your solution for now, I will try to fix this after christmas then. People who want to use the wheel can test your PR for now. Thanks a lot!

NicoHood commented 8 years ago

I am currently trying to add "blind" wheel support. From what I see here (and in your code) the force value seems to be a signed value: https://github.com/dolphin-emu/dolphin/blob/master/Source/Core/Core/HW/SI_DeviceGCSteeringWheel.cpp#L88

So there is a left/right rumble:

unsigned int uStrength = command.Parameter1; // 0 = left strong, 127 = left weak, 128 = right weak, 255 = right strong
unsigned int uType = command.Parameter2; // 06 = motor on, 04 = motor off

What I do not know if there is a "rumble left and right" mode. I think i am going to enable rumble if force != 0.

I will create a "wheel" branch with the changes, so anyone can test.