Archived

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

DInput Scan Codes

This topic is 5616 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have this wierd problem with a DInput class ( I got it from the book "OpenGL Game Programming). Whenever I try to get input from the keyboard, this happens: If I specify any DIK_Fxx key to catch, it works. However, if I specify DIK_LEFT, RIGHT, UP, or DOWN, it acts like the keys are being held down, but they aren''t being touched! It catches LCONTROL, but does the freaky with RCONTROL, and the same for INSERT, DELETE, HOME, END, PRIOR, and NEXT. Has anyone seen this before? It is driving me crazy... En taro Adun! Doom to all who threaten the homeworld! *Protoss Zealot - Starcraft*

Share this post


Link to post
Share on other sites
I don''t have the book, so i haven''t seen the code...can u post the code (atleast some fragment)?

Also try these if they are not there already...
Do a ZeroMemory on the diKeys[256] array before calling GetDeviceData.

Are you checking for the key like this...

  
if(diKeys[DIK_LEFT] & 0x80)
{
// Key is pressed, do something...

}


Share this post


Link to post
Share on other sites
Well, the 0x80 stuff is done in another function, which reads
the return of that function.

I''ll see what I can do about the ZeroMemory thingy.

En taro Adun!
Doom to all who threaten the homeworld!
*Protoss Zealot - Starcraft*

Share this post


Link to post
Share on other sites
Here is what I can give you on the code:

/****************************************************************************
InputSystem.cpp

Implementation of a DirectInput class wrapper input system

Author : Dave Astle
Date : 3/5/2001

Written for OpenGL Game Programming
*****************************************************************************/
#include "InputSystem.h"


/*****************************************************************************
CKeyboard::Constructor

Initializes the DI device
*****************************************************************************/
CKeyboard::CKeyboard(LPDIRECTINPUT8 pDI, HWND hwnd)
{
if (FAILED(pDI->CreateDevice(GUID_SysKeyboard, &m_pDIDev, NULL)))
{
// error processing
}

if (FAILED(m_pDIDev->SetDataFormat(&c_dfDIKeyboard)))
{
// error processing
}

if (FAILED(m_pDIDev->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))
{
// error processing
}

if (FAILED(m_pDIDev->Acquire()))
{
// error processing
}

Clear();
} // end CKeyboard::Constructor


/*****************************************************************************
CKeyboard::Destructor

Releases the DI device
*****************************************************************************/
CKeyboard::~CKeyboard()
{
if (m_pDIDev)
{
m_pDIDev->Unacquire();
m_pDIDev->Release();
}
} // end CKeyboard::Destructor


/*****************************************************************************
CKeyboard::Update()

Queries the current state of the keyboard and stores it in the member
variables.
*****************************************************************************/
bool CKeyboard::Update()
{
if (FAILED(m_pDIDev->GetDeviceState(sizeof(m_keys), (LPVOID)m_keys)))
{
if (FAILED(m_pDIDev->Acquire()))
{
return false;
}
if (FAILED(m_pDIDev->GetDeviceState(sizeof(m_keys), (LPVOID)m_keys)))
{
return false;
}
}
return true;
} // end CKeyboard::Update()


/*****************************************************************************
CKeyboard::Acquire()

Acquires the keyboard
*****************************************************************************/
bool CKeyboard::Acquire()
{
Clear();
return (!FAILED(m_pDIDev->Acquire()));
} // end CKeyboard::Acquire()


/*****************************************************************************
CKeyboard::Unacquire()

Unacquires the keyboard
*****************************************************************************/
bool CKeyboard::Unacquire()
{
Clear();
return (!FAILED(m_pDIDev->Unacquire()));
} // end CKeyboard::Unacquire()



/*****************************************************************************
CMouse::Constructor

Initializes the DI device
*****************************************************************************/
CMouse::CMouse(LPDIRECTINPUT8 pDI, HWND hwnd, bool isExclusive)
{
if (FAILED(pDI->CreateDevice(GUID_SysMouse, &m_pDIDev, NULL)))
{
// error processing
}

if (FAILED(m_pDIDev->SetDataFormat(&c_dfDIMouse)))
{
// error processing
}

DWORD flags;
if (isExclusive)
flags = DISCL_FOREGROUND | DISCL_EXCLUSIVE | DISCL_NOWINKEY;
else
flags = DISCL_FOREGROUND | DISCL_NONEXCLUSIVE;


if (FAILED(m_pDIDev->SetCooperativeLevel(hwnd, flags)))
{
// error processing
}

if (FAILED(m_pDIDev->Acquire()))
{
// error processing
}

if (FAILED(m_pDIDev->GetDeviceState(sizeof(DIMOUSESTATE), &m_state)))
{
// error processing
}
} // end CMouse::Constructor


/*****************************************************************************
CMouse::Destructor

Releases the DI device
*****************************************************************************/
CMouse::~CMouse()
{
if (m_pDIDev)
{
m_pDIDev->Unacquire();
m_pDIDev->Release();
}
} // end CMouse::Destructor


/*****************************************************************************
CMouse::Update()

Queries the current state of the mouse and stores it in the member
variables.
*****************************************************************************/
bool CMouse::Update()
{
if (FAILED(m_pDIDev->GetDeviceState(sizeof(DIMOUSESTATE), &m_state)))
{
if (FAILED(m_pDIDev->Acquire()))
{
return false;
}
if (FAILED(m_pDIDev->GetDeviceState(sizeof(DIMOUSESTATE), &m_state)))
{
return false;
}
}

return true;
} // end CMouse::Update()


/*****************************************************************************
CMouse::Acquire()

Acquires the mouse
*****************************************************************************/
bool CMouse::Acquire()
{
return (!FAILED(m_pDIDev->Acquire()));
} // end CMouse::Acquire


/*****************************************************************************
CMouse::Unacquire()

Unacquires the keyboard
*****************************************************************************/
bool CMouse::Unacquire()
{
return (!FAILED(m_pDIDev->Unacquire()));
} // end CMouse::Unacquire()


/*****************************************************************************
CInputSystem::Initialize()

Initializes the input system. isExclusive should be set to true for exclusive
mouse access, false otherwise. Flags should be a combination of
IS_USEKEYBOARD and/or IS_USEMOUSE.
*****************************************************************************/
bool CInputSystem::Initialize(HWND hwnd, HINSTANCE appInstance, bool isExclusive, DWORD flags)
{
// create the DI object
if (FAILED(DirectInput8Create(appInstance,
DIRECTINPUT_VERSION,
IID_IDirectInput8,
(void **)&m_pDI,
NULL)))
return false;

if (flags & IS_USEKEYBOARD)
{
m_pKeyboard = new CKeyboard(m_pDI, hwnd);
if (m_pKeyboard == NULL)
return false;
}
if (flags & IS_USEMOUSE)
{
m_pMouse = new CMouse(m_pDI, hwnd, isExclusive);
if (m_pMouse == NULL)
return false;
}

return true;
} // end CInputSystem::Initialize()


/*****************************************************************************
CInputSystem::Shutdown()

Releases all objects and frees memory.
*****************************************************************************/
bool CInputSystem::Shutdown()
{
UnacquireAll();
if (m_pKeyboard)
{
delete m_pKeyboard;
m_pKeyboard = NULL;
}

if (m_pKeyboard)
{
delete m_pMouse;
m_pMouse = NULL;
}

if (FAILED(m_pDI->Release()))
return false;

return true;
} // end CInputSystem::Shutdown()


/*****************************************************************************
CInputSystem::Update()

Queries the current state of all devices.
*****************************************************************************/
bool CInputSystem::Update()
{
if (m_pKeyboard)
m_pKeyboard->Update();
if (m_pMouse)
m_pMouse->Update();

return true;
} // end CInputSystem::Update()


/*****************************************************************************
CInputSystem::AcquireAll()

Makes sure all input devices are acquired
*****************************************************************************/
void CInputSystem::AcquireAll()
{
if (m_pKeyboard)
m_pKeyboard->Acquire();
if (m_pMouse)
m_pMouse->Acquire();
} // end CInputSystem::AcquireAll()


/*****************************************************************************
CInputSystem::UnacquireAll()

Unacquires all devices
*****************************************************************************/
void CInputSystem::UnacquireAll()
{
if (m_pKeyboard)
m_pKeyboard->Unacquire();
if (m_pMouse)
m_pMouse->Unacquire();
} // end CInputSystem::UnacquireAll()


Then you declare a class of type CInput System, then you call
classname.KeyDown(DIK_XXXXX);

En taro Adun!
Doom to all who threaten the homeworld!
*Protoss Zealot - Starcraft*

Share this post


Link to post
Share on other sites
Last thing, the compiler gives me the warning : conversion "const int" to "char" possible loss of data (or something like that).

It only does this on keys that act like they are stuck down.

En taro Adun!
Doom to all who threaten the homeworld!
*Protoss Zealot - Starcraft*

Share this post


Link to post
Share on other sites
I still stick to my points...
* Do a ZeroMemory on m_keys in CKeyboard::Update

where is your KeyDown() function?
Also can you give the source line where you got the warning
quote:

Last thing, the compiler gives me the warning : conversion "const int" to "char" possible loss of data (or something like that).

Share this post


Link to post
Share on other sites
class CKeyboard
{
public:
CKeyboard(LPDIRECTINPUT8 pDI, HWND hwnd);
~CKeyboard();

bool KeyDown(char key) { return (m_keys[key] & 0x80) ? true : false; }
bool KeyUp(char key) { return (m_keys[key] & 0x80) ? false : true; }

bool Update();

void Clear() { ZeroMemory(m_keys, 256 * sizeof(char)); }

bool Acquire();
bool Unacquire();

private:
LPDIRECTINPUTDEVICE8 m_pDIDev;

char m_keys[256];
};

There is the KeyDown function, and here is the line of code
that returns the error:
if(g_input.KeyDown(DIK_LEFT))

I tried the ZeroMemory thing, but it didn''t do any good.

En taro Adun!
Doom to all who threaten the homeworld!
*Protoss Zealot - Starcraft*

Share this post


Link to post
Share on other sites
I was wrong on the warning, it was actually:
truncation from ''const int'' to ''char''


I really don''t have a clue what''s going on,
and since I haven''t ever used DInput before,
I can''t even begin to try and fix this code
myself.

En taro Adun!
Doom to all who threaten the homeworld!
*Protoss Zealot - Starcraft*

Share this post


Link to post
Share on other sites
Never mind, I got it, but I don''t see why it worked.

I had to change the paramater type from char to const int
on the key down and up functions, now it works fine.

En taro Adun!
Doom to all who threaten the homeworld!
*Protoss Zealot - Starcraft*

Share this post


Link to post
Share on other sites
It worked when you converted to an int because an int has a length of 32 bits, a char can only store 7 bits (and a sign bit).
This is why the Left Control worked and the Right didn''t.

DIK_LCONTROL = 0x1D which is 11101 in binary, and so needs 5 bits to represent it.

DIK_RCONTROL = 0x9D which is 10011101 in binary, and so needs 8 bits to represent it. So, because the first bit was used as the sign it was interpreting the value differently.

It would also have worked if you used an unsigned char as this uses all 8 bits (there is no bit reserved for the sign).

It just goes to show ... Don''t ignore the warning messages. :-)

Cheers,
John

Share this post


Link to post
Share on other sites