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