Mercurial > repos > blastem
comparison io.c @ 432:18cde14e8c10
Read joystick bindings from config file
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 10 Jul 2013 23:47:48 -0700 |
parents | 440efd7d27a9 |
children | afbea09d7fb4 |
comparison
equal
deleted
inserted
replaced
431:440efd7d27a9 | 432:18cde14e8c10 |
---|---|
250 handle_binding_up(dpad->bindings + i); | 250 handle_binding_up(dpad->bindings + i); |
251 } | 251 } |
252 } | 252 } |
253 } | 253 } |
254 | 254 |
255 int parse_binding_target(char * target, tern_node * padbuttons, int * ui_out, int * padnum_out, int * padbutton_out) | |
256 { | |
257 int gpadslen = strlen("gamepads."); | |
258 if (!memcmp(target, "gamepads.", gpadslen)) { | |
259 if (target[gpadslen] >= '1' && target[gpadslen] <= '8') { | |
260 int padnum = target[gpadslen] - '0'; | |
261 int button = tern_find_int(padbuttons, target + gpadslen + 1, 0); | |
262 if (button) { | |
263 *padnum_out = padnum; | |
264 *padbutton_out = button; | |
265 return 1; | |
266 } else { | |
267 if (target[gpadslen+1]) { | |
268 fprintf(stderr, "Gamepad mapping string '%s' refers to an invalid button '%s'\n", target, target + gpadslen + 1); | |
269 } else { | |
270 fprintf(stderr, "Gamepad mapping string '%s' has no button component\n", target); | |
271 } | |
272 } | |
273 } else { | |
274 fprintf(stderr, "Gamepad mapping string '%s' refers to an invalid gamepad number %c\n", target, target[gpadslen]); | |
275 } | |
276 } else if(!memcmp(target, "ui.", strlen("ui."))) { | |
277 if (!strcmp(target + 3, "vdp_debug_mode")) { | |
278 *ui_out = UI_DEBUG_MODE_INC; | |
279 } else if(!strcmp(target + 3, "vdp_debug_pal")) { | |
280 *ui_out = UI_DEBUG_PAL_INC; | |
281 } else if(!strcmp(target + 3, "enter_debugger")) { | |
282 *ui_out = UI_ENTER_DEBUGGER; | |
283 } else { | |
284 fprintf(stderr, "Unreconized UI binding type %s\n", target); | |
285 return 0; | |
286 } | |
287 return 2; | |
288 } else { | |
289 fprintf(stderr, "Unrecognized binding type %s\n", target); | |
290 } | |
291 return 0; | |
292 } | |
293 | |
255 void process_keys(tern_node * cur, tern_node * special, tern_node * padbuttons, char * prefix) | 294 void process_keys(tern_node * cur, tern_node * special, tern_node * padbuttons, char * prefix) |
256 { | 295 { |
257 char * curstr; | 296 char * curstr; |
258 int len; | 297 int len; |
259 if (!cur) { | 298 if (!cur) { |
279 if (curstr[1] != 0) { | 318 if (curstr[1] != 0) { |
280 fprintf(stderr, "%s is not recognized as a key identifier, truncating to %c\n", curstr, curstr[0]); | 319 fprintf(stderr, "%s is not recognized as a key identifier, truncating to %c\n", curstr, curstr[0]); |
281 } | 320 } |
282 } | 321 } |
283 char * target = cur->straight.value.ptrval; | 322 char * target = cur->straight.value.ptrval; |
284 int gpadslen = strlen("gamepads."); | 323 int ui_func, padnum, button; |
285 if (!memcmp(target, "gamepads.", gpadslen)) { | 324 int bindtype = parse_binding_target(target, padbuttons, &ui_func, &padnum, &button); |
286 if (target[gpadslen] >= '1' && target[gpadslen] <= '8') { | 325 if (bindtype == 1) { |
287 int padnum = target[gpadslen] - '0'; | 326 bind_gamepad(keycode, padnum, button); |
288 int button = tern_find_int(padbuttons, target + gpadslen + 1, 0); | 327 } else if(bindtype == 2) { |
289 if (button) { | 328 bind_ui(keycode, ui_func); |
290 bind_gamepad(keycode, padnum, button); | |
291 } else { | |
292 if (target[gpadslen+1]) { | |
293 fprintf(stderr, "Gamepad mapping string '%s' refers to an invalid button '%s'\n", target, target + gpadslen + 1); | |
294 } else { | |
295 fprintf(stderr, "Gamepad mapping string '%s' has no button component\n", target); | |
296 } | |
297 } | |
298 } else { | |
299 fprintf(stderr, "Gamepad mapping string '%s' refers to an invalid gamepad number %c\n", target, target[gpadslen]); | |
300 } | |
301 } else if(!memcmp(target, "ui.", strlen("ui."))) { | |
302 if (!strcmp(target + 3, "vdp_debug_mode")) { | |
303 bind_ui(keycode, UI_DEBUG_MODE_INC); | |
304 } else if(!strcmp(target + 3, "vdp_debug_pal")) { | |
305 bind_ui(keycode, UI_DEBUG_PAL_INC); | |
306 } else if(!strcmp(target + 3, "enter_debugger")) { | |
307 bind_ui(keycode, UI_ENTER_DEBUGGER); | |
308 } else { | |
309 fprintf(stderr, "Unreconized UI binding type %s for key %s\n", target, curstr); | |
310 } | |
311 } else { | |
312 fprintf(stderr, "Unrecognized binding type %s for key %s\n", target, curstr); | |
313 } | 329 } |
314 } | 330 } |
315 process_keys(cur->left, special, padbuttons, prefix); | 331 process_keys(cur->left, special, padbuttons, prefix); |
316 process_keys(cur->right, special, padbuttons, prefix); | 332 process_keys(cur->right, special, padbuttons, prefix); |
317 } | 333 } |
337 padbuttons = tern_insert_int(padbuttons, ".start", BUTTON_START); | 353 padbuttons = tern_insert_int(padbuttons, ".start", BUTTON_START); |
338 padbuttons = tern_insert_int(padbuttons, ".mode", BUTTON_MODE); | 354 padbuttons = tern_insert_int(padbuttons, ".mode", BUTTON_MODE); |
339 | 355 |
340 tern_node * keys = tern_find_prefix(config, "bindingskeys"); | 356 tern_node * keys = tern_find_prefix(config, "bindingskeys"); |
341 process_keys(keys, special, padbuttons, NULL); | 357 process_keys(keys, special, padbuttons, NULL); |
342 | 358 char prefix[] = "bindingspads00"; |
343 bind_dpad_gamepad(0, 0, RENDER_DPAD_UP, 2, DPAD_UP); | 359 for (int i = 0; i < 100 && i < render_num_joysticks(); i++) |
344 bind_dpad_gamepad(0, 0, RENDER_DPAD_DOWN, 2, DPAD_DOWN); | 360 { |
345 bind_dpad_gamepad(0, 0, RENDER_DPAD_LEFT, 2, DPAD_LEFT); | 361 if (i < 10) { |
346 bind_dpad_gamepad(0, 0, RENDER_DPAD_RIGHT, 2, DPAD_RIGHT); | 362 prefix[strlen("bindingspads")] = i + '0'; |
347 bind_button_gamepad(0, 0, 2, BUTTON_A); | 363 prefix[strlen("bindingspads")+1] = 0; |
348 bind_button_gamepad(0, 1, 2, BUTTON_B); | 364 } else { |
349 bind_button_gamepad(0, 2, 2, BUTTON_C); | 365 prefix[strlen("bindingspads")] = i/10 + '0'; |
350 bind_button_gamepad(0, 3, 2, BUTTON_X); | 366 prefix[strlen("bindingspads")+1] = i%10 + '0'; |
351 bind_button_gamepad(0, 4, 2, BUTTON_Y); | 367 } |
352 bind_button_gamepad(0, 5, 2, BUTTON_Z); | 368 tern_node * pad = tern_find_prefix(config, prefix); |
353 bind_button_gamepad(0, 6, 2, BUTTON_START); | 369 if (pad) { |
354 bind_button_gamepad(0, 7, 2, BUTTON_MODE); | 370 char dprefix[] = "dpads0"; |
371 for (int dpad = 0; dpad < 10 && dpad < render_joystick_num_hats(i); dpad++) | |
372 { | |
373 dprefix[strlen("dpads")] = dpad + '0'; | |
374 tern_node * pad_dpad = tern_find_prefix(pad, dprefix); | |
375 char * dirs[] = {"up", "down", "left", "right"}; | |
376 int dirnums[] = {RENDER_DPAD_UP, RENDER_DPAD_DOWN, RENDER_DPAD_LEFT, RENDER_DPAD_RIGHT}; | |
377 for (int dir = 0; dir < sizeof(dirs)/sizeof(dirs[0]); dir++) { | |
378 char * target = tern_find_ptr(pad_dpad, dirs[dir]); | |
379 if (target) { | |
380 int ui_func, padnum, button; | |
381 int bindtype = parse_binding_target(target, padbuttons, &ui_func, &padnum, &button); | |
382 if (bindtype == 1) { | |
383 bind_dpad_gamepad(i, dpad, dirnums[dir], padnum, button); | |
384 } | |
385 //TODO: Handle UI bindings | |
386 } | |
387 } | |
388 } | |
389 char bprefix[] = "buttons00"; | |
390 for (int but = 0; but < 100 && but < render_joystick_num_buttons(i); but++) | |
391 { | |
392 if (but < 10) { | |
393 bprefix[strlen("buttons")] = but + '0'; | |
394 bprefix[strlen("buttons")+1] = 0; | |
395 } else { | |
396 bprefix[strlen("buttons")] = but/10 + '0'; | |
397 bprefix[strlen("buttons")+1] = but%10 + '0'; | |
398 } | |
399 char * target = tern_find_ptr(pad, bprefix); | |
400 if (target) { | |
401 int ui_func, padnum, button; | |
402 int bindtype = parse_binding_target(target, padbuttons, &ui_func, &padnum, &button); | |
403 if (bindtype == 1) { | |
404 bind_button_gamepad(i, but, padnum, button); | |
405 } | |
406 //TODO: Handle UI bindings | |
407 } | |
408 } | |
409 } | |
410 } | |
355 } | 411 } |
356 | 412 |
357 #define TH 0x40 | 413 #define TH 0x40 |
358 #define TH_TIMEOUT 8000 | 414 #define TH_TIMEOUT 8000 |
359 | 415 |