Fix some messages.
[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 #include <time.h>
9
10 #include "conio.h"
11 #include "sstlinux.h"
12 #include "sst.h"
13
14 #ifndef SERGEEV
15 static int linecount;   /* for paging */
16 #endif /* SERGEEV */
17 static int screenheight = 24, screenwidth = 80;
18 #ifndef SERGEEV
19 static int curses = FALSE;
20 #else /* SERGEEV */
21 static int curses = TRUE;
22 #endif /* SERGEEV */
23
24 #ifdef SERGEEV
25 wnd wnds[6]={{1,1,80,25},       /* FULLSCREEN_WINDOW */
26              {1,1,25,12},       /* LEFTUPPER_WINDOW */
27              {26,2,80,12},      /* SRSCAN_WINDOW */
28              {65,1,80,10},      /* LRSCAN_WINDOW */
29              {1,13,80,23},      /* LOWER_WINDOW */
30              {1,24,80,25},      /* BOTTOM_WINDOW */
31 };
32 short curwnd;
33 #endif /* SERGEEV */
34
35 static void outro(int sig) {
36 /* wrap up, either normally or due to signal */
37     if (curses) {
38         clear();
39         (void)refresh();
40         (void)resetterm();
41         //(void)echo();
42         (void)endwin();
43     }
44 }
45
46 static void fastexit(int sig) {
47     outro(sig);
48     putchar('\n');
49     exit(0);
50 }
51
52 void iostart(int usecurses) {
53 #ifdef SERGEEV
54         textattr(7);
55         clrscr();
56         setwnd(FULLSCREEN_WINDOW);
57 #else
58         (void) signal(SIGINT, fastexit);
59         (void) signal(SIGINT, fastexit);
60 #ifdef SIGIOT
61         (void) signal(SIGIOT,fastexit);         /* for assert(3) */
62 #endif /* SIGIOT */
63         if(signal(SIGQUIT,SIG_IGN) != SIG_IGN)
64             (void)signal(SIGQUIT,fastexit);
65
66         if ((curses = usecurses)) {
67                 (void)initscr();
68 #ifdef KEY_MIN
69                 keypad(stdscr, TRUE);
70 #endif /* KEY_MIN */
71                 (void)saveterm();
72                 (void)nonl();
73                 (void)cbreak();
74                 //(void)noecho();
75                 scrollok(stdscr, TRUE);
76                 getmaxyx(stdscr, screenheight, screenwidth);
77         } else {
78                 char *LINES = getenv("LINES");
79                 if (LINES)
80                     screenheight = atoi(LINES);
81         }
82 #endif /* SERGEEV */
83 }
84
85 void ioend(void) {
86 #ifndef SERGEEV
87     outro(0);
88 #endif /* SERGEEV */
89 }
90
91 void waitfor(void) {
92 /* wait for user action -- OK to do nothing if on a TTY */
93 #ifdef SERGEEV
94         getche();
95 #endif /* SERGEEV */
96 }
97
98 void pause_game(int i) {
99         char *prompt;
100 #ifndef SERGEEV
101         char buf[BUFSIZ];
102 #else /* SERGEEV */
103         drawmaps(0);
104         setwnd(BOTTOM_WINDOW);
105 #endif /* SERGEEV */
106         if (i==1) {
107                 if (skill > 2)
108                         prompt = "[ANOUNCEMENT ARRIVING...]";
109                 else
110                         prompt = "[IMPORTANT ANNOUNCEMENT ARRIVING -- PRESS ENTER TO CONTINUE]";
111         }
112         else {
113                 if (skill > 2)
114                         prompt = "[CONTINUE?]";
115                 else
116                         prompt = "[PRESS ENTER TO CONTINUE]";
117
118         }
119 #ifndef SERGEEV
120         if (curses) {
121             waddch(stdscr, '\n');
122                 waddstr(stdscr, prompt);
123                 wgetnstr(stdscr, buf, sizeof(buf));
124                 wclear(stdscr);
125                 wrefresh(stdscr);
126         } else {
127                 putchar('\n');
128                 proutn(prompt);
129                 fgets(buf, sizeof(buf), stdin);
130                 if (i != 0) {
131                     /* much more in that old-TTY spirit to throw linefeeds */
132                     int j;
133                     for (j = 0; j < screenheight; j++)
134                         putchar('\n');
135                 }
136                 linecount = 0;
137         }
138 #else /* SERGEEV */
139         proutn(prompt);
140         getche();
141         clrscr();
142         setwnd(LOWER_WINDOW);
143         clrscr();
144 #endif /* SERGEEV */
145 }
146
147
148 void skip(int i) {
149 #ifndef SERGEEV
150     while (i-- > 0) {
151         if (curses) {
152             int y, x;
153             getyx(stdscr, y, x);
154             if (y == screenheight-1)
155                 pause_game(0);
156             else
157                 waddch(stdscr, '\n');
158         } else {
159             linecount++;
160             if (linecount >= screenheight)
161                 pause_game(0);
162             else
163                 putchar('\n');
164         }
165 #else /* SERGEEV */
166         while (i-- > 0) proutn("\n\r");
167 #endif /* SERGEEV */
168 }
169
170 static void vproutn(char *fmt, va_list ap) {
171 #ifdef SERGEEV
172     char *s, *p;
173     vasprintf(&s, fmt, ap);
174     p=s;
175     if ((curwnd==LOWER_WINDOW)&&(wherey()==wnds[curwnd].wndbottom-wnds[curwnd].wndtop)){
176        if (strchr(s,'\n')) {
177           p=strchr(s,'\n');
178           p[0]=0;
179           cprintf("%s",s);
180           p++;
181           pause_game(0);
182        }
183 #endif /* SERGEEV */
184     }
185 #ifdef SERGEEV
186     if ((curwnd==LOWER_WINDOW)&&(wherey()>wnds[curwnd].wndbottom-wnds[curwnd].wndtop+1))
187        cprintf("\r");
188 //        setwnd(curwnd);
189     if (strchr(s,'\n') || strchr(s,'\r')) clreol();
190     cprintf("%s",p);
191     free(s);
192 #endif /* SERGEEV */
193 }
194
195 void proutn(char *fmt, ...) {
196     va_list ap;
197     va_start(ap, fmt);
198 #ifndef SERGEEV
199     if (curses) {
200         vw_printw(stdscr, fmt, ap);
201         wrefresh(stdscr);
202     } else
203         vprintf(fmt, ap);
204 #else /* SERGEEV */
205     vproutn(fmt, ap);
206 #endif /* SERGEEV */
207     va_end(ap);
208 }
209
210 void prout(char *fmt, ...) {
211     va_list ap;
212     va_start(ap, fmt);
213 #ifndef SERGEEV
214     if (curses) {
215         vw_printw(stdscr, fmt, ap);
216         wrefresh(stdscr);
217     } else
218         vprintf(fmt, ap);
219 #else /* SERGEEV */
220     vproutn(fmt, ap);
221 #endif /* SERGEEV */
222     va_end(ap);
223     skip(1);
224 }
225
226 void proutc(char *line) {
227     line[strlen(line)-1] = '\0';
228 #ifndef SERGEEV
229     if (curses)
230         waddstr(stdscr, line);
231     else
232         fputs(line, stdout);
233 #else /* SERGEEV */
234     cputs(line);
235 #endif /* SERGEEV */
236     skip(1);
237 }
238
239 #ifdef SERGEEV
240 static void prchr(char *s){
241      char str[2];
242      strncpy(str,s,1);
243      str[1]=0;
244      proutn(str);
245 }
246
247 static void vprouts(char *fmt, va_list ap) {
248     char *s, *p;
249     vasprintf(&s, fmt, ap);
250     p=s;
251     while (*p) {
252         prchr(p++);
253         delay(30);
254     }
255     free(s);
256 }
257 #endif /* SERGEEV */
258
259 void prouts(char *fmt, ...) {
260 #ifndef SERGEEV
261         clock_t endTime;
262         char *s, buf[BUFSIZ];
263         /* print slowly! */
264         va_list ap;
265         va_start(ap, fmt);
266         vsprintf(buf, fmt, ap);
267         va_end(ap);
268         skip(1);
269         for (s = buf; *s; s++) {
270                 endTime = clock() + CLOCKS_PER_SEC*0.05;
271                 while (clock() < endTime) continue;
272                 if (curses) {
273                     waddch(stdscr, *s);
274                     wrefresh(stdscr);
275                 }
276                 else {
277                     putchar(*s);
278                     fflush(stdout);
279                 }
280         }
281 #else /* SERGEEV */
282     va_list ap;
283     va_start(ap, fmt);
284     vprouts(fmt, ap);
285     va_end(ap);
286 #endif /* SERGEEV */
287 }
288
289 void c_printf (char *format, ... )
290 {
291     char buffer[BUFSIZ]; /* Well, BUFSIZ is from ncurses...  */
292     va_list argp;
293     va_start(argp,format);
294     vsprintf(buffer,format,argp);
295     va_end(argp);
296 #ifdef SERGEEV
297     waddstr(conio_scr,buffer);
298 #else
299     proutn(buffer);
300 #endif /* SERGEEV */
301 }
302
303 void cgetline(char *line, int max) {
304     if (curses) {
305 #ifndef SERGEEV
306         wgetnstr(stdscr, line, max);
307         wrefresh(stdscr);
308 #else /* SERGEEV */
309         line[0]=max-1;
310         cgets(line);
311         memmove(line,&line[2],max-3);
312 #endif /* SERGEEV */
313     } else {
314         fgets(line, max, stdin);
315         line[strlen(line)-1] = '\0';
316     }
317 }
318
319 void setwnd(short wndnum){
320 /* change windows -- OK for this to be a no-op in tty mode */
321 #ifdef SERGEEV
322      int cury;
323      cury=wherey()+wnds[curwnd].wndtop-wnds[wndnum].wndtop;
324      if ((curwnd==FULLSCREEN_WINDOW)&&(wndnum!=FULLSCREEN_WINDOW)) clrscr();
325      window(wnds[wndnum].wndleft, wnds[wndnum].wndtop, wnds[wndnum].wndright, wnds[wndnum].wndbottom);
326      if ((curwnd==wndnum)&&(cury>wnds[wndnum].wndbottom-wnds[wndnum].wndtop+1)){
327         gotoxy(wnds[wndnum].wndright-wnds[wndnum].wndleft+1,wnds[wndnum].wndbottom-wnds[wndnum].wndtop+1);
328         skip(1);
329      }
330      curwnd=wndnum;
331      gotoxy(1,cury);
332 #endif /* SERGEEV */
333 }
334
335 void commandhook(char *cmd, int before) {
336 }
337
338 /*
339  * Things past this point have policy implications.
340  */
341
342 void drawmaps(short l) {
343 /* hook to be called after moving to redraw maps */
344 #ifdef SERGEEV
345      _setcursortype(_NOCURSOR);
346      if (l==1) sensor();
347      if (l!=2) setwnd(LEFTUPPER_WINDOW);
348      gotoxy(1,1);
349      strcpy(line,"s");
350      srscan(1);
351      if (l!=2){
352         setwnd(SRSCAN_WINDOW);
353         clrscr();
354         srscan(2);
355         setwnd(LRSCAN_WINDOW);
356         clrscr();
357         strcpy(line,"l");
358         lrscan();
359         _setcursortype(_NORMALCURSOR);
360      }
361 #endif /* SERGEEV */
362 }
363
364 void boom(int ii, int jj)
365 /* enemy fall down, go boom */ 
366 {
367 #ifdef SERGEEV
368     int crx, cry;
369     crx=wherex();
370     cry=wherey();
371     setwnd(LEFTUPPER_WINDOW);
372     drawmaps(2);
373     gotoxy(jj*2+3,ii+2);
374     highvideo();
375     proutn("%c", game.quad[ii][jj]);
376     gotoxy(wherex()-1,wherey());
377     sound(500);
378     delay(1000);
379     nosound();
380     lowvideo();
381     proutn("%c", game.quad[ii][jj]);
382     setwnd(LOWER_WINDOW);
383     gotoxy(crx,cry);
384     _setcursortype(_NORMALCURSOR);
385     delay(500);
386 #endif /* SERGEEV */
387
388
389 void warble(void)
390 /* sound and visual effects for teleportation */
391 {
392 #ifdef SERGEEV
393     int posx, posy;
394     posx=wherex();
395     posy=wherey();
396     drawmaps(1);
397     setwnd(LOWER_WINDOW);
398     gotoxy(posx,posy);
399     sound(50);
400     delay(1000);
401     nosound();
402 #else
403     prouts(" . . . . . ");
404 #endif /* SERGEEV */
405 }
406
407 void tracktorpedo(int x, int y, int ix, int iy, int wait, int l, int i, int n, int iquad)
408 /* torpedo-track animation */
409 {
410 #ifndef SERGEEV
411     if (l == 1) {
412         if (n != 1) {
413             skip(1);
414             proutn("Track for torpedo number %d-  ", i);
415         }
416         else {
417             skip(1);
418             proutn("Torpedo track- ");
419         }
420     } else if (l==4 || l==9) 
421         skip(1);
422     proutn("%d - %d   ", (int)x, (int)y);
423 #else
424     if (game.damage[DSRSENS]==0 || condit==IHDOCKED) {
425         drawmaps(2);
426         delay((wait!=1)*400);
427         gotoxy(iy*2+3,ix+2);
428         if ((game.quad[ix][iy]==IHDOT)||(game.quad[ix][iy]==IHBLANK)){
429             game.quad[ix][iy]='+';
430             drawmaps(2);
431             game.quad[ix][iy]=iquad;
432             sound(l*10);
433             delay(100);
434             nosound();
435         }
436         else {
437             game.quad[ix][iy]|=128;
438             drawmaps(2);
439             game.quad[ix][iy]=iquad;
440             _setcursortype(_NOCURSOR);
441             sound(500);
442             delay(1000);
443             nosound();
444             lowvideo();
445             _setcursortype(_NORMALCURSOR);
446         }
447     } else {
448         proutn("%d - %d   ", (int)x, (int)y);
449     }
450 #endif /* SERGEEV */
451 }
452
453 void makechart(void) {
454 #ifdef SERGEEV
455     _setcursortype(_NOCURSOR);
456     setwnd(LOWER_WINDOW);
457     clrscr();
458     chart(0);
459     _setcursortype(_NORMALCURSOR);
460 #endif /* SERGEEV */
461 }
462
463 void setpassword(void) {
464 #ifndef SERGEEV
465         while (TRUE) {
466                 scan();
467                 strcpy(game.passwd, citem);
468                 chew();
469                 if (*game.passwd != 0) break;
470                 proutn("Please type in a secret password-");
471         }
472 #else
473         int i;
474         for(i=0;i<3;i++) game.passwd[i]=(char)(97+(int)(Rand()*25));
475         game.passwd[3]=0;
476 #endif /* SERGEEV */
477 }
478