Minor cleanup.
[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 }
168
169 static void vproutn(char *fmt, va_list ap) {
170     char *s, *p;
171     vasprintf(&s, fmt, ap);
172     p=s;
173     if ((curwnd==LOWER_WINDOW)&&(wherey()==wnds[curwnd].wndbottom-wnds[curwnd].wndtop)){
174        if (strchr(s,'\n')) {
175           p=strchr(s,'\n');
176           p[0]=0;
177           cprintf("%s",s);
178           p++;
179           pause_game(0);
180        }
181 #endif /* SERGEEV */
182     }
183 #ifdef SERGEEV
184     if ((curwnd==LOWER_WINDOW)&&(wherey()>wnds[curwnd].wndbottom-wnds[curwnd].wndtop+1))
185        cprintf("\r");
186 //        setwnd(curwnd);
187     if (strchr(s,'\n') || strchr(s,'\r')) clreol();
188     cprintf("%s",p);
189     free(s);
190 #endif /* SERGEEV */
191 }
192
193 void proutn(char *fmt, ...) {
194     va_list ap;
195     va_start(ap, fmt);
196 #ifndef SERGEEV
197     if (curses) {
198         vw_printw(stdscr, fmt, ap);
199         wrefresh(stdscr);
200     } else
201         vprintf(fmt, ap);
202 #else /* SERGEEV */
203     vproutn(fmt, ap);
204 #endif /* SERGEEV */
205     va_end(ap);
206 }
207
208 void prout(char *fmt, ...) {
209     va_list ap;
210     va_start(ap, fmt);
211 #ifndef SERGEEV
212     if (curses) {
213         vw_printw(stdscr, fmt, ap);
214         wrefresh(stdscr);
215     } else
216         vprintf(fmt, ap);
217 #else /* SERGEEV */
218     vproutn(fmt, ap);
219 #endif /* SERGEEV */
220     va_end(ap);
221     skip(1);
222 }
223
224 void proutc(char *line) {
225     line[strlen(line)-1] = '\0';
226 #ifndef SERGEEV
227     if (curses)
228         waddstr(stdscr, line);
229     else
230         fputs(line, stdout);
231 #else /* SERGEEV */
232     cputs(line);
233 #endif /* SERGEEV */
234     skip(1);
235 }
236
237 #ifdef SERGEEV
238 static void prchr(char *s){
239      char str[2];
240      strncpy(str,s,1);
241      str[1]=0;
242      proutn(str);
243 }
244
245 static void vprouts(char *fmt, va_list ap) {
246     char *s, *p;
247     vasprintf(&s, fmt, ap);
248     p=s;
249     while (*p) {
250         prchr(p++);
251         delay(30);
252     }
253     free(s);
254 }
255 #endif /* SERGEEV */
256
257 void prouts(char *fmt, ...) {
258 #ifndef SERGEEV
259         clock_t endTime;
260         char *s, buf[BUFSIZ];
261         /* print slowly! */
262         va_list ap;
263         va_start(ap, fmt);
264         vsprintf(buf, fmt, ap);
265         va_end(ap);
266         skip(1);
267         for (s = buf; *s; s++) {
268                 endTime = clock() + CLOCKS_PER_SEC*0.05;
269                 while (clock() < endTime) continue;
270                 if (curses) {
271                     waddch(stdscr, *s);
272                     wrefresh(stdscr);
273                 }
274                 else {
275                     putchar(*s);
276                     fflush(stdout);
277                 }
278         }
279 #else /* SERGEEV */
280     va_list ap;
281     va_start(ap, fmt);
282     vprouts(fmt, ap);
283     va_end(ap);
284 #endif /* SERGEEV */
285 }
286
287 void c_printf (char *format, ... )
288 {
289     char buffer[BUFSIZ]; /* Well, BUFSIZ is from ncurses...  */
290     va_list argp;
291     va_start(argp,format);
292     vsprintf(buffer,format,argp);
293     va_end(argp);
294 #ifdef SERGEEV
295     waddstr(conio_scr,buffer);
296 #else
297     proutn(buffer);
298 #endif /* SERGEEV */
299 }
300
301 void cgetline(char *line, int max) {
302     if (curses) {
303 #ifndef SERGEEV
304         wgetnstr(stdscr, line, max);
305         wrefresh(stdscr);
306 #else /* SERGEEV */
307         line[0]=max-1;
308         cgets(line);
309         memmove(line,&line[2],max-3);
310 #endif /* SERGEEV */
311     } else {
312         fgets(line, max, stdin);
313         line[strlen(line)-1] = '\0';
314     }
315 }
316
317 void setwnd(short wndnum){
318 /* change windows -- OK for this to be a no-op in tty mode */
319 #ifdef SERGEEV
320      int cury;
321      cury=wherey()+wnds[curwnd].wndtop-wnds[wndnum].wndtop;
322      if ((curwnd==FULLSCREEN_WINDOW)&&(wndnum!=FULLSCREEN_WINDOW)) clrscr();
323      window(wnds[wndnum].wndleft, wnds[wndnum].wndtop, wnds[wndnum].wndright, wnds[wndnum].wndbottom);
324      if ((curwnd==wndnum)&&(cury>wnds[wndnum].wndbottom-wnds[wndnum].wndtop+1)){
325         gotoxy(wnds[wndnum].wndright-wnds[wndnum].wndleft+1,wnds[wndnum].wndbottom-wnds[wndnum].wndtop+1);
326         skip(1);
327      }
328      curwnd=wndnum;
329      gotoxy(1,cury);
330 #endif /* SERGEEV */
331 }
332
333 void commandhook(char *cmd, int before) {
334 }
335
336 /*
337  * Things past this point have policy implications.
338  */
339
340 void drawmaps(short l) {
341 /* hook to be called after moving to redraw maps */
342 #ifdef SERGEEV
343      _setcursortype(_NOCURSOR);
344      if (l==1) sensor();
345      if (l!=2) setwnd(LEFTUPPER_WINDOW);
346      gotoxy(1,1);
347      strcpy(line,"s");
348      srscan(1);
349      if (l!=2){
350         setwnd(SRSCAN_WINDOW);
351         clrscr();
352         srscan(2);
353         setwnd(LRSCAN_WINDOW);
354         clrscr();
355         strcpy(line,"l");
356         lrscan();
357         _setcursortype(_NORMALCURSOR);
358      }
359 #endif /* SERGEEV */
360 }
361
362 void boom(int ii, int jj)
363 /* enemy fall down, go boom */ 
364 {
365 #ifdef SERGEEV
366     int crx, cry;
367     crx=wherex();
368     cry=wherey();
369     setwnd(LEFTUPPER_WINDOW);
370     drawmaps(2);
371     gotoxy(jj*2+3,ii+2);
372     highvideo();
373     proutn("%c", game.quad[ii][jj]);
374     gotoxy(wherex()-1,wherey());
375     sound(500);
376     delay(1000);
377     nosound();
378     lowvideo();
379     proutn("%c", game.quad[ii][jj]);
380     setwnd(LOWER_WINDOW);
381     gotoxy(crx,cry);
382     _setcursortype(_NORMALCURSOR);
383     delay(500);
384 #endif /* SERGEEV */
385
386
387 void warble(void)
388 /* sound and visual effects for teleportation */
389 {
390 #ifdef SERGEEV
391     int posx, posy;
392     posx=wherex();
393     posy=wherey();
394     drawmaps(1);
395     setwnd(LOWER_WINDOW);
396     gotoxy(posx,posy);
397     sound(50);
398     delay(1000);
399     nosound();
400 #else
401     prouts(" . . . . . ");
402 #endif /* SERGEEV */
403 }
404
405 void tracktorpedo(int x, int y, int ix, int iy, int wait, int l, int i, int n, int iquad)
406 /* torpedo-track animation */
407 {
408 #ifndef SERGEEV
409     if (l == 1) {
410         if (n != 1) {
411             skip(1);
412             proutn("Track for torpedo number %d-  ", i);
413         }
414         else {
415             skip(1);
416             proutn("Torpedo track- ");
417         }
418     } else if (l==4 || l==9) 
419         skip(1);
420     proutn("%d - %d   ", (int)x, (int)y);
421 #else
422     if (game.damage[DSRSENS]==0 || condit==IHDOCKED) {
423         drawmaps(2);
424         delay((wait!=1)*400);
425         gotoxy(iy*2+3,ix+2);
426         if ((game.quad[ix][iy]==IHDOT)||(game.quad[ix][iy]==IHBLANK)){
427             game.quad[ix][iy]='+';
428             drawmaps(2);
429             game.quad[ix][iy]=iquad;
430             sound(l*10);
431             delay(100);
432             nosound();
433         }
434         else {
435             game.quad[ix][iy]|=128;
436             drawmaps(2);
437             game.quad[ix][iy]=iquad;
438             _setcursortype(_NOCURSOR);
439             sound(500);
440             delay(1000);
441             nosound();
442             lowvideo();
443             _setcursortype(_NORMALCURSOR);
444         }
445     } else {
446         proutn("%d - %d   ", (int)x, (int)y);
447     }
448 #endif /* SERGEEV */
449 }
450
451 void makechart(void) {
452 #ifdef SERGEEV
453     _setcursortype(_NOCURSOR);
454     setwnd(LOWER_WINDOW);
455     clrscr();
456     chart(0);
457     _setcursortype(_NORMALCURSOR);
458 #endif /* SERGEEV */
459 }
460
461 void setpassword(void) {
462 #ifndef SERGEEV
463         while (TRUE) {
464                 scan();
465                 strcpy(game.passwd, citem);
466                 chew();
467                 if (*game.passwd != 0) break;
468                 proutn("Please type in a secret password-");
469         }
470 #else
471         int i;
472         for(i=0;i<3;i++) game.passwd[i]=(char)(97+(int)(Rand()*25));
473         game.passwd[3]=0;
474 #endif /* SERGEEV */
475 }
476