92598140141e2e12633872e123c3c08ab8fa2965
[super-star-trek.git] / conio.c
1 /****************************************************************************
2  * This is the implementation file for conio.h - a conio.h for Linux.       *
3  * It uses ncurses and some internal functions of Linux to simulate the     *
4  * I/O-functions.                                                           *
5  * This is copyright (c) 1996,97 by Fractor / Mental eXPlosion (MXP)        *
6  * Use and distribution is only allowed if you follow the terms of the      *
7  * GNU Library Public License Version 2.                                    *
8  * Since this work is based on ncurses please read its copyright notices as *
9  * well !                                                                   *
10  * Look into the readme to this file for further information.               *
11  * Thanx to SubZero / MXP for his little tutorial on the curses library !   *
12  * Many thanks to Mark Hahn and Rich Cochran for solving the inpw and inpd  *
13  * mega-bug !!!                                                             *
14  * Watch out for other MXP releases, too !                                  *
15  * Send bugreports to: fractor@germanymail.com                              *
16  ****************************************************************************/
17
18 #define _ISOC99_SOURCE
19 #include <stdio.h>
20 #include <stdarg.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <sys/io.h>
25 #include <ncurses.h>
26 #include "conio.h" 
27
28 static attr_t txtattr,oldattr;
29 static int fgc,bgc;
30 char color_warning=1;
31 int directvideo;
32 WINDOW *conio_scr;
33
34 /* Some internals... */
35 static int colortab(int a) /* convert LINUX Color code to DOS-standard */
36 {
37    switch(a) {
38       case 0 : return COLOR_BLACK;
39       case 1 : return COLOR_BLUE;
40       case 2 : return COLOR_GREEN;
41       case 3 : return COLOR_CYAN;
42       case 4 : return COLOR_RED;
43       case 5 : return COLOR_MAGENTA;
44       case 6 : return COLOR_YELLOW;
45       case 7 : return COLOR_WHITE;
46    }
47    return COLOR_BLACK;
48
49
50 static void docolor (int color) /* Set DOS-like text mode colors */
51 {
52    wattrset(conio_scr,0); /* My curses-version needs this ... */
53    if ((color&128)==128) txtattr=A_BLINK; else txtattr=A_NORMAL;
54    if ((color&15)>7) txtattr|=A_STANDOUT; else txtattr|=A_NORMAL;
55    txtattr|=COLOR_PAIR((1+(color&7)+(color&112)) >> 1);
56    if (((color&127)==15) | ((color&127)==7)) txtattr=COLOR_PAIR(0);
57    if (((color&127)==127) | ((color&127)==119)) txtattr=COLOR_PAIR(8);
58    wattron(conio_scr,txtattr);
59    wattron(conio_scr,COLOR_PAIR(1+(color&7)+((color&112)>>1))); 
60 }
61
62 #ifdef SERGEEV
63 /* Call this before any call to linux conio - except the port functions ! */
64 void __attribute__((constructor)) initconio (void) /* This is needed, because ncurses needs to be initialized */
65 {
66    int x,y;
67    short pair;
68    if (atexit(doneconio)){
69       fprintf(stderr,"Unable to register doneconio(), exiting...\n");
70       exit(1);
71    }
72    initscr();
73    start_color();
74 //   attr_get(&oldattr,&pair,NULL);
75    nonl();
76    raw();
77    if (!has_colors() & (color_warning>-1))
78       fprintf(stderr,"Attention: A color terminal may be required to run this application !\n");   
79    noecho();
80    conio_scr=newwin(0,0,0,0);
81    keypad(conio_scr,TRUE);
82    meta(conio_scr,TRUE);
83    idlok(conio_scr,TRUE);
84    scrollok(conio_scr,TRUE);
85    /* Color initialization */
86    for (y=0;y<=7;y++)
87       for (x=0;x<=7;x++)
88          init_pair((8*y)+x+1, colortab(x), colortab(y));              
89    wattr_get(conio_scr,&txtattr,&pair,NULL);
90    bgc=0;
91    textcolor(7);
92    textbackground(0);
93 }
94 #endif /* SERGEEV */
95
96 /* Call this on exiting your program */
97 void doneconio (void)
98 {
99    endwin();
100 }
101
102 /* Here it starts... */
103 void _setcursortype (int cur_t)
104 {
105    curs_set(cur_t);
106    wrefresh(conio_scr);
107 }
108
109 char *cgets (char *str) /* ugly function :-( */
110 {
111    char strng[257];
112    unsigned char i=2;
113    echo();
114    strncpy(strng,str,1);
115    wgetnstr(conio_scr,&strng[2],(int) strng[0]);
116    while (strng[i]!=0) i++;
117    i=i-2;
118    strng[1]=i;
119    memcpy(str,strng,i+3);
120    noecho();
121    return(&str[2]);
122 }
123
124 void clreol (void)
125 {
126    wclrtoeol(conio_scr);
127    wrefresh(conio_scr);
128 }
129
130 void clrscr (void)
131 {
132    wclear(conio_scr);
133    wmove(conio_scr,0,0);
134    wrefresh(conio_scr);
135 }
136
137 int cprintf (char *format, ... )
138 {
139    int i;
140    char buffer[BUFSIZ]; /* Well, BUFSIZ is from ncurses...  */
141    va_list argp;
142    va_start(argp,format);
143    vsprintf(buffer,format,argp);
144    va_end(argp);
145    i=waddstr(conio_scr,buffer);
146    wrefresh(conio_scr);
147    return(i);
148 }
149
150 void cputs (char *str)
151 {
152    waddstr(conio_scr,str);
153    wrefresh(conio_scr);
154 }
155
156 int cscanf (const char *format, ...)
157 {
158    int i;
159    char buffer[BUFSIZ]; /* See cprintf */
160    va_list argp;
161    echo();
162    if (wgetstr(conio_scr,buffer)==ERR) return(-1);                    
163    va_start(argp,format);
164    i=vsscanf(buffer,format,argp);                         
165    va_end(argp);
166    noecho();
167    return(i);
168 }
169
170 void delline (void)
171 {
172    wdeleteln(conio_scr);
173    wrefresh(conio_scr);
174 }
175
176 int getche (void)
177 {
178    int i;
179    echo();
180    i=wgetch(conio_scr);
181    if (i==-1) i=0;
182    noecho();
183    return(i);
184 }
185
186 void gettextinfo(struct text_info *inforec)
187 {
188    short pair;
189    unsigned char xp,yp;
190    unsigned char x1,x2,y1,y2;
191    attr_t dattr,dnattr,a; /* The "d" stands for DOS */
192    getyx(conio_scr,yp,xp);
193    getbegyx(conio_scr,y1,x1);
194    getmaxyx(conio_scr,y2,x2);
195    dattr=(bgc*16)+fgc;
196    wattr_get(conio_scr,&a,&pair,NULL);
197    if (a==(a & A_BLINK)) dattr=dattr+128;
198    dnattr=oldattr;  /* Well, this cannot be right, 
199                        because we don't know the COLORPAIR values from before initconio() !*/
200    inforec->winleft=x1+1;
201    inforec->wintop=y1+1;
202    if (x1==0) x2--;
203    if (y1==0) y2--;
204    inforec->winright=x1+x2+1;
205    inforec->winbottom=y1+y2+1;
206    inforec->curx=xp+1;
207    inforec->cury=yp+1;
208    inforec->screenheight=y2+1;
209    inforec->screenwidth=x2+1;
210    inforec->currmode=3; /* This is C80 */
211    inforec->normattr=dnattr; /* Don't use this ! */
212    inforec->attribute=dattr;
213
214
215 void gotoxy (int x, int y)
216 {
217    y--;
218    x--;
219    wmove(conio_scr,y,x);
220    wrefresh(conio_scr);
221 }
222
223 void highvideo (void)
224 {
225    textcolor(15); /* White */
226    textbackground(0); /* Black */
227 }
228
229 void insline (void)
230
231    winsertln(conio_scr);
232    wrefresh(conio_scr);
233 }
234
235 int kbhit (void)
236 {
237    int i;
238    nodelay(conio_scr,TRUE);
239    i=wgetch(conio_scr);
240    nodelay(conio_scr,FALSE);
241    if (i==-1) i=0;
242    return(i);
243 }
244
245 void lowvideo (void)
246 {
247    textbackground(0); /* Black */
248    textcolor(8); /* Should be darkgray */
249 }
250
251 void normvideo (void)
252 {
253    wattrset(conio_scr,oldattr);
254 }
255
256 int putch (int c)
257 {
258    if (waddch(conio_scr,c)!=ERR) {
259       wrefresh(conio_scr); 
260       return(c);
261    }
262    return(0);
263 }
264                                      
265 void textattr (int attr)
266 {
267    docolor(attr);
268 }
269
270 void textbackground (int color)
271 {
272    bgc=color;
273    color=(bgc*16)+fgc;
274    docolor(color);
275 }
276
277 void textcolor (int color)
278 {
279    fgc=color;
280    color=(bgc*16)+fgc;
281    docolor(color);
282 }
283  
284 void textmode (int mode)
285 {
286    /* Ignored */
287 }
288
289 int wherex (void)
290 {
291    int y;
292    int x;
293    getyx(conio_scr,y,x);
294    x++;
295    return(x);
296 }
297
298 int wherey (void)
299 {
300    int y;
301    int x;
302    getyx(conio_scr,y,x);
303    y++;
304    return(y);
305 }
306
307 void window (int left,int top,int right,int bottom)
308 {
309    int nlines,ncols;
310    delwin(conio_scr);
311    top--;
312    left--;
313    right--;
314    bottom--;
315    nlines=bottom-top;
316    ncols=right-left;
317    if (top==0) nlines++;
318    if (left==0) ncols++;
319    if ((nlines<1) | (ncols<1)) return;
320    conio_scr=newwin(nlines,ncols,top,left);   
321    keypad(conio_scr,TRUE);
322    meta(conio_scr,TRUE);
323    idlok(conio_scr,TRUE);
324    scrollok(conio_scr,TRUE);
325    wrefresh(conio_scr);
326 }
327
328 /* Linux is cool */