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