Mercurial > repos > blastem
diff io.c @ 1187:6a4503fad67e
Initial support for using SDL2 game controller mapping functionality
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 22 Jan 2017 16:23:59 -0800 |
parents | 3e24de8d8073 |
children | 1ad0ec7e3939 |
line wrap: on
line diff
--- a/io.c Sun Jan 22 16:13:02 2017 -0800 +++ b/io.c Sun Jan 22 16:23:59 2017 -0800 @@ -923,6 +923,49 @@ } } +typedef struct { + int padnum; + tern_node *padbuttons; + tern_node *mousebuttons; +} pad_button_state; + +void process_pad_button(char *key, tern_val val, void *data) +{ + pad_button_state *state = data; + int hostpadnum = state->padnum; + int ui_func, padnum, button; + int bindtype = parse_binding_target(val.ptrval, state->padbuttons, state->mousebuttons, &ui_func, &padnum, &button); + char *end; + long hostbutton = strtol(key, &end, 10); + if (*end) { + //key is not a valid base 10 integer + hostbutton = render_translate_input_name(hostpadnum, key); + if (hostbutton < 0) { + if (hostbutton == RENDER_INVALID_NAME) { + warning("%s is not a valid gamepad input name\n", key); + } else if (hostbutton == RENDER_NOT_MAPPED) { + warning("No mapping exists for input %s on gamepad %d\n", key, hostpadnum); + } + return; + } + if (hostbutton & RENDER_DPAD_BIT) { + if (bindtype == BIND_GAMEPAD1) { + bind_dpad_gamepad(hostpadnum, render_dpad_part(hostbutton), render_direction_part(hostbutton), padnum, button); + } else { + bind_dpad_ui(hostpadnum, render_dpad_part(hostbutton), render_direction_part(hostbutton), ui_func, button); + } + } else if (hostbutton & RENDER_AXIS_BIT) { + //TODO: support analog axes + return; + } + } + if (bindtype == BIND_GAMEPAD1) { + bind_button_gamepad(hostpadnum, hostbutton, padnum, button); + } else if (bindtype == BIND_UI) { + bind_button_ui(hostpadnum, hostbutton, ui_func, button); + } +} + void set_keybindings(sega_io *io) { static uint8_t already_done; @@ -988,6 +1031,9 @@ mousebuttons = tern_insert_int(mousebuttons, ".start", MOUSE_START); mousebuttons = tern_insert_int(mousebuttons, ".motion", PSEUDO_BUTTON_MOTION); + //pump event loop, so initial joystick insertion events are processed + process_events(); + tern_node * keys = tern_get_node(tern_find_path(config, "bindings\0keys\0")); process_keys(keys, special, padbuttons, mousebuttons, NULL); char numstr[] = "00"; @@ -1030,26 +1076,13 @@ } tern_node *button_node = tern_find_ptr(pad, "buttons"); if (button_node) { - for (int but = 0; but < 30; but++) - { - if (but < 10) { - numstr[0] = but + '0'; - numstr[1] = 0; - } else { - numstr[0] = but/10 + '0'; - numstr[1] = but%10 + '0'; - } - char * target = tern_find_ptr(button_node, numstr); - if (target) { - int ui_func, padnum, button; - int bindtype = parse_binding_target(target, padbuttons, mousebuttons, &ui_func, &padnum, &button); - if (bindtype == BIND_GAMEPAD1) { - bind_button_gamepad(i, but, padnum, button); - } else if (bindtype == BIND_UI) { - bind_button_ui(i, but, ui_func, button); - } - } - } + pad_button_state state = { + .padnum = i, + .padbuttons = padbuttons, + .mousebuttons = mousebuttons + }; + tern_foreach(button_node, process_pad_button, &state); + } } }