gl: clear w, h on reinit
[libpicofe.git] / config_file.c
CommitLineData
0418cc5c 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.
f89d8471 8 * - MAME license.
0418cc5c 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
22static 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
39static 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
55void 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
25cfdf0a 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
0418cc5c 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
132static 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
25cfdf0a 145 if ((unsigned int)player > 3)
0418cc5c 146 return -1;
25cfdf0a 147 if (player & 1)
0418cc5c 148 shift = 16;
149
25cfdf0a 150 *type = IN_BINDTYPE_PLAYER12 + (player >> 1);
0418cc5c 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
7b0a2985 166void config_read_keys(const char *cfg_content)
0418cc5c 167{
168 char dev[256], key[128], *act;
169 const char *p;
170 int bind, bindtype;
171 int dev_id;
172
7b0a2985 173 p = cfg_content;
0418cc5c 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}