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