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