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