Correct the prompt-setting.
[super-star-trek.git] / io.c
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <termios.h>
4 #include <curses.h>
5 #include <signal.h>
6 #include <ctype.h>
7 #include <stdarg.h>
8 #include <time.h>
9
10 #include "sst.h"
11 #include "sstlinux.h"
12
13 static int linecount;   /* for paging */
14 static int curses = TRUE;
15
16 WINDOW *curwnd;
17
18 static void outro(void)
19 /* wrap up, either normally or due to signal */
20 {
21     if (curses) {
22         clear();
23         curs_set(1);
24         (void)refresh();
25         (void)resetterm();
26         //(void)echo();
27         (void)endwin();
28         putchar('\n');
29     }
30 }
31
32 void iostart(int usecurses) 
33 {
34     if ((curses = usecurses)) {
35
36         if (atexit(outro)){
37             fprintf(stderr,"Unable to register outro(), exiting...\n");
38             exit(1);
39         }
40         (void)initscr();
41 #ifdef KEY_MIN
42         keypad(stdscr, TRUE);
43 #endif /* KEY_MIN */
44         (void)saveterm();
45         (void)nonl();
46         (void)cbreak();
47 #ifdef FOO
48         {
49         int background = COLOR_WHITE;
50         start_color();
51         init_pair(COLOR_BLACK, COLOR_BLACK, background);
52         init_pair(COLOR_GREEN, COLOR_GREEN, background);
53         init_pair(COLOR_RED, COLOR_RED, background);
54         init_pair(COLOR_CYAN, COLOR_CYAN, background);
55         init_pair(COLOR_WHITE, COLOR_WHITE, background);
56         init_pair(COLOR_MAGENTA, COLOR_MAGENTA, background);
57         init_pair(COLOR_BLUE, COLOR_BLUE, background);
58         init_pair(COLOR_YELLOW, COLOR_YELLOW, background);
59         }
60 #endif /* A_COLOR */
61         //(void)noecho();
62         fullscreen_window = stdscr;
63         srscan_window     = newwin(12, 25, 0,       0);
64         REPORT_WINDOW     = newwin(10, 0,  1,       25);
65         lrscan_window     = newwin(10, 0,  0,       64); 
66         message_window      = newwin(0,  0,  12,      0);
67         prompt_window     = newwin(1,  0,  LINES-1, 0); 
68         scrollok(message_window, TRUE);
69         setwnd(fullscreen_window);
70         textcolor(DEFAULT);
71     }
72 }
73
74
75 void waitfor(void)
76 /* wait for user action -- OK to do nothing if on a TTY */
77 {
78     if (curses)
79         getch();
80 }
81
82 void pause_game(int i) 
83 {
84     char *prompt;
85     char buf[BUFSIZ];
86     if (i==1) {
87         if (skill > 2)
88             prompt = "[ANOUNCEMENT ARRIVING...]";
89         else
90             prompt = "[IMPORTANT ANNOUNCEMENT ARRIVING -- PRESS ENTER TO CONTINUE]";
91     }
92     else {
93         if (skill > 2)
94             prompt = "[CONTINUE?]";
95         else
96             prompt = "[PRESS ENTER TO CONTINUE]";
97
98     }
99     if (curses) {
100         drawmaps(0);
101         setwnd(prompt_window);
102         wclear(prompt_window);
103         waddstr(prompt_window, prompt);
104         wgetnstr(prompt_window, buf, sizeof(buf));
105         wclear(prompt_window);
106         wrefresh(prompt_window);
107         setwnd(message_window);
108     } else {
109         putchar('\n');
110         proutn(prompt);
111         fgets(buf, sizeof(buf), stdin);
112         if (i != 0) {
113             int j;
114             for (j = 0; j < 24; j++)
115                 putchar('\n');
116         }
117         linecount = 0;
118     }
119 }
120
121
122 void skip(int i) 
123 {
124     while (i-- > 0) {
125         if (curses) {
126             proutn("\n\r");
127         } else {
128             linecount++;
129             if (linecount >= 24)
130                 pause_game(0);
131             else
132                 putchar('\n');
133         }
134     }
135 }
136
137 static void vproutn(char *fmt, va_list ap) 
138 {
139     if (curses) {
140         vwprintw(curwnd, fmt, ap);
141         wrefresh(curwnd);
142     }
143     else
144         vprintf(fmt, ap);
145 }
146
147 void proutn(char *fmt, ...) 
148 {
149     va_list ap;
150     va_start(ap, fmt);
151     vproutn(fmt, ap);
152     va_end(ap);
153 }
154
155 void prout(char *fmt, ...) 
156 {
157     va_list ap;
158     va_start(ap, fmt);
159     vproutn(fmt, ap);
160     va_end(ap);
161     skip(1);
162 }
163
164 void prouts(char *fmt, ...) 
165 /* print slowly! */
166 {
167     clock_t endTime;
168     char *s, buf[BUFSIZ];
169     va_list ap;
170     va_start(ap, fmt);
171     vsprintf(buf, fmt, ap);
172     va_end(ap);
173     skip(1);
174     for (s = buf; *s; s++) {
175         endTime = clock() + CLOCKS_PER_SEC*0.05;
176         while (clock() < endTime) continue;
177         if (curses) {
178             waddch(curwnd, *s);
179             wrefresh(curwnd);
180         }
181         else {
182             putchar(*s);
183             fflush(stdout);
184         }
185     }
186 }
187
188 void cgetline(char *line, int max)
189 {
190     if (curses) {
191         wgetnstr(curwnd, line, max);
192         strcat(line, "\n");
193         wrefresh(curwnd);
194     } else {
195         fgets(line, max, stdin);
196     }
197     line[strlen(line)-1] = '\0';
198 }
199
200 void setwnd(WINDOW *wnd)
201 /* change windows -- OK for this to be a no-op in tty mode */
202 {
203     if (curses) {
204      curwnd=wnd;
205      curs_set(wnd == fullscreen_window || wnd == message_window || wnd == prompt_window);
206     }
207 }
208
209 void clreol (void)
210 /* clear to end of line -- can be a no-op in tty mode */
211 {
212    if (curses) {
213        wclrtoeol(curwnd);
214        wrefresh(curwnd);
215    }
216 }
217
218 void clrscr (void)
219 /* clear screen -- can be a no-op in tty mode */
220 {
221    if (curses) {
222        wclear(curwnd);
223        wmove(curwnd,0,0);
224        wrefresh(curwnd);
225    }
226 }
227
228 void textcolor (int color)
229 {
230     if (curses) {
231         wattroff(curwnd, A_REVERSE);
232 #ifdef FOO
233         switch(color) {
234         case DEFAULT: 
235             wattrset(curwnd, 0);
236             break;
237         case BLACK: 
238             wattron(curwnd, COLOR_PAIR(BLACK));
239             break;
240         case BLUE: 
241             wattron(curwnd, COLOR_PAIR(BLUE));
242             break;
243         case GREEN: 
244             wattron(curwnd, COLOR_PAIR(GREEN));
245             break;
246         case CYAN: 
247             wattron(curwnd, COLOR_PAIR(CYAN));
248             break;
249         case RED: 
250             wattron(curwnd, COLOR_PAIR(RED));
251             break;
252         case MAGENTA: 
253             wattron(curwnd, COLOR_PAIR(MAGENTA));
254             break;
255         case BROWN: 
256             wattron(curwnd, COLOR_PAIR(YELLOW));
257             break;
258         case LIGHTGRAY: 
259             wattron(curwnd, COLOR_PAIR(WHITE));
260             break;
261         case DARKGRAY: 
262             wattron(curwnd, COLOR_PAIR(BLACK) | A_BOLD);
263             break;
264         case LIGHTBLUE: 
265             wattron(curwnd, COLOR_PAIR(BLUE) | A_BOLD);
266             break;
267         case LIGHTGREEN: 
268             wattron(curwnd, COLOR_PAIR(GREEN) | A_BOLD);
269             break;
270         case LIGHTCYAN: 
271             wattron(curwnd, COLOR_PAIR(CYAN) | A_BOLD);
272             break;
273         case LIGHTRED: 
274             wattron(curwnd, COLOR_PAIR(RED) | A_BOLD);
275             break;
276         case LIGHTMAGENTA: 
277             wattron(curwnd, COLOR_PAIR(MAGENTA) | A_BOLD);
278             break;
279         case YELLOW: 
280             wattron(curwnd, COLOR_PAIR(YELLOW) | A_BOLD);
281             break;
282         case WHITE:
283             wattron(curwnd, COLOR_PAIR(WHITE) | A_BOLD);
284             break;
285         }
286 #endif /* FOO */
287     }
288 }
289
290 void highvideo (void)
291 {
292     if (curses) {
293         wattron(curwnd, A_REVERSE);
294     }
295 }
296  
297 void commandhook(char *cmd, int before) {
298 }
299
300 /*
301  * Things past this point have policy implications.
302  */
303
304 void drawmaps(short l)
305 /* hook to be called after moving to redraw maps */
306 {
307     if (curses) {
308         if (l == 1) 
309             sensor();
310         if (l != 2) {
311             setwnd(srscan_window);
312             wmove(curwnd, 0, 0);
313             enqueue("no");
314             srscan(SCAN_FULL);
315             setwnd(REPORT_WINDOW);
316             wclear(REPORT_WINDOW);
317             wmove(REPORT_WINDOW, 0, 0);
318             srscan(SCAN_NO_LEFTSIDE);
319             setwnd(lrscan_window);
320             wclear(lrscan_window);
321             wmove(lrscan_window, 0, 0);
322             enqueue("l");
323             lrscan();
324         }
325     }
326 }
327
328 void boom(int ii, int jj)
329 /* enemy fall down, go boom */ 
330 {
331     if (curses) {
332         setwnd(srscan_window);
333         drawmaps(2);
334         wmove(srscan_window, ii*2+3, jj+2);
335         wattron(srscan_window, A_REVERSE);
336         waddch(srscan_window, game.quad[ii][jj]);
337         wrefresh(srscan_window);
338         sound(500);
339         delay(1000);
340         nosound();
341         wmove(srscan_window, ii*2+3, jj+2);
342         wattroff(srscan_window, A_REVERSE);
343         waddch(srscan_window, game.quad[ii][jj]);
344         wrefresh(srscan_window);
345         setwnd(message_window);
346         delay(500);
347     }
348
349
350 void warble(void)
351 /* sound and visual effects for teleportation */
352 {
353     if (curses) {
354         drawmaps(1);
355         setwnd(message_window);
356         sound(50);
357         delay(1000);
358         nosound();
359     } else
360         prouts(" . . . . . ");
361 }
362
363 void tracktorpedo(int x, int y, int ix, int iy, int wait, int l, int i, int n, int iquad)
364 /* torpedo-track animation */
365 {
366     if (!curses) {
367         if (l == 1) {
368             if (n != 1) {
369                 skip(1);
370                 proutn("Track for torpedo number %d-  ", i);
371             }
372             else {
373                 skip(1);
374                 proutn("Torpedo track- ");
375             }
376         } else if (l==4 || l==9) 
377             skip(1);
378         proutn("%d - %d   ", (int)x, (int)y);
379     } else {
380         if (game.damage[DSRSENS]==0 || condit==IHDOCKED) {
381             drawmaps(2);
382             delay((wait!=1)*400);
383             if ((game.quad[ix][iy]==IHDOT)||(game.quad[ix][iy]==IHBLANK)){
384                 game.quad[ix][iy]='+';
385                 drawmaps(2);
386                 game.quad[ix][iy]=iquad;
387                 sound(l*10);
388                 delay(100);
389                 nosound();
390             }
391             else {
392                 game.quad[ix][iy] |= DAMAGED;
393                 drawmaps(2);
394                 game.quad[ix][iy]=iquad;
395                 sound(500);
396                 delay(1000);
397                 nosound();
398                 wattroff(curwnd, A_REVERSE);
399             }
400         } else {
401             proutn("%d - %d   ", (int)x, (int)y);
402         }
403     }
404 }
405
406 void makechart(void) 
407 {
408     if (curses) {
409         setwnd(message_window);
410         wclear(message_window);
411         chart(0);
412     }
413 }
414
415 void setpassword(void) 
416 {
417     if (!curses) {
418         while (TRUE) {
419             scan();
420             strcpy(game.passwd, citem);
421             chew();
422             if (*game.passwd != 0) break;
423             proutn("Please type in a secret password-");
424         }
425     } else {
426         int i;
427         for(i=0;i<3;i++) game.passwd[i]=(char)(97+(int)(Rand()*25));
428         game.passwd[3]=0;
429     }
430 }
431