Archived

This topic is now archived and is closed to further replies.

sfltfnt

DirectInput Keyboard question

Recommended Posts

Hi..currently to detect ''click''/''release'' on the keyboard i uses two buffer to store states of the keyboard data using GetDeviceState. one buffer stores the current state and the other one stores the previous one..i then compare the two buffer to determine click/release etc how do i achieve this using buffered data , getdevicedata instead ? which is a better way ? thanks

Share this post


Link to post
Share on other sites
Its pretty much done the same way for the keyboard. I have a wrapper that wraps up the entirety of direct input and handles both mouse and keyboard processing.


bool EPIDirectInput::UpdateBufferedDirectInput()
{
DWORD dwItems = MAX_UIBUFFERSIZE;

if (FAILED(m_Keyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA),
m_KeyboardBuffer, &dwItems, 0 )))
m_KeyboardBufferElements = 0;
else
m_KeyboardBufferElements = dwItems;

return true;
}


The above code gets the buffers using GetDeviceData. Once I have the buffers full I cycle through the buffers and I process each event. Remember that when using buffered data you can get any amount of data each time through the loop. Look at the following code.


bool EPIDirectInput:: ProcessBufferedInput()
{
UpdateBufferedDirectInput();


for (DWORD i = 0; i < m_KeyboardBufferElements; i++)
{
//Track Keyboard state here.

if (m_KeyboardBuffer->dwOfs == DIK_LSHIFT || m_KeyboardBuffer->dwOfs == DIK_RSHIFT)
{
if (m_KeyboardBuffer->dwData & 0x080)
m_KeyboardState.m_SHFTState = true;
else
m_KeyboardState.m_SHFTState = false;
}
else if (m_KeyboardBuffer->dwOfs == DIK_LMENU || m_KeyboardBuffer->dwOfs == DIK_RMENU)
{
if (m_KeyboardBuffer->dwData & 0x080)
m_KeyboardState.m_ALTState = true;
else
m_KeyboardState.m_ALTState = false;
}
else if (m_KeyboardBuffer->dwOfs == DIK_LCONTROL || m_KeyboardBuffer->dwOfs == DIK_RCONTROL)
{
if (m_KeyboardBuffer->dwData & 0x080)
m_KeyboardState.m_CTRLState = true;
else
m_KeyboardState.m_CTRLState = false;
}
else
{
//Just pass the key along with the keyboard state
if (m_KeyboardBuffer->dwData & 0x080)
//send press message

else
//send release message

}
}

return true;
}


First the above code checks the state of the shift, control, and ALT keys on both sides of the keyboard and sets a state struct, m_KeyboardState for each value. If the event is not a control, shift, or alt keypress or release it sends the key to our event processor along with the state of the control, shift, and alt keys. The buffer is time ordered and in this regard will record each and every key press and release. In the last part of the function with the "send press message" and "send release message" it is up to you to handle building an event and sending it to your UI. (that code is not included in the example because it is specific to our game)

Our keyboard state is kept in the following class. Note that it is not necessary to track the actual key pressed because it is part of the Direct Input buffer. Direct Input keyboard buffers do not repeat keys so you will receive only a single event for the press and the release meaning that all you really need to know is when you receive a keypress was it between a press/release of a shift, alt or control key. In this regard buffered keyboard input is much easier.


class KeyboardState
{
public:
KeyboardState();
virtual ~KeyboardState();

bool m_SHFTState;
bool m_CTRLState;
bool m_ALTState;
};


Kressilac

[edited by - kressilac on November 8, 2002 5:14:47 PM]

[edited by - kressilac on November 8, 2002 5:17:54 PM]

Share this post


Link to post
Share on other sites