本篇是创建游戏内核(15)【OO改良版】的续篇,关于该内核的细节说明请参阅创建游戏内核(16)。
接口:
/*************************************************************************
PURPOSE:
Defines DirectInput component for game core.
*************************************************************************/
#ifndef _CORE_INPUT_H_
#define _CORE_INPUT_H_
// enumerated list of device types
enum INPUT_DEVICE_TYPE
{
NONE = 0,
KEYBOARD,
MOUSE,
JOYSTICK
};
//============================================================================
// Keyboard Key definitions
//============================================================================
#define KEY_RELEASED FALSE
#define KEY_PRESSED TRUE
#define KEY_UNLOCKED FALSE
#define KEY_LOCKED TRUE
#define KEY_ESC DIK_ESCAPE
#define KEY_ESCAPE DIK_ESCAPE
#define KEY_MINUS DIK_MINUS
#define KEY_EQUALS DIK_EQUALS
#define KEY_BACKSPACE DIK_BACK
#define KEY_TAB DIK_TAB
#define KEY_LBRACKET DIK_LBRACKET
#define KEY_RBRACKET DIK_RBRACKET
#define KEY_ENTER DIK_RETURN
#define KEY_RETURN DIK_RETURN
#define KEY_CTRL DIK_LCONTROL
#define KEY_LCTRL DIK_LCONTROL
#define KEY_RCTRL DIK_RCTRL
#define KEY_SHIFT DIK_LSHIFT
#define KEY_LSHIFT DIK_LSHIFT
#define KEY_RSHIFT DIK_RSHIFT
#define KEY_ALT DIK_LMENU
#define KEY_LALT DIK_LMENU
#define KEY_RALT DIK_RMENU
#define KEY_0 DIK_0
#define KEY_1 DIK_1
#define KEY_2 DIK_2
#define KEY_3 DIK_3
#define KEY_4 DIK_4
#define KEY_5 DIK_5
#define KEY_6 DIK_6
#define KEY_7 DIK_7
#define KEY_8 DIK_8
#define KEY_9 DIK_9
#define KEY_A DIK_A
#define KEY_B DIK_B
#define KEY_C DIK_C
#define KEY_D DIK_D
#define KEY_E DIK_E
#define KEY_F DIK_F
#define KEY_G DIK_G
#define KEY_H DIK_H
#define KEY_I DIK_I
#define KEY_J DIK_J
#define KEY_K DIK_K
#define KEY_L DIK_L
#define KEY_M DIK_M
#define KEY_N DIK_N
#define KEY_O DIK_O
#define KEY_P DIK_P
#define KEY_Q DIK_Q
#define KEY_R DIK_R
#define KEY_S DIK_S
#define KEY_T DIK_T
#define KEY_U DIK_U
#define KEY_V DIK_V
#define KEY_W DIK_W
#define KEY_X DIK_X
#define KEY_Y DIK_Y
#define KEY_Z DIK_Z
#define KEY_SEMICOLON DIK_SEMICOLON
#define KEY_APOSTROPHE DIK_APOSTROPHE
#define KEY_TILDE DIK_GRAVE
#define KEY_GRAVE DIK_GRAVE
#define KEY_BACKSLASH DIK_BACKSLASH
#define KEY_COMMA DIK_COMMA
#define KEY_PERIOD DIK_PERIOD
#define KEY_FORWARDSLASH DIK_SLASH
#define KEY_SLASH DIK_SLASH
#define KEY_SPACE DIK_SPACE
#define KEY_CAPSLOCK DIK_CAPITAL
#define KEY_CAPITAL DIK_CAPITAL
#define KEY_F1 DIK_F1
#define KEY_F2 DIK_F2
#define KEY_F3 DIK_F3
#define KEY_F4 DIK_F4
#define KEY_F5 DIK_F5
#define KEY_F6 DIK_F6
#define KEY_F7 DIK_F7
#define KEY_F8 DIK_F8
#define KEY_F9 DIK_F9
#define KEY_F10 DIK_F10
#define KEY_F11 DIK_F11
#define KEY_F12 DIK_F12
#define KEY_SYSRQ DIK_SYSRQ
#define KEY_SCROLLLOCK DIK_SCROLL
#define KEY_PAUSE DIK_PAUSE
#define KEY_NUMLOCK DIK_NUMLOCK
#define KEY_NUMPAD0 DIK_NUMPAD0
#define KEY_NUMPAD1 DIK_NUMPAD1
#define KEY_NUMPAD2 DIK_NUMPAD2
#define KEY_NUMPAD3 DIK_NUMPAD3
#define KEY_NUMPAD4 DIK_NUMPAD4
#define KEY_NUMPAD5 DIK_NUMPAD5
#define KEY_NUMPAD6 DIK_NUMPAD6
#define KEY_NUMPAD7 DIK_NUMPAD7
#define KEY_NUMPAD8 DIK_NUMPAD8
#define KEY_NUMPAD9 DIK_NUMPAD9
#define KEY_ADD DIK_ADD
#define KEY_SUBTRACT DIK_SUBTRACT
#define KEY_DIVIDE DIK_DEVICE
#define KEY_MULTIPLY DIK_MULTIPLY
#define KEY_DECIMAL DIK_DECIMAL
#define KEY_NUMPADENTER DIK_NUMPADENTER
#define KEY_INSERT DIK_INSERT
#define KEY_DELETE DIK_DELETE
#define KEY_HOME DIK_HOME
#define KEY_END DIK_END
#define KEY_PAGEUP DIK_PRIOR
#define KEY_PAGEDOWN DIK_NEXT
#define KEY_UP DIK_UP
#define KEY_DOWN DIK_DOWN
#define KEY_LEFT DIK_LEFT
#define KEY_RIGHT DIK_RIGHT
#define KEY_LWIN DIK_LWIN
#define KEY_RWIN DIK_RWIN
#define KEY_APPS DIK_APPS
//============================================================================
// Mouse and Joystick definitions
//============================================================================
#define BUTTON_RELEASED FALSE
#define BUTTON_PRESSED TRUE
#define BUTTON_UNLOCKED FALSE
#define BUTTON_LOCKED TRUE
#define MOUSE_LBUTTON 0
#define MOUSE_RBUTTON 1
#define MOUSE_MBUTTON 2
#define JOYSTICK_BUTTON0 0
#define JOYSTICK_BUTTON1 1
#define JOYSTICK_BUTTON2 2
#define JOYSTICK_BUTTON3 3
#define JOYSTICK_BUTTON4 4
#define JOYSTICK_BUTTON5 5
//============================================================================
// This class encapsulates DirectInput initialize and release.
//============================================================================
class INPUT
{
public:
INPUT();
~INPUT();
IDirectInput8* get_directinput();
HWND get_hwnd();
BOOL create(HWND hwnd, HINSTANCE inst);
void shutdown();
private:
HWND m_hwnd;
IDirectInput8* m_directinput;
};
//============================================================================
// This class encapsulate for all input devices (keyboard, mouse, joystick).
//============================================================================
class INPUT_DEVICE
{
public:
INPUT_DEVICE();
~INPUT_DEVICE();
IDirectInputDevice8* get_device();
BOOL create(INPUT* input, short type, BOOL window_mode);
void free();
void clear();
BOOL read();
BOOL acquire(BOOL is_active);
BOOL get_lock(uchar index);
void set_lock(uchar index, BOOL lock_flag);
long get_x_pos();
void set_x_pos(long x_pos);
long get_y_pos();
void set_y_pos(long y_pos);
long get_x_delta();
long get_y_delta();
// keyboard specific functions
BOOL get_key_state(uchar index);
void set_key_state(uchar index, BOOL state);
BOOL get_pure_key_state(uchar index);
short get_key_press(long timeout);
long get_num_key_press();
long get_num_pure_key_press();
// mouse/joystick specific functions
BOOL get_button_state(uchar index);
BOOL set_button_state(uchar index, BOOL state);
BOOL get_pure_button_state(uchar index);
long get_num_button_press();
long get_num_pure_button_press();
static BOOL FAR PASCAL enum_joysticks(LPCDIDEVICEINSTANCE device_inst, LPVOID ref);
public:
INPUT* m_input;
IDirectInputDevice8* m_di_device;
short m_type; // device type, can be (MOUSE, KEYNOARD, JOYSTICK)
BOOL m_use_window_mode; // whether use window mode to read mouse coordinate
char m_state[256]; // all keys information and button press information
DIMOUSESTATE* m_mouse_state; // pointer to mouse state information
DIJOYSTATE* m_joystick_state; // pointer to joystick state information
BOOL m_locks[256]; // lock flags for keyboard or button
long m_x_pos, m_y_pos; // mouse or joystick coordinate
};
#endif
实现:
/*************************************************************************
PURPOSE:
Defines DirectInput component for game core.
*************************************************************************/
#include "core_common.h"
#include "core_input.h"
///////////////////////////////////// Defines for class INPUT /////////////////////////////////////
//---------------------------------------------------------------------
// Constructor, initialize member data.
//---------------------------------------------------------------------
INPUT::INPUT()
{
// only need to clear the DirectInput interface pointer
m_directinput = NULL;
}
//---------------------------------------------------------------------
// Release all DirectInput objects.
//---------------------------------------------------------------------
INPUT::~INPUT()
{
// force a shutdown
shutdown();
}
//---------------------------------------------------------------------
// Release all DirectInput objects.
//---------------------------------------------------------------------
void INPUT::shutdown()
{
release_com(m_directinput);
m_hwnd = NULL;
}
//---------------------------------------------------------------------
// Return the parent window handle.
//---------------------------------------------------------------------
HWND INPUT::get_hwnd()
{
return m_hwnd;
}
//---------------------------------------------------------------------
// Return a pointer to IDirectInput8 object.
//---------------------------------------------------------------------
IDirectInput8* INPUT::get_directinput()
{
return m_directinput;
}
//---------------------------------------------------------------------
// Create DirectInput and set window handle which pointer parent window.
//---------------------------------------------------------------------
BOOL INPUT::create(HWND hwnd, HINSTANCE inst)
{
// free DirectInput resource first
shutdown();
// record parent window handle
m_hwnd = hwnd;
// create a DirectInput interface
if(FAILED(DirectInput8Create(inst, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**) &m_directinput, NULL)))
return FALSE;
return TRUE;
}
///////////////////////////////////// Defines for class INPUT_DEVICE /////////////////////////////////////
//---------------------------------------------------------------------
// Constructor, initialize member data.
//---------------------------------------------------------------------
INPUT_DEVICE::INPUT_DEVICE()
{
memset(this, 0, sizeof(*this));
m_use_window_mode = TRUE; // set windowed usage to TRUE
// point the mouse and joystick structures to the state buffer
m_mouse_state = (DIMOUSESTATE*) &m_state;
m_joystick_state = (DIJOYSTATE*) &m_state;
}
//---------------------------------------------------------------------
// Destructor, free resource.
//---------------------------------------------------------------------
INPUT_DEVICE::~INPUT_DEVICE()
{
free();
}
//---------------------------------------------------------------------
// clear state information and lock flags, reset mouse or joystick
// position.
//---------------------------------------------------------------------
void INPUT_DEVICE::clear()
{
ZeroMemory(&m_state, 256);
for(short i = 0; i < 256; i++)
m_locks[i] = FALSE;
m_x_pos = m_y_pos = 0;
}
//---------------------------------------------------------------------
// Release DirectInput device resource, reset state informations and
// lock flags.
//---------------------------------------------------------------------
void INPUT_DEVICE::free()
{
// unaquire and release the object
if(m_di_device)
{
m_di_device->Unacquire();
release_com(m_di_device);
}
// set to no device installed
m_type = NONE;
// clear state information and lock flags, reset mouse or joystick position.
clear();
}
//---------------------------------------------------------------------
// Return the pointer to the IDirectDevice8 object
//---------------------------------------------------------------------
IDirectInputDevice8* INPUT_DEVICE::get_device()
{
return m_di_device;
}
//---------------------------------------------------------------------
// Create DirectInput device with specified type.
//---------------------------------------------------------------------
BOOL INPUT_DEVICE::create(INPUT* input, short type, BOOL window_mode)
{
DIDATAFORMAT* _data_format;
// free a pior device
free();
// check for a valid parent INPUT class
if((m_input = input) == NULL)
return FALSE;
// create the device and rember device data format
switch(type)
{
case KEYBOARD:
if(FAILED(m_input->get_directinput()->CreateDevice(GUID_SysKeyboard, &m_di_device, NULL)))
return FALSE;
_data_format = (DIDATAFORMAT*) &c_dfDIKeyboard;
break;
case MOUSE:
if(FAILED(m_input->get_directinput()->CreateDevice(GUID_SysMouse, &m_di_device, NULL)))
return FALSE;
_data_format = (DIDATAFORMAT*) &c_dfDIMouse;
break;
case JOYSTICK:
if(FAILED(m_input->get_directinput()->EnumDevices(DI8DEVCLASS_GAMECTRL, enum_joysticks, this,
DIEDFL_ATTACHEDONLY)))
return FALSE;
if(m_di_device == NULL)
return FALSE;
_data_format = (DIDATAFORMAT*) &c_dfDIJoystick;
break;
default:
return FALSE;
}
// set the windowed usage
m_use_window_mode = window_mode;
if(FAILED(m_di_device->SetDataFormat(_data_format)))
return FALSE;
if(FAILED(m_di_device->SetCooperativeLevel(m_input->get_hwnd(), DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))
return FALSE;
DIPROPRANGE _prop_range;
DIPROPDWORD _prop_dword;
// set the special properties if it's a joystick
if(type == JOYSTICK)
{
// set the special properties of the joystick (range)
_prop_range.diph.dwSize = sizeof(DIPROPRANGE);
_prop_range.diph.dwHeaderSize = sizeof(DIPROPHEADER);
_prop_range.diph.dwHow = DIPH_BYOFFSET;
_prop_range.lMin = -1024;
_prop_range.lMax = +1024;
// set x range
_prop_range.diph.dwObj = DIJOFS_X;
if(FAILED(m_di_device->SetProperty(DIPROP_RANGE, &_prop_range.diph)))
return FALSE;
// set y range
_prop_range.diph.dwObj = DIJOFS_Y;
if(FAILED(m_di_device->SetProperty(DIPROP_RANGE, &_prop_range.diph)))
return FALSE;
// set the special properties of the joystick (deadzone 12%)
_prop_dword.diph.dwSize = sizeof(DIPROPDWORD);
_prop_dword.diph.dwHeaderSize = sizeof(DIPROPHEADER);
_prop_dword.diph.dwHow = DIPH_BYOFFSET;
_prop_dword.dwData = 1200;
// set x deadzone
_prop_dword.diph.dwObj = DIJOFS_X;
if(FAILED(m_di_device->SetProperty(DIPROP_DEADZONE, &_prop_dword.diph)))
return FALSE;
// set y deadzone
_prop_dword.diph.dwObj = DIJOFS_Y;
if(FAILED(m_di_device->SetProperty(DIPROP_DEADZONE, &_prop_dword.diph)))
return FALSE;
}
// acquire the device for use
if(FAILED(m_di_device->Acquire()))
return FALSE;
// set the device type
m_type = type;
return TRUE;
}
//---------------------------------------------------------------------
// Read data from DirectInput device.
//---------------------------------------------------------------------
BOOL INPUT_DEVICE::read()
{
long _buffer_sizes[3] = { 256, sizeof(DIMOUSESTATE), sizeof(DIJOYSTATE) };
// make sure to have a valid IDirectInputDevice8 object
if(m_di_device == NULL)
return FALSE;
// make sure devicec type if in range
if(m_type < 1 || m_type > 3)
return FALSE;
HRESULT _rv;
// loop polling and reading until succeeded or unknown error, also take care of lost-foucs problems.
while(1)
{
m_di_device->Poll();
// read in state
if(SUCCEEDED(_rv = m_di_device->GetDeviceState(_buffer_sizes[m_type-1], (LPVOID) m_state)))
break;
// return on an unknown error
if(_rv != DIERR_INPUTLOST && _rv != DIERR_NOTACQUIRED)
return FALSE;
// reacquire an try again
if(FAILED(m_di_device->Acquire()))
return FALSE;
}
// since only the mouse coordinate are relative, you will have to deal with them now.
if(m_type == MOUSE)
{
// if windowed usage, ask windows for coordinates
if(m_use_window_mode)
{
POINT mouse_pos;
GetCursorPos(&mouse_pos);
ScreenToClient(m_input->get_hwnd(), &mouse_pos);
m_x_pos = mouse_pos.x;
m_y_pos = mouse_pos.y;
}
else
{
m_x_pos += m_mouse_state->lX;
m_y_pos += m_mouse_state->lY;
}
}
// released keys and button need to be unlocked
switch(m_type)
{
case KEYBOARD:
for(short i = 0; i < 256; i++)
{
if(! (m_state[i] & 0x80))
m_locks[i] = FALSE;
}
break;
case MOUSE:
for(short i = 0; i < 4; i++)
{
if(! (m_mouse_state->rgbButtons[i]))
m_locks[i] = FALSE;
}
break;
case JOYSTICK:
for(short i = 0; i < 32; i++)
{
if(! (m_joystick_state->rgbButtons[i]))
m_locks[i] = FALSE;
}
break;
}
return TRUE;
}
//---------------------------------------------------------------------
// Acquire or unacquire DirectInput device.
//---------------------------------------------------------------------
BOOL INPUT_DEVICE::acquire(BOOL is_active)
{
if(m_di_device == NULL)
return FALSE;
if(is_active)
m_di_device->Acquire();
else
m_di_device->Unacquire();
return TRUE;
}
//---------------------------------------------------------------------
// Get key or button lock flag with specified index.
//---------------------------------------------------------------------
BOOL INPUT_DEVICE::get_lock(uchar index)
{
return m_locks[index];
}
//---------------------------------------------------------------------
// Set lock flag.
//---------------------------------------------------------------------
void INPUT_DEVICE::set_lock(uchar index, BOOL lock_flag)
{
m_locks[index] = lock_flag;
}
//---------------------------------------------------------------------
// Get x coordinate of mouse or joystick.
//---------------------------------------------------------------------
long INPUT_DEVICE::get_x_pos()
{
// update coordinates if a joystick
if(m_type == JOYSTICK)
m_x_pos = m_joystick_state->lX;
return m_x_pos;
}
//---------------------------------------------------------------------
// Set x coordinate of mouse or joystick.
//---------------------------------------------------------------------
void INPUT_DEVICE::set_x_pos(long x_pos)
{
m_x_pos = x_pos;
}
//---------------------------------------------------------------------
// Get y coordinate of mouse or joystick.
//---------------------------------------------------------------------
long INPUT_DEVICE::get_y_pos()
{
// update coordinates if a joystick
if(m_type == JOYSTICK)
m_y_pos = m_joystick_state->lY;
return m_y_pos;
}
//---------------------------------------------------------------------
// Set y coordinate of mouse or joystick.
//---------------------------------------------------------------------
void INPUT_DEVICE::set_y_pos(long y_pos)
{
m_y_pos = y_pos;
}
//---------------------------------------------------------------------
// Get x coordinate delta of mouse or joystick.
//---------------------------------------------------------------------
long INPUT_DEVICE::get_x_delta()
{
switch(m_type)
{
case MOUSE:
return m_mouse_state->lX;
case JOYSTICK:
return m_joystick_state->lX - m_x_pos;
}
return 0;
}
//---------------------------------------------------------------------
// Get y coordinate delta of mouse or joystick.
//---------------------------------------------------------------------
long INPUT_DEVICE::get_y_delta()
{
switch(m_type)
{
case MOUSE:
return m_mouse_state->lY;
case JOYSTICK:
return m_joystick_state->lY - m_y_pos;
}
return 0;
}
//---------------------------------------------------------------------
// Check if key/button is pressed, check lock flag.
//---------------------------------------------------------------------
BOOL INPUT_DEVICE::get_key_state(uchar index)
{
if((m_state[index] & 0x80) && m_locks[index] == FALSE)
return TRUE;
return FALSE;
}
//---------------------------------------------------------------------
// Set key state for specified key.
//---------------------------------------------------------------------
void INPUT_DEVICE::set_key_state(uchar index, BOOL state)
{
m_state[index] = state;
}
//---------------------------------------------------------------------
// Check if key/button is pressed, do not check lock flag.
//---------------------------------------------------------------------
BOOL INPUT_DEVICE::get_pure_key_state(uchar index)
{
return (m_state[index] & 0x80) ? TRUE : FALSE;
}
//---------------------------------------------------------------------
// Get key which has been pressed and return it's ascii value.
//---------------------------------------------------------------------
short INPUT_DEVICE::get_key_press(long timeout)
{
// Retrieves the active input locale identifier (formerly called the keyboard layout) for the specified thread.
// If the idThread parameter is zero, the input locale identifier for the active thread is returned.
static HKL s_keyboard_layout = GetKeyboardLayout(0);
// make sure it's a keyboard and it is initialized
if((m_type != KEYBOARD) || (m_di_device == NULL))
return 0;
// calculate end time for timeout
ulong _end_time = GetTickCount() + timeout;
uchar _win_key_states[256], _di_key_states[256];
// loop until timeout or key pressed
while(1)
{
// get windows keyboard state
GetKeyboardState(_win_key_states);
// get DirectInput keyboard state
m_di_device->GetDeviceState(256, _di_key_states);
// scan through looking for key presses
for(ushort i = 0; i < 256; i++)
{
// if one found, try to convert it.
if(_di_key_states[i] & 0x80)
{
ushort scan_code = i;
ushort virtual_key, ascii_char;
// get virtual key code
if((virtual_key = MapVirtualKeyEx(scan_code, 1, s_keyboard_layout)))
{
// get ascii code of key and return it
if(ToAsciiEx(virtual_key, scan_code, _win_key_states, &ascii_char, 0, s_keyboard_layout))
return ascii_char;
}
}
}
// check for timeout
if(timeout && GetTickCount() > _end_time)
return 0;
}
return 0;
}
//---------------------------------------------------------------------
// Return number of key which have been pressed down, check lock flag.
//---------------------------------------------------------------------
long INPUT_DEVICE::get_num_key_press()
{
long _num = 0;
for(long i = 0; i < 256; i++)
{
if((m_state[i] & 0x80) && m_locks[i] == FALSE)
_num++;
}
return _num;
}
//---------------------------------------------------------------------
// Return number of key which have been pressed down, ignore lock flag.
//---------------------------------------------------------------------
long INPUT_DEVICE::get_num_pure_key_press()
{
long _num = 0;
for(long i = 0; i < 256; i++)
{
if(m_state[i] & 0x80)
_num++;
}
return _num;
}
//---------------------------------------------------------------------
// Return button state of mouse or joystick, check lock flag.
//---------------------------------------------------------------------
BOOL INPUT_DEVICE::get_button_state(uchar index)
{
char _state = 0;
if(m_type == MOUSE)
_state = m_mouse_state->rgbButtons[index];
if(m_type == JOYSTICK)
_state = m_joystick_state->rgbButtons[index];
// check if key/button is pressed
if((_state & 0x80) && m_locks[index] == FALSE)
return TRUE;
return FALSE;
}
//---------------------------------------------------------------------
// Set button state of mouse or joystick.
//---------------------------------------------------------------------
BOOL INPUT_DEVICE::set_button_state(uchar index, BOOL state)
{
if(m_type == MOUSE)
{
m_mouse_state->rgbButtons[index] = state;
return TRUE;
}
if(m_type == JOYSTICK)
{
m_joystick_state->rgbButtons[index] = state;
return TRUE;
}
return FALSE;
}
//---------------------------------------------------------------------
// Return button state of mouse or joystick, ignore lock flag.
//---------------------------------------------------------------------
BOOL INPUT_DEVICE::get_pure_button_state(uchar index)
{
if(m_type == MOUSE)
return m_mouse_state->rgbButtons[index];
if(m_type == JOYSTICK)
return m_joystick_state->rgbButtons[index];
return FALSE;
}
//---------------------------------------------------------------------
// Return number of buttons of mouse and joystick which have been pressed
// down, check lock flag.
//---------------------------------------------------------------------
long INPUT_DEVICE::get_num_button_press()
{
long _num = 0;
if(m_type == MOUSE)
{
for(long i = 0; i < 4; i++)
{
if((m_mouse_state->rgbButtons[i] & 0x80) && m_locks[i] == FALSE)
_num++;
}
}
else if(m_type == JOYSTICK)
{
for(long i = 0; i < 32; i++)
{
if((m_joystick_state->rgbButtons[i] & 0x80) && m_locks[i] == FALSE)
_num++;
}
}
return _num;
}
//---------------------------------------------------------------------
// Return number of buttons of mouse and joystick which have been pressed
// down, ignore lock flag.
//---------------------------------------------------------------------
long INPUT_DEVICE::get_num_pure_button_press()
{
long _num = 0;
if(m_type == MOUSE)
{
for(long i = 0; i < 4; i++)
{
if(m_mouse_state->rgbButtons[i] & 0x80)
_num++;
}
}
else if(m_type == JOYSTICK)
{
for(long i = 0; i < 32; i++)
{
if(m_joystick_state->rgbButtons[i] & 0x80)
_num++;
}
}
return _num;
}
//---------------------------------------------------------------------
// Enumerate first usable joystick.
//---------------------------------------------------------------------
BOOL FAR PASCAL INPUT_DEVICE::enum_joysticks(LPCDIDEVICEINSTANCE device_inst, LPVOID ref)
{
INPUT_DEVICE* _input_device = (INPUT_DEVICE*) ref;
// stop enumeration if no parent INPUT_DEVICE pointer
if(_input_device == NULL)
return DIENUM_STOP;
IDirectInput8* _di = _input_device->m_input->get_directinput();
// try to create a joystick interface
if(FAILED(_di->CreateDevice(device_inst->guidInstance, &_input_device->m_di_device, NULL)))
return DIENUM_CONTINUE;
// all done, stop enumeration.
return DIENUM_STOP;
}
测试代码:
/*****************************************************************************
PURPOSE:
Test for class INPUT and INPUT_DEVICE.
*****************************************************************************/
#include "core_common.h"
#include "core_framework.h"
#include "core_graphics.h"
#include "core_input.h"
class APP : public FRAMEWORK
{
public:
APP()
{
m_joystick_x = m_joystick_y = 0;
}
BOOL init()
{
// get screen width and height
int screen_width = GetSystemMetrics(SM_CXSCREEN);
int screen_height = GetSystemMetrics(SM_CYSCREEN);
// Create Direct3D and Direct3DDevice object
if(! create_display(g_hwnd, screen_width, screen_height, 16, TRUE, FALSE))
return FALSE;
// initialize DirectInput
m_input.create(g_hwnd, get_window_inst());
// create keyboad, mouse, joystick
m_keyboard.create(&m_input, KEYBOARD, FALSE);
m_mouse.create(&m_input, MOUSE, FALSE);
m_joystick.create(&m_input, JOYSTICK, FALSE);
return TRUE;
}
BOOL frame()
{
// clear display with specified color
clear_display_buffer(D3DCOLOR_RGBA(0, 0, 0, 255));
// read current state information
m_keyboard.read();
m_mouse.read();
m_joystick.read();
// begin scene
if(g_d3d_device->BeginScene())
{
// if key 'ESC' has been pressed, show message box.
if(m_keyboard.get_key_state(KEY_ESC))
{
// show information
MessageBox(g_hwnd, "ESCAPE", "Key Pressed!", MB_OK);
}
char _buffer[200];
// if left button of mouse is pressed, show message box.
if(m_mouse.get_pure_button_state(MOUSE_LBUTTON))
{
sprintf(_buffer, "%ld, %ld", m_mouse.get_x_pos(), m_mouse.get_y_pos());
MessageBox(g_hwnd, _buffer, "Mouse Coordinate!", MB_OK);
}
if(m_joystick.get_button_state(JOYSTICK_BUTTON0))
{
MessageBox(g_hwnd, "Joystick button0 is pressed down!", "Joystick", MB_OK);
m_joystick.set_lock(JOYSTICK_BUTTON0, TRUE);
}
if(m_joystick_x != m_joystick.get_x_pos() || m_joystick_y != m_joystick.get_y_pos())
{
sprintf(_buffer, "%ld, %ld", m_joystick.get_x_pos(), m_joystick.get_y_pos());
MessageBox(g_hwnd, _buffer, "Joystick Coordinate!", MB_OK);
m_joystick_x = m_joystick.m_x_pos;
m_joystick_y = m_joystick.m_y_pos;
}
// end the scene
g_d3d_device->EndScene();
}
// display video _buffer
present_display();
return TRUE;
}
BOOL shutdown()
{
release_com(g_d3d_device);
release_com(g_d3d);
return TRUE;
}
private:
INPUT m_input;
INPUT_DEVICE m_keyboard;
INPUT_DEVICE m_mouse;
INPUT_DEVICE m_joystick;
LONG m_joystick_x, m_joystick_y;
};
int PASCAL WinMain(HINSTANCE inst, HINSTANCE, LPSTR cmd_line, int cmd_show)
{
APP app;
if(! build_window(inst, "MainClass", "MainWindow", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480))
return -1;
app.run();
return 0;
}