주요 차이점
XInput과 GameInput 간의 주요 차이점은 다음 섹션에서 설명합니다.C vs. C++
XInput API는 플랫 C 함수의 모음입니다. 반면 GameInput은 (그래픽 및 오디오 API와 마찬가지로) C++이며 인터페이스를 사용합니다. 실제로는 이로 인해 GameInput API를 사용하는 코드가 복잡해지지 않으며, 성능에 영향을 주지 않고, GameInput의 작동 방식에 익숙해지면 몇 가지 이점이 명확해집니다. 이러한 인터페이스가 COM처럼 보일 수 있지만, COM은 아니라는 점을 이해하는 것이 중요합니다. 이러한 인터페이스를 사용하려면 참조 카운팅에 대한 기본적인 이해만 있으면 됩니다. 자세한 내용은 GameInput 기본 사항의 인터페이스 섹션 항목을 참조하세요.입력 얻기
XInput에서는 대부분의 게임이 연결된 장치가 있는 사용자 인덱스가 발견될 때까지 사용자 인덱스를 순회하고, 그 다음 해당 장치에서 상태를 읽습니다. 게임은 다음 번에 다시 순회하지 않아도 되도록 종종 사용자 인덱스를 기억합니다. 예를 들어 다음 코드는 사용자에게 컨트롤러에서 “A를 누르세요”라고 안내하는 게임에 일반적입니다.럼블 피드백
XInput에서는 게임이 단순히XInputSetState를 호출하여 장치로 럼블(진동) 명령을 보냅니다. GameInput에서는 게임이 장치에 대한 IGameInputDevice 인스턴스를 얻은 다음 해당 SetRumbleState 메서드를 호출해야 합니다. 이 두 메서드 사이의 사용법은 비슷합니다. 이는 장치가 단순한 식별자가 아니라 장치 인터페이스의 함수를 호출하는 경우의 예입니다.
애플리케이션 포커스
콘솔에서는 GameInput이 애플리케이션이 포커스 상태일 때만 입력을 제공합니다. 그렇지 않으면 반환되는 상태에는 마치 사용자가 장치를 전혀 만지지 않은 것처럼 중립 또는 “정지(rest)” 값이 포함됩니다. 이렇게 하면 포커스 변경을 처리하는 추가 입력 코드(예:XInputEnable 호출)가 필요 없어집니다.
PC에서는 입력이 기본적으로 모든 프로세스로 전달됩니다. 앞으로 이 동작은 SetFocusPolicy 메서드를 사용하여 변경할 수 있게 됩니다.
XInputOnGameInput 래퍼
Microsoft Game Development Kit(GDK)에는 GameInput 위에 XInput API 구현을 포함하는XInputOnGameInput.h라는 헤더 파일이 함께 제공됩니다. 특히 키보드와 마우스 또는 기타 입력 장치를 사용하려는 경우 GameInput으로 직접 포팅하는 것을 권장합니다. 그러나 XInputOnGameInput 래퍼는 기존 XInput 코드에 아무런 변경 없이 초기 포팅 작업을 부트스트랩하는 데 도움이 되도록 사용할 수 있습니다.
XInputOnGameInput 래퍼를 사용하려면 다음 코드를
XInput과 XInputOnGameInput의 차이점
일반적으로 XInputOnGameInput 래퍼는 기존 XInput API의 직접 대체입니다. 그러나 몇 가지 사소한 차이점이 있습니다.- 간결성을 위해 게임패드 장치 지원만 래퍼에 코딩되어 있습니다. 레이싱 휠이나 아케이드 스틱과 같은 다른 장치를 지원해야 하는 경우, GameInput을 직접 사용하거나 XInputOnGameInput 코드에서 해당 장치에 대한 지원을 추가하세요.
-
래퍼는 게임이 포커스 상태일 때만 게임패드 입력을 반환합니다. 게임이 포커스 상태가 아닐 때는 반환된 모든 게임패드 상태가 마치 사용자가 게임패드를 만지고 있지 않은 것처럼 중립 또는 “정지(rest)” 값으로 설정됩니다. 이는
XInputEnable호출 여부에 관계없이 수행됩니다. -
XUSER_MAX_COUNT의 값이 4에서 8로 증가되었습니다. 이는 대부분의 기존 XInput 코드에 대해 일반적으로 투명해야 합니다. 그러나 코드에서XInputGetKeystroke함수를 사용하는 부분이 있다면,XINPUT_KEYSTROKE구조체의UserIndex멤버에서 최대값 4가 반환된다고 가정하여 하드 코딩된 것이 없는지 신중히 검토하세요. 그렇지 않으면 버퍼 오버런이 발생할 수 있습니다. - 몇 가지 새로운 함수가 추가되었습니다(다음 참조). 이는 프로덕션 코드에서 XInput 래퍼를 계속 사용할 계획인 경우에만 관심의 대상이 되어야 합니다.
프로덕션 코드에서 XInputOnGameInput 사용
XInputOnGameInput 래퍼는 고성능이고 락 프리로 작성되었으며, GameInput API의 모든 성능 최적화를 상속받으므로 프로덕션 코드에서 사용하기에 적합합니다. 또한 GameInput의 더 넓은 장치 지원(예: 인기 있는 HID 게임패드)을 상속받으며, API에 다음의 새 함수를 추가합니다.-
__
XInputSetStateEx__는XInputSetState와 유사하지만 트리거 모터에 대한 지원을 추가합니다. -
__
XInputGetStateWithToken__은XInputGetState와 유사하지만, 호출자가 D3DX 프레임 파이프라인 토큰을 제공하여 특정 입력 판독값을 그래픽 프레임과 연결해 나중에 PIX에서 분석할 수 있도록 합니다.[!NOTE] 5월 프리뷰 릴리스에서는 기반 GameInput 코드가 완전히 구현되지 않았기 때문에
XInputGetStateWithToken이 현재XInputGetState와 동일하게 동작합니다. -
__
XInputGetDeviceId__는 주어진 사용자 인덱스에 있는 장치의APP_LOCAL_DEVICE_ID를 반환합니다. 이 ID를 IGameInput의 FindDeviceFromId 메서드에 전달하면 해당 사용자 인덱스에 대응하는 IGameInputDevice가 반환됩니다. 그런 다음 이를 사용하여 XInput 래퍼를 통해 노출되지 않는 GameInput API의 추가 기능에 액세스할 수 있습니다.
래퍼 코드 최적화
기본적으로 XInputOnGameInput 래퍼는 기존 XInput API와 직접 호환되도록 구성되어 있습니다. 100% 호환되는 동작이 필요하지 않은 게임은 다음 전처리기 매크로 중 하나를 정의하여 래퍼의 동작과 성능을 세부 조정할 수 있습니다.XINPUT_ON_GAMEINPUT_EXPLICIT_INITIALIZATION
기본적으로 XInput 래퍼는 래퍼 함수 중 하나가 처음 호출될 때 자동으로 기반 GameInput API를 지연 초기화합니다. 이는 기존 XInput 코드와의 직접 호환성을 보장하지만 몇 가지 사소한 단점이 있습니다.- 첫 번째 XInput 래퍼 함수 호출의 실행 시간이 평소보다 길어집니다.
- 모든 XInput 래퍼 함수는 호출될 때마다 지연 초기화가 수행되었는지 확인해야 합니다. 이는 전역 변수의 단순한 테스트이므로 분기 예측기가 비용을 줄여야 하지만, 여분의 오버헤드입니다.
- 실패해서는 안 되지만, 기반 GameInput API의 지연 초기화가 성공했는지 확인할 방법이 없습니다.
- 기반 IGameInput 인스턴스는 XInput 래퍼의 전역 변수가 정리될 때까지(모듈 언로드 또는 프로세스 종료로 인해) 해제되지 않습니다.
XINPUT_ON_GAMEINPUT_EXPLICIT_INITIALIZATION 매크로를 정의하여 래퍼의 초기화와 종료를 수동으로 제어할 수 있습니다. 이렇게 하면 초기화와 종료가 발생하는 시점을 정확하게 제어할 수 있는 두 개의 새 함수 XInputOnGameInputInitialize와 XInputOnGameInputUninitialize가 추가됩니다.
XINPUT_ON_GAMEINPUT_NO_XINPUTENABLE
XInputEnable 함수를 구현하는 데 필요한 코드는 XInputGetState, XInputGetStateWithToken, XInputSetState, XInputSetStateEx, XInputGetKeystroke 함수의 매 호출마다 추가 오버헤드를 발생시킵니다. 코드에서 XInputEnable을 호출하지 않거나 코드에서 쉽게 제거할 수 있다면, XINPUT_ON_GAMEINPUT_NO_XINPUTENABLE 매크로를 정의하여 XInputEnable 지원과 관련 오버헤드를 제거할 수 있습니다. 기반 GameInput 코드는 어차피 포커스 변경 시 XInputEnable의 기능을 자동으로 수행하므로, 가능하다면 대부분의 게임이 이 매크로를 정의하고 싶어할 것입니다.
XINPUT_ON_GAMEINPUT_NO_XINPUTGETKEYSTROKE
XInputGetKeystroke 함수를 구현하는 데 필요한 코드는 래퍼의 구현에 몇 가지 추가 함수와 변수를 추가합니다. 다른 XInput API 함수에 오버헤드를 추가하지는 않지만, 코드에서 XInputGetKeystroke를 호출하지 않는 경우 XINPUT_ON_GAMEINPUT_NO_XINPUTGETKEYSTROKE 매크로를 정의하여 XInput 래퍼의 코드/데이터 크기를 약간 줄일 수 있습니다.
