I am creating a game in C. I'm not playing it in stdscr, but in a win called basewin. I want, when the user press 'P', to open another window, called pausewin, and pause the game running on basewin. Then, when the user press 'R' for resume, I want to "close" pausewin, and get my game resumes. Especially, I want to see my basewin in the same state I left it before pressing 'P'.
I was thinking I can do that by using window because:
- It would make my code cleaner.
- Windows are pointer on memory space, so I can restore
basewineasily. - It will be a general method to pause any game, without getting trouble with
printwafter quittingpausewin.
But my idea didn't work. I tried this on a simplified game:
#include <ncurses.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdlib.h>
int main() {
/* INIT NCURSES */
initscr();
curs_set(0);
noecho();
/* INIT PAUSE WIN */
WINDOW *pausewin = newwin(LINES/3, COLS/3,LINES/3, COLS/3);
keypad(pausewin,TRUE);
int cMax_pause, lMax_pause; getmaxyx(pausewin,lMax_pause, cMax_pause);
box(pausewin,0,0);
mvwprintw(pausewin,1,cMax_pause/2 -5,"PAUSE WIN");
mvwprintw(pausewin,lMax_pause/2, cMax_pause/3-4, "[R]ESUME");
mvwprintw(pausewin,lMax_pause/2, 2*cMax_pause/3-3, "[Q]UIT");
/* INIT BASE WIN */
WINDOW *basewin = newwin(LINES, COLS/2, 0, COLS/4);
keypad(basewin,TRUE);
int lMax, cMax; getmaxyx(basewin, lMax, cMax);
box(basewin,0,0);
mvwprintw(basewin,0,2, "[P]AUSE");
mvwprintw(basewin,1,cMax/2 -4,"BASE WIN");
/* INIT VAR */
bool loop = true;
bool pause = false;
int ch,chp;
/* INIT VARS PLAYER */
int pline = lMax/2;
int pcol = cMax/2;
char pch[2] ; pch[0] = 'M';
/* AFFICHAGE BASE WIN : PRE-LOOP */
wrefresh(basewin);
/* "GAME" LOOP */
while(loop){
ch = wgetch(basewin);
switch(ch){
case 'p': /* On met le jeu en pause */
case 'P':
pause = true;
break;
case KEY_LEFT: /* Sinon deplacement */
pcol -= 1;
break;
case KEY_RIGHT:
pcol += 1;
break;
case KEY_UP:
pline -= 1;
break;
case KEY_DOWN:
pline += 1;
break;
default:
break;
}
if (pause){
wrefresh(pausewin); // HERE IS THE PLACE I HAVE MY PROBLEM
while(pause){
chp = wgetch(pausewin);
switch (chp){
case 'q':
case 'Q':
pause = false;
loop = false;
break;
case 'r':
case 'R':
pause = false;
wrefresh(basewin); // HERE TOO
break;
default:
break;
}
}
}
else{
mvwprintw(basewin,pline,pcol,pch);
}
wrefresh(basewin);
}
delwin(pausewin);
delwin(basewin);
endwin();
return EXIT_SUCCESS;
}
I have a relatively good comprehension of ncurses manual, but I can't get this working.
I tried to solve that with a tempwin, but it work one time and then never print pausewin again.
I also tried to use overwrite() but it doesn't really look like the good way to solve that.
A very simple approach would be to call
touchwinto indicate that the entire window should be redrawn to the screen.(Note that
wgetch(pausewin)implieswrefresh(pausewin)when the window has been modified [in this case marked as such bytouchwin], otherwisewrefreshmust be called to actually produce output.wrefresh(basewin)is called at the bottom of the main loop, regardless of the pause.)