1 /* Hey EMACS -*- linux-c -*- */
2 /* $Id: keymap.c 2610 2007-07-19 21:35:03Z kevinkofler $ */
3
4 /* TiEmu - Tiemu Is an EMUlator
5 *
6 * Copyright (c) 2000-2001, Thomas Corvazier, Romain Lievin
7 * Copyright (c) 2001-2003, Romain Lievin
8 * Copyright (c) 2003, Julien Blache
9 * Copyright (c) 2004, Romain Li�vin
10 * Copyright (c) 2005, Romain Li�vin
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
25 */
26
27 #ifdef HAVE_CONFIG_H
28 # include <config.h>
29 #endif
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <gtk/gtk.h>
35
36 #include "keydefs.h"
37 #include "pckeys.h"
38 #include "ti68k_int.h"
39 #include "keymap.h"
40 #include "logging.h"
41
42 #ifdef _MSC_VER
43 Pc2TiKey keymap[KEYMAP_MAX] = {0};
44 #else
45 Pc2TiKey keymap[KEYMAP_MAX] = {};
46 #endif
47
48 // search for key name and return key value (or -1 if not found)
keymap_string_to_value(const KeyTuple * array,const char * key_name)49 int keymap_string_to_value(const KeyTuple *array, const char *key_name)
50 {
51 KeyTuple *p;
52
53 for(p = (KeyTuple *)array; p->value != -1; p++)
54 if(!strcmp(p->name, key_name))
55 return p->value;
56
57 return -1;
58 }
59
60 // search for key value and return key name
keymap_value_to_string(const KeyTuple * array,int key_value)61 const char* keymap_value_to_string(const KeyTuple *array, int key_value)
62 {
63 KeyTuple *p;
64
65 for(p = (KeyTuple *)array; p->value != -1; p++)
66 if(key_value == p->value)
67 return p->name;
68
69 return "";
70 }
71
72 // return calc type or -1
keymap_read_header(const char * filename)73 int keymap_read_header(const char *filename)
74 {
75 FILE *f;
76 char line[256] = { 0 };
77
78 // open file
79 f = fopen(filename, "rt");
80 if(f == NULL)
81 {
82 fprintf(stderr, "unable to open keymap file <%s>.\n", filename);
83 return -1;
84 }
85
86 // read first line
87 if (!fgets(line, sizeof(line), f))
88 {
89 fprintf(stderr, "No calc model found !\n");
90 fclose(f);
91 return -1;
92 }
93 line[strlen(line) - 1] = '\0';
94 if(strncmp(line, "Model", strlen("Model")))
95 {
96 fprintf(stderr, "No calc model found !\n");
97 fclose(f);
98 return -1;
99 }
100
101 // close file
102 fclose(f);
103
104 // and convert
105 return ti68k_string_to_calctype(line + 7);
106 }
107
keymap_load(const char * filename)108 int keymap_load(const char *filename)
109 {
110 FILE *f;
111 char line[256];
112 int pckey, tikey, mod;
113 int idx = 0;
114
115 // open file
116 f = fopen(filename, "rt");
117 if(f == NULL)
118 {
119 fprintf(stderr, "unable to open keymap file <%s>.\n", filename);
120 return -1;
121 }
122
123 if (!fgets(line, sizeof(line), f))
124 {
125 fprintf(stderr, "No calc model found !\n");
126 fclose(f);
127 return -1;
128 }
129 line[strlen(line) - 1] = '\0';
130 if(strncmp(line, "Model", strlen("Model")))
131 {
132 fprintf(stderr, "No calc model found !\n");
133 fclose(f);
134 return -1;
135 }
136
137 // parse file
138 while(!feof(f))
139 {
140 gchar **split = { 0 };
141 gchar **split2 = { 0 };
142 char *p;
143
144 // remove cr/lf
145 if (!fgets(line, sizeof(line), f))
146 break;
147 //line[strlen(line) - 2] = '\0';
148 p = strrchr(line, '\r');
149 if(p != NULL) *p = '\0';
150 p = strrchr(line, '\n');
151 if(p != NULL) *p = '\0';
152
153 // skip comments
154 if((line[0] == '#') || (line[0] == '/'))
155 continue;
156
157 // split string
158 split = g_strsplit(line, ":", 2);
159 if((split[0] == NULL) || (split[1] == NULL))
160 {
161 g_strfreev(split);
162 continue;
163 }
164
165 // split sub-string
166 split2 = g_strsplit(split[1], ",", 2);
167 if(split2[0] == NULL)
168 {
169 g_strfreev(split2);
170 continue;
171 }
172
173 // convert key names into values
174 pckey = keymap_string_to_value(pckeys, split[0]);
175 if(pckey == -1)
176 {
177 fprintf(stderr, "Warning: non-existent PC key: <%s>\n", split[0]);
178 g_strfreev(split);
179 continue;
180 }
181
182 tikey = keymap_string_to_value(tikeys, split2[0]);
183 if(tikey == -1)
184 {
185 fprintf(stderr, "Warning: non-existent TI key: <%s>\n", split[1]);
186 g_strfreev(split);
187 continue;
188 }
189
190 if(split2[1] == NULL)
191 mod = -1;
192 else
193 mod = keymap_string_to_value(tikeys, split2[1]);
194
195 // and store value
196 keymap[idx].pc_key = pckey;
197 keymap[idx].ti_key = tikey;
198 keymap[idx].modifier = mod;
199 idx++;
200
201 // free mem
202 g_strfreev(split);
203 g_strfreev(split2);
204 }
205
206 // close file
207 tiemu_info(_("loading keymap: %s (%i keys)"), g_basename(filename), idx);
208 fclose(f);
209
210 return 0;
211 }
212