Mercurial > repos > blastem
diff nuklear_ui/blastem_nuklear.c @ 2317:e836cf11783b
Make deadzones configurable and bump up the default value
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 02 Apr 2023 23:21:39 -0700 |
parents | ef5dc4d02d27 |
children | ab3d8759da08 |
line wrap: on
line diff
--- a/nuklear_ui/blastem_nuklear.c Sun Apr 02 23:21:04 2023 -0700 +++ b/nuklear_ui/blastem_nuklear.c Sun Apr 02 23:21:39 2023 -0700 @@ -1044,7 +1044,7 @@ if (nk_begin(context, "Controller Bindings", nk_rect(0, 0, render_width(), render_height()), NK_WINDOW_NO_SCROLLBAR)) { if (!bindings) { bindings = calloc(1, sizeof(*bindings)); - tern_node *pad = get_binding_node_for_pad(selected_controller); + tern_node *pad = get_binding_node_for_pad(selected_controller, &selected_controller_info); if (pad) { tern_foreach(tern_find_node(pad, "buttons"), button_iter, bindings); tern_foreach(tern_find_node(pad, "axes"), axis_iter, bindings); @@ -1488,6 +1488,123 @@ nk_end(context); } } +static uint8_t stick_nav_disabled; +static SDL_GameController *current_controller; +static uint8_t deadzones_dirty; +void stick_deadzone_widget(float left, float top, float size, SDL_GameControllerAxis x_axis) +{ + float crosshair_size = context->style.font->height; + nk_stroke_rect(&context->current->buffer, nk_rect(left, top, size, size), context->style.window.rounding, context->style.window.border, nk_rgb(255, 255, 255)); + float deadzone_size = selected_controller_info.stick_deadzone * size / 65535.0f; + int16_t raw_x = SDL_GameControllerGetAxis(current_controller, x_axis); + int16_t raw_y = SDL_GameControllerGetAxis(current_controller, x_axis + 1); + if (raw_x > selected_controller_info.stick_deadzone) { + float points[] = { + left + size * 0.5f + deadzone_size, top + size * 0.5f - deadzone_size, + left + size, top, + left + size, top + size, + left + size * 0.5f + deadzone_size, top + size * 0.5f + deadzone_size, + }; + nk_fill_polygon(&context->current->buffer, points, sizeof(points)/(2 * sizeof(float)), context->style.checkbox.cursor_normal.data.color); + } else if (raw_x < -selected_controller_info.stick_deadzone) { + float points[] = { + left, top, + left + size * 0.5f - deadzone_size, top + size * 0.5f - deadzone_size, + left + size * 0.5f - deadzone_size, top + size * 0.5f + deadzone_size, + left, top + size, + }; + nk_fill_polygon(&context->current->buffer, points, sizeof(points)/(2 * sizeof(float)), context->style.checkbox.cursor_normal.data.color); + } + if (raw_y > selected_controller_info.stick_deadzone) { + float points[] = { + left, top + size, + left + size, top + size, + left + size * 0.5f + deadzone_size, top + size * 0.5f + deadzone_size, + left + size * 0.5f - deadzone_size, top + size * 0.5f + deadzone_size, + }; + nk_fill_polygon(&context->current->buffer, points, sizeof(points)/(2 * sizeof(float)), context->style.checkbox.cursor_normal.data.color); + } else if (raw_y < -selected_controller_info.stick_deadzone) { + float points[] = { + left, top, + left + size, top, + left + size * 0.5f + deadzone_size, top + size * 0.5f - deadzone_size, + left + size * 0.5f - deadzone_size, top + size * 0.5f - deadzone_size, + }; + nk_fill_polygon(&context->current->buffer, points, sizeof(points)/(2 * sizeof(float)), context->style.checkbox.cursor_normal.data.color); + } + nk_stroke_rect(&context->current->buffer, nk_rect(left + 0.5f * size - deadzone_size, top + 0.5f * size - deadzone_size, 2 * deadzone_size, 2 * deadzone_size), context->style.window.rounding, 0.5f * context->style.window.border, nk_rgb(200, 200, 200)); + //nk_layout_space_push(context, nk_rect(left, top, size, size)); + float x = raw_x * size / 65535.0f + size / 2.0f - crosshair_size / 2.0f; + float y = raw_y * size / 65535.0f + size / 2.0f - crosshair_size / 2.0f; + nk_draw_symbol(&context->current->buffer, NK_SYMBOL_X, nk_rect(left + x, top + y, crosshair_size, crosshair_size), nk_rgb(0, 0, 0), nk_rgb(255, 255, 255), 1, context->style.font); +} + +void trigger_deadzone_widget(float left, float top, float size, SDL_GameControllerAxis axis) +{ + float crosshair_size = context->style.font->height; + nk_stroke_rect(&context->current->buffer, nk_rect(left, top, size, crosshair_size * 1.5f), context->style.window.rounding, context->style.window.border, nk_rgb(255, 255, 255)); + float deadzone_size = selected_controller_info.trigger_deadzone * size / 32767.0f; + int16_t raw = SDL_GameControllerGetAxis(current_controller, axis); + if (raw < 0) { + raw = 0; + } + if (raw > selected_controller_info.trigger_deadzone) { + nk_fill_rect(&context->current->buffer, nk_rect(left + deadzone_size, top, size - deadzone_size, 1.5f * crosshair_size), context->style.window.rounding, context->style.checkbox.cursor_normal.data.color); + } + nk_stroke_line(&context->current->buffer, left + deadzone_size, top, left + deadzone_size, top + 1.5f * crosshair_size, 0.5f * context->style.window.border, nk_rgb(200, 200, 200)); + float x = raw * size / 32767.0f - crosshair_size / 2.0f; + nk_draw_symbol(&context->current->buffer, NK_SYMBOL_X, nk_rect(left + x, top + 0.25f * crosshair_size, crosshair_size, crosshair_size), nk_rgb(0, 0, 0), nk_rgb(255, 255, 255), 1, context->style.font); +} + +void view_deadzones(struct nk_context *context) +{ + if (nk_begin(context, "Deadzones", nk_rect(0, 0, render_width(), render_height()), NK_WINDOW_NO_SCROLLBAR)) { + nk_layout_space_begin(context, NK_STATIC, render_height() - 3 * context->style.font->height, 4); + + float left = render_width() / 8.0f, top = render_height() / 8.0f; + float size = render_height() / 3.0f; + stick_deadzone_widget(left, top, size, SDL_CONTROLLER_AXIS_LEFTX); + stick_deadzone_widget(left + 1.25f * size, top, size, SDL_CONTROLLER_AXIS_RIGHTX); + + top += size + context->style.font->height; + nk_layout_space_push(context, nk_rect(left, top, size * 2, context->style.font->height)); + int val = selected_controller_info.stick_deadzone; + nk_property_int(context, "Stick Deadzone", 250, &val, 32000, 250, 1.0f); + if (val != selected_controller_info.stick_deadzone) { + selected_controller_info.stick_deadzone = val; + deadzones_dirty = 1; + } + + top += 2.0f * context->style.font->height; + trigger_deadzone_widget(left, top, size, SDL_CONTROLLER_AXIS_TRIGGERLEFT); + trigger_deadzone_widget(left + 1.25f * size, top, size, SDL_CONTROLLER_AXIS_TRIGGERRIGHT); + + top += context->style.font->height * 2.5f; + nk_layout_space_push(context, nk_rect(left, top, size * 2, context->style.font->height)); + val = selected_controller_info.trigger_deadzone; + nk_property_int(context, "Trigger Deadzone", 250, &val, 32000, 250, 1.0f); + if (val != selected_controller_info.trigger_deadzone) { + selected_controller_info.trigger_deadzone = val; + deadzones_dirty = 1; + } + + nk_layout_space_end(context); + + nk_layout_row_static(context, context->style.font->height, (render_width() - 2 * context->style.font->height) / 2, 2); + if (nk_button_label(context, "Back")) { + stick_nav_disabled = 0; + if (current_controller) { + SDL_GameControllerClose(current_controller); + current_controller = NULL; + } + if (deadzones_dirty) { + save_controller_info(selected_controller, &selected_controller_info); + } + pop_view(); + } + nk_end(context); + } +} void view_controllers(struct nk_context *context) { @@ -1498,10 +1615,12 @@ int bindings_width = font->width(font->userdata, font->height, "Bindings", strlen("Bindings")) + context->style.button.padding.x * 2; int remap_width = font->width(font->userdata, font->height, "Remap", strlen("Remap")) + context->style.button.padding.x * 2; int change_type_width = font->width(font->userdata, font->height, "Change Type", strlen("Change Type")) + context->style.button.padding.x * 2; - int total = bindings_width + remap_width + change_type_width; + int deadzones_width = font->width(font->userdata, font->height, "Deadzones", strlen("Deadzones")) + context->style.button.padding.x * 2; + int total = bindings_width + remap_width + change_type_width + deadzones_width; float bindings_ratio = (float)bindings_width / total; float remap_ratio = (float)remap_width / total; float change_type_ratio = (float)change_type_width / total; + float deadzones_ratio = (float)deadzones_width / total; uint8_t found_controller = 0; @@ -1563,8 +1682,19 @@ initial_controller_config = 0; push_view(view_controller_type); } + button_start += change_type_width + context->style.window.spacing.x; + deadzones_width = deadzones_ratio * button_area_width; + nk_layout_space_push(context, nk_rect(button_start, height/2, deadzones_width, inner_height/2)); + if (nk_button_label(context, "Deadzones")) { + selected_controller = i; + selected_controller_info = info; + current_controller = render_get_controller(i); + stick_nav_disabled = 1; + deadzones_dirty = 0; + push_view(view_deadzones); + } } - //nk_layout_row_end(context); + nk_layout_space_end(context); } } if (!found_controller) { @@ -2322,6 +2452,9 @@ } else if (event->type == SDL_MOUSEBUTTONUP && event->button.button == 0) { click = 0; } + if (stick_nav_disabled && event->type == SDL_CONTROLLERAXISMOTION) { + return; + } nk_sdl_handle_event(event); }