🔒 Locked
Good SDL string input
Advertisement
Original Post
Hey, Ive been trying to input into strings using SDL. At the moment im directly checking each letter in every loop. This is working, but i have come to a problem. To slow down presses i put in an SDL_Delay() after each key press. This improves the input. It keeps everythin nice and smooth. So when pressing "A" i dont end up with "AAAAAA" on the input. But even delaying after each press isnt working. Sometimes i have to wait before the next key. Or Sometimes it still goes too fast and i end up with sentances like "Hhheo Wrrrld". At first i tried an string input tutorial on LazyFoo. But the entire setup did not work well with my game code. I am not using a loop to poll events. But simply checking every key, every game loop. Is there an easy way to fix up this entire process? So my input is fast and responsive like windows? Thanks.
There is an easy fix! Check out the SDL_EnableKeyRepeat function. This will allow you to slow down the key events coming in to any value like.
HTH
HTH
Are you using SDL_PollEvent or SDL_GetKeyState to get your keyboard info? If you are using polling, this method really should work. Did you call it with SDL_DEFAULT_REPEAT_DELAY and SDL_DEFAULT_REPEAT_INTERVAL?
If you are using SDL_GetKeyState, I don't know if this function will help you or not.
If you are using SDL_GetKeyState, I don't know if this function will help you or not.
You're right, enabling key repeat does not affect the SDL_GetKeyStates information at all. I just tried it out.
You could either switch to using polling, or implement this behavior yourself. If you do it yourself, I'd use a timer to only check the keys every X milliseconds rather than using SDL_Delay, which as you found out, is too unpredictable for this.
Here is a quick demo of this:
HTH
You could either switch to using polling, or implement this behavior yourself. If you do it yourself, I'd use a timer to only check the keys every X milliseconds rather than using SDL_Delay, which as you found out, is too unpredictable for this.
Here is a quick demo of this:
// keys.cpp#include <SDL/SDL.h>#include <iostream>int main( int argc, char** argv ){ SDL_Init( SDL_INIT_VIDEO ); SDL_Surface* screen = SDL_SetVideoMode( 800, 600, 0, SDL_SWSURFACE ); Uint8 *keys = SDL_GetKeyState( NULL ); unsigned int timer = 0; unsigned int last_time = 0; while( true ) { SDL_PumpEvents( ); timer += SDL_GetTicks( ) - last_time; last_time = SDL_GetTicks( ); if( timer > 500 ) // half a second { timer = 0; if( keys[SDLK_LEFT] ) std::cout << "LEFT" << std::endl; else if( keys[SDLK_ESCAPE] ) break; } SDL_FillRect( screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0) ); SDL_Flip( screen ); } SDL_Quit( ); return 0;}HTH
If you just block the key from being pressed for 100ms, then slow typers (who hold a key down longer than 100 ms) will have problems.
You can use both polling and SDL_GetKeyStates() together. Use polling to test for things like typing text and pressing 'event' buttons (escape, menu button, fire missiles button, etc.) and use SDL_GetKeyStates() to test for things like smooth motion (arrow keys, other keys that are either up or down from the game's perspective).
SDL makes both types of information available to you; you might as well use whichever is easier for a given part of your program.
You can use both polling and SDL_GetKeyStates() together. Use polling to test for things like typing text and pressing 'event' buttons (escape, menu button, fire missiles button, etc.) and use SDL_GetKeyStates() to test for things like smooth motion (arrow keys, other keys that are either up or down from the game's perspective).
SDL makes both types of information available to you; you might as well use whichever is easier for a given part of your program.
Ya I'd have to agree with jyk, just have a polling loop like in every SDL tutorial , and have any key up event inside the ASCII range your looking for casted to a char and send to your buffer.
Guess it's important to note that the SDL Keysym enum is mapped to UNICODE, which in turn has it's lower range of values mapped to ASCII.
*edit* Um, so I'm 100% sure that the SDL Keysym enum has it's lowwer range mapped to ASCII, but I'm not 100% sure of the upper range being mapped to UNICODE. I was looking over the source and they say something about following in the foot steps of X11 with virtual keys for international key boards. So it would be my guess it does not follow UNICODE. Does anyone know for sure?
Hope that helps.
SDL_Event keyevent; //The SDL event that we will poll to get events.String strInputBuffer = ""; // This is where you will store typed keyswhile (SDL_PollEvent(&keyevent)) //Poll our SDL key event for any keystrokes.{ if( keyevent.type == SDL_KEYUP ) // Check if this key is being released // Check if the key is in the upper or lowwer case ASCII ranges if( keyevent.key.keysym.sym >= 65 && keyevent.key.keysym.sym <= 90 || keyevent.key.keysym.sym >= 97 && keyevent.key.keysym.sym <= 122 ) /** This is either an upper or lowwer case letter, * add it to the buffer, This check can obviously * be easily modified to allow for numbers and more. * But it is important to prevent the ASCII values * of control keys or others from being nonsensically * added to your buffer. */ strInputBuffer += reinterpret_cast<char>( keyevent.key.keysym.sym );}Guess it's important to note that the SDL Keysym enum is mapped to UNICODE, which in turn has it's lower range of values mapped to ASCII.
*edit* Um, so I'm 100% sure that the SDL Keysym enum has it's lowwer range mapped to ASCII, but I'm not 100% sure of the upper range being mapped to UNICODE. I was looking over the source and they say something about following in the foot steps of X11 with virtual keys for international key boards. So it would be my guess it does not follow UNICODE. Does anyone know for sure?
Hope that helps.
I tried your method Wave but it wouldnt compile.
So i went on and tried somthing simple like this
And it maybe will catch one or two out of a hundread keystrokes? Be aware this has just been dropped straight into my Update loop.
So i went on and tried somthing simple like this
while (SDL_PollEvent(&event)) { if( event.type == SDL_KEYDOWN ) { switch(event.key.keysym.sym){ case SDLK_a: str = str + 'a'; break; } } }And it maybe will catch one or two out of a hundread keystrokes? Be aware this has just been dropped straight into my Update loop.
It should be catching every single keystroke. The keyboard generates events every time a key is pressed or released. The operating system sends these events to the program, and SDL generates the corresponding event which is then placed in the event queue. The only way to not detect a keystroke is if the keyboard doesn't detect it or there is a glitch in the software somewhere.
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement