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