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