Sunday, October 27, 2013

DualShock 4 for SDL layout.

Here's a quick dump of getting DualShock 4 support in your SDL title that should work for SDL 1.2 and 2.0.  If you're not using the controller mapping in SDL ( like for Steam OS titles ), but want to do it old-school here's the button layout in SDL terms:

You can detect the pad via the string "Sony Computer Entertainment Wireless Controller".  Here's a dump from Linux dmesg for more USB details if you want to fingerprint:

[ 1154.896287] usb 3-1: new full-speed USB device number 5 using xhci_hcd
[ 1154.913200] usb 3-1: New USB device found, idVendor=054c, idProduct=05c4
[ 1154.913209] usb 3-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 1154.913215] usb 3-1: Product: Wireless Controller
[ 1154.913220] usb 3-1: Manufacturer: Sony Computer Entertainment
[ 1154.913420] usb 3-1: ep 0x84 - rounding interval to 32 microframes, ep desc says 40 microframes
[ 1154.913435] usb 3-1: ep 0x3 - rounding interval to 32 microframes, ep desc says 40 microframes
[ 1154.919473] input: Sony Computer Entertainment Wireless Controller as /devices/pci0000:00/0000:00:14.0/usb3/3-1/3-1:1.0/input/input15
[ 1154.919743] hid-generic 0003:054C:05C4.0007: input,hidraw4: USB HID v1.11 Gamepad [Sony Computer Entertainment Wireless Controller] on usb-0000:00:14.0-1/input0

Analog Sticks and Triggers
Axis 0 - Left Stick Hortz
Axis 1 - Left Stick Vert
Axis 2 - Right Stick Hortz
Axis 5 - Right Stick Vert
Axis 3 - Analog L2
Axis 4 - Analog R2

Directional Pad
Up - 1
Right - 2
Down - 4
Left - 8
Up+Right - 3
Down+Right - 6
Up+Left - 9
Down+Left - 12

Digital buttons
Button 0 - Square
Button 1 - Cross
Button 2 - Circle
Button 3 - Triangle
Button 4 - L1
Button 5 - R1
Button 6 - L2
Button 7 - R2
Button 8 - Share
Button 9 - Options
Button 10 - L3
Button 11 - R3
Button 12 - PS Button
Button 13 - Touchpad depress

Setup Loop
Here's some generic code snippets for setup and detection of the controller.

for ( uint32_t i = 0, count = SDL_NumJoysticks(); i < count; ++i )
{
   /* eg "Sony Computer Entertainment Wireless Controller" */
   const char* joystickName = SDL_JoystickNameForIndex( i );
   SDL_JoystickEventState( SDL_ENABLE );
   sdlDevice->mJoystick = SDL_JoystickOpen( i );
   InputJoystickMap( joystickName, sdlDevice->mJoystick, i );  
}


Event Loop Style Sampling
Here's a generic SDL event loop to access the pad input frame by frame if you like.

 SDL_Event event;
 while ( SDL_PollEvent( &event ) )
 {
  switch (event.type)
  {
  case SDL_JOYDEVICEADDED:
   InputJoystickSignalAdd( event.jdevice.which );
   break;

  case SDL_JOYDEVICEREMOVED:
   InputJoystickSignalRemove( event.jdevice.which );
   break;

  case SDL_JOYHATMOTION:
   InputJoystickSignalDpad( event.jhat.which, event.jhat.hat, event.jhat.value );
   break;

  case SDL_JOYAXISMOTION:
   InputJoystickSignalAxis( event.jaxis.which, event.jaxis.axis, event.jaxis.value );
   break;
  
  case SDL_JOYBUTTONUP:
   InputJoystickSignalButtonRelease( event.jbutton.which, event.jbutton.button, event.jbutton.state );
   break;

  case SDL_JOYBUTTONDOWN:
   InputJoystickSignalButtonPress( event.jbutton.which, event.jbutton.button, event.jbutton.state );
   break;

   ...


No comments: