Archived

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

helix

Getting user inputted text

Recommended Posts

I am working on the chat portion of my game currently and I seem to have hit a roadblock. How can I get user input text that they've typed? I have everything all set up for the chatting except for this. My keyboard object can detect keypresses, etc but there is no support for an edit box control kinda thing. What would you do? I am using directx8 and it's a 3d space shooter if that helps. I am trying to make something similar to the standard quake or unreal chat system. [edited by - beoch on November 5, 2002 11:17:20 PM]

Share this post


Link to post
Share on other sites
just append characters to a string as the user strikes character keys, and print the string wherever you want the text to be. add a border and you''ll have your edit box.

Share this post


Link to post
Share on other sites
Well, the problem is that I can only detect key states so I''d have to check every single key each frame to see if something was pressed but even worse, if two keys were pressed in the same frame, I''d have absolutely no idea what order was intended.

My problem is that I have no system in place to recieve user input of this type and I''m trying to figure out what I need to add to my engine to get this sort of thing.

But your sugggestion is exactly what I am intending to do...

Share this post


Link to post
Share on other sites
It''s unlikely that a user will press two keys at the same frame with normal writing.

You should pay attention to the key repeat rate, though.


schiggl

Share this post


Link to post
Share on other sites
If someone presses two keys at the same time, chances are that they don''t know what they''re typing either. I can type pretty fast myself. There are people out there who can get up to 120 words per minute. With an average of 5 characters per word, that averages out to be (without mistakes) 10 keystrokes per second. At 30fps, you should be able to get one key per frame without too much of a problem.

Just include a backspace mechanism and so long as you are displaying what the player is typing, you should be fine.


Looking for an honest video game publisher? Visit www.gamethoughts.com

Share this post


Link to post
Share on other sites
I was thinking about that after I posted -- you guys are right. But I still don't know what I need to add to the engine to recieve an onKeyPress( char c ) sort of functionality. The only thing I can think of is to, each frame, cycle through all the printable characters in my keyboard buffer and call an onKeyPress function that I define on each key that was pressed. Does that sound reasonable? I don't like iterating solutions like this but I can't think of anything better at the moment.

[edited by - beoch on November 6, 2002 10:43:44 PM]

Share this post


Link to post
Share on other sites
I''m not too sure what you''re using to receive input, though GetAsyncKeyState() behaves somewhat like what you described (ie, you have to specify which key''s state you want to check).

What you could do is look through every possible character (ie, letters and numbers, some punctuation too) and append them to a string. If a key has been pressed, assign a certain value to the key meaning that it is being held down and don''t accept input from that key until it has been either released or until ''x'' time has passed.

Not sure how this would perform, but I hope it helps...

Share this post


Link to post
Share on other sites
Yeah, that''s basically what I thinking about. The performance of that approach worries me.

This is the interface for my keyboard object:

  
inline const bool KeyDown( int nKey, int nMods = 0 ) const
{
return (m_keys[nKey] & 0x80) && (nMods == ANY_MODKEYS || nMods == this->m_nMods);
}

inline const bool KeyPress( int nKey, int nMods = 0 ) const
{
return m_press[nKey] && (nMods == ANY_MODKEYS || nMods == this->m_nMods);
}

inline const bool KeyPressAny( void ) const
{
for( int i = 0; i < 256; i++ )
if( m_press[i] )
return true;

return false;
}

// Return whether the indicated modifier key is currently down (left or right)

inline const bool Shift( void ) const
{
return KeyDown( DIK_LSHIFT, ANY_MODKEYS ) || KeyDown( DIK_RSHIFT, ANY_MODKEYS );
}
inline const bool Ctrl( void ) const
{
return KeyDown( DIK_LCONTROL, ANY_MODKEYS ) || KeyDown( DIK_RCONTROL, ANY_MODKEYS );
}
inline const bool Alt( void ) const
{
return KeyDown( DIK_LMENU, ANY_MODKEYS ) || KeyDown( DIK_RMENU, ANY_MODKEYS );
}


I guess I was thinking about making a function similar to KeyPressAny that returns all the chars that were pressed that frame or maybe calls a callback function for all pressed chars. If that sounds resonable to you guys I guess I''ll just go with it and stop worrying about it.

Share this post


Link to post
Share on other sites
If you already have a key press/release callback in place, I personally would just re-direct the keystrokes to a chat buffer (or chat buffer callback if you want), based upon whether the game was in chat mode or gameplay mode. You could simply swap in the chat buffer pointer once you determined the "chat" key was pressed, and then swap in the gameplay buffer pointer when the "end chat" key was pressed. This would also allow you to filter/map the keystrokes depending upon what mode you were in. It could probably also be used for your game''s setup mode when mapping keys to functions and such.

Share this post


Link to post
Share on other sites
What I ended up doing is making a lookup table that would map the DirectInput key defines to the corresponding ascii char (since I only know the DI key define for the pressed key). So for example, DIK_T == ''t''. I have a second lookup table for when shift is pressed so in that case, DIK_5 == ''%'', etc. The looked up char is then added to my chat buffer unless it''s 0 (non-printable char). It seems to work pretty well and there is very little performance hit because I just piggy backed it in the loop that initializes the key press array each frame.

Share this post


Link to post
Share on other sites
for(int i=0;i{
if(lastframekeys!=currentframekeys[i])
{
append to text input string!
}
}

thats all you have to do


[edited by - Basiror on November 9, 2002 6:05:05 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by beoch
What I ended up doing is making a lookup table that would map the DirectInput key defines to the corresponding ascii char (since I only know the DI key define for the pressed key).


How did you handle non-US keyboards ? (Yes, it DOES matter)
Thinking about this will make you a better programmer.

hints
- DIK constants map to keyboard locations (scan codes), not ASCII characters, so that control layouts (left,right,up,down) stay 'right' regardless of the keyboard layout.
- There are functions that do the translation (see here)
- It's also time to think about international character sets - why wouldn't your 'console' support, say, japanese characters ? There are (unicode) fonts for them.

Documents [ GDNet | MSDN | STL | OpenGL | Formats | RTFM | Asking Smart Questions ]
C++ Stuff [ MinGW | Loki | SDL | Boost. | STLport | FLTK | ACCU Recommended Books ]


[edited by - Fruny on November 9, 2002 6:48:52 AM]

Share this post


Link to post
Share on other sites