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