450 lines
15 KiB
C
450 lines
15 KiB
C
/***************************************************************************/
|
|
/* Description: MouseDI.c, part of CPA INO library */
|
|
/* Mouse specific implementation */
|
|
/* */
|
|
/* Author: F. Jentey */
|
|
/* Last Update: 09/08/97 */
|
|
/* */
|
|
/***************************************************************************/
|
|
/********************************************************************
|
|
* Modified by : Jean-Francois Prevost
|
|
* email : jfprevost@ubisoft.qc.ca
|
|
* Date : Mar 25 1998
|
|
*____________________________________________________________________
|
|
* Description
|
|
* -----------
|
|
* - Added functions for mouse sensitivity setting.
|
|
* - Added INO_g_bUsingMouse variable to enable/disable mouse usage.
|
|
* To use the mouse in a program you MUST add the Mouse line in the
|
|
* file device.ipt EVEN if you don't use any IPT functions. To use
|
|
* the mouse with the AI you must change the device.itp file.
|
|
*
|
|
********************************************************************/
|
|
|
|
#include "INO\errINO.h"
|
|
#include "InitDI.h"
|
|
#include "INOInit.h"
|
|
#include "Mouse.h"
|
|
|
|
/*/////////////////////////////*/
|
|
/* Global variable used for mouse control.*/
|
|
/* If TRUE => We use the mouse.*/
|
|
/* If FALSE => We don't use the mouse*/
|
|
/* It is FALSE by default and set to TRUE ONLY if Mouse is present in*/
|
|
/* the file Device.ipt*/
|
|
BOOL INO_g_bUsingMouse = FALSE;
|
|
|
|
/*********************************************************************
|
|
INITIALISATION
|
|
*********************************************************************/
|
|
|
|
/********************************************************************
|
|
* Author: Jean-Francois Prevost
|
|
* email : jfprevost@ubisoft.qc.ca
|
|
* Date : Mar 25 1998
|
|
*____________________________________________________________________
|
|
* Function name : INO_fn_hCreateMouseDevice
|
|
*
|
|
* Parameters
|
|
* ----------
|
|
* _wHistoricSize: The size of the historic to keep.
|
|
*
|
|
* Description
|
|
* -----------
|
|
* Safe mouse device creation function. If the global INO_g_bUsingMouse
|
|
* is FALSE then we skip the creation process. This variable is
|
|
* only set to TRUE when the Mouse line is present in the file
|
|
* Device.ipt.
|
|
*
|
|
********************************************************************/
|
|
INO_tdhDevice INO_fn_hCreateMouseDevice( short _wHistoricSize )
|
|
{
|
|
if( INO_g_bUsingMouse )
|
|
{
|
|
return (INO_fn_hCreateDevice( INO_C_uwMouse , _wHistoricSize ));
|
|
}
|
|
else
|
|
{
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
short INO_fn_wLinkMouseWithGLD(INO_tdhDevice _hDev, GLD_tdhDevice _tdGLDDeviceHandle)
|
|
{
|
|
INO_tdstMouseState *p_stMouseState = (INO_tdstMouseState*)(_hDev->m_p_stState);
|
|
GLD_tdstDeviceAttributes stGLDDevAtt;
|
|
|
|
if (!GLD_bIsDeviceHandleValid(_tdGLDDeviceHandle))
|
|
{
|
|
INO_fn_vUpdateLastError(E_uwINO_Mouse_InvalidGLDDeviceHandle);
|
|
return (0);
|
|
}
|
|
|
|
if (GLD_bGetDeviceAttributes(_tdGLDDeviceHandle, &stGLDDevAtt))
|
|
{
|
|
/* Check the window handle of the device */
|
|
/* if (stGLDDevAtt.bFullScreen)
|
|
WndHandle = stGLDDevAtt.hFullScreenModeWnd;
|
|
else
|
|
WndHandle = stGLDDevAtt.hNormalModeWnd;
|
|
*/
|
|
_hDev->m_p_stState->m_ucStatus |= INO_C_ucGLDLink;
|
|
|
|
p_stMouseState->m_tdGLDDeviceHandle = _tdGLDDeviceHandle;
|
|
p_stMouseState->m_fPixelsPerMickeys = 1.0f;
|
|
p_stMouseState->m_fGLDX = 0.5f;
|
|
p_stMouseState->m_fGLDY = 0.5f;
|
|
p_stMouseState->m_fMouseSensitivity = 1.0f;
|
|
return (1);
|
|
}
|
|
else
|
|
{
|
|
if (Erm_M_uwCheckError(GLD,C_ucErmDefaultChannel))
|
|
Erm_M_ClearLastError(C_ucErmDefaultChannel);
|
|
INO_fn_vUpdateLastError(E_uwINO_Mouse_FailedGettingDeviceAttributes);
|
|
return (0);
|
|
}
|
|
}
|
|
|
|
|
|
short INO_fn_wInitMouseCaps(INO_tdhDevice _hDev)
|
|
{
|
|
HRESULT DInputErr;
|
|
DIPROPRANGE stAxisRange;
|
|
|
|
/* JFP changed the values to the mouse values!! It used to be the joystick values.*/
|
|
DWORD a_ulAxis[INO_C_wNbMaxAxis] = { DIMOFS_X, DIMOFS_Y, DIMOFS_Z };
|
|
|
|
short i;
|
|
short wDev;
|
|
INO_tdstMouseCaps *p_stMouseCaps = (INO_tdstMouseCaps*)(_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);
|
|
|
|
/* Mouse sub-type */
|
|
switch (ulSubType)
|
|
{
|
|
case DIDEVTYPEMOUSE_TRADITIONAL:
|
|
_hDev->m_uwType |= INO_C_uwSubTypeMouse;
|
|
break;
|
|
|
|
case DIDEVTYPEMOUSE_TOUCHPAD:
|
|
_hDev->m_uwType |= INO_C_uwSubTypeTouchPad;
|
|
break;
|
|
|
|
case DIDEVTYPEMOUSE_TRACKBALL:
|
|
_hDev->m_uwType |= INO_C_uwSubTypeTrackball;
|
|
break;
|
|
|
|
case DIDEVTYPEMOUSE_FINGERSTICK:
|
|
_hDev->m_uwType |= INO_C_uwSubTypeFingerStick;
|
|
break;
|
|
|
|
default:
|
|
_hDev->m_uwType |= INO_C_uwUnknown;
|
|
}
|
|
|
|
/* Get Axis capabilities */
|
|
for (i=0; i<3; i++) /* Maxi = 3 axes for mouse, testing Rx return INVALIDPARM */
|
|
{
|
|
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_stMouseCaps->m_a_stAxisCaps[i].m_lCenter = ((stAxisRange.lMin + stAxisRange.lMax) >> 1);
|
|
p_stMouseCaps->m_a_stAxisCaps[i].m_lRange = stAxisRange.lMax - p_stMouseCaps->m_a_stAxisCaps[i].m_lCenter;
|
|
p_stMouseCaps->m_ulCapsFlags |= 1 << i;
|
|
break;
|
|
|
|
case DIERR_OBJECTNOTFOUND:
|
|
break;
|
|
|
|
case DIERR_INVALIDPARAM:
|
|
case DIERR_NOTINITIALIZED:
|
|
case DIERR_UNSUPPORTED:
|
|
default:
|
|
INO_fn_vUpdateLastError(E_uwINO_DirectInputError);
|
|
return (0);
|
|
}
|
|
}
|
|
|
|
_hDev->m_p_stState->m_ucStatus &= ~INO_C_ucGLDLink;
|
|
|
|
return (1);
|
|
}
|
|
|
|
|
|
/*********************************************************************
|
|
POLLING FUNCTION, GETTING MOUSE STATE
|
|
*********************************************************************/
|
|
/********************************************************************
|
|
* Author: Jean-Francois Prevost
|
|
* email : jfprevost@ubisoft.qc.ca
|
|
* Date : Feb 25 1998
|
|
*____________________________________________________________________
|
|
* Function name : INO_fn_bMouseMoved
|
|
*
|
|
* Parameters
|
|
* ----------
|
|
* _hDev : The handle of the mouse device.
|
|
*
|
|
* Description
|
|
* -----------
|
|
* Returns TRUE if the mouse has moved since the last frame.
|
|
*
|
|
********************************************************************/
|
|
short INO_fn_bMouseMoved(INO_tdhDevice _hDev)
|
|
{
|
|
short wCpt;
|
|
long* lAxis = ((INO_tdstMouseState*)(_hDev->m_p_stState))->m_a_lAxisValue;
|
|
|
|
for( wCpt = 0 ; wCpt < INO_C_wNbMaxAxis ; wCpt++ )
|
|
{
|
|
if( MTH_M_xAbs( lAxis[ wCpt ] ) > 0 )
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
/********************************************************************
|
|
* Author: Jean-Francois Prevost
|
|
* email : jfprevost@ubisoft.qc.ca
|
|
* Date : Feb 25 1998
|
|
*____________________________________________________________________
|
|
* Function name : INO_fn_bMouseButtonPressed
|
|
*
|
|
* Parameters
|
|
* ----------
|
|
* _hDev : The handle of the mouse device.
|
|
*
|
|
* Description
|
|
* -----------
|
|
* Returns TRUE if a mouse button is pressed
|
|
*
|
|
********************************************************************/
|
|
short INO_fn_bMouseButtonPressed(INO_tdhDevice _hDev)
|
|
{
|
|
if( INO_M_bLeftMBJustDown(_hDev) || INO_M_bRightMBJustDown(_hDev) )
|
|
{
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
/********************************************************************
|
|
* Author : F. Jentey
|
|
*____________________________________________________________________
|
|
* Modified by : Jean-Francois Prevost
|
|
* email : jfprevost@ubisoft.qc.ca
|
|
* Date : Mar 11 1998
|
|
*____________________________________________________________________
|
|
* Function name : INO_fn_wReadMouse
|
|
*
|
|
* Parameters
|
|
* ----------
|
|
* _hDev : Handle on the mouse device.
|
|
*
|
|
* Description
|
|
* -----------
|
|
* This function is responsible for reading the date from the mouse
|
|
* device and updating all of the mouse related data.
|
|
*
|
|
*____________________________________________________________________
|
|
* Modified by Date Changes
|
|
* ------------ ----------- ----------------------------------------
|
|
* JF Prevost Mar 11 1998 GLD data is modified according to the mouse
|
|
* sensitivity. (I also added the member
|
|
* m_wMouseSensitivity to the INO_tdstMouseState
|
|
* structure.
|
|
********************************************************************/
|
|
short INO_fn_wReadMouse(INO_tdhDevice _hDev)
|
|
{
|
|
short i;
|
|
short wDev;
|
|
HRESULT DInputErr;
|
|
DIMOUSESTATE stMouseState;
|
|
|
|
INO_tdstMouseState* p_stMouseState = MState(_hDev);
|
|
GLD_tdstDeviceAttributes stGLDDevAtt;
|
|
INO_tdstMouseRecord* p_stH = (INO_tdstMouseRecord*)_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 mouse if necessary */
|
|
if (!(p_stMouseState->m_ucStatus & INO_C_ucAcquired) ||
|
|
(p_stMouseState->m_ucStatus & INO_C_ucAccessError) )
|
|
{
|
|
DInputErr = M_DIAcquire(wDev);
|
|
switch (DInputErr)
|
|
{
|
|
case DI_OK:
|
|
case S_FALSE:
|
|
p_stMouseState->m_ucStatus |= INO_C_ucAcquired;
|
|
p_stMouseState->m_ucStatus &= ~INO_C_ucAccessError;
|
|
break;
|
|
case DIERR_INPUTLOST:
|
|
case DIERR_NOTACQUIRED:
|
|
case DIERR_OTHERAPPHASPRIO:
|
|
/*
|
|
INO_g_bUsingMouse = FALSE;
|
|
if( _hDev != NULL )
|
|
{
|
|
// Destroy the device
|
|
INO_fn_wReleaseDevice( _hDev );
|
|
}
|
|
*/
|
|
return (0);
|
|
default:
|
|
p_stMouseState->m_ucStatus |= INO_C_ucAccessError;
|
|
p_stMouseState->m_ucStatus &= ~INO_C_ucAcquired;
|
|
INO_fn_vUpdateLastError(E_uwINO_DirectInputError);
|
|
return (0);
|
|
}
|
|
}
|
|
|
|
/* Get mouse state */
|
|
DInputErr = M_DIGetState(wDev,sizeof(DIMOUSESTATE),&stMouseState);
|
|
switch (DInputErr)
|
|
{
|
|
case DI_OK:
|
|
case E_PENDING:
|
|
break;
|
|
|
|
case DIERR_INPUTLOST:
|
|
case DIERR_NOTACQUIRED:
|
|
p_stMouseState->m_ucStatus &= ~INO_C_ucAcquired;
|
|
return (0);
|
|
|
|
default:
|
|
p_stMouseState->m_ucStatus |= INO_C_ucAccessError;
|
|
p_stMouseState->m_ucStatus &= ~INO_C_ucAcquired;
|
|
INO_fn_vUpdateLastError(E_uwINO_DirectInputError);
|
|
return (0);
|
|
}
|
|
|
|
/* JFP: This is where we consider the sensitivity. We could change it to a float value*/
|
|
/* instead and multiply the mickeys varitation instead. It would have a broader*/
|
|
/* range of settings.*/
|
|
p_stMouseState->m_a_lAxisValue[0] = max(-INO_C_ulMouseMaxSpeedValue,min(INO_C_ulMouseMaxSpeedValue,(long)(stMouseState.lX * INO_fn_fGetMouseSensitivity(_hDev))));
|
|
p_stMouseState->m_a_lAxisValue[1] = max(-INO_C_ulMouseMaxSpeedValue,min(INO_C_ulMouseMaxSpeedValue,(long)(stMouseState.lY * INO_fn_fGetMouseSensitivity(_hDev))));
|
|
p_stMouseState->m_a_lAxisValue[2] = max(-INO_C_ulMouseMaxSpeedValue,min(INO_C_ulMouseMaxSpeedValue,(long)(stMouseState.lZ * INO_fn_fGetMouseSensitivity(_hDev))));
|
|
|
|
/* Copy buttons info */
|
|
p_stMouseState->m_ulButtons = 0;
|
|
for (i=0; i<_hDev->m_p_stCaps->m_ucNbButtons; i++)
|
|
if (stMouseState.rgbButtons[i] & INO_C_ucButtonDown)
|
|
p_stMouseState->m_ulButtons |= 1 << i;
|
|
|
|
/* If linked with a GLD device, get the device attributes */
|
|
if (p_stMouseState->m_ucStatus & INO_C_ucGLDLink)
|
|
{
|
|
if (GLD_bGetDeviceAttributes(p_stMouseState->m_tdGLDDeviceHandle,&stGLDDevAtt))
|
|
{
|
|
/* Set the X (percent) coordinate*/
|
|
p_stMouseState->m_fGLDX += ((float)p_stMouseState->m_a_lAxisValue[0] * p_stMouseState->m_fPixelsPerMickeys)
|
|
/ (float)(stGLDDevAtt.dwWidth-1);
|
|
if (p_stMouseState->m_fGLDX < 0.0f) p_stMouseState->m_fGLDX = 0.0f;
|
|
if (p_stMouseState->m_fGLDX > 1.0f) p_stMouseState->m_fGLDX = 1.0f;
|
|
|
|
/* Set the Y (percent) coordinate*/
|
|
p_stMouseState->m_fGLDY += ((float)p_stMouseState->m_a_lAxisValue[1] * p_stMouseState->m_fPixelsPerMickeys)
|
|
/ (float)(stGLDDevAtt.dwHeight-1);
|
|
if (p_stMouseState->m_fGLDY < 0.0f) p_stMouseState->m_fGLDY = 0.0f;
|
|
if (p_stMouseState->m_fGLDY > 1.0f) p_stMouseState->m_fGLDY = 1.0f;
|
|
}
|
|
else
|
|
{
|
|
if (Erm_M_uwCheckError(GLD,C_ucErmDefaultChannel))
|
|
Erm_M_ClearLastError(C_ucErmDefaultChannel);
|
|
INO_fn_vUpdateLastError(E_uwINO_Mouse_FailedGettingDeviceAttributes);
|
|
return (0);
|
|
}
|
|
}
|
|
|
|
/* Update historic. */
|
|
if (_hDev->m_wRecordNumber == 0)
|
|
{
|
|
p_stH[0].m_ulDate = _hDev->m_ulLastTimeCount;
|
|
p_stH[0].m_ulButtons = p_stMouseState->m_ulButtons;
|
|
_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_stMouseState->m_ulButtons;
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
|
|
/*//////////////////////////////////////*/
|
|
/* Mouse sensitivity related FUNCTIONS*/
|
|
void INO_fn_vSetMouseSensitivity(INO_tdhDevice _hDev, float _sensitivity)
|
|
{
|
|
MState(_hDev)->m_fMouseSensitivity=((_sensitivity>=0)?(_sensitivity):1);
|
|
}
|
|
|
|
|
|
float INO_fn_fGetMouseSensitivity(INO_tdhDevice _hDev)
|
|
{
|
|
return MState(_hDev)->m_fMouseSensitivity;
|
|
}
|
|
|
|
|
|
void INO_fn_vIncrementSensitivity(INO_tdhDevice _hDev)
|
|
{
|
|
MState(_hDev)->m_fMouseSensitivity++;
|
|
}
|
|
|
|
|
|
void INO_fn_vDecrementSensitivity(INO_tdhDevice _hDev)
|
|
{
|
|
if((MState(_hDev)->m_fMouseSensitivity-1)<=0)
|
|
{
|
|
(MState(_hDev)->m_fMouseSensitivity=1);
|
|
}
|
|
else
|
|
{
|
|
(MState(_hDev)->m_fMouseSensitivity-=1);
|
|
}
|
|
}
|
|
|
|
|