Wrecked Games

Please login or register.

Login with username, password and session length
Advanced search  

News:

We're just that awesome.

Author Topic: Joystick thrust axis (solved)  (Read 2174 times)

pfo

  • Newbie
  • *
  • Karma: +0/-0
  • Posts: 4
    • View Profile
Joystick thrust axis (solved)
« on: February 17, 2006, 08:24:51 PM »

It seems I can't get values from my joystick (MS SideWindow Precision Pro 2) for the thrust axis.  In my experience it's axis 2, so it should be returned in the Stick axis as Z.  OIS::JoyStick is reporting 4 axes, and it looks like the Win32Joystick class should pick it up through DirectInput.  If I output the value of all axes, X and Y change for the Stick axis and Z changes on the rotation axis.  Everything else stays 0.  Any suggestions?  Maybe I need to implement something to get the thruster access when it reads non-buffered input.
Logged

pjcast

  • Administrator
  • Veteran
  • *****
  • Karma: +1/-0
  • Posts: 2661
    • View Profile
    • http://www.wreckedgames.com
Joystick thrust axis (solved)
« Reply #1 on: February 17, 2006, 08:55:26 PM »

Are you saying that there is absolutely no value in any axis for your thrust control? IS this the same in beffered and nonbuffered mode?

ie. If you run the Actionmap demo, and try to configure a joystick movement to an axis, and then move your thrust, it does nothing? In buffered and nonbuffered the internal JoyStick code is just directly copying values received from DirectInput. I could find no good way to determine which axes were in use besides just reading them all hence, buffered mode is a little better since you get an axis number that created the event.

I guess this in under windows? Is this using the VC++ compilers (as Mingw may have some offset difficulties that are not yet addressed).
Logged

pfo

  • Newbie
  • *
  • Karma: +0/-0
  • Posts: 4
    • View Profile
Joystick thrust axis (solved)
« Reply #2 on: February 18, 2006, 12:35:38 AM »

Quote
   
Are you saying that there is absolutely no value in any axis for your thrust control? IS this the same in beffered and nonbuffered mode?
In buffered mode, there is only one axis and it is at index 1, it corresponds with the X, Y of the joystick and joystick rudder as z.  In un-buffered mode, the axis at Stick index corresponds with X and Y of the joystick and the axis at Rotational index's z component reflects the joystick rudder.  I've tried hitting a breakpoint in buffered mode on joystick axis movement to catch the accelerator axis and it didn't generate events.  It doesn't seem to be getting them in buffered mode either.  I really don't like buffered mode, if I move the joystick fast sometimes it misses events (like moving it all the way to the edge) and sometimes when moving fast it would randomly invert axis vector values.  Non-buffered mode works much better.

I can't get any of the demos to compile, one is saying OIS::INFINITE is an unresolved symbol, the other two can't find afxres.h.  I suppose I really could have tried harder but I didn't  :)

edit: I should mention that in some games I play this happens too, so it might be a DirectX issue.  I'm pretty sure Microsoft stopped supporting this joystick at Windows XP, but it still works with lots of games, but in some of them: no thrust control.

I'm using windows and VC Express
Logged

pjcast

  • Administrator
  • Veteran
  • *****
  • Karma: +1/-0
  • Posts: 2661
    • View Profile
    • http://www.wreckedgames.com
Joystick thrust axis (solved)
« Reply #3 on: February 18, 2006, 08:11:40 AM »

Hmm, this is odd about the OIS::INFINITE unresolved issue - someone else menioned this in regards to trying to use pyOIS.. It is definately defined in OISEffect.cpp which is included in both Windows and Linux build. Which version of OIS are you using? He also reported that it went away in the latest cvs head. So, i would recommend upgrading to that if you are not already there.

DirectInput not generating effects.. There is no DirectInput functions I'm aware of that could stop that from working. One thing you could try (though, this would require some code removal in Win32joystick) is to use the regular joystick guiid (c_dfDIJoystick) instead of the one I use in OIS c_dfDIJoystick2 when creating the device.

What does this mean? Well, you will have to change the Buffered and Non-buffered (or just the buffered one for testing) to be compatiable with that reduced DIJOYSTATE structure.. it has less available axis (I think only two) and fewer buttons and POVs. Though, as this sounds like a driver issue, you will probably see the same results. I think the work to get it working if as you say that MS has ceased support and it does not work well in other games is to much (which is one reason why I didn't develop force feedback support in Linux - I had a FF controller, but I spent days trying to get it to work there with no luck). If you try that method I mentioned, hopefully it works for you.
Logged

pfo

  • Newbie
  • *
  • Karma: +0/-0
  • Posts: 4
    • View Profile
Joystick thrust axis (solved)
« Reply #4 on: February 18, 2006, 06:52:31 PM »

There's another variable in the DIJOYSTATE2 struct, the slider variables.  I think if I implement them I can fix my problem.  After scouring the internet for advice it seems the thrust axis defaults to a slider.  Supposedly there is some way to change that and make it appear in the Z axis for the stick but I couldn't find it.  Anyway, I'm going to implement a Slider OIS::Component, add it into the API and try it out.  I'll let you know how it works but I think it will fix the problem.  The control panel under joysticks shows the thrust axis as a slider control.
Logged

pjcast

  • Administrator
  • Veteran
  • *****
  • Karma: +1/-0
  • Posts: 2661
    • View Profile
    • http://www.wreckedgames.com
Joystick thrust axis (solved)
« Reply #5 on: February 18, 2006, 06:55:25 PM »

Hmm, good point, didn't think about that. I don't think linux has an equivalent notion of a slider, I think it just puts it in a axis. If you implement it for both buffered and non-buffered and you get it to work then go ahead and submit a patch please :supz:
Logged

pfo

  • Newbie
  • *
  • Karma: +0/-0
  • Posts: 4
    • View Profile
Joystick thrust axis (solved)
« Reply #6 on: February 18, 2006, 07:18:29 PM »

Excellent, it is a slider.  Here's my modifications for anyone else experiencing this problem:

Code: [Select]
//OISPrereqs.h

struct _OISExport Slider : Component
{
Slider() : Component(OIS_Slider),
abX(0), abY(0) {};

long abX, abY;
};

 // add thgis to JoyStickState
Slider mSliders[4];

// Win32JoyStick.cpp

// add this to the end of _read inside the if {} block

mState.mSliders[0].abX = state.rglSlider[0]; mState.mSliders[0].abY = state.rglSlider[1];
mState.mSliders[1].abX = state.rglASlider[0]; mState.mSliders[1].abY = state.rglASlider[1];
mState.mSliders[2].abX = state.rglFSlider[0]; mState.mSliders[2].abY = state.rglFSlider[1];
mState.mSliders[3].abX = state.rglVSlider[0]; mState.mSliders[3].abY = state.rglVSlider[1];
This was just a quick hack to get it in their and working, only works in un-buffered mode
Logged

pjcast

  • Administrator
  • Veteran
  • *****
  • Karma: +1/-0
  • Posts: 2661
    • View Profile
    • http://www.wreckedgames.com
Joystick thrust axis (solved)
« Reply #7 on: February 20, 2006, 10:03:20 PM »

I've modified OIS to handle sliders, there is even an Joystick listener event now: sliderMoved for buffered mode. I made that a regular virtual method (along with the POV moved) instead of the pure virtual so not everyone had to overload those, as those are less used controls of a joystick.. but still imporatnt though, which is why I just added this for DX. AFAIK, linux has no notion of sliders, but I may discover in the future that MacOSX does, or that linux does too and I missed it :)

Anyway, while I was hacking away at the DX code, I came across the worst case statement I've ever had to write .. and I just had to make it bigger for sliders to work.. I tell you, DX really has a perverse idea of how events should work. Perhaps XInput is better (and maybe I need to support that sometime). For the unintiated to DX people, take a look at this monstrosity:

Code: [Select]

//DX Only defines macros for the JOYSTICK not JOYSTICK2, so we redeclare
//them to match what we are using
#undef DIJOFS_BUTTON
#undef DIJOFS_POV
#define DIJOFS_BUTTON(n) (FIELD_OFFSET(DIJOYSTATE2, rgbButtons) + (n))
#define DIJOFS_POV(n) (FIELD_OFFSET(DIJOYSTATE2, rgdwPOV)+(n)*sizeof(DWORD))

#define DIJOFS_SLIDER0(n) (FIELD_OFFSET(DIJOYSTATE2, rglSlider)+(n) * sizeof(LONG))
#define DIJOFS_SLIDER1(n) (FIELD_OFFSET(DIJOYSTATE2, rglVSlider)+(n) * sizeof(LONG))
#define DIJOFS_SLIDER2(n) (FIELD_OFFSET(DIJOYSTATE2, rglASlider)+(n) * sizeof(LONG))
#define DIJOFS_SLIDER3(n) (FIELD_OFFSET(DIJOYSTATE2, rglFSlider)+(n) * sizeof(LONG))

for(unsigned int i = 0; i < entries; ++i)
{
//Indeed, a nasty nasty switch :) I agree. Blah, DX has a nasty notion
//of how events should happen. Anyway, this may seem outof order, but, for
//maximum performance, this is in order of the way these variables
//are declared in the JoyStick State 2 structure.
switch(diBuff->dwOfs)
{
case FIELD_OFFSET(DIJOYSTATE2, lX):
moved[JoyStickState::Stick] = true;
mState.mAxes[JoyStickState::Stick].abX = diBuff[i].dwData;
break;
case FIELD_OFFSET(DIJOYSTATE2, lY):
moved[JoyStickState::Stick] = true;
mState.mAxes[JoyStickState::Stick].abY = diBuff[i].dwData;
break;
case FIELD_OFFSET(DIJOYSTATE2, lZ):
moved[JoyStickState::Stick] = true;
mState.mAxes[JoyStickState::Stick].abZ = diBuff[i].dwData;
break;
case FIELD_OFFSET(DIJOYSTATE2, lRx):
moved[JoyStickState::Rotational] = true;
mState.mAxes[JoyStickState::Rotational].abX = diBuff[i].dwData;
break;
case FIELD_OFFSET(DIJOYSTATE2, lRy):
moved[JoyStickState::Rotational] = true;
mState.mAxes[JoyStickState::Rotational].abY = diBuff[i].dwData;
break;
case FIELD_OFFSET(DIJOYSTATE2, lRz):
moved[JoyStickState::Rotational] = true;
mState.mAxes[JoyStickState::Rotational].abZ = diBuff[i].dwData;
break;
//------ extra axes positions, slider -//
case DIJOFS_SLIDER0(0):
sliderMoved[0] = true;
mState.mSliders[0].abX = diBuff[i].dwData;
break;
case DIJOFS_SLIDER0(1):
sliderMoved[0] = true;
mState.mSliders[0].abY = diBuff[i].dwData;
break;
//----- Max 4 POVs Next ---------------//
case DIJOFS_POV(0):
_changePOV(0,diBuff[i]);
break;
case DIJOFS_POV(1):
_changePOV(1,diBuff[i]);
break;
case DIJOFS_POV(2):
_changePOV(2,diBuff[i]);
break;
case DIJOFS_POV(3):
_changePOV(3,diBuff[i]);
break;
//------ The remaining Axes ------------//
case FIELD_OFFSET(DIJOYSTATE2, lVX):
moved[JoyStickState::Velocity] = true;
mState.mAxes[JoyStickState::Velocity].abX = diBuff[i].dwData;
break;
case FIELD_OFFSET(DIJOYSTATE2, lVY):
moved[JoyStickState::Velocity] = true;
mState.mAxes[JoyStickState::Velocity].abY = diBuff[i].dwData;
break;
case FIELD_OFFSET(DIJOYSTATE2, lVZ):
moved[JoyStickState::Velocity] = true;
mState.mAxes[JoyStickState::Velocity].abZ = diBuff[i].dwData;
break;
case FIELD_OFFSET(DIJOYSTATE2, lVRx):
moved[JoyStickState::AngularVelocity] = true;
mState.mAxes[JoyStickState::AngularVelocity].abX = diBuff[i].dwData;
break;
case FIELD_OFFSET(DIJOYSTATE2, lVRy):
moved[JoyStickState::AngularVelocity] = true;
mState.mAxes[JoyStickState::AngularVelocity].abY = diBuff[i].dwData;
break;
case FIELD_OFFSET(DIJOYSTATE2, lVRz):
moved[JoyStickState::AngularVelocity] = true;
mState.mAxes[JoyStickState::AngularVelocity].abZ = diBuff[i].dwData;
break;
//------ extra axes velocities, slider -//
case DIJOFS_SLIDER1(0):
sliderMoved[1] = true;
mState.mSliders[1].abX = diBuff[i].dwData;
break;
case DIJOFS_SLIDER1(1):
sliderMoved[1] = true;
mState.mSliders[1].abY = diBuff[i].dwData;
break;
//--------------------------------------//
case FIELD_OFFSET(DIJOYSTATE2, lAX):
moved[JoyStickState::Acceleration] = true;
mState.mAxes[JoyStickState::Acceleration].abX = diBuff[i].dwData;
break;
case FIELD_OFFSET(DIJOYSTATE2, lAY):
moved[JoyStickState::Acceleration] = true;
mState.mAxes[JoyStickState::Acceleration].abY = diBuff[i].dwData;
break;
case FIELD_OFFSET(DIJOYSTATE2, lAZ):
moved[JoyStickState::Acceleration] = true;
mState.mAxes[JoyStickState::Acceleration].abZ = diBuff[i].dwData;
break;
case FIELD_OFFSET(DIJOYSTATE2, lARx):
moved[JoyStickState::AngularAcceleration] = true;
mState.mAxes[JoyStickState::AngularAcceleration].abX = diBuff[i].dwData;
break;
case FIELD_OFFSET(DIJOYSTATE2, lARy):
moved[JoyStickState::AngularAcceleration] = true;
mState.mAxes[JoyStickState::AngularAcceleration].abY = diBuff[i].dwData;
break;
case FIELD_OFFSET(DIJOYSTATE2, lARz):
moved[JoyStickState::AngularAcceleration] = true;
mState.mAxes[JoyStickState::AngularAcceleration].abZ = diBuff[i].dwData;
break;
//------ extra axes accelerations, slider -//
case DIJOFS_SLIDER2(0):
sliderMoved[2] = true;
mState.mSliders[2].abX = diBuff[i].dwData;
break;
case DIJOFS_SLIDER2(1):
sliderMoved[2] = true;
mState.mSliders[2].abY = diBuff[i].dwData;
break;
//-----------------------------------------//
case FIELD_OFFSET(DIJOYSTATE2, lFX):
moved[JoyStickState::Force] = true;
mState.mAxes[JoyStickState::Force].abX = diBuff[i].dwData;
break;
case FIELD_OFFSET(DIJOYSTATE2, lFY):
moved[JoyStickState::Force] = true;
mState.mAxes[JoyStickState::Force].abY = diBuff[i].dwData;
break;
case FIELD_OFFSET(DIJOYSTATE2, lFZ):
moved[JoyStickState::Force] = true;
mState.mAxes[JoyStickState::Force].abZ = diBuff[i].dwData;
break;
case FIELD_OFFSET(DIJOYSTATE2, lFRx):
moved[JoyStickState::Torque] = true;
mState.mAxes[JoyStickState::Torque].abX = diBuff[i].dwData;
break;
case FIELD_OFFSET(DIJOYSTATE2, lFRy):
moved[JoyStickState::Torque] = true;
mState.mAxes[JoyStickState::Torque].abY = diBuff[i].dwData;
break;
case FIELD_OFFSET(DIJOYSTATE2, lFRz):
moved[JoyStickState::Torque] = true;
mState.mAxes[JoyStickState::Torque].abZ = diBuff[i].dwData;
break;
//------ extra axes forces, slider -//
case DIJOFS_SLIDER3(0):
sliderMoved[3] = true;
mState.mSliders[3].abX = diBuff[i].dwData;
break;
case DIJOFS_SLIDER3(1):
sliderMoved[3] = true;
mState.mSliders[3].abY = diBuff[i].dwData;
break;
//-----------------------------------------//
default:
//Handle Button Events Easily using the DX Offset Macros
if( diBuff->dwOfs >= DIJOFS_BUTTON(0) && diBuff->dwOfs <= DIJOFS_BUTTON(30) )
{
if(!_doButtonClick((diBuff->dwOfs - DIJOFS_BUTTON0), diBuff[i]))
return;
}
break;
} //end case

Logged