diff --git a/src/Makefile.am b/src/Makefile.am index 6cd625a..e63a5ed 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -32,6 +32,7 @@ bin_PROGRAMS = trader trader_SOURCES = \ trader.c trader.h \ globals.c globals.h \ + intf.c intf.h \ utils.c utils.h \ system.h diff --git a/src/intf.c b/src/intf.c index 3fc955c..916a01b 100644 --- a/src/intf.c +++ b/src/intf.c @@ -30,3 +30,132 @@ #include "system.h" #include "intf.h" +#include "utils.h" + + +/************************************************************************ +* Basic text input/output function definitions * +************************************************************************/ + + +/*----------------------------------------------------------------------- + Function: init_screen - Initialise the screen (terminal) + Arguments: (none) + Returns: (nothing) + + This function initialises the input (keyboard) and output (screen) + using the Curses library. +*/ + +void init_screen (void) +{ + initscr(); + + if ((COLS < MIN_COLUMNS) || (LINES < MIN_LINES)) { + err_exit("terminal size is too small (%d x %d required)", + MIN_COLUMNS, MIN_LINES); + } + + noecho(); + curs_set(CURS_INVISIBLE); + raw(); + + if (has_colors()) { + start_color(); + + init_pair(WHITE_ON_BLACK, COLOR_WHITE, COLOR_BLACK); + init_pair(WHITE_ON_BLUE, COLOR_WHITE, COLOR_BLUE); + init_pair(YELLOW_ON_CYAN, COLOR_YELLOW, COLOR_CYAN); + init_pair(WHITE_ON_RED, COLOR_WHITE, COLOR_RED); + init_pair(BLACK_ON_WHITE, COLOR_BLACK, COLOR_WHITE); + + bkgd(COLOR_PAIR(WHITE_ON_BLACK)); + } + + clear(); + move(0, 0); + + attrset(has_colors() ? COLOR_PAIR(YELLOW_ON_CYAN) | A_BOLD : + A_REVERSE | A_BOLD); + center(stdscr, true, PACKAGE_NAME); + attrset(A_NORMAL); + + refresh(); +} + + +/*----------------------------------------------------------------------- + Function: end_screen - End using the screen (terminal) + Arguments: (none) + Returns: (nothing) + + This function closes the input (keyboard) and output (screen) using the + Curses library. It makes sure the screen is cleared before doing so. +*/ + +void end_screen (void) +{ + clear(); + refresh(); + endwin(); +} + + +/*----------------------------------------------------------------------- + Function: center - Centre a string on the current line + Arguments: win - Window to use + clrline - True to print spaces on both sides of line + format - printf()-like format string + ... - printf()-like arguments + Returns: int - Return code from wprintw() + + This function prints a string (formated with wprintw(format, ...)) in + the centre of the current line in the window win. If clrline is TRUE, + spaces are printed before and after the line to make sure the current + attributes are set. The cursor is then moved to the start of the next + line, or the start of the current line (if already on the last line of + the screen). Please note that wrefresh() is NOT called. +*/ + +int center (WINDOW *win, const bool clrline, const char *format, ...) +{ + va_list args; + + int len, ret; + int y, x, maxy, maxx; + int fill; + + char *buf = malloc(OUTBUFSIZE); + if (buf == NULL) { + err_exit("out of memory"); + } + + va_start(args, format); + len = vsnprintf(buf, OUTBUFSIZE, format, args); + if (len < 0) { + return ERR; + } + + getyx(win, y, x); + getmaxyx(win, maxy, maxx); + + fill = (maxx - len) / 2; + + if (clrline) { + wmove(win, y, 0); + if (fill > 0) { + wprintw(win, "%*c", fill, ' '); + } + ret = wprintw(win, "%s", buf); + if (maxx - len - fill > 0) { + wprintw(win, "%*c", maxx - len - fill, ' '); + } + } else { + ret = mvwprintw(win, y, fill > 0 ? fill : 0, "%s", buf); + } + + wmove(win, (y + 1 >= maxy ? y : y + 1), 0); + + free(buf); + return ret; +} diff --git a/src/intf.h b/src/intf.h index af1d82f..6a44ab0 100644 --- a/src/intf.h +++ b/src/intf.h @@ -32,6 +32,9 @@ #define included_INTF_H 1 +#include "system.h" + + /************************************************************************ * Constants and type declarations * ************************************************************************/ @@ -39,5 +42,29 @@ #define MIN_COLUMNS (80) /* Minimum number of columns in terminal */ #define MIN_LINES (24) /* Minimum number of lines in terminal */ +#define OUTBUFSIZE (1024) /* Output string buffer size */ + + +// Colour pairs used in Star Traders +enum color_pairs { + DEFAULT_COLORS = 0, + WHITE_ON_BLACK, + WHITE_ON_BLUE, + WHITE_ON_RED, + YELLOW_ON_CYAN, + BLACK_ON_WHITE, +}; + + +/************************************************************************ +* Basic text input/output function declarations * +************************************************************************/ + +extern void init_screen (void); +extern void end_screen (void); + +extern int center (WINDOW *win, const bool clrline, const char *format, ...) + __attribute__((format (printf, 3, 4))); + #endif /* included_INTF_H */ diff --git a/src/trader.c b/src/trader.c index 46171d3..8727fdc 100644 --- a/src/trader.c +++ b/src/trader.c @@ -62,21 +62,7 @@ int main (int argc, char *argv[]) // Testing... - initscr(); - noecho(); - curs_set(CURS_INVISIBLE); - timeout(-1); - keypad(stdscr, true); - raw(); - - if (has_colors() == true) { - start_color(); - init_pair(1, COLOR_WHITE, COLOR_BLACK); - init_pair(2, COLOR_WHITE, COLOR_BLUE); - bkgd(COLOR_PAIR(1)); - } - clear(); - move(0, 0); + init_screen(); printw("Program name: %s\n", program_name()); printw("Home directory: %s\n", home_directory()); @@ -93,16 +79,20 @@ int main (int argc, char *argv[]) WINDOW *w1, *w2; w1 = newwin(0, 0, 7, 0); - wbkgd(w1, COLOR_PAIR(2)); + wbkgd(w1, COLOR_PAIR(WHITE_ON_BLUE)); box(w1, 0, 0); wrefresh(w1); w2 = newwin(LINES - 9, COLS - 8, 8, 4); - wbkgd(w2, COLOR_PAIR(2)); + wbkgd(w2, COLOR_PAIR(WHITE_ON_BLUE)); + + wattrset(w2, has_colors() ? COLOR_PAIR(WHITE_ON_RED) | A_BOLD : A_REVERSE | A_BOLD); + center(w2, true, "Type some keys (^C to exit):"); + wattrset(w2, A_NORMAL); - mvwprintw(w2, 0, 0, "Type some keys (^C to exit):\n\n"); wrefresh(w2); + scrollok(w2, true); keypad(w2, true); meta(w2, true); wtimeout(w2, -1); @@ -124,9 +114,7 @@ int main (int argc, char *argv[]) wrefresh(w2); } - clear(); - refresh(); - endwin(); + end_screen(); return EXIT_SUCCESS; } diff --git a/src/trader.h b/src/trader.h index fc07637..675b2ec 100644 --- a/src/trader.h +++ b/src/trader.h @@ -45,6 +45,7 @@ #include "system.h" #include "globals.h" +#include "intf.h" #include "utils.h" diff --git a/src/utils.c b/src/utils.c index 79112bb..ae288cd 100644 --- a/src/utils.c +++ b/src/utils.c @@ -30,6 +30,7 @@ #include "system.h" #include "utils.h" +#include "intf.h" /************************************************************************ @@ -218,9 +219,9 @@ char *intto_game_filename (const int game_num) /*----------------------------------------------------------------------- - Function: err_exit - Print an error and exit - Arguments: format - printf()-like format of error message - ... - printf()-like arguments + Function: err_exit - Print an error and exit + Arguments: format - printf()-like format of error message + ... - printf()-like arguments Returns: (does not return) This function closes all curses windows, prints the name of the program @@ -238,9 +239,7 @@ void err_exit (const char *format, ...) va_list args; - clear(); - refresh(); - endwin(); + end_screen(); fprintf(stderr, "%s: ", program_name()); va_start(args, format); @@ -253,9 +252,9 @@ void err_exit (const char *format, ...) /*----------------------------------------------------------------------- - Function: errno_exit - Print an error (using errno) and exit - Arguments: format - printf()-like format of error message - ... - printf()-like arguments + Function: errno_exit - Print an error (using errno) and exit + Arguments: format - printf()-like format of error message + ... - printf()-like arguments Returns: (does not return) This function closes all curses windows, prints the name of the @@ -273,9 +272,7 @@ void errno_exit (const char *format, ...) int saved_errno = errno; - clear(); - refresh(); - endwin(); + end_screen(); fprintf(stderr, "%s: ", program_name()); if (format != NULL) {