c0af0c4d46a21c57a5cdd76cb74fc0258c83a61f
[ansitris] / src / ansi.c
1 #include <stdio.h>
2 #include <string.h>
3
4 enum {
5         CS_ASCII = 'B',
6         CS_GRAPH = '0'
7 };
8
9 #define GMAP_FIRST      0xb0
10 #define GMAP_LAST       0xda
11
12 unsigned char gmap[] = {
13         0x61, 0x61, 0x61,               /* checker */
14         0x78,                                   /* vline */
15         0x75, 0x75, 0x75,               /* right T */
16         0x6b, 0x6b,                             /* upper-right corner */
17         0x75,                                   /* right T */
18         0x78,                                   /* vline */
19         0x6b,                                   /* upper-right corner */
20         0x6a, 0x6a, 0x6a,               /* lower-right corner */
21         0x6b,                                   /* upper-right corner */
22         0x6d,                                   /* lower-left corner */
23         0x76,                                   /* bottom T */
24         0x77,                                   /* top T */
25         0x74,                                   /* left T */
26         0x71,                                   /* hline */
27         0x6e,                                   /* cross */
28         0x74, 0x74,                             /* left T */
29         0x6d,                                   /* lower-left corner */
30         0x6c,                                   /* upper-left corner */
31         0x76,                                   /* bottom T */
32         0x77,                                   /* top T */
33         0x74,                                   /* left T */
34         0x71,                                   /* hline */
35         0x6e,                                   /* cross */
36         0x76, 0x76,                             /* bottom T */
37         0x77, 0x77,                             /* top T */
38         0x6d, 0x6d,                             /* lower-left corner */
39         0x6c, 0x6c,                             /* upper-left corner */
40         0x6e, 0x6e,                             /* cross */
41         0x6a,                                   /* lower-right corner */
42         0x6c                                    /* upper-left corner */
43 };
44
45 static unsigned char cmap[] = {0, 4, 2, 6, 1, 5, 3, 7};
46
47 static unsigned char cur_attr = 0xff;
48 static int cur_cs = CS_ASCII;
49
50 void ansi_reset(void)
51 {
52         fputs("\033c", stdout);
53         fflush(stdout);
54 }
55
56 void ansi_clearscr(void)
57 {
58         fputs("\033[2J", stdout);
59 }
60
61 void ansi_setcursor(int row, int col)
62 {
63         printf("\033[%d;%dH", row + 1, col + 1);
64 }
65
66 void ansi_ibmchar(unsigned char c, unsigned char attr)
67 {
68         char cmd[32];
69         char *ptr = cmd;
70
71         if(c >= GMAP_FIRST && c <= GMAP_LAST) {
72                 if(cur_cs == CS_ASCII) {
73                         memcpy(ptr, "\033(0", 3);
74                         ptr += 3;
75                         cur_cs = CS_GRAPH;
76                 }
77
78                 c = gmap[c - GMAP_FIRST];
79         } else {
80                 if(cur_cs == CS_GRAPH) {
81                         memcpy(ptr, "\033(B", 3);
82                         ptr += 3;
83                         cur_cs = CS_ASCII;
84                 }
85         }
86
87         if(attr != cur_attr) {
88                 unsigned char fg = cmap[attr & 7];
89                 unsigned char bg = cmap[(attr >> 4) & 7];
90
91                 ptr += sprintf(ptr, "\033[;%d;%dm", fg + 30, bg + 40);
92                 cur_attr = attr;
93         }
94
95         *ptr++ = c;
96         *ptr = 0;
97
98         fputs(cmd, stdout);
99 }