/* * * ncursesdemo.c * * REFERENCES * https://tldp.org/HOWTO/pdf/NCURSES-Programming-HOWTO.pdf * * Hyperlinked man page - very useful * https://man.netbsd.org/curses.3 * */ #include #include #include #include int main(int argc, char* argv[ ]) { WINDOW* W = 0; /* Curses Window handle */ int rowLimit, colLimit; /* Num of rows and columns in terminal window */ int playerRow, playerCol; /* Player row-column position */ int deltaRow, deltaCol; /* Change in row-column position based on key input */ /* Initialize ncurses -- you will want to use the following settings */ W = initscr(); /* Determine terminal type and initialize curses data structures */ start_color(); /* Enable use of color with ncurses */ cbreak(); /* Disable line buffering and make char inputs immediately accessible to program */ noecho(); /* Disable echo printing of chars type by user */ nodelay(W, true); /* Make getch( ) a non-blocking call */ keypad(W, true); /* Enable keypad and arrow keys */ curs_set(0); /* Set cursor to be invisible - 0 */ getmaxyx(W, rowLimit, colLimit); /* Query terminal dimensions */ /* Define color pallete foreground-background color pairs */ /* PairID#, Foreground Color, Background Color */ /* Foreground color == Background color ==> solid color block */ init_pair(1, COLOR_BLACK, COLOR_BLACK); /* Black text on Black background */ init_pair(2, COLOR_RED, COLOR_BLACK); /* Red text on Black background */ init_pair(3, COLOR_WHITE, COLOR_BLUE); /* White text on Blue background */ init_pair(4, COLOR_YELLOW, COLOR_YELLOW); /* Yellow text on Yellow background */ /* Draw some obstacle */ attron(COLOR_PAIR(2)); /* Turn on color attribute #2 */ wmove(W, rowLimit/2, colLimit/2); /* Position cursor in middle of terminal window */ waddch(W, '#'); /* Draw # symbol */ attroff(COLOR_PAIR(2)); /* Turn off color attribute #2 */ /* Initialize player movement variables */ playerRow = rowLimit/4; playerCol = colLimit/4; deltaCol = 0; deltaRow = 0; /* Player movement loop */ do { int kb = wgetch(W); /* Grab keypress */ /* Support player movement via WASD, IJKL, and arrow keys */ if (kb == 'a' || kb == 'j' || kb == KEY_LEFT) { /* Move Left */ deltaCol = -1; deltaRow = 0; } else if (kb == 'd' || kb == 'l' || kb == KEY_RIGHT) { /* Move Right */ deltaCol = 1; deltaRow = 0; } else if (kb == 'w' || kb == 'i' || kb == KEY_UP) { /* Move Up */ deltaCol = 0; deltaRow = -1; } else if (kb == 's' || kb == 'k' || kb == KEY_DOWN) { /* Move Down */ deltaCol = 0; deltaRow = 1; } else if (kb == 'q') { /* q to exit player movement loop */ break; }; /* Erase player from current position */ /* An alternate option is to invoke clear() */ /* which erases everything on the screen */ /* If you comment out this code, the player will leave an onscreen trail */ /* */ /* Algorithm: */ /* - Turn on color attribute #1 (solid block of background color) */ /* - Position cursor */ /* - Draw player symbol */ /* - Turn off color attribute #1 */ attron(COLOR_PAIR(1)); wmove(W, playerRow, playerCol); waddch(W, 'P'); attroff(COLOR_PAIR(1)); /* Compute new player position without checking to see if new position is valid */ playerRow = playerRow + deltaRow; playerCol = playerCol + deltaCol; /* Redraw player in new position */ attron(COLOR_PAIR(3)); /* Turn on color attribute #3 */ wmove(W, playerRow, playerCol); /* Position cursor */ waddch(W, 'P'); /* Draw player symbol */ attroff(COLOR_PAIR(3)); /* Turn off color attribute #3 */ /* Zero offsets prior to next key press */ deltaRow = 0; deltaCol = 0; wrefresh(W); /* Refresh ncurses window */ } while (true); /* Repeat until user selects q to quit */ endwin(); /* Terminate ncurses window -- very important */ return 0; }