LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 02-28-2015, 10:31 AM   #1
Ace Blackwell
Member
 
Registered: Mar 2004
Location: Kentucky, USA
Distribution: SlamD 12.1 / Slack 12.0 ~ 14.2_64
Posts: 345

Rep: Reputation: 54
Clear Keyboard Buffer


I've Googled for the last couple of days. I can't find a way of totally clearing the keyboard buffer without hanging the machine up.

I'm using Allegro 4 with C++. My simple (console) grid type game requires moving in one of four directions. (like checkers I suppose) However if the direction key is held a little too long, the player continues to move independently the next time through the loop after the game pieces have moved.

I have tried clear_keybuf() (Allegro specific) but it doesn't clear all the keys. I've tried using keypressed() (Again Allegro specific)to read the buffer so I can disregard all until the buffer is empty, but after it's empty it stops waiting on a key hit.

I've looked at flush (C++) but really can't get enough good examples to understand how to use correctly or if it's even applicable to what I'm trying to do.

Any suggestions you may have would be greatly appreciated.

Thanks in advance
Ace

Last edited by Ace Blackwell; 02-28-2015 at 10:33 AM.
 
Old 02-28-2015, 10:35 AM   #2
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: distro hopper
Posts: 11,222

Rep: Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320Reputation: 5320
This was one of my first hits on google. Does it help?

I am not able to flush stdin
 
Old 02-28-2015, 11:04 AM   #3
Ace Blackwell
Member
 
Registered: Mar 2004
Location: Kentucky, USA
Distribution: SlamD 12.1 / Slack 12.0 ~ 14.2_64
Posts: 345

Original Poster
Rep: Reputation: 54
Thanks for the research dugan but as I understood this one, it deals more with strings. It also appears you have to know the length in advance. I was thinking of more like the

while ((c = getchar()) != '\n' && c != EOF);

listed at the bottom of the web page, but because the inputs are more likely to be a repetitive keystroke or some random chars there will not be a newline char to stop the loop.

But i'll dig into it a little more. thanks again.
 
Old 02-28-2015, 11:08 AM   #4
genss
Member
 
Registered: Nov 2013
Posts: 741

Rep: Reputation: Disabled
you could just run read() in a loop until it returns less then you asked for
 
Old 02-28-2015, 11:18 AM   #5
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,862
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
If you want to to read the keyboard without line buffering, then either use ncurses, or directly termios.
termios example:
Code:
    struct termios oldtio, newtio;
    int rc;

    rc= tcgetattr (0, &oldtio);
    if (rc) {
        perror ("tcgetattr (0, &oldtio)");
	return 4;
    }
    memcpy (&newtio, &oldtio, sizeof (newtio));
    newtio.c_lflag &= ~(ISIG | ICANON | ECHO);
    newtio.c_iflag &= ~(INLCR | ICRNL | IXON | IXOFF);
    newtio.c_cflag &= ~(PARENB);
    newtio.c_cflag = (newtio.c_cflag & ~CSIZE) | CS8;
    newtio.c_cc[VMIN] = 1;
    rc= tcsetattr (0, TCSAFLUSH, &newtio);
    if (rc) {
	perror ("tcsetattr (0, TCSAFLUSH, &newtio)");
	return 12;
    } 
    ...
    rc= tcsetattr (0, TCSAFLUSH, &oldtio);
    if (rc) {
	perror ("tcsetattr (0, TCSAFLUSH, &oldtio)");
	return 12;
    }
    return 0;
PS: also google for nonblocking-mode and/or select/poll
 
Old 02-28-2015, 11:27 AM   #6
Ace Blackwell
Member
 
Registered: Mar 2004
Location: Kentucky, USA
Distribution: SlamD 12.1 / Slack 12.0 ~ 14.2_64
Posts: 345

Original Poster
Rep: Reputation: 54
Thanks for the input,

genss, from what I can tell read() is designed for file reading. I suppose you could change your input to be from file to keyboard somehow,but not sure if the keyboard buffer includes EOF

NevermTeve. That looks like some hardcore coding for my abilities, but will investigate. I may have led us a stray. Reading the buffer isn't important to me. I just want to empty (ignore it) until I'm ready for the next player move. I was thinking if i could "getch" until empty, that might work. the only problem is once empty the program stops. I have seen some talk of nonblocking and polling, maybe that's a direction to take. I'll look into it.

thanks again

Ace
 
Old 02-28-2015, 11:55 AM   #7
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,862
Blog Entries: 1

Rep: Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869Reputation: 1869
In Unix, this thing is called 'teletype' or 'tty' or 'terminal, and it is treated as a file, so 'read' is perfectly ok. Still you should check if your standard input is a terminal, see 'isatty'
By default, your standard input is in 'blocking mode' and works line-buffered. For games, one would prefer non-buffered mode (read keystrokes individually), and also might want to switch to non-blocking mode.

For a start, read this: Low-Level Terminal Interface

Last edited by NevemTeve; 02-28-2015 at 11:57 AM.
 
Old 02-28-2015, 11:57 AM   #8
Ace Blackwell
Member
 
Registered: Mar 2004
Location: Kentucky, USA
Distribution: SlamD 12.1 / Slack 12.0 ~ 14.2_64
Posts: 345

Original Poster
Rep: Reputation: 54
Well I got it solved. It appears Allegro has a way to clear the buffer. Which ironically their clear_keybuf() command doesn't do very well. There is a command called keypressed(). It doesn't wait for a key hit, it just reads whats in the buffer. It returns Ascii code for any keys and FALSE if empty. Allegro also has a readkey() function that does require a key input and will wait if there aren't any. I put the two in a while loop.


While(keypressed()) // cycles until no keys are left and then moves on
readkey(); // "gets" the keys as read thus emptying the buffer.


Sorry for the trouble as I had the solution at my finger tips the whole time. Thanks for all the input

[Edit] I did have one quick question, if you use a non buffered mode, would the program only see one key? The first one hit and ignore any repeats / random keystrokes? That might be a better long term way of game programming.

Ace

Last edited by Ace Blackwell; 02-28-2015 at 12:04 PM. Reason: One more thing....
 
Old 02-28-2015, 12:14 PM   #9
genss
Member
 
Registered: Nov 2013
Posts: 741

Rep: Reputation: Disabled
Quote:
Originally Posted by Ace Blackwell View Post
genss, from what I can tell read() is designed for file reading. I suppose you could change your input to be from file to keyboard somehow,but not sure if the keyboard buffer includes EOF
file descriptor 0 is stdin (1 stdout, 2 stderr)
i think it's the same on windows too (it's standard POSIX)
 
Old 02-28-2015, 12:52 PM   #10
Ace Blackwell
Member
 
Registered: Mar 2004
Location: Kentucky, USA
Distribution: SlamD 12.1 / Slack 12.0 ~ 14.2_64
Posts: 345

Original Poster
Rep: Reputation: 54
Thanks genss. makes sense.

Well I have to apologize to the Allegro team as I've misspoken lol. I ended up being a victim of my own programming novice. Allegro clear_keybuf() seems to work fine for my application.

The realization came when trying to make my work around into it's own function. I noticed that every time I copied my new "clear_kbuffer()" function, the editor would not highlight unless i preceded it with the "int". What I didn't realize was I was just redeclaring it everywhere I posted it. So once I did the initial declaration at the top of the file, I just needed to use the name like any other function. At that time I understood that by using Allegro's "void clear_keybuf();" I was just declaring it all over the place and not actually invoking it. So I went back and removed the "void"s and they worked fine.

I thought it was odd that I could use keypressed() with readkey(); and clear the buffer but that Allegro hadn't thought to do that. LOL.

It's like I've often said. If I think I have discovered an easy solution. It's probably wrong"

Thanks All
Ace
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
How to Clear buffer/cache memory deepak_message Linux - Server 5 01-29-2013 07:56 AM
Ncurses/C how to clear (stdin?) buffer? errigour Programming 1 01-28-2013 08:13 PM
Exceed on Demand client doesn't clear buffer sharky Linux - Software 0 02-03-2010 10:37 AM
Clear Print Buffer? FlameKhan General 2 03-15-2005 02:29 AM
How do I clear less' buffer? hussar Slackware 7 12-24-2004 04:44 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 11:29 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration