Good SDL string input

Started by
12 comments, last by Vorpy 17 years, 1 month ago
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.
Game Development Tutorials, a few good game development tutorials located on my site.
Advertisement
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
Ive placed this in my code and it dosent make a difference?

I cant find an example anywhere? Could you show me how to use this?
Game Development Tutorials, a few good game development tutorials located on my site.
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.
Im using SDL_GetKeyStates. And its not helping at all...

Im using the default settings too. Is there a way of emulating somthing like it in my own code?
Game Development Tutorials, a few good game development tutorials located on my site.
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:
// 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
Hmm. Trying that, im getting the same problem as before. As much as i tinker, the input is still irritatingly bad.

I was thinking, possibly if i could only block the same key being pressed again for 100ms? But im not sure on how to implement this?
Game Development Tutorials, a few good game development tutorials located on my site.
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.
Just wanted to reinforce that you should use polling rather than key state querying for text input. The behavior that you're trying to emulate you will then get 'for free' (assuming appropriate key repeat and delay settings, of course).
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.

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.
==============================
A Developers Blog | Dark Rock Studios - My Site

This topic is closed to new replies.

Advertisement