Using pov2 actions
by Robert DeMaria · in Torque Game Builder · 04/03/2007 (7:04 pm) · 7 replies
Right now, I'm trying to get support for the d-pad to work. When you press the up or down button and then press the left button, the function bound to lpov2 action will be called. Unfortunately, when you let go of all the d-pad buttons, neither the lpov or the lpov2 functions will be called to let the program know that the user has stopped pressing a d-pad button. The same thing happens with the right dpad button. Is this a bug, or am I simply using the ActionMap incorrectly?
Here is my code:
Here is my code:
actionMap.bind("joystick", "lpov", "dpadLeft");
actionMap.bind("joystick", "lpov2", "dpadLeft2");
#2
To better describe what's going on, I'll step through it:
I will press up or down on the d-pad.
Then, while still pressing up or down, I will press left or right on the d-pad.
The function bound to lpov2 or rpov2 will be called.
I will then release all the buttons on the d-pad.
Here's the problem: no functions will be called indicating that the left or right d-pad buttons have been released.
Because no functions have been called indicating that the buttons have been released, the game still thinks that that the left or right buttons are still being pressed.
This problem does not occur if you simply press and release the left or right d-pad buttons without holding up or down first.
04/04/2007 (10:29 am)
Yes I have checked the reference documents. Unfortunately, I haven't come across anything that explains why I'm not receiving input events for the left or right d-pad buttons being released after lpov2 or rpov2 send input events indicating they're being pressed.To better describe what's going on, I'll step through it:
I will press up or down on the d-pad.
Then, while still pressing up or down, I will press left or right on the d-pad.
The function bound to lpov2 or rpov2 will be called.
I will then release all the buttons on the d-pad.
Here's the problem: no functions will be called indicating that the left or right d-pad buttons have been released.
Because no functions have been called indicating that the buttons have been released, the game still thinks that that the left or right buttons are still being pressed.
This problem does not occur if you simply press and release the left or right d-pad buttons without holding up or down first.
#3
04/06/2007 (4:11 pm)
Could someone with a gamepad put in the following code, then go through the steps I've outlined in my previous post and tell me what gets printed to the console? I am completely stumped and I'd like to know if the same thing happens to someone else.actionMap.bind("joystick", "lpov", "dpadLeft");
actionMap.bind("joystick", "lpov2", "dpadLeft2");
actionMap.bind("joystick", "rpov", "dpadRight");
actionMap.bind("joystick", "rpov2", "dpadRight2");
actionMap.bind("joystick", "upov", "dpadUp");
actionMap.bind("joystick", "upov2", "dpadUp2");
actionMap.bind("joystick", "dpov", "dpadDown");
function dpadLeft(%val)
{
echo("left "@%val);
}
function dpadLeft2(%val)
{
echo("left 2 "@%val);
}
function dpadRight(%val)
{
echo("right "@%val);
}
function dpadRight2(%val)
{
echo("right 2 "@%val);
}
function dpadUp(%val)
{
echo("up "@%val);
}
function dpadDown(%val)
{
echo("down "@%val);
}
#4
Here's the svn change log:
- rewrote d-pad input on win32, fixing a bug and improving overall behavior.
-- fixed a bug where, if a dpad button was pressed, and the dpad was rotated to another button, the 'pressed' event would incorrectly go to the 2nd dpad instance.
-- diagonal input is now possible: for example if the dpad is pressed to the upper right, both the up and right buttons get pressed, and if dpad is rotated from up smoothly to right, the up button is not released until the dpad leaves the upperright quadrant.
The new code will be available in the TGB 1.5 Beta 3, which we're pushing out the door in the next day or so, last I checked.
The bug itself can be fixed like so:
In winDInputDevice.cc, in DInputDevice::buildEvent(), before:
A patch that contains the full fix follows.
Share and Enjoy.
/Paul
04/16/2007 (7:34 pm)
Ok, bug fixed.Here's the svn change log:
- rewrote d-pad input on win32, fixing a bug and improving overall behavior.
-- fixed a bug where, if a dpad button was pressed, and the dpad was rotated to another button, the 'pressed' event would incorrectly go to the 2nd dpad instance.
-- diagonal input is now possible: for example if the dpad is pressed to the upper right, both the up and right buttons get pressed, and if dpad is rotated from up smoothly to right, the up button is not released until the dpad leaves the upperright quadrant.
The new code will be available in the TGB 1.5 Beta 3, which we're pushing out the door in the next day or so, last I checked.
The bug itself can be fixed like so:
In winDInputDevice.cc, in DInputDevice::buildEvent(), before:
switch( newData )
{
...
}insert the linenewEvent.objInst = objInfo.mInst;
A patch that contains the full fix follows.
Share and Enjoy.
/Paul
#5
04/16/2007 (7:36 pm)
Index: winDInputDevice.cc
===================================================================
--- winDInputDevice.cc (revision 8133)
+++ winDInputDevice.cc (revision 8134)
@@ -949,6 +949,68 @@
}
//------------------------------------------------------------------------------
+enum Win32POVDirBits
+{
+ POV_up = 1 << 0,
+ POV_right = 1 << 1,
+ POV_down = 1 << 2,
+ POV_left = 1 << 3,
+};
+
+enum Win32POVDirsInQuadrant
+{
+ POVq_center = 0,
+ POVq_up = POV_up,
+ POVq_upright = POV_up | POV_right,
+ POVq_right = POV_right,
+ POVq_downright = POV_down | POV_right,
+ POVq_down = POV_down,
+ POVq_downleft = POV_down | POV_left,
+ POVq_left = POV_left,
+ POVq_upleft = POV_up | POV_left,
+};
+
+static const U32 Win32POVQuadrantMap[] =
+{
+ POVq_up, POVq_upright, POVq_right, POVq_downright, POVq_down, POVq_downleft,
+ POVq_left, POVq_upleft
+};
+
+static U32 _Win32GetPOVDirs(U32 data)
+{
+ U32 quadrant = (data / 4500) % 8;
+ U32 dirs = (data == 0xffff) ? POVq_center : Win32POVQuadrantMap[quadrant];
+ return dirs;
+}
+
+#if defined(LOG_INPUT)
+static void _Win32LogPOVInput(InputEvent &newEvent)
+{
+ U32 inst = 0xffff;
+ const char* sstate = ( newEvent.action == SI_MAKE ) ? "pressed" : "released";
+ const char* dir = "";
+ switch( newEvent.objInst )
+ {
+ case SI_UPOV:
+ case SI_UPOV2:
+ dir = "Up"; inst = (newEvent.objInst == SI_UPOV) ? 1 : 2; break;
+ case SI_RPOV:
+ case SI_RPOV2:
+ dir = "Right"; inst = (newEvent.objInst == SI_RPOV) ? 1 : 2; break;
+ case SI_DPOV:
+ case SI_DPOV2:
+ dir = "Down"; inst = (newEvent.objInst == SI_DPOV) ? 1 : 2; break;
+ case SI_LPOV:
+ case SI_LPOV2:
+ dir = "Left"; inst = (newEvent.objInst == SI_LPOV) ? 1 : 2; break;
+ }
+ Con::printf( "EVENT (DInput): %s POV %d %s.\n", dir, inst, sstate);
+}
+#else
+#define _Win32LogPOVInput( a )
+#endif
+
#6
04/16/2007 (7:36 pm)
+//------------------------------------------------------------------------------
bool DInputDevice::buildEvent( DWORD offset, S32 newData, S32 oldData )
{
DIDEVICEOBJECTINSTANCE &objInstance = mObjInstance[offset];
@@ -1120,92 +1182,77 @@
newData = LOWORD( newData );
oldData = LOWORD( oldData );
- newData = ( newData == 0xffff ) ? 5 : ( ( ( newData + 31500 ) / 9000 ) -3 ) & 0x03;
- oldData = ( oldData == 0xffff ) ? 5 : ( ( ( oldData + 31500 ) / 9000 ) -3 ) & 0x03;
- if ( newData != oldData )
+ newData = _Win32GetPOVDirs(newData);
+ oldData = _Win32GetPOVDirs(oldData);
+
+ U32 setkeys = newData & (~oldData);
+ U32 clearkeys = oldData & (~newData);
+ U32 objInst = newEvent.objInst;
+
+ if ( setkeys || clearkeys )
{
- if ( oldData != 5 )
+ if ( clearkeys )
{
newEvent.action = SI_BREAK;
newEvent.fValue = 0.0f;
- switch ( oldData )
+ // post events for all buttons that need to be cleared.
+ if( clearkeys & POV_up)
{
- case 0:
- newEvent.objInst = ( newEvent.objInst == 0 ) ? SI_UPOV : SI_UPOV2;
-#ifdef LOG_INPUT
- Input::log( "EVENT (DInput): Up POV %d released.\n",
- ( newEvent.objInst == SI_UPOV ) ? 1 : 2 );
-#endif
- break;
-
- case 1:
- newEvent.objInst = ( newEvent.objInst == 0 ) ? SI_RPOV : SI_RPOV2;
-#ifdef LOG_INPUT
- Input::log( "EVENT (DInput): Right POV %d released.\n",
- ( newEvent.objInst == SI_RPOV ) ? 1 : 2 );
-#endif
- break;
-
- case 2:
- newEvent.objInst = ( newEvent.objInst == 0 ) ? SI_DPOV : SI_DPOV2;
-#ifdef LOG_INPUT
- Input::log( "EVENT (DInput): Down POV %d released.\n",
- ( newEvent.objInst == SI_DPOV ) ? 1 : 2 );
-#endif
- break;
-
- case 3:
- newEvent.objInst = ( newEvent.objInst == 0 ) ? SI_LPOV : SI_LPOV2;
-#ifdef LOG_INPUT
- Input::log( "EVENT (DInput): Left POV %d released.\n",
- ( newEvent.objInst == SI_LPOV ) ? 1 : 2 );
-#endif
- break;
+ newEvent.objInst = ( objInst == 0 ) ? SI_UPOV : SI_UPOV2;
+ _Win32LogPOVInput(newEvent);
+ Game->postEvent(newEvent);
}
- Game->postEvent( newEvent );
- }
+ if( clearkeys & POV_right)
+ {
+ newEvent.objInst = ( objInst == 0 ) ? SI_RPOV : SI_RPOV2;
+ _Win32LogPOVInput(newEvent);
+ Game->postEvent(newEvent);
+ }
+ if( clearkeys & POV_down)
+ {
+ newEvent.objInst = ( objInst == 0 ) ? SI_DPOV : SI_DPOV;
+ _Win32LogPOVInput(newEvent);
+ Game->postEvent(newEvent);
+ }
+ if( clearkeys & POV_left)
+ {
+ newEvent.objInst = ( objInst == 0 ) ? SI_LPOV : SI_LPOV2;
+ _Win32LogPOVInput(newEvent);
+ Game->postEvent(newEvent);
+ }
+ } // clear keys
- if ( newData != 5 )
+ if ( setkeys )
{
newEvent.action = SI_MAKE;
newEvent.fValue = 1.0f;
- switch( newData )
+ // post events for all buttons that need to be set.
+ if( setkeys & POV_up)
{
- case 0:
- newEvent.objInst = ( newEvent.objInst == 0 ) ? SI_UPOV : SI_UPOV2;
-#ifdef LOG_INPUT
- Input::log( "EVENT (DInput): Up POV %d pressed.\n",
- ( newEvent.objInst == SI_UPOV ) ? 1 : 2 );
-#endif
- break;
-
- case 1:
- newEvent.objInst = ( newEvent.objInst == 0 ) ? SI_RPOV : SI_RPOV2;
-#ifdef LOG_INPUT
- Input::log( "EVENT (DInput): Right POV %d pressed.\n",
- ( newEvent.objInst == SI_RPOV ) ? 1 : 2 );
-#endif
- break;
-
- case 2:
- newEvent.objInst = ( newEvent.objInst == 0 ) ? SI_DPOV : SI_DPOV2;
-#ifdef LOG_INPUT
- Input::log( "EVENT (DInput): Down POV %d pressed.\n",
- ( newEvent.objInst == SI_DPOV ) ? 1 : 2 );
-#endif
- break;
-
- case 3:
- newEvent.objInst = ( newEvent.objInst == 0 ) ? SI_LPOV : SI_LPOV2;
-#ifdef LOG_INPUT
- Input::log( "EVENT (DInput): Left POV %d pressed.\n",
- ( newEvent.objInst == SI_LPOV ) ? 1 : 2 );
-#endif
- break;
+ newEvent.objInst = ( objInst == 0 ) ? SI_UPOV : SI_UPOV2;
+ _Win32LogPOVInput(newEvent);
+ Game->postEvent(newEvent);
}
- Game->postEvent( newEvent );
- }
+ if( setkeys & POV_right)
+ {
+ newEvent.objInst = ( objInst == 0 ) ? SI_RPOV : SI_RPOV2;
+ _Win32LogPOVInput(newEvent);
+ Game->postEvent(newEvent);
+ }
+ if( setkeys & POV_down)
+ {
+ newEvent.objInst = ( objInst == 0 ) ? SI_DPOV : SI_DPOV;
+ _Win32LogPOVInput(newEvent);
+ Game->postEvent(newEvent);
+ }
+ if( setkeys & POV_left)
+ {
+ newEvent.objInst = ( objInst == 0 ) ? SI_LPOV : SI_LPOV2;
+ _Win32LogPOVInput(newEvent);
+ Game->postEvent(newEvent);
+ }
+ } // set keys
}
break;
}
#7
04/18/2007 (11:49 am)
Thanks!
Torque Owner Kevin James
Oh, and the forums here use [ and ] not < and >