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