Add support for the P5 Glove to Torque
by Brian Richardson · 12/14/2004 (11:09 pm) · 26 comments
Download Code File
Adding new input devices to Torque
Add support for the P5 Glove to The Torque Game Engine!
This article will explain how I added support for the P5 Glove to Torque. I'm attempting to document the discovery process I went through to add the feature. I hope this will help you learn strategies to learn things about a large piece of new code. If you don't care about that, and just want to get the glove supported, look at the CODE CHANGE: blocks. Also, it's a good introduction to the input system, so you could use this as a guide to add new device support to Torque.
When approaching a new system, you need to figure out ways to discover how it works. I'm a big fan of using the debugger. I'll set some breakpoints then look at the callstack to see how the program flows. Another thing to do is to think of something that behaves similiar to what you're trying to accomplish. We are going to use this method in this article. In this case, the mouse acts very simliar to the glove. So a good place to start learning is to look at how the mouse gets handled in Torque.
GET TO WORK!
I have a lot of experence with the Windows API, and I've played around with other windowing systems. They all share the idea of having events placed in a message queue that gets processed. Based on this experience, I took a guess that Torque behaved similiarly. It would have to take the events that it received in whatever runtime environment it was in and translate it into's own messages. The first place to poke around would be the platform layer!
I'm working with windows, so I do a find in files for "mouse" in the platformwin32 directory. If you do this, you'll see a bunch of results that look like it's using the DirectInput interface to use the mouse, and also some results in winWindow.cc. Which one gets used? In my case, it was the winWindow.cc. I checked this by running "echoInputState()" in the console. (TODO: Confirm this). I found this function in winDirectInput.cc. Which was found by the find-in-files. So, I started looking closer at winWindow.cc. If you do, you'll quickly run into a function called "CheckCursorPos". Bingo! You'll see it is injecting events into Torques message queue! We'll add our own CheckCursorPos() call right after that does essientially the same thing.
Ok, we can now add new messages into Torque's message queue. Isn't that exciting! woo! What happens to these messages though? Right now, they'll just disappear into the abyss. We need to add some method of responding to these events. Let's go back to looking at the mouse as an example. In order to map the mouse to a game event, you use the moveMap.bind script command. Let's find out how this works. I did a find in files in the Torque directory for ::bind. Why the double colon? This will filter out all of the glBindTexture calls, and just get us to the class that implements the bind command quickly. If you do this, you'll get a couple hits with Net::bind, and actionMap.cc.
Let's look at actionmap.cc, this file implements the logic that maps an input event (mouse, keyboard, glove!) to a script command. Let's just keep searching for "mouse". The first hit you see is getDeviceTypeAndInstance. This little function maps a string to fields in the InputEvent structure. You can see the compare for "mouse" and the deviceType = mouseDeviceType line. So let's add our glove additions in here!
Let's continue searching for mouse. The next hit you get is "getDeviceName" which does basically the opposite. Add this block in:
So I did a bit of debugging and found out that ActionMap::processAction was the function that actually processed input events. I noticed that the inputEvents I was creating in winWindow.cc where making it here. So at least I was that far! If I was a bit smarter, I could have just continued to search for "mouse", if you do that you'll see a nice little conditional statement here:
To use the code included, download this file. Then add the winP5Device.cc file to your Torque project. Put both the cc, and the h file into your engine/platformWin32 directory. Then, unzip the P5 SDK into the lib/p5 directory. Finally, add the lib to your Torque project. Compile for 2 minutes and let it cool before serving to guests.
Hope that helps someone out there! Please contact me and let me know how I can improve this article!
Brian Richardson
skinny at knowhere.net
Adding new input devices to Torque
Add support for the P5 Glove to The Torque Game Engine!
This article will explain how I added support for the P5 Glove to Torque. I'm attempting to document the discovery process I went through to add the feature. I hope this will help you learn strategies to learn things about a large piece of new code. If you don't care about that, and just want to get the glove supported, look at the CODE CHANGE: blocks. Also, it's a good introduction to the input system, so you could use this as a guide to add new device support to Torque.
When approaching a new system, you need to figure out ways to discover how it works. I'm a big fan of using the debugger. I'll set some breakpoints then look at the callstack to see how the program flows. Another thing to do is to think of something that behaves similiar to what you're trying to accomplish. We are going to use this method in this article. In this case, the mouse acts very simliar to the glove. So a good place to start learning is to look at how the mouse gets handled in Torque.
GET TO WORK!
I have a lot of experence with the Windows API, and I've played around with other windowing systems. They all share the idea of having events placed in a message queue that gets processed. Based on this experience, I took a guess that Torque behaved similiarly. It would have to take the events that it received in whatever runtime environment it was in and translate it into's own messages. The first place to poke around would be the platform layer!
I'm working with windows, so I do a find in files for "mouse" in the platformwin32 directory. If you do this, you'll see a bunch of results that look like it's using the DirectInput interface to use the mouse, and also some results in winWindow.cc. Which one gets used? In my case, it was the winWindow.cc. I checked this by running "echoInputState()" in the console. (TODO: Confirm this). I found this function in winDirectInput.cc. Which was found by the find-in-files. So, I started looking closer at winWindow.cc. If you do, you'll quickly run into a function called "CheckCursorPos". Bingo! You'll see it is injecting events into Torques message queue! We'll add our own CheckCursorPos() call right after that does essientially the same thing.
CODE CHANGE: In engine/platformWin32/winWindow.cc In the include block, add this include: #include "winP5Device.h" In Platform::process(), under CheckCursorPos() add the following: if(windowLocked && windowActive) P5Glove::Glove().CheckCursorPos();Ok, we've got a hook to inject new messages into Torque. What's next? We need to know how to fill up that event. If you look at the CheckCursorPos code in winWindow.cc, you'll see the "InputEvent" structure that gets filled up with data, and added to the queue with the Game->postEvent call. If you just wanted the glove to emulate the mouse, you could stop here and just fill up the structure the same way. However, I wanted to add a full new device type in. If you look at event.deviceType, it gets set to MouseDeviceType. We need to find out where this is defined and add a GloveDeviceType to it. I did a search for MouseDeviceType in platformWin32 and ended up with no good hits. So I went up and did a serch in the engine directory and ended up with a good hit in engine/platform/events.h.
CODE CHANGE:
In engine/platform/events.h:
In add this to the enum InputDeviceTypes list:
/// Input device types
enum InputDeviceTypes
{
UnknownDeviceType,
MouseDeviceType,
KeyboardDeviceType,
JoystickDeviceType,
GloveDeviceType
};Ok, we can now add new messages into Torque's message queue. Isn't that exciting! woo! What happens to these messages though? Right now, they'll just disappear into the abyss. We need to add some method of responding to these events. Let's go back to looking at the mouse as an example. In order to map the mouse to a game event, you use the moveMap.bind script command. Let's find out how this works. I did a find in files in the Torque directory for ::bind. Why the double colon? This will filter out all of the glBindTexture calls, and just get us to the class that implements the bind command quickly. If you do this, you'll get a couple hits with Net::bind, and actionMap.cc.
Let's look at actionmap.cc, this file implements the logic that maps an input event (mouse, keyboard, glove!) to a script command. Let's just keep searching for "mouse". The first hit you see is getDeviceTypeAndInstance. This little function maps a string to fields in the InputEvent structure. You can see the compare for "mouse" and the deviceType = mouseDeviceType line. So let's add our glove additions in here!
CODE CHANGE:
In engine/sim/actionMap.cc:
In ActionMap::getDeviceTypeAndInstance, Add this block after the joystick block:
} else if (dStrnicmp(pDeviceName, "glove", dStrlen("glove")) == 0) {
deviceType = GloveDeviceType;
offset = dStrlen("glove");Let's continue searching for mouse. The next hit you get is "getDeviceName" which does basically the opposite. Add this block in:
CODE CHANGE In ActionMap::getDeviceName, add this block after the joystick block: case GloveDeviceType: dSprintf(buffer, 16, "glove%d", deviceInstance); break;I stopped at this point. I reasoned that the functions to convert the string to the structure and back where done, and that should be all it needed to begin working! I compiled and waved my arm around and nothing got triggered.
So I did a bit of debugging and found out that ActionMap::processAction was the function that actually processed input events. I noticed that the inputEvents I was creating in winWindow.cc where making it here. So at least I was that far! If I was a bit smarter, I could have just continued to search for "mouse", if you do that you'll see a nice little conditional statement here:
CODE CHANGE:
Finally in ActionMap::processAction, find the following lines:
} else if (pEvent->action == SI_MOVE) {
if (pEvent->deviceType == MouseDeviceType) {
const Node* pNode = findNode(pEvent->deviceType, pEvent->deviceInst,
pEvent->modifier, pEvent->objType);
I just added another compare to allow this code to run for mouse or glove.
Change the if statement to this:
if ((pEvent->deviceType == MouseDeviceType) || (pEvent->deviceType == GloveDeviceType)) {Finally, waving my hand around caused my script triggers to be called, and I could continue working on my project! To use the code included, download this file. Then add the winP5Device.cc file to your Torque project. Put both the cc, and the h file into your engine/platformWin32 directory. Then, unzip the P5 SDK into the lib/p5 directory. Finally, add the lib to your Torque project. Compile for 2 minutes and let it cool before serving to guests.
Hope that helps someone out there! Please contact me and let me know how I can improve this article!
Brian Richardson
skinny at knowhere.net
About the author
#22
echoInputState(); or echo(isMouseEnabled());
I added additional Console Functions for the P5. However, as long as the resource is implemented properly, the mouse is enabled and active, and direct input is active, the P5 should work fine.
11/27/2006 (5:26 am)
There are a couple of functions you can call from the console to check if everything is working:echoInputState(); or echo(isMouseEnabled());
I added additional Console Functions for the P5. However, as long as the resource is implemented properly, the mouse is enabled and active, and direct input is active, the P5 should work fine.
#23
Where can I find the p5dll? It wasn't on the CD or in the zip file in this resource...
(EDIT:)
Also, where are these files: (rest of SDK)
"P5Bend.cpp, P5Bend.h, P5DLL.lib, P5Motion.cpp, "
02/06/2007 (1:31 am)
Please excause my newb question in advance =-)Where can I find the p5dll? It wasn't on the CD or in the zip file in this resource...
(EDIT:)
Also, where are these files: (rest of SDK)
"P5Bend.cpp, P5Bend.h, P5DLL.lib, P5Motion.cpp, "
#25
However, the link is broken =-(
I tried to look elsewhere on the net, but only found part of the files mentioned above.
Does anyone have these files, or alink to them?
Any help would be greatly appreciated!
02/07/2007 (4:28 am)
Thanx MichaelHowever, the link is broken =-(
I tried to look elsewhere on the net, but only found part of the files mentioned above.
Does anyone have these files, or alink to them?
Any help would be greatly appreciated!
#26
02/07/2007 (5:30 am)
I can absolutely guarantee you the link isn't broken, because I just downloaded the SDK. However, shoot me an e-mail at the address listed in my profile and I can send you the files.
Torque Owner _____________ _
On trying to configure the glove with torque with the instruction provided, I noticed that the mouse isnt working when i try to navigate the game with it. Could this be the reason that it doesnt recognise the P5 glove?
The program generated the following in the console log file:
Activating DirectInput...
keyboard0 input device acquired.
keyboard0 input device unacquired.
DirectInput deactivated.
keyboard0 input device created.
mouse0 input device created.
Thanks for all your help again
Irura