setwnd() is now a save no-op in TTY mode.
[super-star-trek.git] / io.c
1 #define _GNU_SOURCE
2 #include <stdio.h>
3 #include <unistd.h>
4 #include <termios.h>
5 #include <curses.h>
6 #include <signal.h>
7 #include <ctype.h>
8 #include <stdarg.h>
9 #include <time.h>
10
11 #include "conio.h"
12 #include "sstlinux.h"
13 #include "sst.h"
14
15 #ifndef SERGEEV
16 static int linecount;   /* for paging */
17 #endif /* SERGEEV */
18 static int screenheight = 24, screenwidth = 80;
19 #ifndef SERGEEV
20 static int curses = FALSE;
21 #else /* SERGEEV */
22 static int curses = TRUE;
23 #endif /* SERGEEV */
24
25 #ifdef SERGEEV
26 wnd wnds[6]={{1,1,80,25},       /* FULLSCREEN_WINDOW */
27              {1,1,25,12},       /* LEFTUPPER_WINDOW */
28              {26,2,80,12},      /* SRSCAN_WINDOW */
29              {65,1,80,10},      /* LRSCAN_WINDOW */
30              {1,13,80,23},      /* LOWER_WINDOW */
31              {1,24,80,25},      /* BOTTOM_WINDOW */
32 };
33 short curwnd;
34 #endif /* SERGEEV */
35
36 static void outro(int sig) {
37 /* wrap up, either normally or due to signal */
38     if (curses) {
39         clear();
40         (void)refresh();
41         (void)resetterm();
42         //(void)echo();
43         (void)endwin();
44     }
45 }
46
47 static void fastexit(int sig) {
48     outro(sig);
49     putchar('\n');
50     exit(0);
51 }
52
53 void iostart(int usecurses) {
54         (void) signal(SIGINT, fastexit);
55         (void) signal(SIGINT, fastexit);
56 #ifdef SIGIOT
57         (void) signal(SIGIOT,fastexit);         /* for assert(3) */
58 #endif /* SIGIOT */
59         if(signal(SIGQUIT,SIG_IGN) != SIG_IGN)
60             (void)signal(SIGQUIT,fastexit);
61
62         if ((curses = usecurses)) {
63                 (void)initscr();
64 #ifdef KEY_MIN
65                 keypad(stdscr, TRUE);
66 #endif /* KEY_MIN */
67                 (void)saveterm();
68                 (void)nonl();
69                 (void)cbreak();
70                 //(void)noecho();
71                 scrollok(stdscr, TRUE);
72                 getmaxyx(stdscr, screenheight, screenwidth);
73         } else {
74                 char *LINES = getenv("LINES");
75                 if (LINES)
76                     screenheight = atoi(LINES);
77         }
78 }
79
80 void ioend(void) {
81     outro(0);
82 }
83
84 void waitfor(void) {
85 /* wait for user action -- OK to do nothing if on a TTY */
86 #ifdef SERGEEV
87         getche();
88 #endif /* SERGEEV */
89 }
90
91 void pause_game(int i) {
92         char *prompt;
93 #ifndef SERGEEV
94         char buf[BUFSIZ];
95 #else /* SERGEEV */
96         drawmaps(0);
97         setwnd(BOTTOM_WINDOW);
98 #endif /* SERGEEV */
99         if (i==1) {
100                 if (skill > 2)
101                         prompt = "[ANOUNCEMENT ARRIVING...]";
102                 else
103                         prompt = "[IMPORTANT ANNOUNCEMENT ARRIVING -- PRESS ENTER TO CONTINUE]";
104         }
105         else {
106                 if (skill > 2)
107                         prompt = "[CONTINUE?]";
108                 else
109                         prompt = "[PRESS ENTER TO CONTINUE]";
110
111         }
112 #ifndef SERGEEV
113         if (curses) {
114             waddch(stdscr, '\n');
115                 waddstr(stdscr, prompt);
116                 wgetnstr(stdscr, buf, sizeof(buf));
117                 wclear(stdscr);
118                 wrefresh(stdscr);
119         } else {
120                 putchar('\n');
121                 proutn(prompt);
122                 fgets(buf, sizeof(buf), stdin);
123                 if (i != 0) {
124                     /* much more in that old-TTY spirit to throw linefeeds */
125                     int j;
126                     for (j = 0; j < screenheight; j++)
127                         putchar('\n');
128                 }
129                 linecount = 0;
130         }
131 #else /* SERGEEV */
132         proutn(prompt);
133         getche();
134         clrscr();
135         setwnd(LOWER_WINDOW);
136         clrscr();
137 #endif /* SERGEEV */
138 }
139
140
141 void skip(int i) {
142 #ifndef SERGEEV
143     while (i-- > 0) {
144         if (curses) {
145             int y, x;
146             getyx(stdscr, y, x);
147             if (y == screenheight-1)
148                 pause_game(0);
149             else
150                 waddch(stdscr, '\n');
151         } else {
152             linecount++;
153             if (linecount >= screenheight)
154                 pause_game(0);
155             else
156                 putchar('\n');
157         }
158 #else /* SERGEEV */
159         while (i-- > 0) proutn("\n\r");
160 }
161
162 static void vproutn(char *fmt, va_list ap) {
163     char *s, *p;
164     vasprintf(&s, fmt, ap);
165     p=s;
166     if ((curwnd==LOWER_WINDOW)&&(wherey()==wnds[curwnd].wndbottom-wnds[curwnd].wndtop)){
167        if (strchr(s,'\n')) {
168           p=strchr(s,'\n');
169           p[0]=0;
170           cprintf("%s",s);
171           p++;
172           pause_game(0);
173        }
174 #endif /* SERGEEV */
175     }
176 #ifdef SERGEEV
177     if ((curwnd==LOWER_WINDOW)&&(wherey()>wnds[curwnd].wndbottom-wnds[curwnd].wndtop+1))
178        cprintf("\r");
179 //        setwnd(curwnd);
180     if (strchr(s,'\n') || strchr(s,'\r')) clreol();
181     cprintf("%s",p);
182     free(s);
183 #endif /* SERGEEV */
184 }
185
186 void proutn(char *fmt, ...) {
187     va_list ap;
188     va_start(ap, fmt);
189 #ifndef SERGEEV
190     if (curses) {
191         vw_printw(stdscr, fmt, ap);
192         wrefresh(stdscr);
193     } else
194         vprintf(fmt, ap);
195 #else /* SERGEEV */
196     vproutn(fmt, ap);
197 #endif /* SERGEEV */
198     va_end(ap);
199 }
200
201 void prout(char *fmt, ...) {
202     va_list ap;
203     va_start(ap, fmt);
204 #ifndef SERGEEV
205     if (curses) {
206         vw_printw(stdscr, fmt, ap);
207         wrefresh(stdscr);
208     } else
209         vprintf(fmt, ap);
210 #else /* SERGEEV */
211     vproutn(fmt, ap);
212 #endif /* SERGEEV */
213     va_end(ap);
214     skip(1);
215 }
216
217 void proutc(char *line) {
218     line[strlen(line)-1] = '\0';
219 #ifndef SERGEEV
220     if (curses)
221         waddstr(stdscr, line);
222     else
223         fputs(line, stdout);
224 #else /* SERGEEV */
225     cputs(line);
226 #endif /* SERGEEV */
227     skip(1);
228 }
229
230 #ifdef SERGEEV
231 static void prchr(char *s){
232      char str[2];
233      strncpy(str,s,1);
234      str[1]=0;
235      proutn(str);
236 }
237
238 static void vprouts(char *fmt, va_list ap) {
239     char *s, *p;
240     vasprintf(&s, fmt, ap);
241     p=s;
242     while (*p) {
243         prchr(p++);
244         delay(30);
245     }
246     free(s);
247 }
248
249 #endif /* SERGEEV */
250 void prouts(char *fmt, ...) {
251 #ifndef SERGEEV
252         clock_t endTime;
253         char *s, buf[BUFSIZ];
254         /* print slowly! */
255         va_list ap;
256         va_start(ap, fmt);
257         vsprintf(buf, fmt, ap);
258         va_end(ap);
259         skip(1);
260         for (s = buf; *s; s++) {
261                 endTime = clock() + CLOCKS_PER_SEC*0.05;
262                 while (clock() < endTime) continue;
263                 if (curses) {
264                     waddch(stdscr, *s);
265                     wrefresh(stdscr);
266                 }
267                 else {
268                     putchar(*s);
269                     fflush(stdout);
270                 }
271         }
272 #else /* SERGEEV */
273     va_list ap;
274     va_start(ap, fmt);
275     vprouts(fmt, ap);
276     va_end(ap);
277 #endif /* SERGEEV */
278 }
279
280 void c_printf (char *format, ... )
281 {
282     char buffer[BUFSIZ]; /* Well, BUFSIZ is from ncurses...  */
283     va_list argp;
284     va_start(argp,format);
285     vsprintf(buffer,format,argp);
286     va_end(argp);
287 #ifdef SERGEEV
288     waddstr(conio_scr,buffer);
289 #else
290     proutn(buffer);
291 #endif /* SERGEEV */
292 }
293
294 void warble(void)
295 /* sound and visual effects for teleportation */
296 {
297 #ifdef SERGEEV
298     int posx, posy;
299     posx=wherex();
300     posy=wherey();
301     drawmaps(1);
302     setwnd(LOWER_WINDOW);
303     gotoxy(posx,posy);
304     sound(50);
305     delay(1000);
306     nosound();
307 #else
308     prouts(" . . . . . ");
309 #endif /* SERGEEV */
310 }
311
312 void setpassword(void) {
313 #ifndef SERGEEV
314         while (TRUE) {
315                 scan();
316                 strcpy(game.passwd, citem);
317                 chew();
318                 if (*game.passwd != 0) break;
319                 proutn("Please type in a secret password-");
320         }
321 #else
322         int i;
323         for(i=0;i<3;i++) game.passwd[i]=(char)(97+(int)(Rand()*25));
324         game.passwd[3]=0;
325 #endif /* SERGEEV */
326 }
327
328 void cgetline(char *line, int max) {
329     if (curses) {
330 #ifndef SERGEEV
331         wgetnstr(stdscr, line, max);
332         wrefresh(stdscr);
333 #else /* SERGEEV */
334         line[0]=max-1;
335         cgets(line);
336         memmove(line,&line[2],max-3);
337 #endif /* SERGEEV */
338     } else {
339         fgets(line, max, stdin);
340         line[strlen(line)-1] = '\0';
341     }
342 }
343
344 void setwnd(short wndnum){
345 /* change windows -- OK for this to be a no-op in tty mode */
346 #ifdef SERGEEV
347      int cury;
348      cury=wherey()+wnds[curwnd].wndtop-wnds[wndnum].wndtop;
349      if ((curwnd==FULLSCREEN_WINDOW)&&(wndnum!=FULLSCREEN_WINDOW)) clrscr();
350      window(wnds[wndnum].wndleft, wnds[wndnum].wndtop, wnds[wndnum].wndright, wnds[wndnum].wndbottom);
351      if ((curwnd==wndnum)&&(cury>wnds[wndnum].wndbottom-wnds[wndnum].wndtop+1)){
352         gotoxy(wnds[wndnum].wndright-wnds[wndnum].wndleft+1,wnds[wndnum].wndbottom-wnds[wndnum].wndtop+1);
353         skip(1);
354      }
355      curwnd=wndnum;
356      gotoxy(1,cury);
357 #endif /* SERGEEV */
358 }
359
360 void commandhook(char *cmd, int before) {
361 }