Game Accessibility Library logo SourceForge.net Logo
Game Accessibility Suite: CAT/CATDIJoystick.cpp Source File

CATDIJoystick.cpp

Go to the documentation of this file.
00001 /// \file  CATDIJoystick.cpp
00002 /// \brief Joystick class for DirectInput
00003 /// \ingroup CAT
00004 ///
00005 /// Copyright (c) 2002-2008 by Michael Ellison.
00006 /// See COPYING.txt for the \ref gaslicense License (MIT License).
00007 ///
00008 // $Author: mikeellison $
00009 // $Date: 2008-01-31 20:30:30 -0600 (Thu, 31 Jan 2008) $
00010 // $Revision:   $
00011 // $NoKeywords: $
00012 #include "CATDIJoystick.h"
00013 #include "CATString.h"
00014 const int kMaxProp = 1000;
00015 
00016 CATDIJoystick::CATDIJoystick(IDirectInput8* dInput) : 
00017 CATJoystick()
00018 {
00019     fDirectInput = dInput;
00020     fInputDevice = 0;
00021     memset(&fInputDevCaps,0,sizeof(DIDEVCAPS));
00022 }
00023 
00024 
00025 CATDIJoystick::~CATDIJoystick()
00026 {
00027     if (fInputDevice != 0)
00028     {
00029         fInputDevice->Unacquire();
00030         fInputDevice->Release();
00031         fInputDevice = 0;
00032     }
00033 }
00034 
00035 
00036 bool CATDIJoystick::Init(DIDEVICEINSTANCE* devInstance)
00037 {
00038     // Check if we've pre-allocated the device (we should have in the menu callback)
00039     if (fInputDevice)
00040     {
00041         fInputDevice->Unacquire();
00042         fInputDevice->Release();
00043         fInputDevice = 0;
00044     }
00045     
00046     // Allocate direct input device
00047     if (FAILED(fDirectInput->CreateDevice( devInstance->guidInstance, &fInputDevice, NULL )))
00048     {
00049         return false;
00050     }
00051     
00052     // Get capabilities
00053     memset(&fInputDevCaps,0,sizeof(DIDEVCAPS));
00054     fInputDevCaps.dwSize = sizeof(DIDEVCAPS);
00055     if (FAILED(fInputDevice->GetCapabilities(&fInputDevCaps)))
00056     {
00057         fInputDevice->Release();
00058         fInputDevice = 0;
00059         return false;
00060     }
00061     
00062     // Set device format
00063     if (FAILED(fInputDevice->SetDataFormat(&c_dfDIJoystick)))
00064     {
00065         fInputDevice->Release();
00066         fInputDevice = 0;
00067         return false;
00068     }
00069 
00070     // Set device behaviour
00071     HWND hwnd = 0;
00072 
00073     // Set cooperative level so we'll always be able to receive data 
00074     if (FAILED(fInputDevice->SetCooperativeLevel(hwnd, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND)))
00075     {
00076         fInputDevice->Release();
00077         fInputDevice = 0;
00078         return false;
00079     }
00080 
00081     // Determine valid axes
00082     fValidAxis = 0;
00083     fInputDevice->EnumObjects(AxesCallback, this, DIDFT_AXIS);
00084     
00085     if (FAILED(fInputDevice->Acquire()))
00086     {
00087         fInputDevice->Release();
00088         fInputDevice = 0;
00089         return false;
00090     }
00091 
00092     return true;
00093 }
00094 
00095 // Callback from direct input for valid axis
00096 BOOL CALLBACK CATDIJoystick::AxesCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef )
00097 {   
00098     CATDIJoystick* jstick = (CATDIJoystick*)pvRef;
00099     if (jstick == 0)
00100     {
00101         return TRUE;
00102     }
00103 
00104     CATUInt32* validAxis = (CATUInt32*)&jstick->fValidAxis;
00105     if (validAxis == 0)
00106     {
00107         return TRUE;
00108     }
00109 
00110 
00111     // Save valid axis
00112     if (0 == memcmp(&lpddoi->guidType,&GUID_XAxis, sizeof(GUID)))
00113     {
00114         *validAxis |= X_AXIS | X_AXIS_LOW | X_AXIS_HIGH;
00115     }
00116     else if (0 == memcmp(&lpddoi->guidType,&GUID_YAxis,sizeof(GUID)))
00117     {
00118         *validAxis |= Y_AXIS | Y_AXIS_LOW | Y_AXIS_HIGH;
00119     }
00120     else if (0 == memcmp(&lpddoi->guidType,&GUID_ZAxis,sizeof(GUID)))
00121     {
00122         *validAxis |= Z_AXIS;
00123     }
00124     else if (0 == memcmp(&lpddoi->guidType,&GUID_RxAxis,sizeof(GUID)))
00125     {
00126         *validAxis |= X_ROT | X_ROT_LOW | X_ROT_HIGH;
00127     }
00128     else if (0 == memcmp(&lpddoi->guidType,&GUID_RyAxis,sizeof(GUID)))
00129     {
00130         *validAxis |= Y_ROT | Y_ROT_LOW | Y_ROT_HIGH;
00131     }
00132     else if (0 == memcmp(&lpddoi->guidType,&GUID_RzAxis,sizeof(GUID)))
00133     {
00134         *validAxis |= Z_ROT | Z_ROT_LOW | Z_ROT_HIGH;;
00135     }
00136 
00137     
00138     // Set min/max for axis
00139     DIPROPRANGE diprg;  
00140     diprg.diph.dwSize       = sizeof(DIPROPRANGE); 
00141     diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);     
00142     diprg.diph.dwHow        = DIPH_BYID; 
00143     diprg.diph.dwObj        = lpddoi->dwType;
00144     diprg.lMin              = 0;
00145     diprg.lMax              = kMaxProp;
00146     
00147     if (FAILED(jstick->fInputDevice->SetProperty(DIPROP_RANGE, &diprg.diph)))
00148     {
00149     }
00150     
00151     return TRUE;
00152 }
00153 
00154 bool CATDIJoystick::Configure(HWND hwnd)
00155 {
00156     if (fInputDevice)
00157     {
00158 
00159         fInputDevice->RunControlPanel(hwnd,0);
00160     }
00161     else
00162     {
00163         fDirectInput->RunControlPanel(hwnd,0);
00164     }
00165 
00166     return true;
00167 }
00168 
00169 bool CATDIJoystick::GetStatus(CATJOYSTICKSTRUCT& status)
00170 {
00171     if (this->fInputDevice)
00172     {
00173         if (FAILED(fInputDevice->Poll()))
00174         {
00175             if (FAILED(fInputDevice->Acquire()))
00176             {
00177                 return false;
00178             }
00179             fInputDevice->Poll();
00180         }
00181 
00182         DIJOYSTATE curState;
00183         if (FAILED(fInputDevice->GetDeviceState(sizeof(DIJOYSTATE), &curState)))
00184         {
00185             return false;
00186         }
00187 
00188         status.xAxis = (curState.lX)/10;
00189         status.yAxis = (curState.lY)/10;
00190         status.zAxis = (curState.lZ)/10;
00191         status.xRot  = (curState.lRx)/10;
00192         status.yRot  = (curState.lRy)/10;
00193         status.zRot  = (curState.lRz)/10;
00194         
00195         // rgdwPOV - 100ths of degrees clockwise from north, mostly.        
00196         // Per msdn, some drivers only set low word for centered.
00197         if (LOWORD(curState.rgdwPOV[0]) == 0xffff)
00198         {
00199             status.xPov = status.yPov = 50;
00200         }
00201         else
00202         {
00203             CATFloat32 rads = (curState.rgdwPOV[0]/100.0)*kCATDEGTORAD;
00204             status.xPov = -sin(rads)*50 + 50;
00205             status.yPov = -cos(rads)*50 + 50;
00206         }        
00207         
00208         // Half axis
00209         status.xLow  = (curState.lX <  kMaxProp/2) ? ((kMaxProp/2  - curState.lX)/5) : 0;
00210         status.xHigh = (curState.lX >= kMaxProp/2) ? ((curState.lX - kMaxProp/2)/5)  : 0;
00211         status.yLow  = (curState.lY <  kMaxProp/2) ? ((kMaxProp/2  - curState.lY)/5) : 0;
00212         status.yHigh = (curState.lY >= kMaxProp/2) ? ((curState.lY - kMaxProp/2)/5)  : 0;
00213         status.zLow  = (curState.lZ <  kMaxProp/2) ? ((kMaxProp/2  - curState.lZ)/5) : 0;
00214         status.zHigh = (curState.lZ >= kMaxProp/2) ? ((curState.lZ - kMaxProp/2)/5)  : 0;
00215 
00216         status.xRotLow  = (curState.lRx <  kMaxProp/2) ? ((kMaxProp/2   - curState.lRx)/5) : 0;
00217         status.xRotHigh = (curState.lRx >= kMaxProp/2) ? ((curState.lRx - kMaxProp/2)/5)   : 0;
00218         status.yRotLow  = (curState.lRy <  kMaxProp/2) ? ((kMaxProp/2   - curState.lRy)/5) : 0;
00219         status.yRotHigh = (curState.lRy >= kMaxProp/2) ? ((curState.lRy - kMaxProp/2)/5)   : 0;
00220         status.zRotLow  = (curState.lRz <  kMaxProp/2) ? ((kMaxProp/2   - curState.lRz)/5) : 0;
00221         status.zRotHigh = (curState.lRz >= kMaxProp/2) ? ((curState.lRz - kMaxProp/2)/5)   : 0;
00222         
00223             
00224 
00225         status.buttonMap = 0;       
00226         for (CATInt32 i = kCATJOYSTICKBTNMAX - 1; i >= 0; i--)
00227         {
00228             status.buttonMap <<= 1;
00229             status.buttonMap |= (curState.rgbButtons[i] > 0)?1:0;           
00230         }
00231     }
00232     return true;
00233 }

Generated on Mon Feb 11 04:09:42 2008 for Game Accessibility Suite by doxygen 1.5.4