25
Chapter 14 Chapter 14 DirectInput DirectInput 의 의의 의 의의

Chapter 14 DirectInput 의 전말. 2 이 장에서는 - DirectDinput 에 대해서 파악하기 - 키보드 장치 생성하고 사용하기 - 마우스 사용하기 - 조이스틱

Embed Size (px)

Citation preview

Chapter 14Chapter 14

DirectInputDirectInput 의 전말 의 전말

2

이 장에서는이 장에서는

• - DirectDinput 에 대해서 파악하기• - 키보드 장치 생성하고 사용하기• - 마우스 사용하기• - 조이스틱 설정하기

3

DirectX DirectX 가 지원하는 입력장치 가 지원하는 입력장치

• 키보드 : 표준 QWERTY 키보드• 마우스 : 2 버튼 그리고 3 버튼 마우스• 조이스틱과 비행 요크 : 아날로그와 디지털 조이스틱 /

비행 - 요크는 6 만큼의 자유도와 최대 32 개의 버튼을 지원한다 .

• 운전대 컨트롤 : 아날로그 디지털 운전 시뮬레이션용• 패들 : 다양한 회전 장치• 포스 - 피드백 (force-feedback) 장치 : 기계적인

액튜에이터 (actuator) 가 있어서 , 컴퓨터가 진동시키거나 모양을 바꿀 수 있는 조이스틱 또는 다른 장치들 .

• 가상현실 헤드기어 트래킹 시스템 (virtual reality headgear tracking system): 가상현실 헤드기어의 위치와 회전을 지원 . ( 착용자의 머리의 상태를 전송 .)

4

DirectInput DirectInput 인터페이스의 구조 인터페이스의 구조

5

DirectInputDirectInput 의 사용의 사용

• DINPUT.LIB, DINPUT8.LIB, DINPUT.H

6

DirectInput DirectInput 사용 순서사용 순서

1. DirectInput8Create() 으로 주요 DirectInput 객체를 생성한다 .

2. CreateDevicde() 으로 하나 혹은 그 이상의 입력 장치를 생성한다 .

각각에 대해서 GUID 가 필요하다 . 따라서 , DirectInput 이 모든 입력 장치를 나열하도록 요청할 수도 있다 .

3. SetCooperativeLevel() 으로 , 각 장치의 협력 수준을 설정한다 .

4. SetDataFormat() 으로 각장치의 데이터 형식을 설정하고 , SetProperty() 로 특별한 속성들을 설정한다 .

5. Acquire() 로 각 입력장치를 획득한다 .

이 단계는 각 입력 장치를 주요 DirectInputDevice8 에 추가한다 .

6. GetDeviceState() 로 입력을 받는다 .

수동 폴링이 필요한 장치는 Poll() 을 호출한다

7

DirectInput DirectInput 생성생성

LPDIRECTINPUT8 lpdi; // main DirectInput object

HRESULT WINAPI DirectInput8Create(

HINSTANCE hinst, // instance of application

DWORD dwVersion, // backward version compatibility

REFIID riidltf, // interface id being requested

LPVOID* ppvOut, // pointer to interface

LPUNKNOWN punkOuter); // com stuff, null

#include “DINPUT.H”

LPDIRECTINPUT8 lpdi; // pointer to DirectInput object

// create DirectInput object

if (DirectInput8Create(main_instance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void **)&lpdi,NULL)!=DI_OK)

{ /* error */ }

8

키보드 입력키보드 입력

• 1. 키보드 장치를 생성한다 .• 2. 키보드의 협력 수준을 설정한다 .• 3. 키보드 장치를 위한 데이터 형식을 설정한다 .• 4. 키보드 장치를 얻어온다 (aquire).

9

여러 개의 여러 개의 devicedevice 들이 하나의 들이 하나의 DirectInput DirectInput devicedevice 를 구성할 수도 있다를 구성할 수도 있다 ..

10

DirectInput Object (DirectInput Object ( 객체객체 ))

• 하나의 device 에 여러 개의 object 가 존재 가능

11

CreateDevice FunctionCreateDevice Function

HRESULT CreateDevice(

REFGUID rguid, // GUID of device to create

LPDIRECTINPUTDEVICE *lplpDIDev,// ptr to device interface

LPUNKNOWN pUnkOuter); // always NULL

• GUID_SysKeyboard: 기본 시스템 키보드• GUID_SysMouse: 기본 시스템 마우스• #define INITGUID 와 OBJBASE.H 필요

12

CreateDevice ExampleCreateDevice Example

#define INITGUID // needed to get the GUIDS in here

#include <OBJBASE.H> // COM stuff

#include “DINPUT.H” // you need this!

LPDIRECTINPUT8 lpdi; // main DirectInput object

// create DirectInput object

if (DirectInput8Create(main_instance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void **)&lpdi,NULL)!=DI_OK)

{ /* error */ }

LPDIRECTINPUTDEVICE8 lpdikey; // the keyboard device

// create keyboard device

if (lpdi->CreateDevice(GUID_SysKeyboard, &lpdikey,NULL)!=DI_OK) { /* error */ }

13

협력 수준의 설정협력 수준의 설정Value Meaning

DISCL_BACKGROUND Your application can use a DirectInput device whether the application is idling in the background or active in the foreground.

DISCL_FOREGROUND The application requires foreground access. If foreground access is granted, the device is automatically unacquired when the associated window moves to the background.

DISCL_EXCLUSIVE After you acquire the device, no other application can request exclusive access to it; however, other applications can still request nonexclusive access.

DISCL_NONEXCLUSIVE The application requires nonexclusive access. Access to the device does not interfere with other applications that are accessing the same device.

14

협력 수준의 설정협력 수준의 설정

• DISCL_BACKGROUND | DISCL_NONEXCLISIVE 를 협력 설정으로 사용해야 한다 .

if (lpdikey->SetCooperativeLevel(main_window_handle,

DISCL_BACKGROUND | DISCL_NONEXCLUSIVE)!=DI_OK)

{ /* error */ }

15

데이터 형식의 설정데이터 형식의 설정

DIDATAFORMAT df;

SetDataFormat(&df); // ptr to data format structure

• Custom-made Data formats

c_dfDIKeyboard

c_dfDIMouse

c_dfDIJoystick

c_dfDIJoystick2 : for force feedback device

if (FAILED(lpdikey->SetDataFormat(&c_dfDIKeyboard))) { … }

16

AcquireAcquire

• Device 를 입력 스트림에 추가하고 데이터를 입수할 수 있도록 만드는 것이다 .

if (FAILED(lpdikey->Acquire())) { … }

17

Keyboard Keyboard 읽어오기읽어오기

int ship_x = 100, ship_y = 100; // initial ship position

// storage for the keyboard data

UCHAR keystate[256];

// in your main loop, you would do this

if (lpdikey->GetDeviceState(256, keystate)!=DI_OK)

{ /* something’s amiss */ }

// test whether the player is “moving” the ship

if (keystate[DIK_RIGHT] & 0x80) ship_x++;

if (keystate[DIK_LEFT] & 0x80) ship_x--;

if (keystate[DIK_DOWN] & 0x80) ship_y++;

if (keystate[DIK_UP] & 0x80) ship_y--;

• 키보드 상태는 256 BYTE 요소의 배열

18

DirectInput DirectInput 키보드 가상 키 코드 키보드 가상 키 코드

• DIK_ESCAPE ESC 키• DIK_0 - DIK_9 메인 키보드의 0-9• DIK_A - DIK_Z A-Z• DIK_RETURN 메인 키보드의 엔터키• DIK_LCONTROL 왼쪽 Ctrl 키• DIK_RCONTROL 오른쪽 Ctrl 키• DIK_SPACE 스페이스바• DIK_F1 - DIK_F12 펑션키 F1-F12• DIK_UP ( 위 ) 화살표• DIK_DOWN ( 아래 ) 화살표• DIK_LEFT ( 왼쪽 ) 화살표• DIK_RIGHT ( 오른쪽 ) 화살표• DIK_PRIOR Page Up• DIK_NEXT Page Down

19

UnacquireUnacquire

• lpdikey->Unacquire( ) – Temporarily stop to get the device input– By Acquire( ) the input can be reactivated.

20

DEMO 14_1DEMO 14_1

21

마우스 입력마우스 입력

LPDIRECTINPUTDEVICE8 lpdimouse; // the mouse device

// create mouse device

if (lpdi->CreateDevice(GUID_SysMouse, &lpdimouse,NULL)!=DI_OK) { }

if (lpdimouse->SetCooperativeLevel(main_window_handle,

DISCL_BACKGROUND | DISCL_NONEXCLUSIVE)!=DI_OK) { }

// set data format, notice the use of the address operator

if (lpdikey->SetDataFormat(&c_dfDIMouse)!=DI_OK) { /* error */ }

// acquire the mouse

if (lpdimouse->Acquire()!=DI_OK) { /* error */ }

22

Mouse – Relative ModeMouse – Relative Mode

23

마우스 입력마우스 입력

typedef struct {

LONG lX; // x-axis of mouse

LONG lY; // y-axis of mouse

LONG lZ; // z-axis of mouse, typically a wheel or dial

BYTE rgbButtons[4]; // buttons of the mouse, high bit means pressed

} DIMOUSESTATE, *LPDIMOUSESTATE;

// this holds the mouse data

DIMOUSESTATE mouse_state;

// get mouse data

if (lpdimouse->GetDeviceState(sizeof(DIMOUSESTATE) (LPVOID)&mouse_state)!=DI_OK) { /* problem */ }

// test left button

if (mouse_state.rgbButtons[0]) { /* do whatever */ }

else if (mouse_state.rgbButtons[1]) { /* do whatever */ }

24

마우스 입력마우스 입력

// is the mouse moving right

if (mouse_state.lX > 0 )

{ /* right *}

else // check for left motion

if (mouse_state.lX < 0)

{ /* left */ }

// is the mouse moving down

if (mouse_state.lY > 0 )

{ /* down *}

else // check for upward motion

if (mouse_state.lY < 0)

{ /* up */ }

25

DEMO14_2DEMO14_2