Example #1
0
//-----------------------------------------------------------------------------
// Name: EnumObjectsCallback()
// Desc: Callback function for enumerating objects (axes, buttons, POVs) on a 
//       g_pJoystick. This function enables user interface elements for objects
//       that are found to exist, and scales axes min/max values.
//-----------------------------------------------------------------------------
BOOL CALLBACK EnumObjectsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi,
                                   VOID* pContext )
{
    HWND hDlg = ( HWND )pContext;

    static int nSliderCount = 0;  // Number of returned slider controls
    static int nPOVCount = 0;     // Number of returned POV controls

    // For axes that are returned, set the DIPROP_RANGE property for the
    // enumerated axis in order to scale min/max values.
    if( pdidoi->dwType & DIDFT_AXIS )
    {
        DIPROPRANGE diprg;
        diprg.diph.dwSize = sizeof( DIPROPRANGE );
        diprg.diph.dwHeaderSize = sizeof( DIPROPHEADER );
        diprg.diph.dwHow = DIPH_BYID;
        diprg.diph.dwObj = pdidoi->dwType; // Specify the enumerated axis
        diprg.lMin = -1000;
        diprg.lMax = +1000;

        // Set the range for the axis
        if( VP_FAILED( g_pJoystick->SetProperty( DIPROP_RANGE, &diprg.diph ) ) )
            return DIENUM_STOP;

    }
	return DIENUM_CONTINUE;
}
Example #2
0
//------------------------------------------------------
//		コントローラー初期化
//------------------------------------------------------
LPDIRECTINPUTDEVICE8 iexInputManager::GetDevice( int n )
{
	HRESULT	hr;
	LPDIRECTINPUTDEVICE8	lpDevice;

	//	デバイス生成
	hr = pDI->CreateDevice( didi[n].guidInstance, &lpDevice, NULL);
	if( FAILED(hr) ) return NULL;

	if( lpDevice->SetDataFormat( &c_dfDIJoystick2 ) != DI_OK ) return FALSE;
	if( lpDevice->SetCooperativeLevel( iexSystem::Window, DISCL_EXCLUSIVE | DISCL_FOREGROUND ) != DI_OK ) return FALSE;

	//	自動センタリング無効
	DIPROPDWORD	dipdw;
    dipdw.diph.dwSize       = sizeof(DIPROPDWORD);
    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
    dipdw.diph.dwObj        = 0;
    dipdw.diph.dwHow        = DIPH_DEVICE;
    dipdw.dwData            = DIPROPAUTOCENTER_OFF;
    lpDevice->SetProperty( DIPROP_AUTOCENTER, &dipdw.diph );

	// 各軸設定
	lpDevice->EnumObjects(EnumAxes, lpDevice, DIDFT_AXIS);

	// 入力制御開始
	lpDevice->Acquire();

	return lpDevice;
}
Example #3
0
//DirectInputデバイスの初期化
bool Application::InitDinputDevice()
{
	//DirectInputデバイスを作成
	if (FAILED(directInput->CreateDevice(GUID_SysMouse, &dinputDevice, nullptr)))
		return false;

	//データフォーマットを設定
	if (FAILED(dinputDevice->SetDataFormat(&c_dfDIMouse2)))
		return false;

	//協調モードを設定
	if (FAILED(dinputDevice->SetCooperativeLevel(hWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND)))
		return false;

	//	軸モードを設定
	DIPROPDWORD diprop;
	diprop.diph.dwSize = sizeof(diprop);
	diprop.diph.dwHeaderSize = sizeof(diprop.diph);
	diprop.diph.dwObj = 0;
	diprop.diph.dwHow = DIPH_DEVICE;
	diprop.dwData = DIPROPAXISMODE_REL;

	if (FAILED(dinputDevice->SetProperty(DIPROP_AXISMODE, &diprop.diph)))
	{
		MessageBox(NULL, "設定に失敗", "Direct Input Error", MB_OK);
		return false;
	}

	// 入力制御開始
	dinputDevice->Acquire();

	return true;
}
Example #4
0
//-----------------------------------------------------------------------------
// Name: InitDirectInput()
// Desc: Initialize the DirectInput variables.
//-----------------------------------------------------------------------------
HRESULT InitDirectInput( HWND hWnd )
{
    HRESULT hr;

    // Register with the DirectInput subsystem and get a pointer
    // to a IDirectInput interface we can use.
    // Create a DInput object
    if( FAILED( hr = DirectInput8Create( GetModuleHandle(NULL), DIRECTINPUT_VERSION, 
                                         IID_IDirectInput8, (VOID**)&g_pDI, NULL ) ) )
        return hr;
    
    // Obtain an interface to the system mouse device.
    if( FAILED( hr = g_pDI->CreateDevice( GUID_SysMouse, &g_pMouse, NULL ) ) )
        return hr;

    // Set the data format to "mouse format" - a predefined data format 
    //
    // A data format specifies which controls on a device we
    // are interested in, and how they should be reported.
    //
    // This tells DirectInput that we will be passing a
    // DIMOUSESTATE structure to IDirectInputDevice::GetDeviceState.
    if( FAILED( hr = g_pMouse->SetDataFormat( &c_dfDIMouse ) ) )
        return hr;

    // Set the cooperativity level to let DirectInput know how
    // this device should interact with the system and with other
    // DirectInput applications.
    if( FAILED( hr = g_pMouse->SetCooperativeLevel( hWnd, 
                                         DISCL_EXCLUSIVE|DISCL_FOREGROUND ) ) )
        return hr;

    // Create a win32 event which is signaled when mouse data is availible
    g_hMouseEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
    if( NULL == g_hMouseEvent )
        return E_FAIL;

    // Give the event to the mouse device
    if( FAILED( hr = g_pMouse->SetEventNotification( g_hMouseEvent ) ) )
        return hr;

    // Setup the buffer size for the mouse data
    DIPROPDWORD dipdw;
    dipdw.diph.dwSize       = sizeof(DIPROPDWORD);
    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
    dipdw.diph.dwObj        = 0;
    dipdw.diph.dwHow        = DIPH_DEVICE;
    dipdw.dwData            = SAMPLE_BUFFER_SIZE; // Arbitary buffer size

    if( FAILED( hr = g_pMouse->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph ) ) )
        return hr;

    // Not necessary, but nice for left handed users that have
    // their swapped mouse buttons
    g_bSwapMouseButtons = GetSystemMetrics( SM_SWAPBUTTON );

    return S_OK;
}
Example #5
0
//-----------------------------------------------------------------------------
// Name: InitDirectInput()
// Desc: Initialize the DirectInput variables.
//-----------------------------------------------------------------------------
HRESULT InitDirectInput( HWND hDlg )
{
    HRESULT hr;

    // Setup the g_EffectsList circular linked list
    ZeroMemory( &g_EffectsList, sizeof( EFFECTS_NODE ) );
    g_EffectsList.pNext = &g_EffectsList;

    // Create a DInput object
    if( FAILED( hr = DirectInput8Create( GetModuleHandle(NULL), DIRECTINPUT_VERSION, 
                                         IID_IDirectInput8, (VOID**)&g_pDI, NULL ) ) )
        return hr;

    // Get the first enumerated force feedback device
    if( FAILED( hr = g_pDI->EnumDevices( 0, EnumFFDevicesCallback, 0, 
                                         DIEDFL_ATTACHEDONLY | 
                                         DIEDFL_FORCEFEEDBACK ) ) )
        return hr;
    
    if( g_pFFDevice == NULL )
    {
        MessageBox( hDlg, _T("No force feedback device found.  ")
                          _T("The sample will now exit."), 
                          _T("ReadFFE"), MB_ICONERROR | MB_OK );
        EndDialog( hDlg, 0 );
        return S_OK;
    }

    // Set the data format
    if( FAILED( hr = g_pFFDevice->SetDataFormat( &c_dfDIJoystick ) ) )
        return hr;

    // Set the coop level
    if( FAILED( hr = g_pFFDevice->SetCooperativeLevel( hDlg, DISCL_EXCLUSIVE | 
                                                             DISCL_BACKGROUND ) ) )
        return hr;

    // Disable auto-centering spring
    DIPROPDWORD dipdw;
    dipdw.diph.dwSize       = sizeof(DIPROPDWORD);
    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
    dipdw.diph.dwObj        = 0;
    dipdw.diph.dwHow        = DIPH_DEVICE;
    dipdw.dwData            = FALSE;

    if( FAILED( hr = g_pFFDevice->SetProperty( DIPROP_AUTOCENTER, &dipdw.diph ) ) )
        return hr;

    // Acquire the device
    if( FAILED( hr = g_pFFDevice->Acquire() ) )
        return hr;

    return S_OK;
}
Example #6
0
		void initialize(HWND hwnd_) {


			// DirectInputの作成
			LPDIRECTINPUT8 keyboard = NULL;
			HRESULT hr = DirectInput8Create(::GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&keyboard, NULL); 
			if (FAILED(hr)) {
				debug_out::trace("DirectInputオブジェクトの生成に失敗しました。");
				throw nyx::com_exception("DirectInputオブジェクトの生成に失敗しました。", hr);
			}

			// デバイス・オブジェクトを作成
			LPDIRECTINPUTDEVICE8 keyboardDevice = NULL;
			hr = keyboard->CreateDevice(GUID_SysKeyboard, &keyboardDevice, NULL); 
			if (FAILED(hr)) {
				debug_out::trace("DirectInputDeviceオブジェクトの生成に失敗しました。");
				throw nyx::com_exception("DirectInputDeviceオブジェクトの生成に失敗しました。", hr);
			}


			// データ形式を設定
			hr = keyboardDevice->SetDataFormat(&c_dfDIKeyboard);
			if (FAILED(hr)) {
				debug_out::trace("データ形式の設定に失敗しました。");
				throw nyx::com_exception("データ形式の設定に失敗しました。", hr);
			}
			//モードを設定(フォアグラウンド&非排他モード)
			hr = keyboardDevice->SetCooperativeLevel(hwnd_, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
			if (FAILED(hr)) {
				debug_out::trace("制御モードの設定に失敗しました。");
				throw nyx::com_exception("制御モードの設定に失敗しました。", hr);
			}
			// バッファリング・データを取得するため、バッファ・サイズを設定
			DIPROPDWORD diprop = {};
			diprop.diph.dwSize	= sizeof(diprop); 
			diprop.diph.dwHeaderSize	= sizeof(diprop.diph); 
			diprop.diph.dwObj	= 0;
			diprop.diph.dwHow	= DIPH_DEVICE;
			diprop.dwData = 255;
			hr = keyboardDevice->SetProperty(DIPROP_BUFFERSIZE, &diprop.diph);
			if (FAILED(hr)) {
				debug_out::trace("バッファサイズの設定に失敗しました。");
				throw nyx::com_exception("バッファサイズの設定に失敗しました。", hr);
			}


			keyboard_ = DirectInputPtr(keyboard, false);
			keyboardDevice_ = DirectInputDevicePtr(keyboardDevice, false);

			isInitialized = true;
		}
//=============================================================================
// マウスの初期化
//=============================================================================
HRESULT InitMouse(HINSTANCE hInst, HWND hWnd)
{
	HRESULT hr;

	// デバイスオブジェクトを作成
	hr = g_pDInput->CreateDevice(GUID_SysMouse, &g_pDIDevMouse, NULL);
	if(FAILED(hr))
	{
		MessageBox(hWnd, "マウスがねぇ!", "警告!", MB_ICONWARNING);
		return hr;
	}

	// データフォーマットを設定
	hr = g_pDIDevMouse->SetDataFormat(&c_dfDIMouse2);
	if(FAILED(hr))
	{
		MessageBox(hWnd, "マウスのデータフォーマットを設定できませんでした。", "警告!", MB_ICONWARNING);
		return hr;
	}

	// 協調モードを設定(フォアグラウンド&非排他モード)
	hr = g_pDIDevMouse->SetCooperativeLevel(hWnd, (DISCL_FOREGROUND | DISCL_NONEXCLUSIVE));
	if(FAILED(hr))
	{
		MessageBox(hWnd, "マウスの協調モードを設定できませんでした。", "警告!", MB_ICONWARNING);
		return hr;
	}

	// デバイスのプロパティを設定
	{
		DIPROPDWORD dipdw;

		dipdw.diph.dwSize = sizeof(dipdw);
		dipdw.diph.dwHeaderSize = sizeof(dipdw.diph);
		dipdw.diph.dwObj = 0;
		dipdw.diph.dwHow = DIPH_DEVICE;
		dipdw.dwData = DIPROPAXISMODE_REL;

		hr = g_pDIDevMouse->SetProperty(DIPROP_AXISMODE, &dipdw.diph);
		if(FAILED(hr))
		{
			MessageBox(hWnd, "マウスのデバイスのプロパティを設定できませんでした。", "警告!", MB_ICONWARNING);
			return hr;
		}
	}

	// マウスへのアクセス権を獲得(入力制御開始)
	g_pDIDevMouse->Acquire();

	return S_OK;
}
Example #8
0
BOOL CALLBACK Input::EnumObject( LPCDIDEVICEOBJECTINSTANCE pInstance, LPVOID pvRef )
{
	DIPROPRANGE range;
	range.diph.dwSize = sizeof( DIPROPRANGE );
	range.diph.dwHeaderSize = sizeof( DIPROPHEADER );
	range.diph.dwObj = pInstance->dwType;
	range.diph.dwHow = DIPH_BYID;

	range.lMin = -10;
	range.lMax = +10;

	LPDIRECTINPUTDEVICE8 pInputDev = ( LPDIRECTINPUTDEVICE8 )pvRef;
	pInputDev->SetProperty( DIPROP_RANGE, &range.diph );

	return DIENUM_CONTINUE;
}
Example #9
0
// Called by an axis enumerator in GetInputDevice.  Set the min and max range so we can pass the rec'd value right to the emulator.
BOOL CALLBACK EnumSetObjectsAxis( LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef)
{
	LPDIRECTINPUTDEVICE8 lpDirectInputDevice = (LPDIRECTINPUTDEVICE8)pvRef;
	DIPROPRANGE diprg; 

	diprg.diph.dwSize       = sizeof(DIPROPRANGE);
	diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
	diprg.diph.dwHow        = DIPH_BYID;
	diprg.diph.dwObj        = lpddoi->dwType;
	diprg.lMin              = MINAXISVALUE;
	diprg.lMax              = MAXAXISVALUE;

	lpDirectInputDevice->SetProperty(DIPROP_RANGE, &diprg.diph); // HACK: Usually works, but not all devices support setting range.

	return DIENUM_CONTINUE;
}
Example #10
0
// Axis enumeration callback
// For each joystick axis we can find, tell it to report values in [-1000, 1000]
BOOL CALLBACK vrpn_DirectXRumblePad::axis_enum_cb(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID ref) {
	LPDIRECTINPUTDEVICE8 gamepad = reinterpret_cast<LPDIRECTINPUTDEVICE8>(ref);

	DIPROPRANGE prop;
	prop.diph.dwSize = sizeof(DIPROPRANGE);
	prop.diph.dwHeaderSize = sizeof(DIPROPHEADER);
	prop.diph.dwHow = DIPH_BYID;
	prop.diph.dwObj = lpddoi->dwType;
	prop.lMin = -1000;
	prop.lMax = 1000;

	if (FAILED(gamepad->SetProperty(DIPROP_RANGE, &prop.diph))) {
		return DIENUM_STOP;
	}

	return DIENUM_CONTINUE;
}
Example #11
0
BOOL CALLBACK DI_CLASS::EnumObjects(const DIDEVICEOBJECTINSTANCE* pdidoi,VOID* pContext)
{
	if( pdidoi->dwType & DIDFT_AXIS )
	{
		DIPROPRANGE diprg; 
        diprg.diph.dwSize       = sizeof(DIPROPRANGE); 
        diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER); 
        diprg.diph.dwHow        = DIPH_BYID; 
        diprg.diph.dwObj        = pdidoi->dwType;
        diprg.lMin              = -3; 
        diprg.lMax              = 3; 
   
        if( FAILED(tmp_Joystick->SetProperty(DIPROP_RANGE, &diprg.diph)) ) 
			return DIENUM_STOP;
	}
	return DIENUM_CONTINUE;
}
Example #12
0
//=============================================================================
// マウス関係の処理
//=============================================================================
// マウスの初期化
HRESULT InitializeMouse(HINSTANCE hInst,HWND hWindow)
{
	HRESULT result;
	// デバイス作成
	result = g_pDInput->CreateDevice(GUID_SysMouse,&pMouse,NULL);
	if(FAILED(result) || pMouse==NULL)
	{
		MessageBox(hWindow,"No mouse","Warning",MB_OK | MB_ICONWARNING);
		return result;
	}
	// データフォーマット設定
	result = pMouse->SetDataFormat(&c_dfDIMouse2);
	if(FAILED(result))
	{
		MessageBox(hWindow,"Can't setup mouse","Warning",MB_OK | MB_ICONWARNING);
		return result;
	}
	// 他のアプリと協調モードに設定
	result = pMouse->SetCooperativeLevel(hWindow, (DISCL_FOREGROUND | DISCL_NONEXCLUSIVE));
	if(FAILED(result))
	{
		MessageBox(hWindow,"Mouse mode error","Warning",MB_OK | MB_ICONWARNING);
		return result;
	}
	
	// デバイスの設定
	DIPROPDWORD prop;
	
	prop.diph.dwSize = sizeof(prop);
	prop.diph.dwHeaderSize = sizeof(prop.diph);
	prop.diph.dwObj = 0;
	prop.diph.dwHow = DIPH_DEVICE;
	prop.dwData = DIPROPAXISMODE_REL;		// マウスの移動値 相対値

	result = pMouse->SetProperty(DIPROP_AXISMODE,&prop.diph);
	if(FAILED(result))
	{
		MessageBox(hWindow,"Mouse property error","Warning",MB_OK | MB_ICONWARNING);
		return result;	
	}
	
	// アクセス権を得る
	pMouse->Acquire();
	return result;
}
Example #13
0
static int Open(void *hwnd, int bForceFeedback)
{
    SYS_DXTRACE(g_lpDI->EnumDevices(DI8DEVCLASS_GAMECTRL, EnumFFJoysticksCallback, NULL, DIEDFL_ATTACHEDONLY | (bForceFeedback ? DIEDFL_FORCEFEEDBACK : 0)));

    if (g_pJoystick == NULL)
    {
        return FALSE;
    }

    if (SYS_DXTRACE(g_pJoystick->SetDataFormat(&c_dfDIJoystick2)))
    {
        return FALSE;
    }

    if (SYS_DXTRACE(g_pJoystick->SetCooperativeLevel((HWND)hwnd, DISCL_EXCLUSIVE | DISCL_BACKGROUND)))
    {
        return FALSE;
    }

    if (bForceFeedback)
    {
        DIPROPDWORD dipdw;
        dipdw.diph.dwSize  = sizeof(DIPROPDWORD);
        dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
        dipdw.diph.dwObj = 0;
        dipdw.diph.dwHow = DIPH_DEVICE;
        dipdw.dwData = FALSE;
        return !SYS_DXTRACE(g_pJoystick->SetProperty(DIPROP_AUTOCENTER, &dipdw.diph));
    }

	DIDEVCAPS caps;
	caps.dwSize = sizeof(caps);
	g_pJoystick->GetCapabilities(&caps);

	if (!SYS_DXTRACE(g_pJoystick->GetCapabilities(&caps)))
	{
		sJOY->numButtons = caps.dwButtons;
		sJOY->numAxes = caps.dwAxes;
		sJOY->numPOVs = caps.dwPOVs;
	}
	sJOY->numControllers = 1;
	SYS_DXTRACE(g_pJoystick->Acquire());

    return TRUE;
}
Example #14
0
BOOL CALLBACK  
enumAxesCallback(const DIDEVICEOBJECTINSTANCE* instance, VOID* context)  
{  
    HWND hDlg = (HWND)context;  
  
    DIPROPRANGE propRange;   
    propRange.diph.dwSize       = sizeof(DIPROPRANGE);   
    propRange.diph.dwHeaderSize = sizeof(DIPROPHEADER);   
    propRange.diph.dwHow        = DIPH_BYID;   
    propRange.diph.dwObj        = instance->dwType;  
    if (instance->guidType == GUID_XAxis )//方向盘  
    {  
        propRange.lMin              = -4500;   
        propRange.lMax              = +4500;   
    }  
    else if(instance->guidType == GUID_Slider )//离合  
    {  
        propRange.lMin              = 0;   
        propRange.lMax              = 1000;   
    }  
    else if(instance->guidType == GUID_RzAxis )//刹车  
    {  
        propRange.lMin              = 0;   
        propRange.lMax              = +1000;   
    }  
    else if(instance->guidType == GUID_YAxis )//油门  
    {  
        propRange.lMin              = 0;   
        propRange.lMax              = +1000;   
    }  
    else  
    {  
        propRange.lMin              = -1000;   
        propRange.lMax              = +1000;   
    }  
  
  
  
    // Set the range for the axis  
    if (FAILED(g_pJoystick->SetProperty(DIPROP_RANGE, &propRange.diph))) {  
        return DIENUM_STOP;  
    }  
  
    return DIENUM_CONTINUE;  
}  
Example #15
0
	// スティックなどの軸を列挙する
	BOOL CALLBACK Gamepad::EnumAxis(LPCDIDEVICEOBJECTINSTANCE oInstance, LPVOID ref)
	{
		DIPROPRANGE range;
		ZeroMemory(&range, sizeof(range));
		range.diph.dwSize = sizeof(range);
		range.diph.dwHeaderSize = sizeof(range.diph);
		range.diph.dwObj = oInstance->dwType;
		range.diph.dwHow = DIPH_BYID;
		range.lMin = -10000;
		range.lMax = 10000;

		if (FAILED(dpad->SetProperty(DIPROP_RANGE, &range.diph)))
		{
			return DIENUM_STOP;
		}

		return DIENUM_CONTINUE;
	}
Example #16
0
BOOL CALLBACK EnumObjectProc ( LPCDIDEVICEOBJECTINSTANCE lpddi, LPVOID lpRef )
{
	LPDIRECTINPUTDEVICE8	lpCurDID = (LPDIRECTINPUTDEVICE8)lpRef ;

	if ( lpddi->dwType & DIDFT_AXIS )
	{
        DIPROPRANGE diprg; 
        diprg.diph.dwSize       = sizeof(DIPROPRANGE); 
        diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER); 
        diprg.diph.dwHow        = DIPH_BYID; 
        diprg.diph.dwObj        = lpddi->dwType; // Specify the enumerated axis
        diprg.lMin              = -1000; 
        diprg.lMax              = +1000; 
    
        if( FAILED( lpCurDID->SetProperty( DIPROP_RANGE, &diprg.diph ) ) ) 
            return FALSE;
	}
	return TRUE ;
}
Example #17
0
s32 F_API INPKBInit(void *hMain)
{
	INPKBDestroy();

	HRESULT hr;

	//create the keyboard device
	hr = g_pDInput->CreateDevice(GUID_SysKeyboard, &g_pDKeyboard, NULL);
	if(FAILED(hr))
	{ DInputError(hr, L"_INPKBInit"); return RETCODE_FAILURE; }

	//set keyboard device as a REAL keyboard
	hr = g_pDKeyboard->SetDataFormat(&c_dfDIKeyboard);
	if(FAILED(hr))
	{ DInputError(hr, L"_INPKBInit"); return RETCODE_FAILURE; }

	//set up keyboard coop level
	hr = g_pDKeyboard->SetCooperativeLevel((HWND)hMain, g_coopFlag);
	if(FAILED(hr))
	{ DInputError(hr, L"_INPKBInit"); return RETCODE_FAILURE; }

	//set up buffering
	DIPROPDWORD dipdw;

    dipdw.diph.dwSize       = sizeof(DIPROPDWORD);
    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
    dipdw.diph.dwObj        = 0;
    dipdw.diph.dwHow        = DIPH_DEVICE;
    dipdw.dwData            = SAMPLE_BUFFER_SIZE; // Arbitary buffer size

	//set up keyboard property to tell that we are using buffer
	hr = g_pDKeyboard->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph);
    if(FAILED(hr))
	{ DInputError(hr, L"_INPKBInit"); return RETCODE_FAILURE; }

	//acquire keyboard device
	g_pDKeyboard->Acquire();

	return RETCODE_SUCCESS;
}
Example #18
0
BOOL CALLBACK nxInputManager::EnumObjectsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi,VOID* pContext )
{
    //MAKEWORD(low,high)

    // For axes that are returned, set the DIPROP_RANGE property for the
    // enumerated axis in order to scale min/max values.
    LPDIRECTINPUTDEVICE8 ptDevice = reinterpret_cast<LPDIRECTINPUTDEVICE8>(pContext);
    if( ptDevice && pdidoi->dwType & DIDFT_AXIS )
    {
        DIPROPRANGE diprg;
        diprg.diph.dwSize = sizeof( DIPROPRANGE );
        diprg.diph.dwHeaderSize = sizeof( DIPROPHEADER );
        diprg.diph.dwHow = DIPH_BYID;
        diprg.diph.dwObj = pdidoi->dwType; // Specify the enumerated axis
        diprg.lMin = INPUT_MIN;
        diprg.lMax = INPUT_MAX;
        // Set the range for the axis
        if( ptDevice->SetProperty( DIPROP_RANGE, &diprg.diph ) != DI_OK )
            return DIENUM_STOP;

    }
    return DIENUM_CONTINUE;
}
Example #19
0
//===============================================
//オブジェクトの列挙
//===============================================
//[input]
//
//[return]
//
//===============================================
BOOL CALLBACK CInput::EnumObjectsCallback(const DIDEVICEOBJECTINSTANCE *pdidoi, void *pContext)
{
	HRESULT hr;
	
	DIPROPRANGE diprg;
	diprg.diph.dwSize = sizeof(DIPROPRANGE);
	diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
	diprg.diph.dwHow = DIPH_BYID;
	diprg.diph.dwObj = pdidoi->dwType;
	diprg.lMin = -1000;
	diprg.lMax = +1000;
	
	LPDIRECTINPUTDEVICE8 Joy = (LPDIRECTINPUTDEVICE8)pContext;
	
	hr = Joy->SetProperty(DIPROP_RANGE, &diprg.diph);
	
	if(FAILED(hr) )
	{
		return DIENUM_STOP;
	}

	return DIENUM_CONTINUE;
}
//-----------------------------------------------------------------------------
// Name: EnumObjectsCallback()
// Desc: Callback function for enumerating objects (axes, buttons, POVs) on a
//       joystick. This function enables user interface elements for objects
//       that are found to exist, and scales axes min/max values.
//-----------------------------------------------------------------------------
BOOL CALLBACK CJoystickDirectInput::EnumObjectsCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext)
{
  LPDIRECTINPUTDEVICE8 pJoy = static_cast<LPDIRECTINPUTDEVICE8>(pContext);

  // For axes that are returned, set the DIPROP_RANGE property for the
  // enumerated axis in order to scale min/max values.
  if (pdidoi->dwType & DIDFT_AXIS)
  {
    DIPROPRANGE diprg;
    diprg.diph.dwSize = sizeof(DIPROPRANGE);
    diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
    diprg.diph.dwHow = DIPH_BYID;
    diprg.diph.dwObj = pdidoi->dwType; // Specify the enumerated axis
    diprg.lMin = AXIS_MIN;
    diprg.lMax = AXIS_MAX;

    // Set the range for the axis
    HRESULT hr = pJoy->SetProperty(DIPROP_RANGE, &diprg.diph);
    if (FAILED(hr))
      esyslog("%s : Failed to set property on %s", __FUNCTION__, pdidoi->tszName);
  }
  return DIENUM_CONTINUE;
}
Example #21
0
//-----------------------------------------------------------------------------
// Name: EnumObjectsCallback()
// Desc: Callback function for enumerating objects (axes, buttons, POVs) on a
//       joystick. This function enables user interface elements for objects
//       that are found to exist, and scales axes min/max values.
//-----------------------------------------------------------------------------
BOOL CALLBACK CJoystick::EnumObjectsCallback( const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext )
{

  LPDIRECTINPUTDEVICE8 pJoy = (LPDIRECTINPUTDEVICE8) pContext;

  // For axes that are returned, set the DIPROP_RANGE property for the
  // enumerated axis in order to scale min/max values.
  if( pdidoi->dwType & DIDFT_AXIS )
  {
      DIPROPRANGE diprg;
      diprg.diph.dwSize = sizeof( DIPROPRANGE );
      diprg.diph.dwHeaderSize = sizeof( DIPROPHEADER );
      diprg.diph.dwHow = DIPH_BYID;
      diprg.diph.dwObj = pdidoi->dwType; // Specify the enumerated axis
      diprg.lMin = AXIS_MIN;
      diprg.lMax = AXIS_MAX;

      // Set the range for the axis
      if( FAILED( pJoy->SetProperty( DIPROP_RANGE, &diprg.diph ) ) )
        return DIENUM_STOP;
  }

  return DIENUM_CONTINUE;
}
void PsychHIDOSKbQueueStart(int deviceIndex)
{
    LPDIRECTINPUTDEVICE8 kb;
    DIPROPDWORD  dipdw;
    psych_bool queueActive;
    int i;

    if (deviceIndex < 0) {
        deviceIndex = PsychHIDGetDefaultKbQueueDevice();
        // Ok, deviceIndex now contains our default keyboard to use - The first suitable keyboard.
    }

    if ((deviceIndex < 0) || (deviceIndex >= ndevices)) {
        // Out of range index:
        PsychErrorExitMsg(PsychError_user, "Invalid 'deviceIndex' specified. No such device!");
    }

    // Does Keyboard queue for this deviceIndex already exist?
    if (NULL == psychHIDKbQueueFirstPress[deviceIndex]) {
        // No. Bad bad...
        printf("PsychHID-ERROR: Tried to start processing on non-existent keyboard queue for deviceIndex %i! Call KbQueueCreate first!\n", deviceIndex);
        PsychErrorExitMsg(PsychError_user, "Invalid keyboard 'deviceIndex' specified. No queue for that device yet!");
    }

    // Keyboard queue already stopped? Then we ain't nothing to do:
    if (psychHIDKbQueueActive[deviceIndex]) return;

    // Queue is inactive. Start it:

    // Will this be the first active queue, ie., aren't there any queues running so far?
    queueActive = FALSE;
    for (i = 0; i < PSYCH_HID_MAX_DEVICES; i++) {
        queueActive |= psychHIDKbQueueActive[i];
    }

    PsychLockMutex(&KbQueueMutex);

    // Clear out current state for this queue:
    memset(psychHIDKbQueueFirstPress[deviceIndex]   , 0, (256 * sizeof(double)));
    memset(psychHIDKbQueueFirstRelease[deviceIndex] , 0, (256 * sizeof(double)));
    memset(psychHIDKbQueueLastPress[deviceIndex]    , 0, (256 * sizeof(double)));
    memset(psychHIDKbQueueLastRelease[deviceIndex]  , 0, (256 * sizeof(double)));

    // Setup event mask, so events from our associated xinput device
    // get enqueued in our event queue:
    kb = GetXDevice(deviceIndex);

    // Device specific data format setup:
    switch (info[deviceIndex].dwDevType & 0xff) {
    case DI8DEVTYPE_KEYBOARD:
        if (DI_OK != kb->SetDataFormat(&c_dfDIKeyboard)) {
            PsychUnlockMutex(&KbQueueMutex);
            printf("PsychHID-ERROR: Tried to start processing on keyboard queue for deviceIndex %i, but setting dataformat failed!\n", deviceIndex);
            PsychErrorExitMsg(PsychError_user, "Starting keyboard queue failed!");
        }
        break;

    case DI8DEVTYPE_MOUSE:
    case DI8DEVTYPE_SCREENPOINTER:
        if (DI_OK != kb->SetDataFormat(&c_dfDIMouse2)) {
            PsychUnlockMutex(&KbQueueMutex);
            printf("PsychHID-ERROR: Tried to start processing on keyboard queue for deviceIndex %i, but setting dataformat failed!\n", deviceIndex);
            PsychErrorExitMsg(PsychError_user, "Starting keyboard queue failed!");
        }
        break;

    case DI8DEVTYPE_JOYSTICK:
        if (DI_OK != kb->SetDataFormat(&c_dfDIJoystick2)) {
            PsychUnlockMutex(&KbQueueMutex);
            printf("PsychHID-ERROR: Tried to start processing on keyboard queue for deviceIndex %i, but setting dataformat failed!\n", deviceIndex);
            PsychErrorExitMsg(PsychError_user, "Starting keyboard queue failed!");
        }
        break;
    }

    // Set device event buffer size to 256 elements:
    dipdw.diph.dwSize = sizeof(DIPROPDWORD);
    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
    dipdw.diph.dwObj = 0;
    dipdw.diph.dwHow = DIPH_DEVICE;
    dipdw.dwData = 256;

    if (DI_OK != kb->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph)) {
        PsychUnlockMutex(&KbQueueMutex);
        printf("PsychHID-ERROR: Tried to start processing on keyboard queue for deviceIndex %i, but setting buffersize on device failed!\n", deviceIndex);
        PsychErrorExitMsg(PsychError_user, "Starting keyboard queue failed!");
    }

    // Enable state-change event notifications:
    if (DI_OK != kb->SetEventNotification(hEvent)) {
        PsychUnlockMutex(&KbQueueMutex);
        printf("PsychHID-ERROR: Tried to start processing on keyboard queue for deviceIndex %i, but setting device state notifications failed!\n", deviceIndex);
        PsychErrorExitMsg(PsychError_user, "Starting keyboard queue failed!");
    }

    if (DI_OK != kb->Acquire()) {
        PsychUnlockMutex(&KbQueueMutex);
        printf("PsychHID-ERROR: Tried to start processing on keyboard queue for deviceIndex %i, but acquiring device failed!\n", deviceIndex);
        PsychErrorExitMsg(PsychError_user, "Starting keyboard queue failed!");
    }

    // Mark this queue as logically started:
    psychHIDKbQueueActive[deviceIndex] = TRUE;

    // Queue started.
    PsychUnlockMutex(&KbQueueMutex);

    // If other queues are already active then we're done:
    if (queueActive) return;

    // No other active queues. We are the first one.

    // Start the common processing thread for all queues:
    PsychLockMutex(&KbQueueMutex);
    KbQueueThreadTerminate = FALSE;

    if (PsychCreateThread(&KbQueueThread, NULL, KbQueueWorkerThreadMain, NULL)) {
        // We are soo screwed:

        // Cleanup the mess:
        psychHIDKbQueueActive[deviceIndex] = FALSE;
        PsychUnlockMutex(&KbQueueMutex);

        // Whine a little bit:
        printf("PsychHID-ERROR: Start of keyboard queue processing failed!\n");
        PsychErrorExitMsg(PsychError_system, "Creation of keyboard queue background processing thread failed!");
    }

    // Up and running, we're done!
    PsychUnlockMutex(&KbQueueMutex);

    return;
}
Example #23
0
bool input_Init(HWND h)
{
    RECT rc;
    if (!GetWindowRect(h, &rc))
        return false;

    g_hwnd = h;

    SetCursorPos(rc.left, rc.top);

    HRESULT hr;
    DWORD   dwCoopFlags;
    if( FAILED( hr = DirectInput8Create( GetModuleHandle(NULL), DIRECTINPUT_VERSION,
                                         IID_IDirectInput8, (VOID**)&g_pDI, NULL ) ) )
    {
        return false;
    }
    if( FAILED( hr = g_pDI->CreateDevice( GUID_SysMouse, &g_pMouse, NULL ) ) )
    {
        return false;
    }

    if( FAILED( hr = g_pDI->CreateDevice( GUID_SysKeyboard, &g_pKeyboard, NULL ) ) )
    {
        return false;
    }
    //Sets the data format for the Microsoft DirectInput device
    if( FAILED( hr = g_pMouse->SetDataFormat( &c_dfDIMouse ) ) )
    {
        return false;
    }
    if( FAILED( hr = g_pKeyboard->SetDataFormat( &c_dfDIKeyboard ) ) )
    {
        return false;
    }
///#define DINPUT_BUFFERSIZE 16
    DIPROPDWORD dipdw;
    dipdw.diph.dwSize = sizeof(DIPROPDWORD);
    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
    dipdw.diph.dwObj = 0;
    dipdw.diph.dwHow = DIPH_DEVICE;

    dipdw.dwData = DINPUT_BUFFERSIZE ;
    g_pMouse->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph );
    g_pKeyboard->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph );
    /**
    	dipdw.dwData = DIPROPAXISMODE_ABS ;
        g_pMouse->SetProperty(DIPROP_AXISMODE, &dipdw.diph);
        **/
    //检测设备是否可以独占使用
    dwCoopFlags = DISCL_NONEXCLUSIVE|DISCL_BACKGROUND;
    //dwCoopFlags = DISCL_EXCLUSIVE|DISCL_BACKGROUND;
    hr = g_pMouse->SetCooperativeLevel( h, dwCoopFlags );
    if (DI_OK!=hr)
    {
        return false;
    }
    hr = g_pKeyboard->SetCooperativeLevel( h, dwCoopFlags );
    if (DI_OK!=hr)
    {
        return false;
    }
    //Obtains access to the input device.

    g_pMouse->Acquire();
    g_pKeyboard->Acquire();
    return true;
}
int Game_Init(void *parms,  int num_parms)
{
// this function is where you do all the initialization 
// for your game

int index;         // looping var
char filename[80]; // used to build up files names

// start up DirectDraw (replace the parms as you desire)
DDraw_Init(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_BPP, WINDOWED_APP);

// joystick creation section ////////////////////////////////

// first create the direct input object
if (DirectInput8Create(main_instance,DIRECTINPUT_VERSION, IID_IDirectInput8, (void **)&lpdi,NULL)!=DI_OK)
   return(0);

// first find the f*****g GUID of your particular joystick
lpdi->EnumDevices(DI8DEVCLASS_GAMECTRL, 
                  DI_Enum_Joysticks, 
                  &joystickGUID, 
                  DIEDFL_ATTACHEDONLY | DIEDFL_FORCEFEEDBACK); 

if (lpdi->CreateDevice(joystickGUID, &lpdijoy, NULL)!=DI_OK)
   return(0);

// set cooperation level
if (lpdijoy->SetCooperativeLevel(main_window_handle, 
	                 DISCL_EXCLUSIVE | DISCL_BACKGROUND)!=DI_OK)
   return(0);

// set data format
if (lpdijoy->SetDataFormat(&c_dfDIJoystick2)!=DI_OK)
   return(0);

// set the range of the joystick
DIPROPRANGE joy_axis_range;

// first x axis
joy_axis_range.lMin = -32;
joy_axis_range.lMax = 32;

joy_axis_range.diph.dwSize       = sizeof(DIPROPRANGE); 
joy_axis_range.diph.dwHeaderSize = sizeof(DIPROPHEADER); 
joy_axis_range.diph.dwObj        = DIJOFS_X;
joy_axis_range.diph.dwHow        = DIPH_BYOFFSET;

lpdijoy->SetProperty(DIPROP_RANGE,&joy_axis_range.diph);

// now y-axis
joy_axis_range.lMin = -32;
joy_axis_range.lMax = 32;

joy_axis_range.diph.dwSize       = sizeof(DIPROPRANGE); 
joy_axis_range.diph.dwHeaderSize = sizeof(DIPROPHEADER); 
joy_axis_range.diph.dwObj        = DIJOFS_Y;
joy_axis_range.diph.dwHow        = DIPH_BYOFFSET;

lpdijoy->SetProperty(DIPROP_RANGE,&joy_axis_range.diph);

// and now the dead band

DIPROPDWORD dead_band; // here's our property word

dead_band.diph.dwSize       = sizeof(dead_band);
dead_band.diph.dwHeaderSize = sizeof(dead_band.diph);
dead_band.diph.dwObj        = DIJOFS_X;
dead_band.diph.dwHow        = DIPH_BYOFFSET;

// 4 will be used on both sides of the range +/-
dead_band.dwData            = 1000;

// finally set the property
lpdijoy->SetProperty(DIPROP_DEADZONE,&dead_band.diph);

dead_band.diph.dwSize       = sizeof(dead_band);
dead_band.diph.dwHeaderSize = sizeof(dead_band.diph);
dead_band.diph.dwObj        = DIJOFS_Y;
dead_band.diph.dwHow        = DIPH_BYOFFSET;

// 4 will be used on both sides of the range +/-
dead_band.dwData            = 1000;

// finally set the property
lpdijoy->SetProperty(DIPROP_DEADZONE,&dead_band.diph);


// acquire the joystick
if (lpdijoy->Acquire()!=DI_OK)
   return(0);


// force feedback setup
DWORD      dwAxes[2] = { DIJOFS_X, DIJOFS_Y };
LONG       lDirection[2] = { 0, 0 };


DIPERIODIC diPeriodic;      // type-specific parameters
DIENVELOPE diEnvelope;      // envelope
DIEFFECT   diEffect;        // general parameters

// setup the periodic structure
diPeriodic.dwMagnitude = DI_FFNOMINALMAX; 
diPeriodic.lOffset = 0; 
diPeriodic.dwPhase = 0; 
diPeriodic.dwPeriod = (DWORD) (0.05 * DI_SECONDS); 

// set the modulation envelope 
diEnvelope.dwSize = sizeof(DIENVELOPE);
diEnvelope.dwAttackLevel = 0; 
diEnvelope.dwAttackTime = (DWORD) (0.01 * DI_SECONDS); 
diEnvelope.dwFadeLevel = 0; 
diEnvelope.dwFadeTime = (DWORD) (3.0 * DI_SECONDS); 
 
// set up the effect structure itself
diEffect.dwSize = sizeof(DIEFFECT); 
diEffect.dwFlags = DIEFF_POLAR | DIEFF_OBJECTOFFSETS; 
diEffect.dwDuration = (DWORD) INFINITE; // (1 * DI_SECONDS);
 
// set up details of effect
diEffect.dwSamplePeriod = 0;               // = default 
diEffect.dwGain = DI_FFNOMINALMAX;         // no scaling
diEffect.dwTriggerButton = DIJOFS_BUTTON0; // connect effect to trigger button
diEffect.dwTriggerRepeatInterval = 0;      
diEffect.cAxes = 2; 
diEffect.rgdwAxes = dwAxes; 
diEffect.rglDirection = &lDirection[0]; 
diEffect.lpEnvelope = &diEnvelope; 
diEffect.cbTypeSpecificParams = sizeof(diPeriodic);
diEffect.lpvTypeSpecificParams = &diPeriodic;  
 
// create the effect and get the interface to it 
lpdijoy->CreateEffect(GUID_Square,  // standard GUID 
                     &diEffect,      // where the data is
                     &lpdieffect,    // where to put interface pointer
                     NULL);          // no aggregation


///////////////////////////////////////////////////////////

// load the background
Load_Bitmap_File(&bitmap16bit, "MUSH_24.BMP");

// load in the four frames of the mushroom
for (index=0; index<4; index++)
    {
    // create mushroom bitmaps
    Create_Bitmap(&mushrooms[index],0,0,32,32,16);
    Load_Image_Bitmap16(&mushrooms[index],&bitmap16bit,index,0,BITMAP_EXTRACT_MODE_CELL);  
    } // end for index

// now create the bug blaster bob
Create_BOB(&blaster,0,0,32,32,3,
           BOB_ATTR_VISIBLE | BOB_ATTR_MULTI_ANIM | BOB_ATTR_ANIM_ONE_SHOT,
           DDSCAPS_SYSTEMMEMORY,0,16);

// load in the four frames of the mushroom
for (index=0; index<3; index++)
     Load_Frame_BOB16(&blaster,&bitmap16bit,index,index,1,BITMAP_EXTRACT_MODE_CELL);  

// unload the bitmap file
Unload_Bitmap_File(&bitmap16bit);

// set the animation sequences for bug blaster
Load_Animation_BOB(&blaster,0,5,blaster_anim);

// set up stating state of bug blaster
Set_Pos_BOB(&blaster,320, 400);
Set_Anim_Speed_BOB(&blaster,3);

// create mushroom playfield bitmap
Create_Bitmap(&playfield,0,0,SCREEN_WIDTH,SCREEN_HEIGHT,16);
playfield.attr |= BITMAP_ATTR_LOADED;

// fill in the background
Load_Bitmap_File(&bitmap16bit, "GRASS_24.BMP");

// load the grass bitmap image
Load_Image_Bitmap16(&playfield,&bitmap16bit,0,0,BITMAP_EXTRACT_MODE_ABS);
Unload_Bitmap_File(&bitmap16bit);

// seed random number generator
srand(Start_Clock());

// create the random mushroom patch
for (index=0; index<50; index++)
    {
    // select a mushroom
    int mush = rand()%4;

    // set mushroom to random position
    mushrooms[mush].x = rand()%(SCREEN_WIDTH-32);
    mushrooms[mush].y = rand()%(SCREEN_HEIGHT-128);

    // now draw the mushroom into playfield
    Draw_Bitmap16(&mushrooms[mush], playfield.buffer, playfield.width*2,1);

    } // end for

// hide the mouse
if (!WINDOWED_APP)
   ShowCursor(FALSE);

// return success
return(1);

} // end Game_Init
bool ForceFeedbackDevice::InitForceFeedback(const LPDIRECTINPUTDEVICE8 device, int axis_count)
{
  if (axis_count == 0)
    return false;

  // We just use the X axis (for wheel left/right).
  // Gamepads seem to not care which axis you use.
  // These are temporary for creating the effect:
  std::array<DWORD, 1> rgdwAxes = {DIJOFS_X};
  std::array<LONG, 1> rglDirection = {-200};

  DIEFFECT eff{};
  eff.dwSize = sizeof(eff);
  eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS;
  eff.dwDuration = DI_SECONDS / 1000 * RUMBLE_LENGTH_MS;
  eff.dwSamplePeriod = 0;
  eff.dwGain = DI_FFNOMINALMAX;
  eff.dwTriggerButton = DIEB_NOTRIGGER;
  eff.dwTriggerRepeatInterval = 0;
  eff.cAxes = DWORD(rgdwAxes.size());
  eff.rgdwAxes = rgdwAxes.data();
  eff.rglDirection = rglDirection.data();
  eff.dwStartDelay = 0;

  // Initialize parameters with zero force (their current state).
  DICONSTANTFORCE diCF{};
  diCF.lMagnitude = 0;
  DIRAMPFORCE diRF{};
  diRF.lStart = diRF.lEnd = 0;
  DIPERIODIC diPE{};
  diPE.dwMagnitude = 0;
  diPE.lOffset = 0;
  diPE.dwPhase = 0;
  diPE.dwPeriod = DI_SECONDS / 1000 * RUMBLE_PERIOD_MS;

  for (auto& f : force_type_names)
  {
    if (f.guid == GUID_ConstantForce)
    {
      eff.cbTypeSpecificParams = sizeof(DICONSTANTFORCE);
      eff.lpvTypeSpecificParams = &diCF;
    }
    else if (f.guid == GUID_RampForce)
    {
      eff.cbTypeSpecificParams = sizeof(DIRAMPFORCE);
      eff.lpvTypeSpecificParams = &diRF;
    }
    else
    {
      // All other forces need periodic parameters:
      eff.cbTypeSpecificParams = sizeof(DIPERIODIC);
      eff.lpvTypeSpecificParams = &diPE;
    }

    LPDIRECTINPUTEFFECT pEffect;
    if (SUCCEEDED(device->CreateEffect(f.guid, &eff, &pEffect, nullptr)))
    {
      if (f.guid == GUID_ConstantForce)
        AddOutput(new ForceConstant(this, f.name, pEffect, diCF));
      else if (f.guid == GUID_RampForce)
        AddOutput(new ForceRamp(this, f.name, pEffect, diRF));
      else
        AddOutput(new ForcePeriodic(this, f.name, pEffect, diPE));
    }
  }

  // Disable autocentering:
  if (Outputs().size())
  {
    DIPROPDWORD dipdw;
    dipdw.diph.dwSize = sizeof(DIPROPDWORD);
    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
    dipdw.diph.dwObj = 0;
    dipdw.diph.dwHow = DIPH_DEVICE;
    dipdw.dwData = DIPROPAUTOCENTER_OFF;
    device->SetProperty(DIPROP_AUTOCENTER, &dipdw.diph);

    m_run_thread.Set();
    m_update_thread = std::thread(&ForceFeedbackDevice::ThreadFunc, this);
  }

  return true;
}
Example #26
0
HRESULT InitDirectInput2( HWND hDlg )
{
    HRESULT hr;
	   
	DIPROPDWORD dipdw;

    // Setup the g_EffectsList circular linked list
    ZeroMemory( &g_EffectsList, sizeof( EFFECTS_NODE ) );
    g_EffectsList.pNext = &g_EffectsList;

    // Create a DInput object
    if( FAILED( hr = DirectInput8Create( GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&g_pDI, NULL ) ) )
	{
		ctx->OutputToConsole("PlayFFE :: DirectInput8Create");
	    return hr;
	}

    // Get the first enumerated force feedback device
    if( FAILED( hr = g_pDI->EnumDevices( DI8DEVCLASS_GAMECTRL, EnumFFDevicesCallback2, 0, 
                                         DIEDFL_ATTACHEDONLY | 
                                         DIEDFL_FORCEFEEDBACK ) ) )
	{
		ctx->OutputToConsole("PlayFFE :: EnumDevices failed");		
		return hr;
	}

    
    if( g_pFFDevice == NULL )
    {

	   ctx->OutputToConsole("PlayFFE :: No force feedback device found.");
       return -1;
    }


    // Set the data format
    if( FAILED( hr = g_pFFDevice->SetDataFormat( &c_dfDIJoystick ) ) )
        return hr;


    // Set the coop level
    //hr = g_pFFDevice->SetCooperativeLevel( hDlg , DISCL_EXCLUSIVE | DISCL_FOREGROUND) ;
	hr = g_pFFDevice->SetCooperativeLevel( hDlg , DISCL_EXCLUSIVE | DISCL_BACKGROUND) ;

	

	//DISCL_NONEXCLUSIVE 

	// Since we will be playing force feedback effects, we should disable the
	// auto-centering spring.
	dipdw.diph.dwSize = sizeof( DIPROPDWORD );
	dipdw.diph.dwHeaderSize = sizeof( DIPROPHEADER );
	dipdw.diph.dwObj = 0;
	dipdw.diph.dwHow = DIPH_DEVICE;
	dipdw.dwData = FALSE;

	if( FAILED( hr = g_pFFDevice->SetProperty( DIPROP_AUTOCENTER, &dipdw.diph ) ) )
		return hr;

	// Enumerate and count the axes of the joystick 
	if( FAILED( hr = g_pFFDevice->EnumObjects( EnumAxesCallback,
		( VOID* )&g_dwNumForceFeedbackAxis, DIDFT_AXIS ) ) )
		return hr;


	// This simple sample only supports one or two axis joysticks
	if( g_dwNumForceFeedbackAxis > 2 )
		g_dwNumForceFeedbackAxis = 2;

	// This application needs only one effect: Applying raw forces.
	DWORD rgdwAxes[2] = { DIJOFS_X, DIJOFS_Y };
	LONG rglDirection[2] = { 0,0 };
	DICONSTANTFORCE cf = { 0 };
	cf.lMagnitude = 0;


	DIEFFECT eff;
	ZeroMemory( &eff, sizeof( eff ) );
	eff.dwSize = sizeof( DIEFFECT );
	eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS;
	eff.dwDuration = INFINITE;
	eff.dwSamplePeriod = 0;
	eff.dwGain = DI_FFNOMINALMAX;
	eff.dwTriggerButton = DIEB_NOTRIGGER;
	eff.dwTriggerRepeatInterval = 0;
	eff.cAxes = g_dwNumForceFeedbackAxis;
	eff.rgdwAxes = rgdwAxes;
	eff.rglDirection = rglDirection;
	eff.lpEnvelope = 0;
	eff.cbTypeSpecificParams = sizeof( DICONSTANTFORCE );
	eff.lpvTypeSpecificParams = &cf;
	eff.dwStartDelay = 0;
	
	// Create the prepared effect
	if( FAILED( hr = g_pFFDevice->CreateEffect( GUID_ConstantForce,
		&eff, &g_pEffect, NULL ) ) )
	{
		return hr;
	}

	if( NULL == g_pEffect )
		return E_FAIL;

    return S_OK;
}
Example #27
0
int DInput_Init_Joystick(int min_x, int max_x, int min_y, int max_y, int dead_zone)
{
// this function initializes the joystick, it allows you to set
// the minimum and maximum x-y ranges 

// first find the f*****g GUID of your particular joystick
lpdi->EnumDevices(DI8DEVCLASS_GAMECTRL, 
                  DInput_Enum_Joysticks, 
                  &joystickGUID, 
                  DIEDFL_ATTACHEDONLY); 

// create a temporary IDIRECTINPUTDEVICE (1.0) interface, so we query for 2
LPDIRECTINPUTDEVICE lpdijoy_temp = NULL;

if (lpdi->CreateDevice(joystickGUID, &lpdijoy, NULL)!=DI_OK)
   return(0);

// set cooperation level
if (lpdijoy->SetCooperativeLevel(main_window_handle, 
	                 DISCL_NONEXCLUSIVE | DISCL_BACKGROUND)!=DI_OK)
   return(0);

// set data format
if (lpdijoy->SetDataFormat(&c_dfDIJoystick)!=DI_OK)
   return(0);

// set the range of the joystick
DIPROPRANGE joy_axis_range;

// first x axis
joy_axis_range.lMin = min_x;
joy_axis_range.lMax = max_x;

joy_axis_range.diph.dwSize       = sizeof(DIPROPRANGE); 
joy_axis_range.diph.dwHeaderSize = sizeof(DIPROPHEADER); 
joy_axis_range.diph.dwObj        = DIJOFS_X;
joy_axis_range.diph.dwHow        = DIPH_BYOFFSET;

lpdijoy->SetProperty(DIPROP_RANGE,&joy_axis_range.diph);

// now y-axis
joy_axis_range.lMin = min_y;
joy_axis_range.lMax = max_y;

joy_axis_range.diph.dwSize       = sizeof(DIPROPRANGE); 
joy_axis_range.diph.dwHeaderSize = sizeof(DIPROPHEADER); 
joy_axis_range.diph.dwObj        = DIJOFS_Y;
joy_axis_range.diph.dwHow        = DIPH_BYOFFSET;

lpdijoy->SetProperty(DIPROP_RANGE,&joy_axis_range.diph);


// and now the dead band
DIPROPDWORD dead_band; // here's our property word

// scale dead zone by 100
dead_zone*=100;

dead_band.diph.dwSize       = sizeof(dead_band);
dead_band.diph.dwHeaderSize = sizeof(dead_band.diph);
dead_band.diph.dwObj        = DIJOFS_X;
dead_band.diph.dwHow        = DIPH_BYOFFSET;

// deadband will be used on both sides of the range +/-
dead_band.dwData            = dead_zone;

// finally set the property
lpdijoy->SetProperty(DIPROP_DEADZONE,&dead_band.diph);

dead_band.diph.dwSize       = sizeof(dead_band);
dead_band.diph.dwHeaderSize = sizeof(dead_band.diph);
dead_band.diph.dwObj        = DIJOFS_Y;
dead_band.diph.dwHow        = DIPH_BYOFFSET;

// deadband will be used on both sides of the range +/-
dead_band.dwData            = dead_zone;


// finally set the property
lpdijoy->SetProperty(DIPROP_DEADZONE,&dead_band.diph);

// acquire the joystick
if (lpdijoy->Acquire()!=DI_OK)
   return(0);

// set found flag
joystick_found = 1;

// return success
return(1);

} // end DInput_Init_Joystick
Example #28
0
HRESULT InitD3D(HINSTANCE hInstance)
{
	// 先创建DInput和DSound
	if(FAILED(DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&g_pDI, NULL)))
		return E_FAIL;
	if(FAILED(g_pDI->CreateDevice(GUID_SysKeyboard, &g_pDIKey, NULL)))
		return E_FAIL;
	if(FAILED(g_pDI->CreateDevice(GUID_SysMouse, &g_pDIMouse, NULL)))
		return E_FAIL;
		// 设置参数
	if(FAILED(g_pDIKey->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))
		return E_FAIL;
	if(FAILED(g_pDIKey->SetDataFormat(&c_dfDIKeyboard)))
		return E_FAIL;
	if(FAILED(g_pDIMouse->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))
		return E_FAIL;
	if(FAILED(g_pDIMouse->SetDataFormat(&c_dfDIMouse)))
		return E_FAIL;
		
		// 缓冲输入,设置数据格式和属性
	DIPROPDWORD dipdw;
	dipdw.diph.dwSize       = sizeof(DIPROPDWORD);
	dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
	dipdw.diph.dwObj        = 0;
	dipdw.diph.dwHow        = DIPH_DEVICE;
	dipdw.dwData            = SAMPLE_BUFFER_SIZE; // Arbitary buffer size

#ifdef USE_BUFFERED_KEYBOARD_INPUT
	if( FAILED( g_pDIKey->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph ) ) )
		return E_FAIL;
#endif
#ifdef USE_BUFFERED_MOUSE_INPUT
	if( FAILED( g_pDIMouse->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph ) ) )
		return E_FAIL;
#endif

		// 开始
	g_pDIKey->Acquire();
	g_pDIMouse->Acquire();



	// 初始化D3D
	if(NULL==(d3d=Direct3DCreate9(D3D_SDK_VERSION)))
		  return E_FAIL;

	//查询当前显卡模式,Desktop是目前桌面设置,d3ddm总是当前使用全屏模式的设置,即使是窗口模式,颜色数值也总和当前的一样
	if(FAILED(d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &DesktopDisplayMode)))
		  return E_FAIL;
	if(FAILED(d3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm)))
		return E_FAIL;

	//全屏的话默认是32位色
	if(!WindowMode) d3ddm.Format = D3DFMT_X8R8G8B8;

	//查询设备能力,并设置顶点处理器模式
	DWORD UserVertexShaderProcessing;

	d3d->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &d3dcaps);

	if(FAILED(DetectDeviceCaps())) return E_FAIL;

	if(d3dcaps.VertexShaderVersion < D3DVS_VERSION(1, 0))
		UserVertexShaderProcessing=D3DCREATE_HARDWARE_VERTEXPROCESSING;
	else
		UserVertexShaderProcessing=D3DCREATE_SOFTWARE_VERTEXPROCESSING;

//创建D3D设备
	ZeroMemory(&d3dpp,sizeof(d3dpp));

	d3dpp.Windowed = WindowMode;
	d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;
	d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
	d3dpp.hDeviceWindow = hWnd;
	d3dpp.BackBufferCount = 1;
	d3dpp.BackBufferWidth = d3ddm.Width;
	d3dpp.BackBufferHeight = d3ddm.Height;
	d3dpp.EnableAutoDepthStencil = TRUE;
	
	if(WindowMode)
	{
		d3ddm.Format = DesktopDisplayMode.Format;
		d3dpp.BackBufferWidth = WindowWidth;
		d3dpp.BackBufferHeight = WindowHeight;
	}

	d3dpp.BackBufferFormat = d3ddm.Format;

	if(d3ddm.Format == D3DFMT_X8R8G8B8)
	{
		d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
		TextureFormat = D3DFMT_A8R8G8B8;
	}
	else
	{
		d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
		TextureFormat = D3DFMT_A4R4G4B4;
	}


	// 先强制以硬件顶点方式创建设备(为了不漏掉MX440这种不支持VS但支持T&L的显卡,XIXI)
	UserVertexShaderProcessing = D3DCREATE_HARDWARE_VERTEXPROCESSING;
	HRESULT hr = d3d->CreateDevice( D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, hWnd, UserVertexShaderProcessing, &d3dpp, &d3ddevice);
	// 这种错误表示顶点处理方式不被硬件支持,强制以软件方式创建设备(为了兼容不支持T&L的DX7显卡,比如某些集成显卡)
	if(hr == D3DERR_INVALIDCALL)
	{
		mymessage("警告:显卡不支持硬件顶点处理,强制以软件方式创建设备,性能会急剧下降!!!");
		UserVertexShaderProcessing = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
		hr = d3d->CreateDevice( D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, hWnd, UserVertexShaderProcessing, &d3dpp, &d3ddevice);
	}
	// 全部失败?有问题吧?
	if(FAILED(hr))
	{
		char szErrorInfo[512] = "";
		sprintf(szErrorInfo, "创建D3D设备失败!请检查系统或硬件设置!比如显卡驱动程序或DirectX是否安装正确!错误号%x", hr);
		mymessage(szErrorInfo);
		return E_FAIL;
	}

	// Shader版本检测
	char pVSVersion[7] = "", pPSVersion[7] = "";
	char pNeedVSVersion[7] = USE_VSVERSION, pNeedPSVersion[7] = USE_PSVERSION;
	char szErrorInfo[100] = "";

#ifdef USE_PIXELSHADER
	// 判断PS版本
	memcpy(pPSVersion, D3DXGetPixelShaderProfile(d3ddevice), 7);
	// 2.x中'b'虽然字母数值大于'a',但它从支持度上来看是小于a的,所以这里强制把它置为小于'a',以便后面比较
	if(pPSVersion[3] == '2' && pPSVersion[5] == 'b')
		pPSVersion[5] = 'a'-1;
	if(pNeedPSVersion[3] == '2' && pNeedPSVersion[5] == 'b')
		pNeedPSVersion[5] = 'a'-1;
	if(pPSVersion[3]<pNeedPSVersion[3] || pPSVersion[3]==pNeedPSVersion[3]&&pPSVersion[5]<pNeedPSVersion[5])
	{
		sprintf(szErrorInfo, "不支持Pixel Shader %c.%c!", pNeedPSVersion[3], pNeedPSVersion[5]);
		mymessage(szErrorInfo);	return E_FAIL;
	}
	
	// 判断PS2.0x的条件是否符合程序的最小需求
	if(!strcmp(USE_PSVERSION, "ps_2_a") || !strcmp(USE_PSVERSION, "ps_2_b") || !strcmp(USE_PSVERSION, "ps_2_x"))
	{
		BOOL bFlowControl = FALSE;
#ifdef PS2x_USE_FLOWCONTROL
		bFlowControl = TRUE;
#endif

		if(!CheckPS2xSupport(PS2x_USE_MAXNUM_TEMP, bFlowControl))
		{
			sprintf(szErrorInfo, "不完整支持Pixel Shader 2.x,无法执行程序!");
			mymessage(szErrorInfo);	return E_FAIL;
		}
	}


#endif USE_PIXELSHADER

#ifdef USE_VERTEXSHADER
	BOOL bSoftwareVertexProcessing = FALSE;
	// 完全不支持的,要跳过版本检测,否则D3DXGetVertexShaderProfile会返回空指针造成非法操作
	if((d3dcaps.VertexShaderVersion&0xffff) == 0) 
	{
		bSoftwareVertexProcessing = TRUE;
	}
	else
	{
		// 判断VS版本
		memcpy(pVSVersion, D3DXGetVertexShaderProfile(d3ddevice), 7);
		if(pVSVersion[3]<pNeedVSVersion[3] || pVSVersion[3]==pNeedVSVersion[3]&&pVSVersion[5]<pNeedVSVersion[5])
		{
			bSoftwareVertexProcessing = TRUE;
		}
		// 判断VS2.0x的条件是否符合程序的最小需求
		if(!strcmp(USE_VSVERSION, "vs_2_a") || !strcmp(USE_VSVERSION, "vs_2_b") || !strcmp(USE_VSVERSION, "vs_2_x"))
		{
#ifdef VS2a_USE_MAXNUM_TEMP
			if(d3dcaps.VS20Caps.NumTemps < VS2x_USE_MAXNUM_TEMP)
			{
				bSoftwareVertexProcessing = TRUE;
			}
#endif
		}
	}

	// 如果刚才是以硬件顶点创建设备的,而现在又需要强制软顶点以运行硬件不支持的VS,那么释放设备,重新创建
	if(bSoftwareVertexProcessing && UserVertexShaderProcessing == D3DCREATE_HARDWARE_VERTEXPROCESSING)
	{
		// 如果不支持指定版本的Vertex Shader,就强制创建软顶点处理设备
		sprintf(szErrorInfo, "警告:显卡不支持Vertex Shader %c.%c!强制以软件方式创建设备,性能会急剧下降!!!", pNeedVSVersion[3], pNeedVSVersion[5]);
		mymessage(szErrorInfo);
		SAFE_RELEASE(d3ddevice);
		hr = d3d->CreateDevice( D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddevice);
		if(FAILED(hr))
		{
			char szErrorInfo[512] = "";
			sprintf(szErrorInfo, "创建D3D设备失败!请检查系统或硬件设置!比如显卡驱动程序或DirectX是否安装正确!错误号%x", hr);
			mymessage(szErrorInfo);
			return E_FAIL;
		}
	}

#endif



	//初始化摄像机,之所以放在这里,是为了设备丢失后不会又重置到初始位置
	D3DXVECTOR3 PtLookAt = g_PtCameraInitPos + g_VecCameraInitDir;
	CameraChange.InitCamera(g_PtCameraInitPos.x, g_PtCameraInitPos.y, g_PtCameraInitPos.z,  PtLookAt.x, PtLookAt.y, PtLookAt.z,  0.0f,1.0f,0.0f, 7,7,90);

	//得到硬件精确计时器的频率
	QueryPerformanceFrequency(&PerformanceFrequency);

	return S_OK;
}
Example #29
0
//-----------------------------------------------------------------------------
// Name: OnCreateDevice()
// Desc: Setups a the mouse device using the flags from the dialog.
//-----------------------------------------------------------------------------
HRESULT OnCreateDevice( HWND hDlg )
{
    HRESULT hr;
    BOOL    bExclusive;
    BOOL    bForeground;
    BOOL    bImmediate;
    DWORD   dwCoopFlags;

    // Cleanup any previous call first
    KillTimer( hDlg, 0 );    
    FreeDirectInput();

    // Detrimine where the buffer would like to be allocated 
    bExclusive         = ( IsDlgButtonChecked( hDlg, IDC_EXCLUSIVE  ) == BST_CHECKED );
    bForeground        = ( IsDlgButtonChecked( hDlg, IDC_FOREGROUND ) == BST_CHECKED );
    bImmediate         = ( IsDlgButtonChecked( hDlg, IDC_IMMEDIATE  ) == BST_CHECKED );

    if( bExclusive )
        dwCoopFlags = DISCL_EXCLUSIVE;
    else
        dwCoopFlags = DISCL_NONEXCLUSIVE;

    if( bForeground )
        dwCoopFlags |= DISCL_FOREGROUND;
    else
        dwCoopFlags |= DISCL_BACKGROUND;

    // Create a DInput object
    if( FAILED( hr = DirectInput8Create( GetModuleHandle(NULL), DIRECTINPUT_VERSION, 
                                         IID_IDirectInput8, (VOID**)&g_pDI, NULL ) ) )
        return hr;
    
    // Obtain an interface to the system mouse device.
    if( FAILED( hr = g_pDI->CreateDevice( GUID_SysMouse, &g_pMouse, NULL ) ) )
        return hr;
    
    // Set the data format to "mouse format" - a predefined data format 
    //
    // A data format specifies which controls on a device we
    // are interested in, and how they should be reported.
    //
    // This tells DirectInput that we will be passing a
    // DIMOUSESTATE2 structure to IDirectInputDevice::GetDeviceState.
    if( FAILED( hr = g_pMouse->SetDataFormat( &c_dfDIMouse2 ) ) )
        return hr;
    
    // Set the cooperativity level to let DirectInput know how
    // this device should interact with the system and with other
    // DirectInput applications.
    hr = g_pMouse->SetCooperativeLevel( hDlg, dwCoopFlags );
    if( hr == DIERR_UNSUPPORTED && !bForeground && bExclusive )
    {
        FreeDirectInput();
        MessageBox( hDlg, _T("SetCooperativeLevel() returned DIERR_UNSUPPORTED.\n")
                          _T("For security reasons, background exclusive mouse\n")
                          _T("access is not allowed."), 
                          _T("Mouse"), MB_OK );
        return S_OK;
    }

    if( FAILED(hr) )
        return hr;

    if( !bImmediate )
    {
        // IMPORTANT STEP TO USE BUFFERED DEVICE DATA!
        //
        // DirectInput uses unbuffered I/O (buffer size = 0) by default.
        // If you want to read buffered data, you need to set a nonzero
        // buffer size.
        //
        // Set the buffer size to SAMPLE_BUFFER_SIZE (defined above) elements.
        //
        // The buffer size is a DWORD property associated with the device.
        DIPROPDWORD dipdw;
        dipdw.diph.dwSize       = sizeof(DIPROPDWORD);
        dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
        dipdw.diph.dwObj        = 0;
        dipdw.diph.dwHow        = DIPH_DEVICE;
        dipdw.dwData            = SAMPLE_BUFFER_SIZE; // Arbitary buffer size

        if( FAILED( hr = g_pMouse->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph ) ) )
            return hr;
    }

    // Acquire the newly created device
    g_pMouse->Acquire();

    // Set a timer to go off 12 times a second, to read input
    // Note: Typically an application would poll the mouse
    //       much faster than this, but this slow rate is simply 
    //       for the purposes of demonstration
    SetTimer( hDlg, 0, 1000 / 12, NULL );

    return S_OK;
}
Example #30
0
BOOL CALLBACK enumCallback(const DIDEVICEINSTANCE* instance, VOID* context) {
	HRESULT hr;
	BOOL xinput = false;

	if (instance->wUsagePage != 1 || instance->wUsage != 5) {
		// Not an actual game controller (see issue #3)
		return DIENUM_CONTINUE;
	}

	// First check if the device is known
	auto it = isXInput.find(instance->guidInstance);
	if (it == isXInput.end()) {
		// Not found yet, so check if it is an XInputDevice
		xinput = isXInputDevice(&instance->guidProduct);
		isXInput[instance->guidInstance] = xinput;
	} else {
		xinput = it->second;
	}

	if (xinput) {
		// If it is an xinput, we can safely ignore
		return DIENUM_CONTINUE;
	}

	// Check if we have a live DI instance of this joystick
	if (joysticks.find(instance->guidInstance) != joysticks.end()) {
		return DIENUM_CONTINUE;
	}

	// If not we must build it...

	LPDIRECTINPUTDEVICE8 joystick;
	// Obtain an interface to the enumerated joystick.
	hr = di->CreateDevice(instance->guidInstance, &joystick, NULL);
	// If it failed, then we can't use this joystick. (Maybe the user unplugged
	// it while we were in the middle of enumerating it.)
	if (FAILED(hr)) {
		// As seen on x360ce, if create device fails on guid instance, try the product
		hr = di->CreateDevice(instance->guidProduct, &joystick, NULL);
		if (FAILED(hr))
			return DIENUM_CONTINUE;
	}

	// Set the data format to "simple joystick" - a predefined data format 
	//
	// A data format specifies which controls on a device we are interested in,
	// and how they should be reported. This tells DInput that we will be
	// passing a DIJOYSTATE2 structure to IDirectInputDevice::GetDeviceState().
	if (FAILED(hr = joystick->SetDataFormat(&c_dfDIJoystick2))) {
		printf("SetDataFormat is f****d %x\n", hr);
		joystick->Release();
		return DIENUM_CONTINUE;
	}

	hr = joystick->SetCooperativeLevel(hWnd, DISCL_EXCLUSIVE | DISCL_BACKGROUND);
	if (FAILED(hr)) {
		hr = joystick->SetCooperativeLevel(hWnd, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND);
		if (FAILED(hr)) {
			printf("Cooperative is f****d %x\n", hr);
		}
	}

	DIPROPDWORD dipdw;
	dipdw.diph.dwSize = sizeof(DIPROPDWORD);
	dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
	dipdw.diph.dwObj = 0;
	dipdw.diph.dwHow = DIPH_DEVICE;
	dipdw.dwData = DIPROPAUTOCENTER_ON;
	joystick->SetProperty(DIPROP_AUTOCENTER, &dipdw.diph);

	// Acquire the device
	if (FAILED(hr = joystick->Acquire())) {
		printf("Acquire is f****d %x\n", hr);
		joystick->Release();
		return DIENUM_CONTINUE;
	}

	// Store the joystick instance accessible via guid
	joysticks[instance->guidInstance] = joystick;

	// Get other devices
	return DIENUM_CONTINUE;
}