/***************************************************************************/ /* 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; im_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; im_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); } }