1 /* CONSOLE INTERFACE */
2 
3 #include <ctype.h>
4 #include <termios.h>
5 #include <sys/time.h>
6 #include <unistd.h>
7 #include <stdio.h>
8 #include <stdarg.h>
9 #include <stdlib.h>
10 
11 #ifdef DOS
12  #include <conio.h>
13 #endif
14 
15 
16 #include "console_token"
17 
18 /* BOTH COORDINATES START AT 0 */
19 
20 int console_ok=1;
21 struct termios term_setting;
22 /***********************************************
23 typedef unsigned char   cc_t;
24 typedef unsigned int    speed_t;
25 typedef unsigned int    tcflag_t;
26 
27 #define NCCS 32
28 struct termios
29   {
30     tcflag_t c_iflag;       // input mode flags
31     tcflag_t c_oflag;       // output mode flags
32     tcflag_t c_cflag;       // control mode flags
33     tcflag_t c_lflag;       // local mode flags
34     cc_t c_line;            // line discipline
35     cc_t c_cc[NCCS];        // control characters
36     speed_t c_ispeed;       // input speed
37     speed_t c_ospeed;       // output speed
38   };
39 ***************************************************/
40 static int  fd_in, fd_out;
41 
42 void
c_refresh(void)43 c_refresh(void)
44 {
45 #ifdef UNIX
46  fflush(stdout);
47 #endif
48 }
49 
50 
51 /* move cursor to [x,y] */
52 void
c_goto(int x,int y)53 c_goto(int x,int y)
54 {
55 #ifdef UNIX
56  printf("\033[%u;%uH",y+1,x+1);
57  /* c_refresh(); */
58 #else
59  gotoxy(x+1,y+1);
60 #endif
61 }
62 
63 
64 void
c_setcolor(char a)65 c_setcolor(char a)
66 /* accepts: 0-9,a-f,A-F */
67 /* sets foreground color */
68 {
69 #ifdef UNIX
70  a=tolower(a);
71  if (a>15)
72  {
73   if (a>='a'&&a<='f')a+=10-'a';
74   else
75   {
76    if(a>='0'&&a<='9')a-='0';
77    else return;
78   }
79  }
80  if (a>7)printf("\033[1;%dm",30+a-8);
81  else printf("\033[0;%dm",30+a);
82 #else
83  textcolor(a);
84 #endif
85 }
86 
87 
88 /* print on the cursor position */
89 void
c_print(const char * text)90 c_print(const char * text)
91 {
92 #ifdef UNIX
93  printf("%s",text);   /* text can contain escape sequencies, % and so on */
94  c_refresh();
95 #else
96  cputs(text);
97 #endif
98 }
99 
100 
101 /* clears the screen */
102 void
c_cls(void)103 c_cls(void)
104 {
105 #ifdef UNIX
106  printf("\033[2J");
107  c_refresh();
108 #else
109  clrscr();
110 #endif
111 }
112 
113 
114 /* clears rectangle on the screen */
115 /* presumtions: x2>=x1 && y2>=y1 */
116 void
c_clear(int x1,int y1,int x2,int y2)117 c_clear(int x1,int y1,int x2,int y2)
118 {
119  static char line[81];
120  int y;
121 
122  for (y=0;y<x2-x1+1;y++)
123   line[y]=' ';
124  line[y]=0;
125  for(y=y1;y<=y2;y++)
126  {
127   c_goto(x1,y);c_print(line);
128  }
129  c_refresh();
130 }
131 
132 
133 /* returns 1, if some key was pressed, otherwise returns 0 */
134 int
c_kbhit(void)135 c_kbhit(void)
136 {
137 #ifdef UNIX
138  fd_set rfds;
139  struct timeval tv;
140  int retval;
141 
142  FD_ZERO(&rfds);
143  FD_SET(fd_in,&rfds);
144  tv.tv_sec=0;
145  tv.tv_usec=0;
146 
147  retval=select(1,&rfds,NULL,NULL,&tv);
148  if (retval)return 1;
149  else return 0;
150 #else
151  return kbhit();
152 #endif
153 }
154 
155 
156 void
c_cursor(int type)157 c_cursor(int type)
158 {
159  switch (type)
160  {
161   case C_NORMAL:
162 #ifdef UNIX
163   printf("\033[?25h");
164 #else
165  _setcursortype(_NORMALCURSOR);
166 #endif
167   break;
168 
169   case C_HIDE:
170 #ifdef UNIX
171   printf("\033[?25l");
172 #else
173  _setcursortype(_NOCURSOR);
174 #endif
175   break;
176  }
177  c_refresh();
178 }
179 
180 
181 /* ring the bell */
182 void
c_bell(void)183 c_bell(void)
184 {
185  printf("\007");
186  c_refresh();
187 }
188 
189 
190 /* initialize console */
191 void
c_init(char a)192 c_init(char a)
193 {
194 #ifdef UNIX
195  struct termios t;
196  fd_in=fileno(stdin);
197  fd_out=fileno(stdout);
198 
199  fflush(stdin);
200  console_ok=0;
201  if (tcgetattr(fd_in,&term_setting))
202     exit((printf("Error: can't get terminal attributes\n"), 3));
203  tcgetattr(fd_in,&t);
204 /*********
205 printf("c_iflag=%8x  c_oflag=%8x  c_cflag=%8x  c_lflag=%8x\n\
206 c_line=%2x  c_ispeed=%8x  c_ospeed=%8x\n",
207 t.c_iflag,t.c_oflag,t.c_cflag,t.c_lflag,t.c_line,t.c_ispeed,t.c_ospeed);
208 for (fd_in=NCCS;fd_in--;)
209   printf("c_cc[%d]=%2x  ",fd_in,t.c_cc[fd_in]);
210 **********/
211 /**  cfmakeraw(&t);  // getchar may not block !!  **/
212  t.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
213                  |INLCR|IGNCR|ICRNL|IXON);
214  t.c_oflag &= ~OPOST;
215  t.c_lflag &= ~(ECHO|ICANON|ISIG|IEXTEN);
216  t.c_cflag &= ~(CSIZE|PARENB);
217  t.c_cflag |= CS8;
218 
219  t.c_oflag |= OPOST;
220  t.c_cc[VMIN]=1;  /* get at least 1 character if read */
221  if (tcsetattr(fd_in, TCSANOW, &t))
222     exit((printf("Error: can't set terminal attributes\n"), 3));
223  printf("\033[=3h"); /* choose color 80x25 resolution */
224  printf("\033[%dm",40+(a&7));
225  c_cls();
226  printf("\033[;H");
227  c_refresh();
228 #else
229  c_cls();
230 #endif
231 }
232 
233 
234 /* waits for a key, returns keycode */
235 unsigned char
c_getkey(void)236 c_getkey(void)
237 {
238  int k;
239 #ifdef UNIX
240  while ((k=getchar()) == EOF); /* getchar may not block in non canonical mode */
241  switch(k)
242  {
243   case 9:
244   return K_TAB;
245 
246   case 13:
247   return K_ENTER;
248 
249   case 27:
250    switch(getchar())
251    {
252     case 91:
253     switch(getchar())
254     {
255      case 65:
256      return K_UP;
257 
258      case 66:
259      return K_DOWN;
260 
261      case 67:
262      return K_RIGHT;
263 
264      case 68:
265      return K_LEFT;
266     }
267    }
268   return K_ESCAPE;
269 
270   case 127:
271   return K_BACKSPACE;
272 
273   default:
274   return k;
275  }
276 #else
277  while ((k=getch()) == EOF); /* getch may not block in non canonical mode */
278  switch (k)
279  {
280   case 9:
281   return K_TAB;
282 
283   case 8:
284   return K_BACKSPACE;
285 
286   case 13:
287   return K_ENTER;
288 
289   case 27:
290   return K_ESCAPE;
291 
292   case 0:
293   switch(getch())
294   {
295    case 72:
296    return K_UP;
297 
298    case 80:
299    return K_DOWN;
300    break;
301 
302    case 75:
303    return K_LEFT;
304 
305    case 77:
306    return K_RIGHT;
307   }
308   break;
309 
310   default:
311   return k;
312  }
313 #endif
314 
315 return 0;  /* some C compilers are shitty and say "control reaches end of non void function" */
316 }
317 
318 
319 /* close console */
320 void
c_shutdown(void)321 c_shutdown(void)
322 {
323 #ifdef UNIX
324  tcsetattr(fd_in,TCSANOW,&term_setting);
325 #endif
326  c_cursor(C_NORMAL);
327 #ifdef UNIX
328  printf("\033[%dm",39); /* default foreground */
329  printf("\033[%dm",49); /* default background */
330 #endif
331  c_cls();
332 #ifdef UNIX
333  printf("\033[;H");
334  c_refresh();
335 #endif
336  console_ok=1;
337 }
338