249 lines
9.0 KiB
C
249 lines
9.0 KiB
C
/***************************************************************************/
|
|
/* 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; i<INO_C_wNbMaxDevice; i++)
|
|
if (INO_g_a_stDIDevice[i].m_hDevice == hDev) break;
|
|
if (i == INO_C_wNbMaxDevice) return (0);
|
|
wDev = i;
|
|
|
|
ulSubType = INO_fn_wFillDeviceCaps(hDev);
|
|
if (!ulSubType) return(0);
|
|
|
|
/* Joystick sub-type */
|
|
switch (ulSubType)
|
|
{
|
|
case DIDEVTYPEJOYSTICK_TRADITIONAL:
|
|
case DIDEVTYPEJOYSTICK_GAMEPAD:
|
|
hDev->m_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; i<INO_C_wNbMaxAxis; i++)
|
|
{
|
|
stAxisRange.diph.dwSize = sizeof(DIPROPRANGE);
|
|
stAxisRange.diph.dwHeaderSize = sizeof(DIPROPHEADER);
|
|
stAxisRange.diph.dwHow = DIPH_BYOFFSET;
|
|
stAxisRange.diph.dwObj = a_ulAxis[i];
|
|
DInputErr = M_DIGetProp(wDev,DIPROP_RANGE,&stAxisRange.diph);
|
|
switch (DInputErr)
|
|
{
|
|
case DI_OK:
|
|
p_stJoyCaps->m_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; i<INO_C_wNbMaxDevice; i++)
|
|
if (INO_g_a_stDIDevice[i].m_hDevice == hDev) break;
|
|
if (i == INO_C_wNbMaxDevice)
|
|
{
|
|
INO_fn_vUpdateLastError(E_uwINO_WarningInvalidDevice);
|
|
return (0);
|
|
}
|
|
wDev = i;
|
|
|
|
/* First, reacquired the joystick if necessary */
|
|
if (!(p_stJoyState->m_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; i<hDev->m_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);
|
|
}
|