Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sleep() in ncurses application

Tags:

c

sleep

ncurses

I'm trying to make a text animation for an application made in ncurses.

User presses a key, selects a direction and an object in a text grid should move from one cell of the grid to the next in the given direction, waiting 500ms before it moves. The code I used is

while (!checkcollisions(pos_f, input)) { // Checks if it can move to next grid
    pos_f = moveobject(pos_f, input, ".."); // Moves object to next cell
    usleep(50000);
}

But when I execute it, instead of moving, waiting and moving again, it waits a long time, and the object suddenly appears at the final cell of the grid, without showing the animation.

Is this because of how ncurses work? I already tried using other solutions like the select() stalling function.

like image 539
user1002327 Avatar asked Jan 18 '23 04:01

user1002327


2 Answers

You need to call refresh() (before the usleep).


Update: the new pastebin-ed code segments (in several comments) point to the real problem, which is the same one in ncurses-refresh: mixing stdscr (implied by the next two calls) and getch and refresh with newwin and wrefresh.
Update 2: using the full code, plus some hacking, I got it to work (for some value of "work", I'm clearly not calling printmap() correctly, and I made up a bogus "map" file).

Without looking closely, I just changed all occurrences of getch() to wgetch(win.window), all mvprintw calls to mvwprintw (to use that same window), and removed at least one unneeded getch/wgetch. Then the heart of the problem:

                while (!checkcollisions(pos_f, input)) {
-                       pos_f = moveobject(pos_f, input, "..");
-                       // sleep + wrefresh(win.window) doesn't work, neither does refresh()
+                       struct position new_pos = moveobject(pos_f, input, "..");
+                       printmap(pos_f, new_pos);
+                       pos_f = new_pos;
+                       wrefresh(win.window);
+                       fflush(stdout);
+                       usleep(50000);
                }

The above call to printmap is definitely wrong, but still you definitely need to do something in the loop to change what's in win.window (or stdscr or some other window you put up or whatever); and then you need to force it to refresh, and force the output to stdout with fflush(stdout), before sleeping.

like image 114
torek Avatar answered Jan 29 '23 02:01

torek


Try something like

while (!checkcollisions(pos_f, input)) { // Checks if it can move to next grid
    pos_f = moveobject(pos_f, input, ".."); // Moves object to next cell
    refresh();
    napms(200);
}
like image 31
Duck Avatar answered Jan 29 '23 00:01

Duck