DirectInput输入——游戏杆设备

//初始化DirectInput COM对象
int DInput_Init(void)
{
	if (FAILED(DirectInput8Create(main_instance,DIRECTINPUT_VERSION,IID_IDirectInput8, (LPVOID*)&lpdi,NULL)))
		return(0);

	return(1);

}
//释放DirectInput COM对象
void DInput_Shutdown(void)
{
	if (lpdi)
		lpdi->Release();
} 

//游戏杆设备
LPDIRECTINPUTDEVICE8 lpdijoy   = NULL; 
//游戏杆名字
char                 joyname[80];    
//游戏杆状态
DIJOYSTATE joy_state;   
//是否找到游戏杆
int joystick_found = 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 

//枚举游戏杆
lpdi->EnumDevices(DI8DEVTYPE_JOYSTICK, 
                  DInput_Enum_Joysticks, 
                  &joystickGUID, 
                  DIEDFL_ATTACHEDONLY); 

LPDIRECTINPUTDEVICE lpdijoy_temp = NULL;

//创建游戏杆,通过旧版本的设备查询新版本的设备
if (lpdi->CreateDevice(joystickGUID, &lpdijoy_temp, NULL)!=DI_OK)
   return(0);
lpdijoy_temp->QueryInterface(IID_IDirectInputDevice2, (void **) &lpdijoy); 
lpdijoy_temp->Release();

//设置游戏杆协作等级
if (lpdijoy->SetCooperativeLevel(main_window_handle, 
	                 DISCL_NONEXCLUSIVE | DISCL_BACKGROUND)!=DI_OK)
   return(0);

//设置数据格式,c_dfDIJoystick2表示力反馈游戏杆
if (lpdijoy->SetDataFormat(&c_dfDIJoystick)!=DI_OK)
   return(0);

//设置游戏杆的输入特性
//(1)设置游戏杆的范围
DIPROPRANGE joy_axis_range;

//设置X轴
joy_axis_range.lMin = min_x;//具体的值eg:1024
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);

//设置Y轴
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);

//(2)设置游戏杆的死区。死区总是0-10000之间的值,如果想死区为50%,用5000;10%则用1000.
DIPROPDWORD dead_band; 

//dead_zone*=100;

dead_band.diph.dwSize       = sizeof(dead_band);
dead_band.diph.dwHeaderSize = sizeof(dead_band.diph);
dead_band.diph.dwObj        = DIJOFS_X; //对于X轴
dead_band.diph.dwHow        = DIPH_BYOFFSET;

dead_band.dwData            = dead_zone; //eg:1000

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; //对于Y轴
dead_band.diph.dwHow        = DIPH_BYOFFSET;

dead_band.dwData            = dead_zone; //eg:1000


lpdijoy->SetProperty(DIPROP_DEADZONE,&dead_band.diph);

//获取游戏杆
if (lpdijoy->Acquire()!=DI_OK)
   return(0);

//表示找到游戏杆
joystick_found = 1;

return(1);

}

//枚举回调函数
BOOL CALLBACK DInput_Enum_Joysticks(LPCDIDEVICEINSTANCE lpddi, LPVOID guid_ptr) 
{
	*(GUID*)guid_ptr = lpddi->guidInstance; 
	strcpy(joyname, (char *)lpddi->tszProductName);
	return(DIENUM_STOP); //找到第一个设备后停止继续枚举
} 

//读取游戏杆数据(状态)
int DInput_Read_Joystick(void)
{
	if (!joystick_found)
		return(0);

	if (lpdijoy)
	{
		//轮询游戏杆,游戏杆是唯一需要轮询的设备,因为一些游戏杆的驱动程序产生中断,而且数据总是最新的
		if (lpdijoy->Poll()!=DI_OK)
			return(0);

		//读取游戏杆状态数据
		if (lpdijoy->GetDeviceState(sizeof(DIJOYSTATE), (LPVOID)&joy_state)!=DI_OK)
			return(0);
	}
	else
	{
		memset(&joy_state,0,sizeof(joy_state));

		return(0);
	}

	return(1);
}

//释放游戏杆设备
void DInput_Release_Joystick(void)
{
	if (lpdijoy)
	{    
		lpdijoy->Unacquire();
		lpdijoy->Release();
	}
} 

	//使用游戏杆,游戏杆的数据如下
	//显示游戏杆的位置和按钮信息
	sprintf(buffer,"Joystick Stats: X-Axis=%d, Y-Axis=%d, buttons(%d,%d,%d,%d,%d,%d,%d,%d)",
		joy_state.lX,joy_state.lY,
		joy_state.rgbButtons[0],
		joy_state.rgbButtons[1],
		joy_state.rgbButtons[2],
		joy_state.rgbButtons[3],
		joy_state.rgbButtons[4],
		joy_state.rgbButtons[5],
		joy_state.rgbButtons[6],
		joy_state.rgbButtons[7]);

原文地址:https://www.cnblogs.com/sifenkesi/p/1947887.html