Commit the first version of the curses interface.
[super-star-trek.git] / io.c
1 #include <stdio.h>
2 #include <termios.h>
3 #include <curses.h>
4 #include <signal.h>
5 #include <ctype.h>
6 #include <stdarg.h>
7 #ifdef MSDOS
8 #include <dos.h>
9 #endif
10 #include <time.h>
11
12 #include "sst.h"
13
14 static int linecount;   /* for paging */
15 static int screenheight = 24, screenwidth = 80;
16 static int curses = FALSE;
17
18 static void outro(int sig) {
19 /* wrap up, either normally or due to signal */
20     if (curses) {
21         clear();
22         (void)refresh();
23         (void)resetterm();
24         //(void)echo();
25         (void)endwin();
26     }
27 }
28
29 static void fastexit(int sig) {
30     outro(sig);
31     putchar('\n');
32     exit(0);
33 }
34
35 void iostart(int usecurses) {
36         (void) signal(SIGINT, fastexit);
37         (void) signal(SIGINT, fastexit);
38 #ifdef SIGIOT
39         (void) signal(SIGIOT,fastexit);         /* for assert(3) */
40 #endif /* SIGIOT */
41         if(signal(SIGQUIT,SIG_IGN) != SIG_IGN)
42             (void)signal(SIGQUIT,fastexit);
43
44         if (curses = usecurses) {
45                 (void)initscr();
46 #ifdef KEY_MIN
47                 keypad(stdscr, TRUE);
48 #endif /* KEY_MIN */
49                 (void)saveterm();
50                 (void)nonl();
51                 (void)cbreak();
52                 //(void)noecho();
53                 scrollok(stdscr, TRUE);
54                 getmaxyx(stdscr, screenheight, screenwidth);
55         } else {
56                 char *LINES = getenv("LINES");
57                 if (LINES)
58                     screenheight = atoi(LINES);
59         }
60 }
61
62 void ioend(void) {
63     outro(0);
64 }
65
66 void clearscreen(void) {
67         /* Somehow we need to clear the screen */
68 #ifdef __BORLANDC__
69         extern void clrscr(void);
70         clrscr();
71 #else
72         if (curses) {
73             wclear(stdscr);
74             wrefresh(stdscr);
75         } else {
76                 // proutn("\033[2J"); /* Hope for an ANSI display */
77                 /* much more in that old-TTY spirit to just throw linefeeds */
78                 int i;
79                 for (i = 0; i < screenheight; i++)
80                     putchar('\n');
81         }
82 #endif
83 }
84
85 void pause(int i) {
86     char buf[BUFSIZ], *prompt;
87         if (i==1) {
88                 if (skill > 2)
89                         prompt = "[ANOUNCEMENT ARRIVING...]";
90                 else
91                         prompt = "[IMPORTANT ANNOUNCEMENT ARRIVING -- PRESS ENTER TO CONTINUE]";
92         }
93         else {
94                 if (skill > 2)
95                         prompt = "[CONTINUE?]";
96                 else
97                         prompt = "[PRESS ENTER TO CONTINUE]";
98
99         }
100         if (curses) {
101                 waddch('\n');
102                 waddstr(stdscr, prompt);
103                 wgetnstr(stdscr, buf, sizeof(buf));
104                 wclear(stdscr);
105                 wrefresh(stdscr);
106         } else {
107                 putchar('\n');
108                 prout(prompt);
109                 fgets(buf, sizeof(buf), stdin);
110                 if (i != 0) {
111                         clearscreen();
112                 }
113                 linecount = 0;
114         }
115 }
116
117
118 void skip(int i) {
119     while (i-- > 0) {
120         if (curses) {
121             int y, x;
122             getyx(stdscr, y, x);
123             if (y == screenheight-1)
124                 pause(0);
125             else
126                 waddch(stdscr, '\n');
127         } else {
128             linecount++;
129             if (linecount >= screenheight)
130                 pause(0);
131             else
132                 putchar('\n');
133         }
134     }
135 }
136
137 void proutn(char *fmt, ...) {
138     va_list ap;
139     va_start(ap, fmt);
140     if (curses) {
141         vw_printw(stdscr, fmt, ap);
142         wrefresh(stdscr);
143     } else
144         vprintf(fmt, ap);
145     va_end(ap);
146 }
147
148 void prout(char *fmt, ...) {
149     va_list ap;
150     va_start(ap, fmt);
151     if (curses) {
152         vw_printw(stdscr, fmt, ap);
153         wrefresh(stdscr);
154     } else
155         vprintf(fmt, ap);
156     va_end(ap);
157     skip(1);
158 }
159
160 void proutc(char *line) {
161     line[strlen(line)-1] = '\0';
162     if (curses)
163         waddstr(stdscr, line);
164     else
165         fputs(line, stdout);
166     skip(1);
167 }
168
169 void prouts(char *fmt, ...) {
170         clock_t endTime;
171         char *s, buf[BUFSIZ];
172         /* print slowly! */
173         va_list ap;
174         va_start(ap, fmt);
175         vsprintf(buf, fmt, ap);
176         va_end(ap);
177         skip(1);
178         for (s = buf; *s; s++) {
179                 endTime = clock() + CLOCKS_PER_SEC*0.05;
180                 while (clock() < endTime) continue;
181                 if (curses) {
182                     waddch(stdscr, *s);
183                     wrefresh(stdscr);
184                 }
185                 else {
186                     putchar(*s);
187                     fflush(stdout);
188                 }
189         }
190 }
191
192 void getline(char *line, int max)
193 {
194     if (curses) {
195         wgetnstr(stdscr, line, max);
196         wrefresh(stdscr);
197     } else {
198         fgets(line, max, stdin);
199         line[strlen(line)-1] = '\0';
200     }
201 }