Jump to content
  • Advertisement

Archived

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

Lupin

Advanced DirectInput keyboard input?

This topic is 5678 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

How could I write an DirectInput keyboard interface wich allows US-Style keyboards and EU-Style keyboards without the key-positions getting changed? I also want to be able to get the input as an string, because I want to write an console window using DirectInput. Could anybody point me to the ultimate DirectInput tutorial/code/whatever wich covers all I need?

Share this post


Link to post
Share on other sites
Advertisement
I noticed that directInput doesen''t allow you to specify the type of keyboard, but I didn''t know the mapping is different!

Do you have a list of the key codes as they appear on the actual keys?



www.cppnow.com

Share this post


Link to post
Share on other sites
No, I don''t have such an list I think...

Then... how could I do an keyboard input for US keyboards only??

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
to get strings with directinput, you have to store the character equivalents of each key and buffer them when you need a string. its really a pain in the arse...at least thats the way i did it...if there''s an easier way let me know. also, you have to handle things like the repeat rate for keys being held down, since directinput doesn''t do that for you, and for each press you will probably get multiple letters, like getting "hhhhhhhhheeeeeeeeellllllllllllllllloooooooo" when pressing the keys H E L L O...to get the repeat rates through the windows api i did this:


// determine keyboard repeat rate for text entry mode
int winKeyDelay;
SystemParametersInfo(
SPI_GETKEYBOARDDELAY,
0,
&winKeyDelay,
0
);
// windows stores the key delay as an int with the range
// 0 - 3; 0 being ~250ms, and 3 being ~1000ms so we have to
// convert it into a millisecond ammount
s_keyRepeatDelay = (winKeyDelay + 1) * 250;

DWORD winKeySpeed;
SystemParametersInfo(
SPI_GETKEYBOARDSPEED,
0,
&winKeySpeed,
0
);
// windows stores the key repeat speed as a DWORD ranging
// from 0 to 31; 0 being ~2.5 repeats per second, and 31
// being ~30 repeats per second; this means that for each
// 1 that the windows value goes up, the number of
// milliseconds between repeats goes down by ~11.5, starting
// at 400 for a windows value of 0
s_keyRepeatRate = 400 - (WORD)(((float)(winKeySpeed)) * 11.5f);

to store the keys with their character equivalents i used an array of these structs:


struct IKey {
bool isPrintable;
char printUpper;
char printLower;
bool isPressed;
bool justPressed;
DWORD timePressed;
DWORD lastRepeat;
bool wasPressed;
};

to populate the struct i had this function:


/***********************************************************
** IInitializeKeystate()
************************************************************/
void IInitializeKeystate () {
// this is gonna be nice and long...
// give appropriate printing characters to the
// keys that require them
for (WORD x = 0; x < NUM_KEYS; x++) {
s_lastKeystate[x].isPrintable = true;
s_lastKeystate[x].isPressed = false;
s_lastKeystate[x].timePressed = 0;
s_lastKeystate[x].lastRepeat = 0;
s_lastKeystate[x].wasPressed = false;

if (x == KEY_1) {
s_lastKeystate[x].printLower = ''1'';
s_lastKeystate[x].printUpper = ''!'';
}
else if (x == KEY_2) {
s_lastKeystate[x].printLower = ''2'';
s_lastKeystate[x].printUpper = ''@'';
}
else if (x == KEY_3) {
s_lastKeystate[x].printLower = ''3'';
s_lastKeystate[x].printUpper = ''#'';
}
else if (x == KEY_4) {
s_lastKeystate[x].printLower = ''4'';
s_lastKeystate[x].printUpper = ''$'';
}
...

note i redefined the DIK_ key names, since this particular implementation is intended to be somewhat portable...

anyway, i don''t know if any of that helps, but thats what i got...

Share this post


Link to post
Share on other sites
also, in that previous post, s_keyRepeatDelay is the time in milliseconds before a key starts repeating, and s_keyRepeatRate is the time in milliseconds between repeasts.

and to test if a key should be repeated, my code looks like this:


// go through the keystates and send text messages as
// needed
for (WORD x = 0; x < NUM_KEYS; x++) {
IKey * key = &s_lastKeystate[x];

// deterime if key should be sent or repeated at all
if (!key->isPressed)
continue;
if (!key->wasPressed) {
// first press; send it
}
else {
if (key->lastRepeat == 0) {
// no repeats yet, see if we should
if (!((TimeGetTicks() - key->timePressed) > s_keyRepeatDelay))
continue; // no repeat yet
else
key->lastRepeat = TimeGetTicks(); // repeat
}
else {
// repeats have happened, see if we should again
if (!((TimeGetTicks() - key->lastRepeat) > s_keyRepeatRate))
continue; // no repeat yet
else
key->lastRepeat = TimeGetTicks(); // repeat
}
}

note: TimeGetTicks() is equivalent to GetTickCount() just redefined to help with portability

Share this post


Link to post
Share on other sites
gotta love how it took all my code spacing out...how do i get it to appear in a text box thing inside the message?

Share this post


Link to post
Share on other sites
Just a general rule:

don''t use the

if()
else if()
else if()
else if()

style of programming.

Use a switch statement. Its much faster.

switch(key)
{
case ''a'':
// do stuff
break;
case ''b'':
// do stuff
break;
}

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Switch is not necessarily faster. If you have case 1 , 2 , 3 etc.. then yes.If you have case 23, 56, 78 then it is slower. Case also only allows integers where if statements allow for any kind of argument. This kind of , don''t do this, don''t do that statements should be done away with. You have no idea what the purpose of that if statement is, or if it will change later. Let him code the way he wants. Also switch statements does have a limit on how many cases you can have. As do if else. It all comes down to planning.

Share this post


Link to post
Share on other sites
Thanks for the input, I will try my hand on it, but I need to handle special chars (like backspace) myself

Share this post


Link to post
Share on other sites
AP, I personally don''t care which way he does thing. I just remember reading in my Ansi C book that switch is much faster because the CPU has 1 compare then a jump, instead of doing a compare for each if statement.

Just trying to give some advice, but...

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!