I want to make a snake game without using graphics. The problem is that the snake will have to change direction when pressing the corresponding button. How do I make my program respond to my button without needing to scan a character. Because, if I add an instruction such as scanf() or getch(), my snake would stop moving and that's not how a snake game works.
The implementation is dependent on the system you want to use. Windows has other functions to check for keypresses than Linux. For Windows you can use Console.KeyAvailable. For Linux you can best look at a console library like ncurses.
On every system it is possible to have getchar()(or similar functions) non-blocking. On Unix system, the solution is to set the terminal (tty) in raw mode. To simplify your life, you can also use some library to do it for you, a lib like curses or one of its variants. Such a lib will also help you to draw chars on screen exactly as you may dream for an ASCII snake program.
There is also different solutions on Windows system.
You can also use multi-threading. One thread blocking on terminal I/Os and transmitting read chars to the other moving the snake.
Related
I am dealing with an issue in Ubuntu. I want to get current keyboard cursor position in terminal via Gcc
any assist...
"Terminal" is a program, or more accurately a description of a large class of programs, which implements a graphical interface emulating an external terminal (which would have been connected to your computer via a serial cable, or in some similar fashion). Your program communicates with the terminal emulator through a kind of bidirectional pipe (a "pseudoterminal") implemented by the operating system; to your program it looks like a pair of ordinary streams (stdin and stdout).
Linux itself has a terminal emulator, called "the console", which can be used instead of a window manager. Few programmers use it these days, but it's still there if you want to experiment. The console is a "terminal" (and there are usually several of them which you can switch between using a control+function key). As you might expect from the words "terminal" and "pseudoterminal", these basically look the same to your application.
There are a ton of details, which I'm skipping over because it would take a book to describe the whole thing.
The only connection between your program and the terminal (or pseudoterminal) is that you can send it a stream of characters, and you can receive a stream of characters from it. There is no other communication. There's no hidden operating system interface, because the terminal emulator is not part of the operating system. It's not even part of the window manager. It's just another userland application running without special privileges, just like your application.
You often want to do things other than just send characters to the output device. Maybe you want to clear the screen, or move the cursor to another location, or change the colour of the text or the background. All of these things are done by sending specially coded sequences interspersed with the text you're displaying. The operating system doesn't mediate or verify these sequences, and there's no definitive standard for how the terminal emulator should interpret them, but there is common framework which most terminal emulators conform to, to some extent, which makes it possible to actually write code which doesn't need to know exactly which terminal emulator is being used at the moment. The terminfo library is commonly used to describe the available terminals; by convention, the environment variable TERM contains the name of the relevant terminfo configuration, and that configuration can be used to create concrete control sequence strings suitable for the configured terminal [Note 1].
Now let's get back to your initial question: "how do I find out the current cursor location?" That's one of a small number of possible queries, which are also implemented as control sequences. Specifically, you send the terminal a control sequnce which asks it where the cursor is (usually the four characters \x1B[6n) and the terminal eventually replies with a control sequence which might look something like \x1B12,7R meaning that the cursor was on row 12 at column 7 at the moment that the control sequence was sent [Note 2]. So you could use terminfo to help you send the query and then attempt to parse the reply when it comes.
Note that the response is not synchronous with the query, since the user could be typing while the query is sent. (However, the response is sent as a contiguous sequence.) So part of the parsing process is disentangling the user input from the query response.
My guess is that you don't actually want to do all that work. In most cases, if you want to write a console application which does something less boring than just write output sequentially to a terminal window, you should use ncurses (also maintained by Thomas Dickey) or some other similar library. Ncurses takes full responsibility for maintaining the console image, jumping through the necessary hoops to communicate with the terminal emulator; one of its features is to keep track of the current cursor position [Note 3].
Another option, if you are only trying to provide better line editing and tab completion, is to use the GNU Readline library, or similar interfaces available for other operating systems.
Notes
This might or might not be the terminal you're actually using, since TERM is just an environment variable. You could set it yourself if you wanted it.
I took those codes from man 4 console_codes; another good source of information is Thomas Dickey's terse list of code sequences understood by xterm.
As far as I know, Ncurses does not use the cursor-position query to figure out where the cursor is on the screen. It maintains its own copy of the screen being displayed, which includes the current cursor position. You can use the macro getyx() to ask for what it considers the current cursor position.
Hello I am new to C programming but I am making a menu for a game. I have a fish in ascii art displayed and it gets moved one character over every .5 secs. I accomplish this by a simple loop and it keeps on going across the screen then when it reaches the end, the fish is cleared and then it gets repeated again. Now while this animation is going on I would like to prompt the user for an input, however when I do that with getchar or scanf for example the fish loop waits until I press something and the animation stops until I press a key. Coould someone please shed some light on my problem??
Thank-you
You can't do this with any of the standard input methods. You're going to either have to use something like ncurses, or put the terminal into raw mode and do some pretty fancy manipulations. I have no idea what platform you're on, but raw mode is difficult under Linux, and even harder under Windows, so I'd stick with a library if you can.
Welcome to the world of Threads.
To understand threads think of how your computer works. If your computer ran without threads, you would not be able to run multiple applications at the same time. Threads allow for multiple parts of a program or interface to run at the same time without depending on eachother.
In your case, you will want a thread for the input and a separate thread for the animation. Thus allowing both to run separately.
Is there a C function that doesn't wait for input but if there is one, it detects it?
What I'm trying to do here is continue a loop endlessly until any key is pressed.
I'm a newbie, and all the input functions I've learned so far waits for the user to input something..
I hope I'm clear, although if I'm not I'm happy to post the code..
WIndows kbhit( ) does exactly this non-blocking keyboard char-ready check, and there's a kbhit( ) for Linux over here
Since nobody's stated it clearly....
The important thing to note is that the standard library provided by C does not provide the capability you're looking for. Achieving it, then, requires the use of third party libraries and/or special knowledge about the operating system you're using.
Typically, you'll have some of those third-party libraries available. If you were using Visual Studio, for example, you would be able to use http://msdn.microsoft.com/en-us/library/58w7c94c(v=VS.100).aspx. I'm not sure what's available to you with your setup.
you should use select or poll
You might also want to check signal() if all you need is a way to stop the loop and run your end of the program function.
It depends what you exactly want to do, but in general:
A) You keep your program single-threaded and check input through a non-blocking input read.
B) You spawn a different thread that will handle the input and communicate the results back to the main thread.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Simulating a BlueScreen
Hello SO,
I'm trying to induce a BSOD somehow inline in my C code. My main background is Java but have been fortunate to have been tutored by some coworkers and am helping out with a simple C utility.
There's two sections:
1) write to a hard drive (I finished this, wasn't too bad)
2) Force a blue screen immediately after sending the last SCSI write command
You can probably tell the intent of the program easily now.
I've tried two things so far:
1) Externally calling pskill.exe (windows utility) to manually crash csrss.exe which forces a blue screen every time since csrss.exe is a required service of windows. This doesn't work because it's not fast enough. The call to the external utility takes too long so we need inline code to compile with the write to disk section in order to crash the computer fast enough.
2) Use the windows.h API to call TerminateProcess: http://msdn.microsoft.com/en-us/library/ms686714%28v=vs.85%29.aspx
The problem is this function cannot end system related tasks so it can't close csrss.exe
This has left me short on options. I need a clever way to kill csrss.exe in our own native code without an external call or a clever way to force a blue screen in internal code OR I need a very simple driver I can load and call which will blue screen the machine immediately. Could be as short as 1 line calling KeBugCheck http://msdn.microsoft.com/en-us/library/ff551948.aspx
Thanks for your time and input.
Your best bet is to write a trivial driver that calls KeBugCheck() as you yourself suggest. You can take the most simple example from the Windows Driver Kit and cut it down to the barebones.
I recomment Not My Fault from sysinternals.
Here are two ways to get a blue screen when running in kernel mode:
Dereference a null pointer, or
Divide by zero
How do i get an input from keyboard, without pressing 'return' in C / Mac Os
On Unix-like systems with terminals (I suppose that MacOS X qualifies), then you need to set the terminal to so-called "cbreak" mode. The point is that the terminal is keeping the data until "return" is pressed, so that there is nothing your C code can do, unless it instructs the terminal not to do such buffering. This is often called "cbreak mode" and involves the tcsetattr() function.
A bit of googling found this code which seems fine. Once the terminal is in cbreak mode, you will be able to read data as it comes with standard getchar() or fgetc() calls.
From the comp.lang.c FAQ:
How can I read a single character from the keyboard without waiting for the RETURN key? How can I stop characters from being echoed on the screen as they're typed?
If you have to handle the details yourself, use a curses variant. If it is available, prefer "ncurses" over "curses". Note that some keys are "Meta" keys which really just modify the base key codes. There are several "modes" for reading key input, which range from "cooked", through "partially cooked", to "raw". Each mode has its own peculiarities, read the documentation carefully.
Sometimes it's better to use existing key handling code from various game programming libraries, I've heard of some good results using SDL's key scanning loops. That was a while back, so perhaps newer (and better) toolkits exist.