天行健 君子当自强而不息

创建游戏内核(16)【OO改良版】

 

本篇是创建游戏内核(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;
}

posted on 2007-10-08 17:38 lovedday 阅读(386) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


公告

导航

统计

常用链接

随笔分类(178)

3D游戏编程相关链接

搜索

最新评论