gl: clear w, h on reinit
[libpicofe.git] / config_file.c
1 /*
2  * (C) GraÅžvydas "notaz" Ignotas, 2011-2012
3  *
4  * This work is licensed under the terms of any of these licenses
5  * (at your option):
6  *  - GNU GPL, version 2 or later.
7  *  - GNU LGPL, version 2.1 or later.
8  *  - MAME license.
9  * See the COPYING file in the top-level directory.
10  */
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include "input.h"
16 #include "menu.h"
17 #include "config_file.h"
18 #include "lprintf.h"
19
20 #define array_size(x) (sizeof(x) / sizeof(x[0]))
21
22 static char *mystrip(char *str)
23 {
24         int i, len;
25
26         len = strlen(str);
27         for (i = 0; i < len; i++)
28                 if (str[i] != ' ') break;
29         if (i > 0) memmove(str, str + i, len - i + 1);
30
31         len = strlen(str);
32         for (i = len - 1; i >= 0; i--)
33                 if (str[i] != ' ' && str[i] != '\r' && str[i] != '\n') break;
34         str[i+1] = 0;
35
36         return str;
37 }
38
39 static void get_line(char *d, size_t size, const char *s)
40 {
41         const char *pe;
42         size_t len;
43
44         for (pe = s; *pe != '\r' && *pe != '\n' && *pe != 0; pe++)
45                 ;
46         len = pe - s;
47         if (len > size - 1)
48                 len = size - 1;
49         strncpy(d, s, len);
50         d[len] = 0;
51
52         mystrip(d);
53 }
54
55 void config_write_keys(FILE *f)
56 {
57         int d;
58
59         for (d = 0; d < IN_MAX_DEVS; d++)
60         {
61                 const int *binds = in_get_dev_binds(d);
62                 const char *name = in_get_dev_name(d, 0, 0);
63                 int k, count = 0;
64
65                 if (binds == NULL || name == NULL)
66                         continue;
67
68                 fprintf(f, "binddev = %s\n", name);
69                 in_get_config(d, IN_CFG_BIND_COUNT, &count);
70
71                 for (k = 0; k < count; k++)
72                 {
73                         int i, kbinds, mask;
74                         char act[32];
75
76                         act[0] = act[31] = 0;
77                         name = in_get_key_name(d, k);
78
79                         kbinds = binds[IN_BIND_OFFS(k, IN_BINDTYPE_PLAYER12)];
80                         for (i = 0; kbinds && me_ctrl_actions[i].name != NULL; i++) {
81                                 mask = me_ctrl_actions[i].mask;
82                                 if (mask & kbinds) {
83                                         strncpy(act, me_ctrl_actions[i].name, 31);
84                                         fprintf(f, "bind %s = player1 %s\n", name, mystrip(act));
85                                         kbinds &= ~mask;
86                                 }
87                                 mask = me_ctrl_actions[i].mask << 16;
88                                 if (mask & kbinds) {
89                                         strncpy(act, me_ctrl_actions[i].name, 31);
90                                         fprintf(f, "bind %s = player2 %s\n", name, mystrip(act));
91                                         kbinds &= ~mask;
92                                 }
93                         }
94
95                         kbinds = binds[IN_BIND_OFFS(k, IN_BINDTYPE_PLAYER34)];
96                         for (i = 0; kbinds && me_ctrl_actions[i].name != NULL; i++) {
97                                 mask = me_ctrl_actions[i].mask;
98                                 if (mask & kbinds) {
99                                         strncpy(act, me_ctrl_actions[i].name, 31);
100                                         fprintf(f, "bind %s = player3 %s\n", name, mystrip(act));
101                                         kbinds &= ~mask;
102                                 }
103                                 mask = me_ctrl_actions[i].mask << 16;
104                                 if (mask & kbinds) {
105                                         strncpy(act, me_ctrl_actions[i].name, 31);
106                                         fprintf(f, "bind %s = player4 %s\n", name, mystrip(act));
107                                         kbinds &= ~mask;
108                                 }
109                         }
110
111                         kbinds = binds[IN_BIND_OFFS(k, IN_BINDTYPE_EMU)];
112                         for (i = 0; kbinds && emuctrl_actions[i].name != NULL; i++) {
113                                 mask = emuctrl_actions[i].mask;
114                                 if (mask & kbinds) {
115                                         strncpy(act, emuctrl_actions[i].name, 31);
116                                         fprintf(f, "bind %s = %s\n", name, mystrip(act));
117                                         kbinds &= ~mask;
118                                 }
119                         }
120                 }
121
122 #ifdef ANALOG_BINDS
123                 for (k = 0; k < array_size(in_adev); k++)
124                 {
125                         if (in_adev[k] == d)
126                                 fprintf(f, "bind_analog = %d\n", k);
127                 }
128 #endif
129         }
130 }
131
132 static int parse_bind_val(const char *val, int *type)
133 {
134         int i;
135
136         *type = IN_BINDTYPE_NONE;
137         if (val[0] == 0)
138                 return 0;
139         
140         if (strncasecmp(val, "player", 6) == 0)
141         {
142                 int player, shift = 0;
143                 player = atoi(val + 6) - 1;
144
145                 if ((unsigned int)player > 3)
146                         return -1;
147                 if (player & 1)
148                         shift = 16;
149
150                 *type = IN_BINDTYPE_PLAYER12 + (player >> 1);
151                 for (i = 0; me_ctrl_actions[i].name != NULL; i++) {
152                         if (strncasecmp(me_ctrl_actions[i].name, val + 8, strlen(val + 8)) == 0)
153                                 return me_ctrl_actions[i].mask << shift;
154                 }
155         }
156         for (i = 0; emuctrl_actions[i].name != NULL; i++) {
157                 if (strncasecmp(emuctrl_actions[i].name, val, strlen(val)) == 0) {
158                         *type = IN_BINDTYPE_EMU;
159                         return emuctrl_actions[i].mask;
160                 }
161         }
162
163         return -1;
164 }
165
166 void config_read_keys(const char *cfg_content)
167 {
168         char dev[256], key[128], *act;
169         const char *p;
170         int bind, bindtype;
171         int dev_id;
172
173         p = cfg_content;
174         while (p != NULL && (p = strstr(p, "binddev = ")) != NULL) {
175                 p += 10;
176
177                 get_line(dev, sizeof(dev), p);
178                 dev_id = in_config_parse_dev(dev);
179                 if (dev_id < 0) {
180                         printf("input: can't handle dev: %s\n", dev);
181                         continue;
182                 }
183
184                 in_unbind_all(dev_id, -1, -1);
185                 while ((p = strstr(p, "bind"))) {
186                         if (strncmp(p, "binddev = ", 10) == 0)
187                                 break;
188
189 #ifdef ANALOG_BINDS
190                         if (strncmp(p, "bind_analog", 11) == 0) {
191                                 int ret = sscanf(p, "bind_analog = %d", &bind);
192                                 p += 11;
193                                 if (ret != 1) {
194                                         printf("input: parse error: %16s..\n", p);
195                                         continue;
196                                 }
197                                 if ((unsigned int)bind >= array_size(in_adev)) {
198                                         printf("input: analog id %d out of range\n", bind);
199                                         continue;
200                                 }
201                                 in_adev[bind] = dev_id;
202                                 continue;
203                         }
204 #endif
205
206                         p += 4;
207                         if (*p != ' ') {
208                                 printf("input: parse error: %16s..\n", p);
209                                 continue;
210                         }
211
212                         get_line(key, sizeof(key), p);
213                         act = strchr(key, '=');
214                         if (act == NULL) {
215                                 printf("parse failed: %16s..\n", p);
216                                 continue;
217                         }
218                         *act = 0;
219                         act++;
220                         mystrip(key);
221                         mystrip(act);
222
223                         bind = parse_bind_val(act, &bindtype);
224                         if (bind != -1 && bind != 0) {
225                                 //printf("bind #%d '%s' %08x (%s)\n", dev_id, key, bind, act);
226                                 in_config_bind_key(dev_id, key, bind, bindtype);
227                         }
228                         else
229                                 lprintf("config: unhandled action \"%s\"\n", act);
230                 }
231         }
232         in_clean_binds();
233 }