# HG changeset patch # User Michael Pavone # Date 1532968681 25200 # Node ID 7f39c40b4b25f66e6948df42825492c4076d9327 # Parent 1fc61c844ec5fe166d0ac7ae036fe197dcbcb9c5 WIP UI for creating an SDL2 mapping for controllers that don't have one diff -r 1fc61c844ec5 -r 7f39c40b4b25 controller_info.c --- a/controller_info.c Fri Jul 27 22:40:56 2018 -0700 +++ b/controller_info.c Mon Jul 30 09:38:01 2018 -0700 @@ -149,6 +149,16 @@ } +void save_controller_mapping(int joystick, char *mapping_string) +{ + char guid_string[33]; + SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(render_get_joystick(joystick)), guid_string, sizeof(guid_string)); + tern_node *existing = tern_find_node(info_config, guid_string); + existing = tern_insert_ptr(existing, "mapping", mapping_string); + info_config = tern_insert_node(info_config, guid_string, existing); + persist_config_at(info_config, "controller_types.cfg"); +} + char const *labels_xbox[] = { "A", "B", "X", "Y", "Back", NULL, "Start", "Click", "Click", "White", "Black", "LT", "RT" }; diff -r 1fc61c844ec5 -r 7f39c40b4b25 controller_info.h --- a/controller_info.h Fri Jul 27 22:40:56 2018 -0700 +++ b/controller_info.h Mon Jul 30 09:38:01 2018 -0700 @@ -44,5 +44,6 @@ const char *get_button_label(controller_info *info, int button); const char *get_axis_label(controller_info *info, int axis); void save_controller_info(int joystick, controller_info *info); +void save_controller_mapping(int joystick, char *mapping_string); #endif //CONTROLLER_INFO_H_ \ No newline at end of file diff -r 1fc61c844ec5 -r 7f39c40b4b25 nuklear_ui/blastem_nuklear.c --- a/nuklear_ui/blastem_nuklear.c Fri Jul 27 22:40:56 2018 -0700 +++ b/nuklear_ui/blastem_nuklear.c Mon Jul 30 09:38:01 2018 -0700 @@ -693,6 +693,67 @@ } } +static int current_button; +static int button_pressed, last_button; +static int hat_moved, hat_value, last_hat, last_hat_value; +static char *mapping_string; +static size_t mapping_pos; +void view_controller_mappings(struct nk_context *context) +{ + char buffer[512]; + uint8_t added_mapping = 0; + if (nk_begin(context, "Controllers", nk_rect(0, 0, render_width(), render_height()), NK_WINDOW_NO_SCROLLBAR)) { + nk_layout_row_static(context, render_height() - context->style.font->height, render_width() - context->style.font->height, 1); + snprintf(buffer, sizeof(buffer), "Press Button %s", get_button_label(&selected_controller_info, current_button)); + nk_label(context, buffer, NK_TEXT_CENTERED); + if (button_pressed >= 0 && button_pressed != last_button) { + mapping_string[mapping_pos++] = ','; + const char *name = SDL_GameControllerGetStringForButton(current_button); + size_t namesz = strlen(name); + memcpy(mapping_string + mapping_pos, name, namesz); + mapping_pos += namesz; + mapping_string[mapping_pos++] = ':'; + mapping_string[mapping_pos++] = 'b'; + if (button_pressed > 9) { + mapping_string[mapping_pos++] = '0' + button_pressed / 10; + } + mapping_string[mapping_pos++] = '0' + button_pressed % 10; + added_mapping = 1; + last_button = button_pressed; + } + else if (hat_moved >= 0 && hat_value && (hat_moved != last_hat || hat_value != last_hat_value)) { + mapping_string[mapping_pos++] = ','; + const char *name = SDL_GameControllerGetStringForButton(current_button); + size_t namesz = strlen(name); + memcpy(mapping_string + mapping_pos, name, namesz); + mapping_pos += namesz; + mapping_string[mapping_pos++] = ':'; + mapping_string[mapping_pos++] = 'h'; + mapping_string[mapping_pos++] = '0' + hat_moved; + mapping_string[mapping_pos++] = '.'; + mapping_string[mapping_pos++] = '0' + hat_value; + added_mapping = 1; + + last_hat = hat_moved; + last_hat_value = hat_value; + } + if (added_mapping) { + current_button++; + if (current_button == SDL_CONTROLLER_BUTTON_MAX) { + mapping_string[mapping_pos] = 0; + save_controller_mapping(selected_controller, mapping_string); + free(mapping_string); + pop_view(); + push_view(view_controller_bindings); + + } + } + button_pressed = -1; + hat_moved = -1; + nk_end(context); + } +} + void controller_type_group(struct nk_context *context, char *name, int type_id, int first_subtype_id, const char **types, uint32_t num_types) { nk_layout_row_static(context, (context->style.font->height + 3) * num_types + context->style.font->height, render_width() - 80, 1); @@ -703,8 +764,27 @@ if (nk_button_label(context, types[i])) { selected_controller_info.subtype = first_subtype_id + i; save_controller_info(selected_controller, &selected_controller_info); + selected_controller_info = get_controller_info(selected_controller); pop_view(); - push_view(view_controller_bindings); + SDL_GameController *controller = render_get_controller(selected_controller); + if (controller) { + push_view(view_controller_bindings); + SDL_GameControllerClose(controller); + } else { + current_button = SDL_CONTROLLER_BUTTON_A; + button_pressed = -1; + last_button = -1; + SDL_Joystick *joy = render_get_joystick(selected_controller); + const char *name = SDL_JoystickName(joy); + size_t namesz = strlen(name); + mapping_string = malloc(512 + namesz); + SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joy), mapping_string, 33); + mapping_string[32] = ','; + memcpy(mapping_string + 33, name, namesz); + mapping_pos = 33+namesz; + + push_view(view_controller_mappings); + } } } nk_group_end(context); @@ -1225,6 +1305,13 @@ if (event->type == SDL_KEYDOWN) { keycode = event->key.keysym.sym; } + else if (event->type == SDL_JOYBUTTONDOWN) { + button_pressed = event->jbutton.button; + } + else if (event->type == SDL_JOYHATMOTION) { + hat_moved = event->jhat.which; + hat_value = event->jhat.value; + } nk_sdl_handle_event(event); } diff -r 1fc61c844ec5 -r 7f39c40b4b25 render_sdl.c --- a/render_sdl.c Fri Jul 27 22:40:56 2018 -0700 +++ b/render_sdl.c Mon Jul 30 09:38:01 2018 -0700 @@ -846,7 +846,7 @@ handle_joyup(find_joystick_index(event->jbutton.which), event->jbutton.button); break; case SDL_JOYHATMOTION: - handle_joy_dpad(find_joystick_index(event->jbutton.which), event->jhat.hat, event->jhat.value); + handle_joy_dpad(find_joystick_index(event->jhat.which), event->jhat.hat, event->jhat.value); break; case SDL_JOYAXISMOTION: handle_joy_axis(find_joystick_index(event->jaxis.which), event->jaxis.axis, event->jaxis.value);