Control Mapping and Joystick axis issues
by Scott Przybylski · in Torque 3D Professional · 09/02/2013 (2:51 pm) · 1 replies
I'm working on a racing game, so controls will most likely be mapped to a steering wheel. Unfortunately by default, the options dialog control mapping doesn't work with joystick axis.
I dug through torque script and C++ code to find the problem. The first issue is that the joystick wasn't enabled in the gui. That was easy to sort out, just had to call activateDirectInput() and enableJoystick().
Still no dice, so I dug into the guiInputCtrl.cpp
I found that:
was not handling event.action == SI_MOVE, which is what the joystick axis events are sent as, so I added the following if statement:
After adding this, I got the control mapping dialog to show me "??" as soon as I tried to re-map a control. From this I could tell that one of my axis was getting triggered immediately, not when it moved which is due to noise. I tracked down the "??" issue in optionsDlg.cs torque script.
onInputEvent calls getMapDisplayName and getMapDisplayName was not handling joystick axis events either, so I added the following:
Now it would display the correct joystick axis name. There was just one more problem, I didn't want it to map the axis until the axis value changed. My guess is that this could be fixed with a deadzone, or what I did was set it up so onInputEvent was only called when there was a significant change in the axis value.
Mainly I'm wondering if you guys think the last part is a good idea or not. Should it only send inputEvents when the axis changes? Or should it always be sending inputEvents.
Also whats the best way to store joystick configuration settings like deadzones? It would need to be per joystick and axis.
I'd like to submit this as a pull request.
Scott
I dug through torque script and C++ code to find the problem. The first issue is that the joystick wasn't enabled in the gui. That was easy to sort out, just had to call activateDirectInput() and enableJoystick().
Still no dice, so I dug into the guiInputCtrl.cpp
I found that:
bool GuiInputCtrl::onInputEvent( const InputEventInfo &event )
was not handling event.action == SI_MOVE, which is what the joystick axis events are sent as, so I added the following if statement:
else if ( event.action == SI_MOVE )
{
const char* actionString = ActionMap::buildActionString( &event );
char deviceString[32];
if ( !ActionMap::getDeviceName( event.deviceType, event.deviceInst, deviceString ) )
return( false );
onInputEvent_callback(deviceString, actionString, 1);
return( true );
}After adding this, I got the control mapping dialog to show me "??" as soon as I tried to re-map a control. From this I could tell that one of my axis was getting triggered immediately, not when it moved which is due to noise. I tracked down the "??" issue in optionsDlg.cs torque script.
onInputEvent calls getMapDisplayName and getMapDisplayName was not handling joystick axis events either, so I added the following:
else
{
%pos = strstr( %action, "axis");
if( %pos != -1)
{
%wordCount = getWordCount( %action );
%mods = %wordCount > 1 ? getWords( %action, 0, %wordCount - 2) @ " " : "";
%object = getWord( %action, %wordCount - 1);
switch$ ( %object )
{
case "xaxis": %object = "X axis";
case "yaxis": %object = "Y axis";
case "zaxis": %object = "Z axis";
case "rxaxis": %object = "RX axis";
case "ryaxis": %object = "RY axis";
case "rzaxis": %object = "RZ axis";
case "slider": %object = "Slider";
default: %object = "??";
}
return( %mods @ %object );
}
else
{
error( "Unsupported Joystick input object passed to getDisplayMapName!" );
}
}Now it would display the correct joystick axis name. There was just one more problem, I didn't want it to map the axis until the axis value changed. My guess is that this could be fixed with a deadzone, or what I did was set it up so onInputEvent was only called when there was a significant change in the axis value.
struct ObjInfo
{
InputEventType mType;
InputObjectInstances mInst;
S32 mMin, mMax;
F32 mLastVal;
};if(newEvent.fValue > objInfo.mLastVal + 0.01 || newEvent.fValue < objInfo.mLastVal - 0.01) {
newEvent.postToSignal(Input::smInputEvent);
}
objInfo.mLastVal = newEvent.fValue;Mainly I'm wondering if you guys think the last part is a good idea or not. Should it only send inputEvents when the axis changes? Or should it always be sending inputEvents.
Also whats the best way to store joystick configuration settings like deadzones? It would need to be per joystick and axis.
I'd like to submit this as a pull request.
Scott
About the author
Attempting to create a Hydroplane Racing simulation with Torque 3D.
Torque Owner Scott Przybylski
HydroSim