/***************************************************************************/ /* Description: InitDI.c, part of CPA INO library */ /* Direct Input device low level init implementation */ /* */ /* Author: F. Jentey */ /* Creation date: 21/04/97 */ /* Last Update: 30/07/97 Direct input initialisation */ /***************************************************************************/ /*======== Direct Input header ========*/ #ifndef INITGUID #define INITGUID #include "DInput.h" #undef INITGUID #else #include "DInput.h" #endif /*=======================================*/ #include "INO\errINO.h" #include "INOInit.h" #include "InitDI.h" #include "INOJoy.h" #include "INOKeyb.h" #include "INOMouse.h" #include "Joystick.h" #define M_DInput() INO_g_p_stDInputInterface->lpVtbl LPDIRECTINPUT INO_g_p_stDInputInterface = NULL; HINSTANCE INO_g_hAppInstance; HWND INO_g_hAppMainWindow; unsigned long m_ulDITargetVersion = DIRECTINPUT_VERSION; /* Version of Direct Input the module was build for*/ unsigned long m_ulDIInstalledVersion; /* Version of Direct Input installed on the machine*/ DIDEVCAPS g_stDIDevCaps; DIDEVCAPS_DX3 g_stDIDevCaps3; INO_tdstDIDevice INO_g_a_stDIDevice[INO_C_wNbMaxDevice]; short INO_g_wNbDevices = 0; /*********************************************************************************/ /* Joystick enumeration callback */ /* Device instance are stored in INO_g_a_stJoystickInstance */ /*********************************************************************************/ BOOL CALLBACK fn_bEnumDeviceCallback(LPCDIDEVICEINSTANCE p_stDeviceInstance, LPVOID p_vRef) { LPDIRECTINPUTDEVICE p_stDevice; LPDIRECTINPUTDEVICE2 p_stDevice2; LPCDIDATAFORMAT p_stDataFormat; DWORD ulCooperativeLevel; HRESULT DInputErr; /* Create the DirectInput joystick device */ DInputErr = M_DInput()->CreateDevice( INO_g_p_stDInputInterface, &p_stDeviceInstance->guidInstance, &p_stDevice, NULL ); if (DInputErr != DI_OK) return FALSE; switch (GET_DIDEVICE_TYPE(p_stDeviceInstance->dwDevType)) { case DIDEVTYPE_MOUSE: p_stDataFormat = &c_dfDIMouse; /* All these settings have been tried in NT 4 with Service Pack 3 installed*/ /* This is the option selected...*/ ulCooperativeLevel = DISCL_NONEXCLUSIVE | DISCL_FOREGROUND; /* This one freezes the mouse...*/ /*ulCooperativeLevel = DISCL_EXCLUSIVE | DISCL_FOREGROUND;*/ /* Works similarly to DISCL_NONEXCLUSIVE | DISCL_FOREGROUND*/ /*ulCooperativeLevel = DISCL_NONEXCLUSIVE | DISCL_BACKGROUND;*/ /* This one causes unhandled exceptions...*/ /*ulCooperativeLevel = DISCL_EXCLUSIVE | DISCL_BACKGROUND;*/ break; case DIDEVTYPE_KEYBOARD: p_stDataFormat = &c_dfDIKeyboard; ulCooperativeLevel = DISCL_NONEXCLUSIVE | DISCL_FOREGROUND; /*ulCooperativeLevel = DISCL_EXCLUSIVE | DISCL_FOREGROUND;*/ break; case DIDEVTYPE_JOYSTICK: p_stDataFormat = &c_dfDIJoystick; ulCooperativeLevel = DISCL_NONEXCLUSIVE | DISCL_FOREGROUND; break; default: return FALSE; } /* Make sure the device is not acquired before calling setDataFormat */ /* and SetCooperativeLevel. */ DInputErr = p_stDevice->lpVtbl->Unacquire(p_stDevice); /* Set joystick data format */ DInputErr = p_stDevice->lpVtbl->SetDataFormat(p_stDevice, p_stDataFormat); if (DInputErr != DI_OK) { p_stDevice->lpVtbl->Release(p_stDevice); return FALSE; } /* Set the cooperative level */ DInputErr = p_stDevice->lpVtbl->SetCooperativeLevel( p_stDevice, INO_g_hAppMainWindow, ulCooperativeLevel ); if (DInputErr != DI_OK) { p_stDevice->lpVtbl->Release(p_stDevice); return FALSE; } /* Everything is OK, keep this joystick */ memcpy( &INO_g_a_stDIDevice[INO_g_wNbDevices].m_stDevInstance, p_stDeviceInstance, sizeof(DIDEVICEINSTANCE) ); INO_g_a_stDIDevice[INO_g_wNbDevices].m_p_stDevInterface = p_stDevice; /* Find the IDirectInput2 interface, for using Poll method */ if (GET_DIDEVICE_TYPE(p_stDeviceInstance->dwDevType) == DIDEVTYPE_JOYSTICK) { DInputErr = p_stDevice->lpVtbl->QueryInterface( p_stDevice, &IID_IDirectInputDevice2, (LPVOID*)&p_stDevice2 ); if (DInputErr == S_OK) { INO_g_a_stDIDevice[INO_g_wNbDevices].m_p_stDevInterface2 = p_stDevice2; INO_g_a_stDIDevice[INO_g_wNbDevices].m_wExtendedInterfaceAvailable = 1; } else { INO_g_a_stDIDevice[INO_g_wNbDevices].m_p_stDevInterface2 = NULL; INO_g_a_stDIDevice[INO_g_wNbDevices].m_wExtendedInterfaceAvailable = 0; } } else { INO_g_a_stDIDevice[INO_g_wNbDevices].m_p_stDevInterface2 = NULL; INO_g_a_stDIDevice[INO_g_wNbDevices].m_wExtendedInterfaceAvailable = 0; } INO_g_wNbDevices++; return DIENUM_CONTINUE; } /***********************************/ /* Init Direct Input */ /* Return 1 if OK, else 0 */ /***********************************/ short INO_fn_wInitAllDevices(HINSTANCE hInstance, HWND hWindow) { HRESULT DInputErr; if (INO_g_p_stDInputInterface) return(1); INO_g_wNbDevices = 0; DInputErr = DirectInputCreate(hInstance,DIRECTINPUT_VERSION,&INO_g_p_stDInputInterface,NULL); if (DInputErr==DIERR_OLDDIRECTINPUTVERSION) { /* If compiled with Direct Input 5, and Direct Input 3 is installed */ DInputErr = DirectInputCreate(hInstance,DIRECTINPUT_VERSION_3,&INO_g_p_stDInputInterface,NULL); if (DInputErr == DI_OK) m_ulDIInstalledVersion = DIRECTINPUT_VERSION_3; } else m_ulDIInstalledVersion = DIRECTINPUT_VERSION; switch (DInputErr) { case DI_OK: INO_g_hAppInstance = hInstance; INO_g_hAppMainWindow = hWindow; break; case DIERR_INVALIDPARAM: case DIERR_OUTOFMEMORY: case DIERR_OLDDIRECTINPUTVERSION: case DIERR_BETADIRECTINPUTVERSION: default: INO_g_p_stDInputInterface = NULL; m_ulDIInstalledVersion = 0; INO_fn_vUpdateLastError(E_uwINO_FatalDirectInpuNotFound); return (0); } memset(INO_g_a_stDIDevice,0,sizeof(INO_tdstDIDevice)*INO_C_wNbMaxDevice); DInputErr = M_DInput()->EnumDevices( INO_g_p_stDInputInterface, 0, fn_bEnumDeviceCallback, NULL, DIEDFL_ALLDEVICES ); if( DInputErr == DI_OK ) { return ( 1 ); } return( 0 ); } /***********************************/ /* Init one device */ /***********************************/ short INO_fn_wInitDevice(INO_tdhDevice hDev) { HRESULT DInputErr; short i, wResult; for (i=0; im_pfnRead = INO_fn_wReadJoystick; wResult = INO_fn_wInitJoystickCaps(hDev); break; case INO_C_uwKeyboard: hDev->m_pfnRead = INO_fn_wReadKeyboard; wResult = INO_fn_wInitKeyboardCaps(hDev); break; case INO_C_uwMouse: /* Initialize the mouse only if the application uses it*/ hDev->m_pfnRead = INO_fn_wReadMouse; wResult = INO_fn_wInitMouseCaps(hDev); break; } if (!wResult) { INO_fn_vUpdateLastError(E_uwINO_DeviceInitFailed); return (-1); } DInputErr = M_DIAcquire(i); switch (DInputErr) { case DI_OK: case S_FALSE: hDev->m_p_stState->m_ucStatus |= INO_C_ucAcquired; break; case DIERR_INPUTLOST: hDev->m_p_stState->m_ucStatus &= ~INO_C_ucAcquired; break; case DIERR_INVALIDPARAM: hDev->m_p_stState->m_ucStatus &= ~INO_C_ucAcquired; INO_fn_vUpdateLastError(E_uwINO_DirectInputError); return (-1); default: break; } return (i); } } return (-1); } /***********************************/ /* Release one device */ /***********************************/ short INO_fn_wDestroyDevice(INO_tdhDevice hDev) { long i; for (i=0; iRelease(INO_g_p_stDInputInterface); INO_g_p_stDInputInterface = NULL; } /****************************************/ /* Free All */ /****************************************/ short INO_fn_wGetNbDevices(unsigned short uwType) { short i, lNb = 0; if (!INO_g_p_stDInputInterface) return (0); for (i=0; im_p_stCaps); for (wDev=0; wDevm_p_stState->m_ucStatus |= INO_C_ucConnected; p_stCaps->m_ucNbButtons = (unsigned char)g_stDIDevCaps3.dwButtons; switch (INO_M_uwType(hDev)) { case INO_C_uwJoystick: ((INO_tdstJoystickCaps*)p_stCaps)->m_ucNbPOVs = (unsigned char)g_stDIDevCaps3.dwPOVs; case INO_C_uwMouse: ((INO_tdstJoystickCaps*)p_stCaps)->m_ucNbAxes = (unsigned char)g_stDIDevCaps3.dwAxes; break; } return (GET_DIDEVICE_SUBTYPE(g_stDIDevCaps3.dwDevType)); } else { if (g_stDIDevCaps.dwFlags & DIDC_ATTACHED) hDev->m_p_stState->m_ucStatus |= INO_C_ucConnected; p_stCaps->m_ucNbButtons = (unsigned char)g_stDIDevCaps.dwButtons; switch (INO_M_uwType(hDev)) { case INO_C_uwJoystick: ((INO_tdstJoystickCaps*)p_stCaps)->m_ucNbAxes = (unsigned char)g_stDIDevCaps.dwAxes; ((INO_tdstJoystickCaps*)p_stCaps)->m_ucNbPOVs = (unsigned char)g_stDIDevCaps.dwPOVs; break; } return (GET_DIDEVICE_SUBTYPE(g_stDIDevCaps.dwDevType)); } } else { hDev->m_p_stState->m_ucStatus &= ~INO_C_ucConnected; hDev->m_p_stState->m_ucStatus &= ~INO_C_ucAcquired; INO_fn_vUpdateLastError(E_uwINO_DeviceInitFailed); return (0); } } short INO_fn_wIsConnected(INO_tdhDevice hDev) { HRESULT DInputErr; short wDev; /* JFP: what is this used for? Is it necessary?*/ for (wDev=0; wDevm_p_stState->m_ucStatus |= INO_C_ucConnected; return (1); } else hDev->m_p_stState->m_ucStatus &= ~INO_C_ucConnected; } return (0); }