Anything related in any way to game development as a whole is welcome here. Tell us about your game, grace us with your project, show us your new YouTube video, etc.
Moderator: PC Supremacists
adikid89
Chaos Rift Cool Newbie
Posts: 94 Joined: Tue Apr 27, 2010 6:59 am
Current Project: small tiny-mini projects
Favorite Gaming Platforms: PC I guess...
Programming Language of Choice: c++
Post
by adikid89 » Thu May 20, 2010 7:00 am
I'm trying to get text input for a console... but it doesn't seem to be working, and I'm pretty lost to figure out what the problem.
Here is some code. The console is not receiving any input. I mean... c = getKey() is 0 every time.
Code: Select all
void Console::handle_input(SDL_Event& event)
{
SDL_EnableUNICODE(SDL_ENABLE);
if(event.type == SDL_KEYDOWN) {
handleKey(event.key);
}
SDL_EnableUNICODE(SDL_DISABLE);
}
void Console::handleKey(const SDL_KeyboardEvent &event)
{
switch(event.keysym.sym) {
case SDLK_BACKSPACE:
if(console_input.size()) {
console_input.erase(--index,1);
} break;
case SDLK_DELETE:
if(index < console_input.size()) {
console_input.erase(index,1);
} break;
case SDLK_LEFT:
if(index <= 0) index = 0;
else index--;
break;
case SDLK_RIGHT:
if(index >= console_input.size()) index = console_input.size();
else index++;
break;
default:
char c = getKey(event);
if(c) console_input += c;
break;
}
}
char Console::getKey(const SDL_KeyboardEvent& event)
{
if(SDL_EnableUNICODE(SDL_QUERY) == SDL_ENABLE) {
Singleton<Log>::getInstance()->print("SDL_EnableUNICODE == SDL_ENABLE)");
} else {
Singleton<Log>::getInstance()->print("SDL_EnableUNICODE == SDL_DISABLED returning)");
return '0';
}
const int INTERNATIONAL_MASK = 0xFF80, UNICODE_MASK = 0x7F;
int uni = event.keysym.unicode;
if(!uni) {
return 0; //this always gets executed
} else if( ( uni & INTERNATIONAL_MASK ) == 0 ) {
return static_cast<char>(uni & UNICODE_MASK); //this never gets executed
} else // we have a funky international character. one we can't read :(
{
// we could do nothing, or we can just show some sign of input, like so:
return 0;
}
}
Here is the function that calls the console::update() function:
renderConsole() gets executed every about 40ms.
Code: Select all
void Game::renderConsole()
{
SDL_Event event;
if(SDL_PollEvent(&event)) {
if(event.type == SDL_QUIT) gameState->setState(EXIT);
else if(event.type == SDL_KEYDOWN) {
if(event.key.keysym.sym == SDLK_BACKQUOTE) {
gameState->setState(GAMEOVER);
}
}
}
Log* log = Singleton<Log>::getInstance();
Console* console = Singleton<Console>::getInstance();
console->update(event);
}
Any idea on why the console is not getting any input whatsoever?
RyanPridgeon
Chaos Rift Maniac
Posts: 447 Joined: Sun Sep 21, 2008 1:34 pm
Current Project: "Triangle"
Favorite Gaming Platforms: PC
Programming Language of Choice: C/C++
Location: UK
Contact:
Post
by RyanPridgeon » Thu May 20, 2010 8:17 am
I know there's no error handling, and it will only work correctly for ASCII input, but out of interest does this work?
Code: Select all
char Console::getKey(const SDL_KeyboardEvent& event)
{
return (char) event.key.keysym.unicode;
}
Ryan Pridgeon
C ,
C++ ,
C# ,
Java ,
ActionScript 3 ,
HaXe ,
PHP ,
VB.Net ,
Pascal
Music | Blog
adikid89
Chaos Rift Cool Newbie
Posts: 94 Joined: Tue Apr 27, 2010 6:59 am
Current Project: small tiny-mini projects
Favorite Gaming Platforms: PC I guess...
Programming Language of Choice: c++
Post
by adikid89 » Thu May 20, 2010 9:13 am
RyanPridgeon wrote: I know there's no error handling, and it will only work correctly for ASCII input, but out of interest does this work?
Code: Select all
char Console::getKey(const SDL_KeyboardEvent& event)
{
return (char) event.key.keysym.unicode;
}
I doubt it ... i kinda figured out what the problem was(I put the code inside handleKey() in a while(!done) loop, so now it gets all the input, I guess it was wasting inputs somewhere else in the code)...But even so it's not really that good. I would sure like to hear some better ideas.
L.E.: Anyone got any idea on why is SDL_PollEvent taking certain keys twice? (backspace, arrow keys, other probably). Here is the code:
Code: Select all
void Console::handleKey()
{
bool done = false;
SDL_Event events;
while(!done) {
render();
SDL_Delay(30);
if(SDL_PollEvent(&events)) {
if(events.type == SDL_QUIT)
Singleton<GameState>::getInstance()->setState(EXIT);
switch(events.key.keysym.sym) {
case SDLK_BACKSPACE:
if(console_input.size() >= 1) {
console_input.erase(--index,1);
Singleton<Log>::getInstance()->print("%s", console_input.c_str());
} break;
case SDLK_DELETE:
if(index < console_input.size()) {
console_input.erase(index,1);
} break;
case SDLK_LEFT:
if(index <= 0) index = 0;
else index--;
break;
case SDLK_RIGHT:
if(index >= console_input.size()) index = console_input.size();
else index++;
break;
case SDLK_RETURN:
done = true;
parseCommand();
console_input.clear();
index = 0;
break;
case SDLK_ESCAPE:
done = true;
Singleton<GameState>::getInstance()->setState(GAMEOVER);
break;
case SDLK_BACKQUOTE: //not working
if(!_active) {
Singleton<GameState>::getInstance()->setState(GAMEOVER);
_active = true;
}
else _active = false;
done = true;
break;
case SDLK_HOME:
index = 0;
break;
case SDLK_END:
index = console_input.size() -1;
break;
case SDLK_UP:
console_input = getInfoUp();
index = console_input.size() -1;
break;
case SDLK_DOWN:
console_input = getInfoDown();
index = console_input.size() - 1;
break;
default:
char c = getKey(events.key);
if(c) {
console_input += c;
Singleton<Log>::getInstance()->print("%s", console_input.c_str());
index++;
}
break;
}
}
}
}
eatcomics
ES Beta Backer
Posts: 2528 Joined: Sat Mar 08, 2008 7:52 pm
Location: Illinois
Post
by eatcomics » Thu May 20, 2010 1:18 pm
It should really be while (SDL_PollEvents(&events))
that I believe is where your problems are coming from, but also maybe not, I don't see a real reason this would be unless the input isn't being cleared, well now that I think about it, if you're holding down the button, the loop doesn't get done, and it just keeps taking in the key, instead of exiting... But yeah I think while (poll events)
will work
X Abstract X
Chaos Rift Regular
Posts: 173 Joined: Thu Feb 11, 2010 9:46 pm
Post
by X Abstract X » Thu May 20, 2010 1:22 pm
Some events are being reported twice because you're checking for both presses and releases of keys. You can find out which event it is like this.
if (event.type == SDL_KEYDOWN)
if(event.type == SDL_KEYUP)
adikid89
Chaos Rift Cool Newbie
Posts: 94 Joined: Tue Apr 27, 2010 6:59 am
Current Project: small tiny-mini projects
Favorite Gaming Platforms: PC I guess...
Programming Language of Choice: c++
Post
by adikid89 » Thu May 20, 2010 3:17 pm
X Abstract X wrote: Some events are being reported twice because you're checking for both presses and releases of keys. You can find out which event it is like this.
if (event.type == SDL_KEYDOWN)
if(event.type == SDL_KEYUP)
OMG .. I didn't notice that.. thanks :D. Works like a charm now :P .