reman3/Rayman_X/cpa/tempgrp/INO/Specif/JoyDI.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);
}