⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gp_input.cpp

📁 国产的RPG源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		{
			//缓冲数据
			if((rgdod[i].dwData & 0x80))	//按下
			{
				KeyBuffer[KeyBuffer_End] = (BYTE)(rgdod[i].dwOfs);
				KeyBuffer_End ++;
				if( KeyBuffer_End >= KEYBUFFERSIZE ) //循环
					KeyBuffer_End = 0;
			}
			else	//释放+128
			{
				KeyBuffer[KeyBuffer_End] = (BYTE)(rgdod[i].dwOfs+128);
				KeyBuffer_End ++;
				if( KeyBuffer_End >= KEYBUFFERSIZE ) KeyBuffer_End = 0;
			}

			//即时数据
			KeyState[rgdod[i].dwOfs] = (BYTE)(rgdod[i].dwData & 0x80);
		}
	}
}

//从缓冲区取一个值(0=无)
unsigned char WINAPI CKey::GetKey()
{
	//缓冲区为空
	if( KeyBuffer_Start == KeyBuffer_End )
		return 0;

	byte ret=KeyBuffer_Start;
	KeyBuffer_Start++;
	if( KeyBuffer_Start >= KEYBUFFERSIZE )
		KeyBuffer_Start = 0;

	return KeyBuffer[ret];
}

//清空键盘缓冲区
void WINAPI CKey::ReleaseKeyBuffer()
{
	while(1)
	{
		GetKeyData();
		if( GetKey()== 0 ) break;
	}
}

//////////////////////////////////////////////////////////////////////////
// Joystick
//////////////////////////////////////////////////////////////////////////
#if USE_DX8
	LPDIRECTINPUT8			CJoystick::g_pDI=NULL;
	LPDIRECTINPUTDEVICE8	CJoystick::m_pJoystick=NULL;
#else
	LPDIRECTINPUT7			CJoystick::g_pDI=NULL;
	LPDIRECTINPUTDEVICE2	CJoystick::m_pJoystick=NULL;
#endif
DIDEVCAPS				CJoystick::m_diDevCaps;

CJoystick::CJoystick()
{
	memset( State, 0, MAXKEY );	
	memset( Buffer, 0, BUFFERSIZE );
	Buffer_Start = Buffer_End = 0;
}

CJoystick::~CJoystick()
{
	
}

//媒举手柄的回调函数
BOOL CALLBACK EnumJoysticksCallback( const DIDEVICEINSTANCE* pdidInstance, VOID* pContext )
{
	HRESULT hr;

	// 得到一个被媒举的手柄的接口
#if USE_DX8
	hr = CJoystick::g_pDI->CreateDevice( pdidInstance->guidInstance,&CJoystick::m_pJoystick, NULL );
#else
	hr = CJoystick::g_pDI->CreateDeviceEx( pdidInstance->guidInstance, IID_IDirectInputDevice2,
		(VOID**)&CJoystick::m_pJoystick, NULL );
#endif
	// 失败了,我们就不能使用这个手柄,那么接着媒举
	if( FAILED(hr) ) 
		return DIENUM_CONTINUE;
	
	
	// 成功了,那么就停止媒举,我们只使用第一个手柄
	return DIENUM_STOP;
}

//媒举手柄的方向轴的回调函数
BOOL CALLBACK EnumAxesCallback( const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pContext )
{
	HWND hDlg = (HWND)pContext;		//pContext放的是窗口句柄
	
	DIPROPRANGE diprg; 
	diprg.diph.dwSize       = sizeof(DIPROPRANGE); 
	diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER); 
	diprg.diph.dwHow        = DIPH_BYOFFSET; 
	diprg.diph.dwObj        = pdidoi->dwOfs; // 媒举方向轴
	diprg.lMin              = -1000; 
	diprg.lMax              = +1000; 
	
	//设置方向轴的范围
	if( FAILED( CJoystick::m_pJoystick->SetProperty( DIPROP_RANGE, &diprg.diph ) ) )
		return DIENUM_STOP;			//失败了,就不继续了
		
	DIPROPDWORD property;

	property.diph.dwSize=sizeof(DIPROPDWORD);
	property.diph.dwHeaderSize=sizeof(DIPROPHEADER);
	property.diph.dwHow = DIPH_BYOFFSET;
	property.diph.dwObj = pdidoi->dwOfs;
	property.dwData = 5000;
	HRESULT hr = CJoystick::m_pJoystick->SetProperty(DIPROP_DEADZONE,&property.diph);
	if(FAILED(hr))
	{
		// 设置死区失败
		MessageBox(hDlg, "error on set Joystick deadzone size", "error", MB_OK);
        return FALSE;
	}
	// 让我们的应用程序根据方向轴所支持的方式做出不同的响应
	// 配合传进来的窗口句柄可以做很多的事情…………
	switch( pdidoi->dwOfs )
	{
	case DIJOFS_X:
		break;
	case DIJOFS_Y:
		break;
	case DIJOFS_Z:
		break;
	case DIJOFS_RX:
		break;
	case DIJOFS_RY:
		break;
	case DIJOFS_RZ:
		break;
	case DIJOFS_SLIDER(0):
		break;
	case DIJOFS_SLIDER(1):
		break;
	}
	
	return DIENUM_CONTINUE;				//继续媒举下一个方向
}

//初始化
HRESULT CJoystick::InitInput_Joystick( HWND hDlg )
{
	HRESULT hr;
	//创建DirectInput
#if USE_DX8
	hr = DirectInput8Create( hInst, DIRECTINPUT_VERSION,IID_IDirectInput8, 
							(LPVOID*)&g_pDI, NULL );
#else
	hr = DirectInputCreateEx( hInst, DIRECTINPUT_VERSION,IID_IDirectInput7, 
							(LPVOID*)&g_pDI, NULL );
#endif
	if( FAILED(hr) ) 
		return hr;
	
	// 媒举一个手柄
#if USE_DX8
#define JOY DI8DEVCLASS_GAMECTRL
#else
#define JOY  DIDEVTYPE_JOYSTICK
#endif
	hr = g_pDI->EnumDevices( JOY, EnumJoysticksCallback, NULL, DIEDFL_ATTACHEDONLY );
	if( FAILED(hr) ) 
		return hr;
	
	// 确认得到了一个手柄,上一个函数只保证它自己调用成功,不保证得到了一个可以用的手柄
	if( NULL == m_pJoystick )
	{
		return E_FAIL;
	}
	//设置数据格式
	hr = m_pJoystick->SetDataFormat( &c_dfDIJoystick );
	if( FAILED(hr) ) 
		return hr;
	//设置协作级
	hr = m_pJoystick->SetCooperativeLevel( hDlg, DISCL_NONEXCLUSIVE|DISCL_FOREGROUND );
	if( FAILED(hr) ) 
		return hr;
	
	m_diDevCaps.dwSize = sizeof(DIDEVCAPS);
	hr = m_pJoystick->GetCapabilities(&m_diDevCaps);
	if ( FAILED(hr) ) 
		return hr;
	//媒举方向轴
	m_pJoystick->EnumObjects( EnumAxesCallback, (VOID*)hDlg, DIDFT_AXIS );
	//设置属性
	DIPROPDWORD property;
	property.diph.dwSize=sizeof(DIPROPDWORD);
	property.diph.dwHeaderSize=sizeof(DIPROPHEADER);
	property.diph.dwObj=0;
	property.diph.dwHow=DIPH_DEVICE;
	property.dwData=32;

	hr = m_pJoystick->SetProperty(DIPROP_BUFFERSIZE, &property.diph);

	if FAILED(hr)
	{
		// 设置缓冲区失败
		MessageBox(hDlg, "error on set Joystick Buffer size", "error", MB_OK);
        return FALSE;
    }

	//得到设备
	SetAcquire(hWnd);

	return true;
}

//获取设备
HRESULT CJoystick::SetAcquire( HWND hWnd )
{
	if( m_pJoystick )
	{
		if( bActive )
			m_pJoystick->Acquire();
		else
			m_pJoystick->Unacquire();
	}
	
	return S_OK;
}

//得到手柄的当前状态
HRESULT CJoystick::GetJoystickState()
{
	HRESULT     hr;
	DIJOYSTATE  js;
	static DIJOYSTATE  oldjs;		//上一个状态

	if( m_pJoystick ) 
	{
		do
		{	//Poll
			hr = m_pJoystick->Poll();
			if( FAILED(hr) )
				return hr;
			//得到当前状态
			hr = m_pJoystick->GetDeviceState( sizeof(DIJOYSTATE), &js );

			if( hr == DIERR_INPUTLOST )
			{
				hr = m_pJoystick->Acquire();
				if( FAILED(hr) )  
					return hr;
			}
		}
		while( DIERR_INPUTLOST == hr );
		
		if( FAILED(hr) )
			return hr;
		//清0
		for(int i =0;i<MAXKEY;i++)
			State[i] =0;
		//我们只是关心这几个的值

		//先是上下方向的
		if(js.lY<0&&abs(oldjs.lY-js.lY)<10)
			State[DIJ_UP] = DIJ_UP+128;
		if(js.lY>0&&abs(oldjs.lY-js.lY)<10)
			State[DIJ_DOWN] = DIJ_DOWN+128;
		if(js.lY>0&&abs(oldjs.lY)<10)
			State[DIJ_DOWN]	= DIJ_DOWN;
		if(js.lY<0&&abs(oldjs.lY)<10)
			State[DIJ_UP]	= DIJ_UP;
		//然后是左右方向的
		if(js.lX<0&&abs(oldjs.lX-js.lX)<10)
			State[DIJ_LEFT] = DIJ_LEFT+128;
		if(js.lX>0&&abs(oldjs.lX-js.lX)<10)
			State[DIJ_RIGHT] = DIJ_RIGHT+128;
		if(js.lX>0&&abs(oldjs.lX)<10)
			State[DIJ_RIGHT] = DIJ_RIGHT;
		if(js.lX<0&&abs(oldjs.lX)<10)
			State[DIJ_LEFT]	= DIJ_LEFT;
		//最后是按纽
		State[DIJ_3] = (js.rgbButtons[0]&0x80?DIJ_3+48:0);	//按下或者是放开
		State[DIJ_4] = (js.rgbButtons[1]&0x80?DIJ_4+48:0);	
		State[DIJ_2] = (js.rgbButtons[2]&0x80?DIJ_2+48:0);
		State[DIJ_1] = (js.rgbButtons[3]&0x80?DIJ_1+48:0);
		memcpy(&oldjs,&js,sizeof(js));
	} 
	return S_OK;
}

//返回一个键当前是否按下
unsigned char CJoystick::GetState(unsigned char Key)
{
	return State[Key];
}

//***************************
//返回缓冲区数据
void WINAPI CJoystick::GetJoystickData()
{
	DIDEVICEOBJECTDATA rgdod[BUFFERSIZE];
	DWORD dwItems = BUFFERSIZE;

	if( m_pJoystick )
	{
	_again:
		// Poll 
		HRESULT hr = m_pJoystick->Poll();
		if( FAILED(hr) ) return;

		hr = m_pJoystick->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), rgdod, &dwItems, 0);
		if(hr != DI_OK)		
		{
			if( FAILED(hr) ) 
			{
				hr = m_pJoystick->Acquire();
				if FAILED(hr)
				{
					return;
				}
				if SUCCEEDED(hr)
				{
					goto _again;
				}
			}
		}

		if( SUCCEEDED(hr) && dwItems>0 )
		{
			DWORD i;
			for(i=0; i<dwItems; i++)
			{
				//缓冲数据,两个按纽的数据
				if(rgdod[i].dwOfs == DIJOFS_BUTTON0)
				{
					if((rgdod[i].dwData & 0x80) )	//按下 
					{
						Buffer[Buffer_End] = (BYTE)(DIJ_3);
						Buffer_End ++;
						if( Buffer_End >= BUFFERSIZE ) 
							Buffer_End = 0;
					}
					else	//释放
					{
						Buffer[Buffer_End] = (BYTE)(DIJ_3+48);
						Buffer_End ++;
						if( Buffer_End >= BUFFERSIZE ) 
							Buffer_End = 0;
					}
				}
				if(rgdod[i].dwOfs == DIJOFS_BUTTON1)
				{
					if((rgdod[i].dwData & 0x80) )	//按下 
					{
						Buffer[Buffer_End] = (BYTE)(DIJ_4);
						Buffer_End ++;
						if( Buffer_End >= BUFFERSIZE ) 
							Buffer_End = 0;
					}
					else	//释放
					{
						Buffer[Buffer_End] = (BYTE)(DIJ_4+48);
						Buffer_End ++;
						if( Buffer_End >= BUFFERSIZE ) 
							Buffer_End = 0;
					}
				}
				if(rgdod[i].dwOfs == DIJOFS_BUTTON2)
				{
					if((rgdod[i].dwData & 0x80) )	//按下 
					{
						Buffer[Buffer_End] = (BYTE)(DIJ_2);
						Buffer_End ++;
						if( Buffer_End >= BUFFERSIZE ) 
							Buffer_End = 0;
					}
					else	//释放
					{
						Buffer[Buffer_End] = (BYTE)(DIJ_2+48);
						Buffer_End ++;
						if( Buffer_End >= BUFFERSIZE ) 
							Buffer_End = 0;
					}
				}
				if(rgdod[i].dwOfs == DIJOFS_BUTTON3)
				{
					if((rgdod[i].dwData & 0x80) )	//按下 
					{
						Buffer[Buffer_End] = (BYTE)(DIJ_1);
						Buffer_End ++;
						if( Buffer_End >= BUFFERSIZE ) 
							Buffer_End = 0;
					}
					else	//释放
					{
						Buffer[Buffer_End] = (BYTE)(DIJ_1+48);
						Buffer_End ++;
						if( Buffer_End >= BUFFERSIZE ) 
							Buffer_End = 0;
					}
				}

			}
		}
	}
}

//从缓冲区取一个值(0=无)
unsigned char WINAPI CJoystick::GetKey()
{
	if( m_pJoystick )
	{
		//缓冲区为空
		if( Buffer_Start == Buffer_End )
			return 0;

		byte ret=Buffer_Start;
		Buffer_Start++;
		if( Buffer_Start >= BUFFERSIZE )
			Buffer_Start = 0;

		return Buffer[ret];
	}
	return 0;
}

//清空缓冲区
void WINAPI CJoystick::ReleaseBuffer()
{
	if( m_pJoystick )
	{
		while(1)
		{
			GetJoystickData();
			if( GetKey()== 0 ) break;
		}
	}
}

//释放手柄
HRESULT CJoystick::FreeInput_Joystick()
{
	if( m_pJoystick !=  NULL ) 
	{
		m_pJoystick->Unacquire();
		m_pJoystick->Release();
		m_pJoystick = NULL;
	}

	if( lpDI ) 
	{
		lpDI->Release();
		lpDI = NULL;
	}
	
	return S_OK;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -