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