How do you make RPG-like scrolling text? C++ on Linux - c++

I'm a beginner coder making a simple text 'choose your own adventure' game, but I want it to scroll out the text like an RPG instead of just spitting out the text. How can I do that?

I believe that the ncurses library is exactly what you are looking for. It allows you lower access to the terminal text, to produce things like full screen text, like this:
A tutorial for how to use it can be found here, and you can download version 6.3 here.
It is used in many applications, like GNU nano. A full list of applications using ncurses can be found here.

I'm going to assume you're just supposed to write to a console.
std::string str = "Your text";
for(char& current_char : str) {
std::cout << current_char << std::flush;
sleep(1000);
}
std::cout << std::endl;
The for loop is going to iterate over each character in the string.
It will then output it to cout. std::flush is here to force the output to be update without using std::endl which would return carriage and we don't want that.
sleep will pause for an amount of time in milliseconds, here 1000 milliseconds (1 second). Be careful though; sleep is a Windows function. On Linux, use usleep. If you need it to be cross-platform you should probably use the thread sleeping functions or make something yourself with chrono.
And finally, we use std::endl to return carriage and update the output.

Related

How do I delete the skipped part of the screen after I used "\33[2J\33[H" many times?

I'm writing a terminal game for Windows, and the refresh was quite slow so I asked here for help.
std::cout << "\33[2J\33[H"; // They told me to write this...
system("cls") // ...instead of this
But sending that ASCII escape sequence just makes the terminal "scroll", without deleting anything.
Lets say I really want to delete the old frames sometimes: how should I do it?
Just to make an example, they told me that...
std::cout << '\n'; // This...
std::cout << std::endl; // ...was faster than this
Then I asked what was missing to \n to become equivalent to std::endl, and they told me std::flush.
So my question is: what is missing to \33[2J\33[H to be equivalent to system("cls")?

C++ Console Output Manipulation [duplicate]

This question already has answers here:
C++ Update console output
(4 answers)
Closed 5 years ago.
I'm developing some application in which I want to manipulate some data comming from the embedded system. So, what do I want to do is that I want to display the values which are comming on the same position where they were before, leaving the static text on the same place and not using new line. Being more specific, I want to output my data in form of a table, and in this table on the same positions I want to update that data. There is some analogy in Linux, when in the terminal there is some update of the value(let's say some progress) while the static text remains and only the value is changing.
So, the output should look like this:
Some_data: 0xFFFF
Some_data2: 0xA1B3
Some_data3: 0x1201
So in this case, "Some_data" remains unchanged on the same place, and only the data itself is updated.
Are there maybe some libraries for doing that? What about Windows Console Functions? Also, it would be very nice if it could be made in such a way, in which the console would not flick, like when you clear the console and print something back. Any hints or suggestions? Thanks very much in advance guys!
P.S. There is no need to write the code, I just need some hints or suggestions, with very short examples if possible(but not required).
On a *nix system you have two options.
1) If you want to manipulate the entire console in table form like you ask, then ncurses is the best option. The complete reference can be found here.
As you can see, that package is quite heavyweight and can often be overkill for simple projects, so I often use . ..
2) If you can contain your changing information on a single line, use the backspace escape char \b and then rewrite the information repeatedly to that line
For example, try this . . .
#include <iostream>
#include <chrono>
#include <thread>
using namespace std;
void writeStuff(int d)
{
cout << string(100,'\b') << flush;
cout << "Thing = " << d;
}
int main()
{
cout << "AMAZING GIZMO" << "\n============" << endl;
while(1) {
writeStuff(rand());
this_thread::sleep_for(chrono::milliseconds(250));
}
}
For a real world example, the sox audio console playback command uses this technique to good effect by displaying a bar chart made of console characters to represent the audio playback level in real time.
Of course, you can get more creative with the method shown above if your console supports ANSI escape sequences.

Why does getchar work like a buffer instead of working as expected in real-time

This is my first question on stackoverflow. Pardon me if I haven't searched properly but I do not seem to find an explanation for this. Was just attempting an example from Bjourne Stroustroup's papers. Added my bits to see the array get re-sized as I type the text.
But it doesn't seem to work that way! getchar() simply waits till I am done with entering all the characters and then it will execute the loop. As per the logic, it doesn't actually go into the loop, get a character, perform its actions and then iterate. I am wondering if this is implementation specific, or intended to be like this?
I am on Ubuntu 14.04 LTS using Codeblocks with gcc 4.8.2. The source was in cpp files if that matters.
while(true)
{
int c = getchar();
if(c=='\n' || c==EOF)
{
text[i] = 0;
break;
}
text[i] = c;
if(i == maxsize-1)
{
maxsize = maxsize+maxsize;
text = (char*)realloc(text,maxsize);
if(text == 0) exit(1);
cout << "\n Increasing array size to " << maxsize << endl;
}
i++;
}
The output is as follows:
Array Size is now: 10
Please enter some text: this is some sample text. I would have liked to see the memory being realloced right here, but apparently that's not how it works!
Increasing array size to 20
Increasing array size to 40
Increasing array size to 80
Increasing array size to 160
You have entered: this is some sample text. I would have liked to see the memory being realloced right here, but apparently that's not how it works!
Array Size is now: 160
This has nothing to do with getchar directly. The "problem" is the underlying terminal, which will buffer your Input. The Input is sent to the program after you press enter. In Linux (dunno if there is a way in Windows) you can workaround this by calling
/bin/stty raw
in terminal or by calling
system ("/bin/stty raw");
in your program. This will cause getchar to immediately return the input character to you.
Dont forget to reset the tty behaviour by calling
/bin/stty cooked
when done!
Here is an example (for Linux):
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int main() {
system ("/bin/stty raw");
char c = getchar();
system ("/bin/stty cooked");
return 0;
}
Also have a look at this SO Post: How to avoid press enter with any getchar()
Also, as suggested in the comments, have a look here: http://linux.die.net/man/3/termios especially on the command tcsetattr, which should work cross-platform.
Actually, tcsetattr does not apply to Windows (which is what is commonly referred to in this site as "cross-platform"). However, the question is tagged for Linux, so "cross-platform" is a moot point.
By default the standard input, output and error streams are set to
line-buffered (input)
block-buffered (output)
line-buffered (error)
You can change that using setbuf, but of course will not solve the problem (the answer calls for single-character input). POSIX terminal I/O (termios) lets you change via a system call any of the flags shown using stty. As a rule, you might call stty directly from a script, rarely from a C program.
Reading a single character is a frequently asked question, e.g.,
How can I read single characters from the terminal? (unix-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? (comp.lang.c FAQ)
You could also use ncurses: the filter function is useful for programs that process a command-line (rather than a full-screen application). There is a sample program in ncurses-examples (filter.c) which does this.

Basic terminal output using C++ - Questions

Well, the question may sound a bit too vague but here's 2 things I need to do and I'd definitely need some input on this :
Output something (e.g. using cout) with color (note: My TERM environment variable is set to xterm-color if that makes any difference; also, is there any uniform way to output colored text that's compatible with both pure mac and *nix terminals in general, so that the code is portable)
Output something at the same position on the terminal screen. OK, this may sound confusing too. Let's take a terminal app which simply outputs a progress percentage. It normally won't start a new line for that. The new value is shown at the very same spot. How is this doable? (Being a once Borland Pascal guy from the good old DOS days, the only thing I could think of is something to do with accessing video memory directly... or not?)
So... any ideas?
You probably want to use ncurses library. And ANSI escape codes can also be used for coloring.
1)
You can try Color cout , but that is not protable. I tried (ANSI escape codes) something like
cout << "\033[1;31mbold red text\033[0m\n";
cout << "\33[0;31m" << "Enter Your String here" << "\33[0m" << std::endl ;
You can also look at
How do I output coloured text to a Linux terminal?
2)
Are you looking for something like watch or top like app which are showing output at the same spot.

Adding a status bar to c++ console applications

I am making a linux application using C++ and it will print info out to the console. Parts of the program will take a while to compute and I would like to add a status bar in the console similar to the one used in wget (I put my own depiction below).
%complete[===========> ] eta
What would be the best way to accomplish this goal? Are there any useful libraries that make it easy to add this functionality?
If your program is like wget, that is, it's basically a batch program without the need for a full-screen UI (for which I would recommend ncurses), you can use the trick to print a carriage return (but not line feed) after your line; the next thing you write will overwrite the same line.
Here's a demonstration.
#include <iostream>
#include <unistd.h>
int main(void)
{
for (int i = 0; i < 10; i++) {
std::cout << "Status: " << i << "\r" << std::flush;
sleep(1);
}
std::cout << "Completed.\n";
}
The ncurses library should be useful to you. Or you can write the progress line char by char, using backspaces, calling fflush or std::flush, etc.
A simpler way would just to output dots...
You can use debconf-apt-progress to run a command while displaying a progress line like apt does. Your command needs to report progress over a pipe fd back to debconf-apt-progress. I haven't figured out how to extract this functionality out of debconf-apt-progress yet.