1*6a5c94d9SSamuel Thibault // SPDX-License-Identifier: GPL-2.0+
2*6a5c94d9SSamuel Thibault /* genmap.c
3*6a5c94d9SSamuel Thibault * originally written by: Kirk Reiser.
4*6a5c94d9SSamuel Thibault *
5*6a5c94d9SSamuel Thibault ** Copyright (C) 2002 Kirk Reiser.
6*6a5c94d9SSamuel Thibault * Copyright (C) 2003 David Borowski.
7*6a5c94d9SSamuel Thibault */
8*6a5c94d9SSamuel Thibault
9*6a5c94d9SSamuel Thibault #include <stdlib.h>
10*6a5c94d9SSamuel Thibault #include <stdio.h>
11*6a5c94d9SSamuel Thibault #include <libgen.h>
12*6a5c94d9SSamuel Thibault #include <string.h>
13*6a5c94d9SSamuel Thibault #include <ctype.h>
14*6a5c94d9SSamuel Thibault #include "utils.h"
15*6a5c94d9SSamuel Thibault
16*6a5c94d9SSamuel Thibault struct st_key_init {
17*6a5c94d9SSamuel Thibault char *name;
18*6a5c94d9SSamuel Thibault int value, shift;
19*6a5c94d9SSamuel Thibault };
20*6a5c94d9SSamuel Thibault
21*6a5c94d9SSamuel Thibault static unsigned char key_data[MAXKEYVAL][16], *kp;
22*6a5c94d9SSamuel Thibault
23*6a5c94d9SSamuel Thibault #include "mapdata.h"
24*6a5c94d9SSamuel Thibault
25*6a5c94d9SSamuel Thibault static const char delims[] = "\t\n ";
26*6a5c94d9SSamuel Thibault static char *cp;
27*6a5c94d9SSamuel Thibault static int map_ver = 119; /* an arbitrary number so speakup can check */
28*6a5c94d9SSamuel Thibault static int shift_table[17];
29*6a5c94d9SSamuel Thibault static int max_states = 1, flags;
30*6a5c94d9SSamuel Thibault /* flags reserved for later, maybe for individual console maps */
31*6a5c94d9SSamuel Thibault
get_shift_value(int state)32*6a5c94d9SSamuel Thibault static int get_shift_value(int state)
33*6a5c94d9SSamuel Thibault {
34*6a5c94d9SSamuel Thibault int i;
35*6a5c94d9SSamuel Thibault
36*6a5c94d9SSamuel Thibault for (i = 0; shift_table[i] != state; i++) {
37*6a5c94d9SSamuel Thibault if (shift_table[i] == -1) {
38*6a5c94d9SSamuel Thibault if (i >= 16)
39*6a5c94d9SSamuel Thibault oops("too many shift states", NULL);
40*6a5c94d9SSamuel Thibault shift_table[i] = state;
41*6a5c94d9SSamuel Thibault max_states = i+1;
42*6a5c94d9SSamuel Thibault break;
43*6a5c94d9SSamuel Thibault }
44*6a5c94d9SSamuel Thibault }
45*6a5c94d9SSamuel Thibault return i;
46*6a5c94d9SSamuel Thibault }
47*6a5c94d9SSamuel Thibault
48*6a5c94d9SSamuel Thibault int
main(int argc,char * argv[])49*6a5c94d9SSamuel Thibault main(int argc, char *argv[])
50*6a5c94d9SSamuel Thibault {
51*6a5c94d9SSamuel Thibault int value, shift_state, i, spk_val = 0, lock_val = 0;
52*6a5c94d9SSamuel Thibault int max_key_used = 0, num_keys_used = 0;
53*6a5c94d9SSamuel Thibault struct st_key *this;
54*6a5c94d9SSamuel Thibault struct st_key_init *p_init;
55*6a5c94d9SSamuel Thibault char buffer[256];
56*6a5c94d9SSamuel Thibault
57*6a5c94d9SSamuel Thibault bzero(key_table, sizeof(key_table));
58*6a5c94d9SSamuel Thibault bzero(key_data, sizeof(key_data));
59*6a5c94d9SSamuel Thibault
60*6a5c94d9SSamuel Thibault shift_table[0] = 0;
61*6a5c94d9SSamuel Thibault for (i = 1; i <= 16; i++)
62*6a5c94d9SSamuel Thibault shift_table[i] = -1;
63*6a5c94d9SSamuel Thibault
64*6a5c94d9SSamuel Thibault if (argc < 2) {
65*6a5c94d9SSamuel Thibault fputs("usage: genmap filename\n", stderr);
66*6a5c94d9SSamuel Thibault exit(1);
67*6a5c94d9SSamuel Thibault }
68*6a5c94d9SSamuel Thibault
69*6a5c94d9SSamuel Thibault for (p_init = init_key_data; p_init->name[0] != '.'; p_init++)
70*6a5c94d9SSamuel Thibault add_key(p_init->name, p_init->value, p_init->shift);
71*6a5c94d9SSamuel Thibault
72*6a5c94d9SSamuel Thibault open_input(NULL, argv[1]);
73*6a5c94d9SSamuel Thibault while (fgets(buffer, sizeof(buffer), infile)) {
74*6a5c94d9SSamuel Thibault lc++;
75*6a5c94d9SSamuel Thibault value = shift_state = 0;
76*6a5c94d9SSamuel Thibault
77*6a5c94d9SSamuel Thibault cp = strtok(buffer, delims);
78*6a5c94d9SSamuel Thibault if (*cp == '#')
79*6a5c94d9SSamuel Thibault continue;
80*6a5c94d9SSamuel Thibault
81*6a5c94d9SSamuel Thibault while (cp) {
82*6a5c94d9SSamuel Thibault if (*cp == '=')
83*6a5c94d9SSamuel Thibault break;
84*6a5c94d9SSamuel Thibault this = find_key(cp);
85*6a5c94d9SSamuel Thibault if (this == NULL)
86*6a5c94d9SSamuel Thibault oops("unknown key/modifier", cp);
87*6a5c94d9SSamuel Thibault if (this->shift == is_shift) {
88*6a5c94d9SSamuel Thibault if (value)
89*6a5c94d9SSamuel Thibault oops("modifiers must come first", cp);
90*6a5c94d9SSamuel Thibault shift_state += this->value;
91*6a5c94d9SSamuel Thibault } else if (this->shift == is_input)
92*6a5c94d9SSamuel Thibault value = this->value;
93*6a5c94d9SSamuel Thibault else
94*6a5c94d9SSamuel Thibault oops("bad modifier or key", cp);
95*6a5c94d9SSamuel Thibault cp = strtok(0, delims);
96*6a5c94d9SSamuel Thibault }
97*6a5c94d9SSamuel Thibault if (!cp)
98*6a5c94d9SSamuel Thibault oops("no = found", NULL);
99*6a5c94d9SSamuel Thibault
100*6a5c94d9SSamuel Thibault cp = strtok(0, delims);
101*6a5c94d9SSamuel Thibault if (!cp)
102*6a5c94d9SSamuel Thibault oops("no speakup function after =", NULL);
103*6a5c94d9SSamuel Thibault
104*6a5c94d9SSamuel Thibault this = find_key(cp);
105*6a5c94d9SSamuel Thibault if (this == NULL || this->shift != is_spk)
106*6a5c94d9SSamuel Thibault oops("invalid speakup function", cp);
107*6a5c94d9SSamuel Thibault
108*6a5c94d9SSamuel Thibault i = get_shift_value(shift_state);
109*6a5c94d9SSamuel Thibault if (key_data[value][i]) {
110*6a5c94d9SSamuel Thibault while (--cp > buffer)
111*6a5c94d9SSamuel Thibault if (!*cp)
112*6a5c94d9SSamuel Thibault *cp = ' ';
113*6a5c94d9SSamuel Thibault oops("two functions on same key combination", cp);
114*6a5c94d9SSamuel Thibault }
115*6a5c94d9SSamuel Thibault key_data[value][i] = (char)this->value;
116*6a5c94d9SSamuel Thibault if (value > max_key_used)
117*6a5c94d9SSamuel Thibault max_key_used = value;
118*6a5c94d9SSamuel Thibault }
119*6a5c94d9SSamuel Thibault fclose(infile);
120*6a5c94d9SSamuel Thibault
121*6a5c94d9SSamuel Thibault this = find_key("spk_key");
122*6a5c94d9SSamuel Thibault if (this)
123*6a5c94d9SSamuel Thibault spk_val = this->value;
124*6a5c94d9SSamuel Thibault
125*6a5c94d9SSamuel Thibault this = find_key("spk_lock");
126*6a5c94d9SSamuel Thibault if (this)
127*6a5c94d9SSamuel Thibault lock_val = this->value;
128*6a5c94d9SSamuel Thibault
129*6a5c94d9SSamuel Thibault for (lc = 1; lc <= max_key_used; lc++) {
130*6a5c94d9SSamuel Thibault kp = key_data[lc];
131*6a5c94d9SSamuel Thibault if (!memcmp(key_data[0], kp, 16))
132*6a5c94d9SSamuel Thibault continue;
133*6a5c94d9SSamuel Thibault num_keys_used++;
134*6a5c94d9SSamuel Thibault for (i = 0; i < max_states; i++) {
135*6a5c94d9SSamuel Thibault if (kp[i] != spk_val && kp[i] != lock_val)
136*6a5c94d9SSamuel Thibault continue;
137*6a5c94d9SSamuel Thibault shift_state = shift_table[i];
138*6a5c94d9SSamuel Thibault if (shift_state&16)
139*6a5c94d9SSamuel Thibault continue;
140*6a5c94d9SSamuel Thibault shift_state = get_shift_value(shift_state+16);
141*6a5c94d9SSamuel Thibault kp[shift_state] = kp[i];
142*6a5c94d9SSamuel Thibault /* fill in so we can process the key up, as spk bit will be set */
143*6a5c94d9SSamuel Thibault }
144*6a5c94d9SSamuel Thibault }
145*6a5c94d9SSamuel Thibault
146*6a5c94d9SSamuel Thibault printf("\t%d, %d, %d,\n\t", map_ver, num_keys_used, max_states);
147*6a5c94d9SSamuel Thibault for (i = 0; i < max_states; i++)
148*6a5c94d9SSamuel Thibault printf("%d, ", shift_table[i]);
149*6a5c94d9SSamuel Thibault printf("%d,", flags);
150*6a5c94d9SSamuel Thibault for (lc = 1; lc <= max_key_used; lc++) {
151*6a5c94d9SSamuel Thibault kp = key_data[lc];
152*6a5c94d9SSamuel Thibault if (!memcmp(key_data[0], kp, 16))
153*6a5c94d9SSamuel Thibault continue;
154*6a5c94d9SSamuel Thibault printf("\n\t%d,", lc);
155*6a5c94d9SSamuel Thibault for (i = 0; i < max_states; i++)
156*6a5c94d9SSamuel Thibault printf(" %d,", (unsigned int)kp[i]);
157*6a5c94d9SSamuel Thibault }
158*6a5c94d9SSamuel Thibault printf("\n\t0, %d\n", map_ver);
159*6a5c94d9SSamuel Thibault
160*6a5c94d9SSamuel Thibault exit(0);
161*6a5c94d9SSamuel Thibault }
162