Introduction

A lot can be found for interfacing a Wii-mote, but almost nothing could be found for accessing the new PS3 controller. This is not yet a complete highly re-usable library. Instead it looks more like a hack. But it does provide the eager programmer a way to communicate with a PS3 controller. The biggest trick is the mapping of the received data-block to a nice and easy struct. I made a variable for all buttons, so even the combined bits in a BYTE are mapped to a 'bool'.

The PS3 controller does get recognized by Windows, but before the controller reacts on our request, the following driver should be installed. (Tested under Windows XP and Windows Vista).

Using the Code

When the application is started it will register for device-connection events. When a PS3 controller is connected the 'ThreadPS3' is created. This thread will contiuosly fill a struct of type PS3_data. This struct will contain all buttons. Digital and analog values.

For demo purposes I also made a 'Format' method, which make a output string, to show in the dialog of the current state of the controller.

One nice thing about C is the ability to let the compiler help in splitting up a raw data structure.

Three of the features used are nameless struct, nameless union and data width settings:

nameless structThis makes it possible to 'group' a set of variables, while not needing to add the struct name in the variable name. Instead of PS3_data.Report.LAnalogX we can simply use PS3_data.LAnalogX.

A second feature is the abilty to use the struct in a union. So you can map two structs to the same location, without the need to give this struct a name.

nameless unionThis makes it possible to let multiple variables be positioned on the same physical memory location. The variable PS3_data.LAnalogX shares the same memory location with PS3_data.data[0].

data width settingsThis makes it possible to map a number of bool's to a BYTE. This way we can use PS3_data.Circle instead of (PS3_data.data[48]&0x02)

Why did I use this? Because now it is possible to fill the complete structure using a memcpy to a PS3Data* and then be able to access all requested attributes both by name and by byte offset. The known parts of the struct can be accessed by name. And the unknown parts can be accessed by the direct data[i] member.

Another interesting code snippet is the use of sprintf instead of CString::Format and t += w;

Every call to += results in allocation of a little bit larger memory block and a copy of the complete previous data and a copy of the new data.

iPos += sprintf(&buffer[iPos],"test %d\r\n", 0 );

The sprintf will return the number of the newly added characters in iPos. This variable is used to feed the next call to sprintf with the offset in the original buffer &buffer[iPos]. Only thing to consider is ... the buffer MUST be large enough.

Comments and Discussions

hello, I'm a 29 year old game dev student.I'm looking to write a "drum brain" and build myself an electronic drum kit out of recycled Rock band parts. I can get the device to recognize,and during the test in <control panel-="">controllers> shows that the buttons are working properly. the problem is in my app, unbuffered input is always returning true and buffered input is always false. Do you know what a likely cause of this may be or could you provide some help in any way please. It is to my understanding that if <control panel-="">controllers> is working properly, then direct input should be recognizing it. Thanks.