Dolphin, the GameCube and Wii emulator - Forums

Full Version: Adding GC Keyboard support
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Does anyone have more detailed documentation(yaGCD doesn't have keyboard commands) or perhaps a homebrew application that tests the GC Keyboard? I'm trying to implement keyboard support into Dolphin for PSO, and I'm not entirely sure how to respond to the commands it's sending to the emulated keyboard. It starts off with a 0xFF, but I have no clue what to respond with.
It is supported is it not? If not it was talked about but I don't remember what happened
No, it's not. The code has a few variables related to it, but there's no code implemented for it [yet]. If I knew how to respond to what it's asking for, it wouldn't be long before we have keyboard support.

Edit 1: I know next to nothing about PowerPC assembly, but I did manage to get a response from PSO by sending it 0x7F. I found this out by printing the Program Counter to the log window and then looking in the debugger where it told me it first started getting keyboard commands: 8042db90. More to come as I get responses from PSO...

Edit 2: Nevermind.It's not looking for 7F. Guess I'm back to where I started. Undecided

Edit 3: It seems to reset the keyboard with a 0x00 command after spamming 0xFF, so I guess it has a timeout period of 30 retries. Progress, at least. I just need to figure out what the heck to reply with..


Edit 4: I got it to respond!!!
09:55:013 Src\HW\SI_Device.cpp:29 E[SI]: Send Data Device(0) - Length(4)
09:55:013 Src\HW\SI_Device.cpp:46 E[SI]: 0xff 0x00 0x00 0x00
09:55:013 Src\HW\SI_DeviceGCKeyboard.cpp:312 E[SI]: Unknown direct command (0x540000)

I had to reply with SI_GC_KEYBOARD, which I guess tells PSO that a Keyboard is connected. Now to deal with this new 0x540000 direct command...

Edit 5: So according to YAGCD I have to do this next:

"set Joy-channel Command Register to 0x00540000"

Which involved me doing this:
Code:
        SerialInterface::Write32(_Cmd, 0x30); //SI_POLL
        SerialInterface::Write32(1, 0x34);//SI_CTRLSTATUS
In order to set that register to 0x00540000, and then 1 to enable polling.

Now I'm getting 128 bytes per frame, though I'm not sure what they mean just yet.
Code:
51:45:023 Src\HW\SI_Device.cpp:29 E[SI]: Send Data Device(0) - Length(128)  
51:45:023 Src\HW\SI_Device.cpp:42 E[SI]: 0x08 0x20 0x00 0x00 0x80 0x80 0x1f 0x1f
51:45:023 Src\HW\SI_Device.cpp:42 E[SI]: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
51:45:023 Src\HW\SI_Device.cpp:42 E[SI]: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
51:45:023 Src\HW\SI_Device.cpp:42 E[SI]: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
51:45:023 Src\HW\SI_Device.cpp:42 E[SI]: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
51:45:023 Src\HW\SI_Device.cpp:42 E[SI]: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
51:45:023 Src\HW\SI_Device.cpp:42 E[SI]: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
51:45:023 Src\HW\SI_Device.cpp:42 E[SI]: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
51:45:023 Src\HW\SI_Device.cpp:42 E[SI]: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
51:45:023 Src\HW\SI_Device.cpp:42 E[SI]: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
51:45:023 Src\HW\SI_Device.cpp:42 E[SI]: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
51:45:023 Src\HW\SI_Device.cpp:42 E[SI]: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
51:45:023 Src\HW\SI_Device.cpp:42 E[SI]: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
51:45:023 Src\HW\SI_Device.cpp:42 E[SI]: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
51:45:023 Src\HW\SI_Device.cpp:42 E[SI]: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
51:45:023 Src\HW\SI_Device.cpp:42 E[SI]: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
As you already figured out, the 0xFF command should be treated the same as 0x00 - by returning the keyboard's SI ID.

The 0x00540000 command doesn't really need any handling in an emulated keyboard (besides incrementing an internal counter, mentioned below). Its real purpose is to tell the physical hardware to poll the current state of the buttons. You shouldn't be touching the other SI registers, the information on yagcd is telling you how to control a keyboard, not what a keyboard should be doing.

Regarding the high and low input words returned by the keyboard, the information on YAGCD is a bit lacking. The high input word has the normal ERRSTAT and ERRLATCH bits (31 and 30 respectively) common to all SI devices, it also uses bits 27-24 to hold a counter variable (as mentioned above).
The low input word returns up to 3 keycodes from the keyboard (one value per byte as described by YAGCD). The final byte holds an xor sum of the other 3 bytes and the 4-bit counter, so the game can verify the high and low input words are from the same polling period.

So for example if the current value of the internal counter was 7 and the A, B and F3 keys were held down:
High word: 0x07000000 // No ERRSTAT/ERRLATCH
Low Word: 0x10114244 // A=0x10, B=0x11, F3=0x42, 0x10 XOR 0x11 XOR 0x42 XOR 0x07 = 0x44
Thanks tueidj! That really helped. I've got PSO showing a bunch of A's and B's now(hardcoded); hopefully it won't be long before it's responding to my actual keyboard(still need to code this part).
Also, am I correct in assuming that 0x00 0x00 0x00 is sent when no key was pressed(for the 3 key bytes)?
[Image: e97vuql.png]

Also, would anyone mind giving me a high level overview of how the input system works in Dolphin? I'm reading through some of the code, but it's sort of confusing. I'd like to map most of the keyboard buttons 1:1 with the GC keyboard, but I'm unsure how currently.

I'll keep looking at it in the meantime.
Yes, the dolphin input system is a little bit "structured". I'll try my best to explain it, but it's probably best to base your code off one of the existing emulated gc control devices like the steering wheel, bongo drums or GBA device. These devices are in the files, SI_DeviceGBA.cpp, SI_DeviceGCController.cpp or SI_DeviceGCSteeringWheel.cpp

GBA uses TCP/IP as the interface whilest the other two hook into the GCPad config dialog. For the GC keyboard, I would probably try adding a checkbox under Options of the GCPad dialog to represent that you want to route all of the PC keyboard controls to the GC keyboard device. That way, you are making use of the input API (e.g. DInput).

Alternatively, you could bypass the GCPad dialog and pass PC keyboard data via some other means like TCP/IP similar to how the GBA device does it.

The SI_Device* class receives input from GCPad.cpp, which gets input from GCPadEmu.cpp, which gets input from ControllerEmu.h, which gets input from ControllerInterface.cpp, which finally gets input from the class that handles the input API (e.g. DInputJoystick.cpp). Don't laugh. Talk to Billiard.

So make a tunnel that pierces the classes above passing through the keyboard data received from the input API. Not sure if DInput will send you the key scancodes for keys that are simultaneously pressed. It would be preferable if you created a new GCKeyboard.cpp that sits alongside GCPad, but you'd need to figure out how to hook the GUI and input API (or ControllerInterface) into this.

Hope that helps a bit...
(04-20-2013, 02:27 AM)daxtsu Wrote: [ -> ]Also, am I correct in assuming that 0x00 0x00 0x00 is sent when no key was pressed(for the 3 key bytes)?

Also, would anyone mind giving me a high level overview of how the input system works in Dolphin? I'm reading through some of the code, but it's sort of confusing. I'd like to map most of the keyboard buttons 1:1 with the GC keyboard, but I'm unsure how currently.
IIRC the "currently held" keys are reported first with trailing zeroes filling the unused slots. So yes, no keys down is all zeroes.
There are a couple of minor issues with mapping keys 1:1 (some of the GC keyboard's shifted states are different from a PC keyboard) but they're not really worth worrying about. As long as the input system can feed you reliable state events (button X went down, button Y was released) including caps lock and num lock it should be easy enough.
I realise this thread is a year old now, but I wanted to voice my support in case anyone is still working on this or might consider taking another stab at it. The software keyboard in PSO really limits your ability to communicate, so this would be a highly useful addition to Dolphin now that the BBA is supported.

j-cutter

Hi, all. Thanks to daxtsu, tueidj, & Co. for looking at this. I Know there's a lot more important issues that this, but it's nice to see it's tracked as a "to do" item already.