/***************************************************************************/ /* Description: JoyDI.c, part of CPA INO library */ /* Joystick specific implementation */ /* */ /* Author: F. Jentey */ /* Last Update: 05/03/97 */ /***************************************************************************/ #include "INO\errINO.h" #include "InitDI.h" #include "INOInit.h" #include "Joystick.h" /**********************************************************************************/ /* Fill the p_stJoyCaps with the capabilities of the specified joystick */ /* Return an error if unable to get these information. */ /* It usually happens when the joystick isn't configurated in the control panel, */ /* but could also appear with some joystick if the joystick isn't connected. */ /**********************************************************************************/ short INO_fn_wInitJoystickCaps(INO_tdhDevice hDev) { HRESULT DInputErr; DIPROPRANGE stAxisRange; DWORD a_ulAxis[INO_C_wNbMaxAxis] = { DIJOFS_X, DIJOFS_Y, DIJOFS_Z, DIJOFS_RX, DIJOFS_RY, DIJOFS_RZ }; short i, wDev; INO_tdstJoystickCaps *p_stJoyCaps = (INO_tdstJoystickCaps*)(hDev->m_p_stCaps); unsigned long ulSubType; for (i=0; im_uwType |= INO_C_uwSubTypeJoypad; break; case DIDEVTYPEJOYSTICK_FLIGHTSTICK: case DIDEVTYPEJOYSTICK_RUDDER: hDev->m_uwType |= INO_C_uwSubTypeJoystick; break; case DIDEVTYPEJOYSTICK_WHEEL: hDev->m_uwType |= INO_C_uwSubTypeSteeringWheel; break; case DIDEVTYPEJOYSTICK_HEADTRACKER: default: hDev->m_uwType |= INO_C_uwUnknown; } /* Get Axis capabilities */ for (i=0; im_a_stAxisCaps[i].m_lCenter = ((stAxisRange.lMax + stAxisRange.lMin) >> 1); p_stJoyCaps->m_a_stAxisCaps[i].m_lRange = ((stAxisRange.lMax - stAxisRange.lMin) >> 1); p_stJoyCaps->m_a_stAxisCaps[i].m_lThreshold = p_stJoyCaps->m_a_stAxisCaps[i].m_lRange >> 1; p_stJoyCaps->m_ulCapsFlags |= 1 << i; break; case DIERR_OBJECTNOTFOUND: break; case DIERR_UNSUPPORTED: case DIERR_INVALIDPARAM: case DIERR_NOTINITIALIZED: default: INO_fn_vUpdateLastError(E_uwINO_DirectInputError); return (0); } } return (1); } /**********************************************************************************/ /* GET JOYSTICK STATE USING DURECT INPUT 5 */ /* Fill the p_stJoyState with the state of the specified joystick */ /* Return an error if unable to get these information. */ /* It usually happens when the joystick isn't configurated in the control panel, */ /* but could also appear with some joystick if the joystick isn't connected. */ /**********************************************************************************/ short INO_fn_wReadJoystick(INO_tdhDevice hDev) { HRESULT DInputErr; DIJOYSTATE stJoyState; short wDev, i; INO_tdstJoystickState *p_stJoyState = (INO_tdstJoystickState*)(hDev->m_p_stState); INO_tdstAxisCaps *p_stAxes = (INO_tdstAxisCaps*)&(((INO_tdstJoystickCaps*)(hDev->m_p_stCaps))->m_a_stAxisCaps); INO_tdstJoystickRecord *p_stH = (INO_tdstJoystickRecord*)hDev->m_pvHistoric; if (!INO_M_bIsConnected(hDev)) return (0); for (i=0; im_ucStatus & INO_C_ucAcquired) || (p_stJoyState->m_ucStatus & INO_C_ucAccessError) ) { DInputErr = M_DIAcquire(wDev); switch (DInputErr) { case DI_OK: case S_FALSE: p_stJoyState->m_ucStatus |= INO_C_ucAcquired; p_stJoyState->m_ucStatus &= ~INO_C_ucAccessError; break; case DIERR_INPUTLOST: case DIERR_NOTACQUIRED: case DIERR_OTHERAPPHASPRIO: return (0); default: INO_fn_vUpdateLastError(E_uwINO_DirectInputError); p_stJoyState->m_ucStatus &= ~INO_C_ucAcquired; p_stJoyState->m_ucStatus |= INO_C_ucAccessError; return (0); } } /* If the direct input extended interface is available, call Poll method */ /* before getting joystick state */ if (M_DIDevEx(wDev)) { DInputErr = M_DIDev2(wDev)->lpVtbl->Poll(M_DIDev2(wDev)); switch (DInputErr) { case DI_OK: case S_FALSE: break; case DIERR_INPUTLOST: case DIERR_NOTACQUIRED: p_stJoyState->m_ucStatus &= ~INO_C_ucAcquired; return (0); default: INO_fn_vUpdateLastError(E_uwINO_DirectInputError); p_stJoyState->m_ucStatus &= ~INO_C_ucAcquired; p_stJoyState->m_ucStatus |= INO_C_ucAccessError; return (0); } } /* Get joystick state */ DInputErr = M_DIGetState(wDev,sizeof(DIJOYSTATE),&stJoyState); switch (DInputErr) { case DI_OK: case E_PENDING: break; case DIERR_INPUTLOST: case DIERR_NOTACQUIRED: p_stJoyState->m_ucStatus &= ~INO_C_ucAcquired; return (0); default: p_stJoyState->m_ucStatus |= INO_C_ucAccessError; p_stJoyState->m_ucStatus &= ~INO_C_ucAcquired; INO_fn_vUpdateLastError(E_uwINO_DirectInputError); return (0); } /* Read axes informations */ p_stJoyState->m_a_lAxisValue[0] = stJoyState.lX - p_stAxes[0].m_lCenter; p_stJoyState->m_a_lAxisValue[1] = stJoyState.lY - p_stAxes[1].m_lCenter; p_stJoyState->m_a_lAxisValue[2] = stJoyState.lZ - p_stAxes[2].m_lCenter; p_stJoyState->m_a_lAxisValue[3] = stJoyState.lRx - p_stAxes[3].m_lCenter; p_stJoyState->m_a_lAxisValue[4] = stJoyState.lRy - p_stAxes[4].m_lCenter; p_stJoyState->m_a_lAxisValue[5] = stJoyState.lRz - p_stAxes[5].m_lCenter; p_stJoyState->m_uwDirections = 0; /* Update X direction */ if (p_stJoyState->m_a_lAxisValue[0] < -p_stAxes[0].m_lThreshold) p_stJoyState->m_uwDirections |= INO_C_uwLeft; else if (p_stJoyState->m_a_lAxisValue[0] > p_stAxes[0].m_lThreshold) p_stJoyState->m_uwDirections |= INO_C_uwRight; /* Update Y direction */ if (p_stJoyState->m_a_lAxisValue[1] > p_stAxes[1].m_lThreshold) p_stJoyState->m_uwDirections |= INO_C_uwDown; else if (p_stJoyState->m_a_lAxisValue[1] < -p_stAxes[1].m_lThreshold) p_stJoyState->m_uwDirections |= INO_C_uwUp; /* Update Z direction */ if (p_stJoyState->m_a_lAxisValue[2] < -p_stAxes[2].m_lThreshold) p_stJoyState->m_uwDirections |= INO_C_uwZDown; else if (p_stJoyState->m_a_lAxisValue[2] > p_stAxes[2].m_lThreshold) p_stJoyState->m_uwDirections |= INO_C_uwZUp; /* Copy buttons info */ p_stJoyState->m_ulButtons = 0; for (i=0; im_p_stCaps->m_ucNbButtons; i++) if (stJoyState.rgbButtons[i] & INO_C_ucButtonDown) p_stJoyState->m_ulButtons |= 1 << i; /* Update historic. */ if (hDev->m_wRecordNumber == 0) { p_stH[0].m_ulDate = hDev->m_ulLastTimeCount; p_stH[0].m_ulButtons = p_stJoyState->m_ulButtons; p_stH[0].m_uwDirections = p_stJoyState->m_uwDirections; hDev->m_wRecordNumber = 1; } else { hDev->m_wHistoricHead++; if (hDev->m_wHistoricHead == hDev->m_wHistoricSize) hDev->m_wHistoricHead = 0; if (hDev->m_wRecordNumber != hDev->m_wHistoricSize) hDev->m_wRecordNumber++; p_stH[hDev->m_wHistoricHead].m_ulDate = hDev->m_ulLastTimeCount; p_stH[hDev->m_wHistoricHead].m_ulButtons = p_stJoyState->m_ulButtons; p_stH[hDev->m_wHistoricHead].m_uwDirections = p_stJoyState->m_uwDirections; } return (1); }