Mercurial > repos > blastem
diff nuklear_ui/blastem_nuklear.c @ 1623:18a946ec74c8
Pull current controller config in binding UI from whatever the actual binding code would end up using
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 24 Oct 2018 21:10:12 -0700 |
parents | 9c8f58740450 |
children | 7bbe0bfedb58 |
line wrap: on
line diff
--- a/nuklear_ui/blastem_nuklear.c Tue Oct 09 09:29:28 2018 -0700 +++ b/nuklear_ui/blastem_nuklear.c Wed Oct 24 21:10:12 2018 -0700 @@ -15,6 +15,7 @@ #include "../io.h" #include "../png.h" #include "../controller_info.h" +#include "../bindings.h" static struct nk_context *context; @@ -514,7 +515,7 @@ #define LEFTSTICK 0x10000000 #define RIGHTSTICK 0x20000000 enum { - UP,DOWN,LEFT,RIGHT + UP,DOWN,RIGHT,LEFT,NUM_AXIS_DIRS }; static char * config_ps_names[] = { @@ -530,71 +531,35 @@ [SDL_CONTROLLER_BUTTON_RIGHTSTICK] = "r3", }; -static void binding_box(struct nk_context *context, char *name, float x, float y, float width, int num_binds, int *binds) +typedef struct { + const char *button_binds[SDL_CONTROLLER_BUTTON_MAX]; + const char *left_stick[NUM_AXIS_DIRS]; + const char *right_stick[NUM_AXIS_DIRS]; + const char *triggers[2]; +} pad_bind_config; + +static void binding_box(struct nk_context *context, pad_bind_config *bindings, char *name, float x, float y, float width, int num_binds, int *binds) { const struct nk_user_font *font = context->style.font; float row_height = font->height * 2; char const **labels = calloc(sizeof(char *), num_binds); - char **conf_keys = calloc(sizeof(char *), num_binds); + char const **conf_vals = calloc(sizeof(char *), num_binds); float max_width = 0.0f; - static const char base_path[] = "bindings\0pads"; - static const char buttons[] = "buttons"; - static const char dpads[] = "dpads\00"; - static const char axes[] = "axes"; - static const char positive[] = ".positive"; - static const char negative[] = ".negative"; - char padkey[] = {'0' + selected_controller, 0}; int skipped = 0; for (int i = 0; i < num_binds; i++) { if (binds[i] & AXIS) { labels[i] = get_axis_label(&selected_controller_info, binds[i] & ~AXIS); - const char *axname = SDL_GameControllerGetStringForAxis(binds[i] & ~AXIS); - size_t namelen = strlen(axname); - conf_keys[i] = malloc(sizeof(base_path) + sizeof(padkey) + sizeof(axes) + namelen + 2); - memcpy(conf_keys[i], base_path, sizeof(base_path)); - memcpy(conf_keys[i] + sizeof(base_path), padkey, sizeof(padkey)); - memcpy(conf_keys[i] + sizeof(base_path) + sizeof(padkey), axes, sizeof(axes)); - memcpy(conf_keys[i] + sizeof(base_path) + sizeof(padkey) + sizeof(axes), axname, namelen+1); - conf_keys[i][sizeof(base_path) + sizeof(padkey) + sizeof(axes) + namelen + 1] = 0; + conf_vals[i] = bindings->triggers[(binds[i] & ~AXIS) - SDL_CONTROLLER_AXIS_TRIGGERLEFT]; } else if (binds[i] & STICKDIR) { - static char const * dirs[] = {"Up", "Down", "Left", "Right"}; + static char const * dirs[] = {"Up", "Down", "Right", "Left"}; labels[i] = dirs[binds[i] & 3]; - uint8_t is_pos = (binds[i] & 3) == 3 || !(binds[i] & 3); - int sdl_axis = (binds[i] & LEFTSTICK ? SDL_CONTROLLER_AXIS_LEFTX : SDL_CONTROLLER_AXIS_RIGHTX) + !(binds[i] & 2); - const char *axname = SDL_GameControllerGetStringForAxis(sdl_axis); - size_t namelen = strlen(axname); - conf_keys[i] = malloc(sizeof(base_path) + sizeof(padkey) + sizeof(axes) + namelen + sizeof(positive) + 1); - memcpy(conf_keys[i], base_path, sizeof(base_path)); - memcpy(conf_keys[i] + sizeof(base_path), padkey, sizeof(padkey)); - memcpy(conf_keys[i] + sizeof(base_path) + sizeof(padkey), axes, sizeof(axes)); - memcpy(conf_keys[i] + sizeof(base_path) + sizeof(padkey) + sizeof(axes), axname, namelen); - memcpy(conf_keys[i] + sizeof(base_path) + sizeof(padkey) + sizeof(axes) + namelen, is_pos ? positive : negative, sizeof(positive)); - conf_keys[i][sizeof(base_path) + sizeof(padkey) + sizeof(axes) + namelen + sizeof(positive)] = 0; + conf_vals[i] = (binds[i] & LEFTSTICK ? bindings->left_stick : bindings->right_stick)[binds[i] & 3]; } else { labels[i] = get_button_label(&selected_controller_info, binds[i]); - static const char* dpdirs[] = {"up", "down", "left", "right"}; - const char *but_name, *mid; - size_t midsz; - if (binds[i] < SDL_CONTROLLER_BUTTON_DPAD_UP) { - but_name = SDL_GameControllerGetStringForButton(binds[i]); - mid = buttons; - midsz = sizeof(buttons); - } else { - but_name = dpdirs[binds[i] - SDL_CONTROLLER_BUTTON_DPAD_UP]; - mid = dpads; - midsz = sizeof(dpads); - } - size_t namelen = strlen(but_name); - conf_keys[i] = malloc(sizeof(base_path) + sizeof(padkey) + midsz + namelen + 2); - memcpy(conf_keys[i], base_path, sizeof(base_path)); - memcpy(conf_keys[i] + sizeof(base_path), padkey, sizeof(padkey)); - memcpy(conf_keys[i] + sizeof(base_path) + sizeof(padkey), mid, midsz); - - memcpy(conf_keys[i] + sizeof(base_path) + sizeof(padkey) + midsz, but_name, namelen+1); - conf_keys[i][sizeof(base_path) + sizeof(padkey) + sizeof(buttons) + namelen + 1] = 0; + conf_vals[i] = bindings->button_binds[binds[i]]; } if (!labels[i]) { skipped++; @@ -614,25 +579,74 @@ continue; } nk_label(context, labels[i], NK_TEXT_LEFT); - if (conf_keys[i]) { - char *assigned = tern_find_path(config, conf_keys[i], TVAL_PTR).ptrval; - if (!assigned) { - assigned = "None"; - } else if (!memcmp("gamepads.", assigned, strlen("gamepads."))) { - assigned += strlen("gamepads.0."); - } - nk_button_label(context, assigned); - } else { - nk_button_label(context, i & 1 ? "Internal Screenshot" : "A"); - } - free(conf_keys[i]); + nk_button_label(context, conf_vals[i] ? conf_vals[i] : "None"); + } + free(labels); + free(conf_vals); + nk_group_end(context); +} + +static void button_iter(char *key, tern_val val, uint8_t valtype, void *data) +{ + pad_bind_config *bindings = data; + if (valtype != TVAL_PTR) { + return; + } + int button = render_lookup_button(key); + if (button != SDL_CONTROLLER_BUTTON_INVALID) { + bindings->button_binds[button] = val.ptrval; + } +} + +static void axis_iter(char *key, tern_val val, uint8_t valtype, void *data) +{ + pad_bind_config *bindings = data; + if (valtype != TVAL_PTR) { + return; } - nk_group_end(context); + int axis; + uint8_t is_negative = 0; + char *period = strchr(key, '.'); + if (period) { + char *tmp = malloc(period-key + 1); + memcpy(tmp, key, period-key); + tmp[period-key] = 0; + axis = render_lookup_axis(key); + free(tmp); + is_negative = strcmp(period+1, "negative") == 0; + } else { + axis = render_lookup_axis(key); + } + switch (axis) + { + case SDL_CONTROLLER_AXIS_LEFTX: + case SDL_CONTROLLER_AXIS_LEFTY: + bindings->left_stick[(axis - SDL_CONTROLLER_AXIS_LEFTX) * 2 + is_negative] = val.ptrval; + break; + case SDL_CONTROLLER_AXIS_RIGHTX: + case SDL_CONTROLLER_AXIS_RIGHTY: + bindings->right_stick[(axis - SDL_CONTROLLER_AXIS_RIGHTX) * 2 + is_negative] = val.ptrval; + break; + case SDL_CONTROLLER_AXIS_TRIGGERLEFT: + case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: + bindings->triggers[axis-SDL_CONTROLLER_AXIS_TRIGGERLEFT] = val.ptrval; + break; + } } void view_controller_bindings(struct nk_context *context) { + static pad_bind_config *bindings; 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); + if (pad) { + tern_foreach(tern_find_node(pad, "buttons"), button_iter, bindings); + tern_foreach(tern_find_node(pad, "axes"), axis_iter, bindings); + } + } + float orig_height = def_font->handle.height; def_font->handle.height *= 0.5f; @@ -686,25 +700,25 @@ bind_box_left = img_right + (render_width() - img_right) / 2.0f - bind_box_width / 2.0f; } - binding_box(context, "Action Buttons", bind_box_left, img_top, bind_box_width, 4, (int[]){ + binding_box(context, bindings, "Action Buttons", bind_box_left, img_top, bind_box_width, 4, (int[]){ SDL_CONTROLLER_BUTTON_A, SDL_CONTROLLER_BUTTON_B, SDL_CONTROLLER_BUTTON_X, SDL_CONTROLLER_BUTTON_Y }); - binding_box(context, "Right Shoulder", bind_box_left, font->height/2, bind_box_width, 2, (int[]){ + binding_box(context, bindings, "Right Shoulder", bind_box_left, font->height/2, bind_box_width, 2, (int[]){ SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, AXIS | SDL_CONTROLLER_AXIS_TRIGGERRIGHT }); - binding_box(context, "Misc Buttons", (render_width() - bind_box_width) / 2, font->height/2, bind_box_width, 3, (int[]){ + binding_box(context, bindings, "Misc Buttons", (render_width() - bind_box_width) / 2, font->height/2, bind_box_width, 3, (int[]){ SDL_CONTROLLER_BUTTON_BACK, SDL_CONTROLLER_BUTTON_GUIDE, SDL_CONTROLLER_BUTTON_START }); - binding_box(context, "Right Stick", img_right - desired_width/3, img_bot, bind_box_width, 5, (int[]){ + binding_box(context, bindings, "Right Stick", img_right - desired_width/3, img_bot, bind_box_width, 5, (int[]){ RIGHTSTICK | UP, RIGHTSTICK | DOWN, RIGHTSTICK | LEFT, @@ -714,7 +728,7 @@ bind_box_left -= img_right; - binding_box(context, "Left Stick", bind_box_left, img_top, bind_box_width, 5, (int[]){ + binding_box(context, bindings, "Left Stick", bind_box_left, img_top, bind_box_width, 5, (int[]){ LEFTSTICK | UP, LEFTSTICK | DOWN, LEFTSTICK | LEFT, @@ -722,12 +736,12 @@ SDL_CONTROLLER_BUTTON_LEFTSTICK }); - binding_box(context, "Left Shoulder", bind_box_left, font->height/2, bind_box_width, 2, (int[]){ + binding_box(context, bindings, "Left Shoulder", bind_box_left, font->height/2, bind_box_width, 2, (int[]){ SDL_CONTROLLER_BUTTON_LEFTSHOULDER, AXIS | SDL_CONTROLLER_AXIS_TRIGGERLEFT }); - binding_box(context, "D-pad", img_left - desired_width/6, img_bot + font->height * 1.5, bind_box_width, 4, (int[]){ + binding_box(context, bindings, "D-pad", img_left - desired_width/6, img_bot + font->height * 1.5, bind_box_width, 4, (int[]){ SDL_CONTROLLER_BUTTON_DPAD_UP, SDL_CONTROLLER_BUTTON_DPAD_DOWN, SDL_CONTROLLER_BUTTON_DPAD_LEFT,