comparison nuklear_ui/blastem_nuklear.c @ 1626:2c3536082c0f

Add new view for selecting a new binding for a gamepad button
author Michael Pavone <pavone@retrodev.com>
date Fri, 26 Oct 2018 23:11:37 -0700
parents 6130e1e72151
children 84ef1eb2c96a
comparison
equal deleted inserted replaced
1625:6130e1e72151 1626:2c3536082c0f
536 const char *left_stick[NUM_AXIS_DIRS]; 536 const char *left_stick[NUM_AXIS_DIRS];
537 const char *right_stick[NUM_AXIS_DIRS]; 537 const char *right_stick[NUM_AXIS_DIRS];
538 const char *triggers[2]; 538 const char *triggers[2];
539 } pad_bind_config; 539 } pad_bind_config;
540 540
541 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) 541 static const char **current_bind_dest;
542
543 const char *translate_binding_option(const char *option)
542 { 544 {
543 static tern_node *conf_names; 545 static tern_node *conf_names;
544 const struct nk_user_font *font = context->style.font;
545 float row_height = font->height * 2;
546
547 char const **labels = calloc(sizeof(char *), num_binds);
548 char const **conf_vals = calloc(sizeof(char *), num_binds);
549 float max_width = 0.0f;
550
551 int skipped = 0;
552 for (int i = 0; i < num_binds; i++)
553 {
554 if (binds[i] & AXIS) {
555 labels[i] = get_axis_label(&selected_controller_info, binds[i] & ~AXIS);
556 conf_vals[i] = bindings->triggers[(binds[i] & ~AXIS) - SDL_CONTROLLER_AXIS_TRIGGERLEFT];
557 } else if (binds[i] & STICKDIR) {
558 static char const * dirs[] = {"Up", "Down", "Right", "Left"};
559 labels[i] = dirs[binds[i] & 3];
560 conf_vals[i] = (binds[i] & LEFTSTICK ? bindings->left_stick : bindings->right_stick)[binds[i] & 3];
561 } else {
562 labels[i] = get_button_label(&selected_controller_info, binds[i]);
563 conf_vals[i] = bindings->button_binds[binds[i]];
564 }
565 if (!labels[i]) {
566 skipped++;
567 continue;
568 }
569 float lb_width = font->width(font->userdata, font->height, labels[i], strlen(labels[i]));
570 max_width = max_width < lb_width ? lb_width : max_width;
571 }
572 nk_layout_space_push(context, nk_rect(x, y, width, (num_binds - skipped) * (row_height + 4) + 4));
573 nk_group_begin(context, name, NK_WINDOW_BORDER | NK_WINDOW_NO_SCROLLBAR);
574
575 if (!conf_names) { 546 if (!conf_names) {
576 conf_names = tern_insert_ptr(conf_names, "gamepads.n.up", "Pad Up"); 547 conf_names = tern_insert_ptr(conf_names, "gamepads.n.up", "Pad Up");
577 conf_names = tern_insert_ptr(conf_names, "gamepads.n.down", "Pad Down"); 548 conf_names = tern_insert_ptr(conf_names, "gamepads.n.down", "Pad Down");
578 conf_names = tern_insert_ptr(conf_names, "gamepads.n.left", "Pad Left"); 549 conf_names = tern_insert_ptr(conf_names, "gamepads.n.left", "Pad Left");
579 conf_names = tern_insert_ptr(conf_names, "gamepads.n.right", "Pad Right"); 550 conf_names = tern_insert_ptr(conf_names, "gamepads.n.right", "Pad Right");
608 conf_names = tern_insert_ptr(conf_names, "ui.soft_reset", "Soft Reset"); 579 conf_names = tern_insert_ptr(conf_names, "ui.soft_reset", "Soft Reset");
609 conf_names = tern_insert_ptr(conf_names, "ui.reload", "Reload ROM"); 580 conf_names = tern_insert_ptr(conf_names, "ui.reload", "Reload ROM");
610 conf_names = tern_insert_ptr(conf_names, "ui.sms_pause", "SMS Pause"); 581 conf_names = tern_insert_ptr(conf_names, "ui.sms_pause", "SMS Pause");
611 conf_names = tern_insert_ptr(conf_names, "ui.toggle_keyboard_captured", "Toggle Keyboard Capture"); 582 conf_names = tern_insert_ptr(conf_names, "ui.toggle_keyboard_captured", "Toggle Keyboard Capture");
612 } 583 }
584 return tern_find_ptr_default(conf_names, option, (void *)option);
585 }
586
587 static void bind_option_group(struct nk_context *context, char *name, const char **options, uint32_t num_options)
588 {
589 float margin = context->style.font->height * 2;
590 nk_layout_row_static(context, (context->style.font->height + 3) * ((num_options + 2) / 3) + context->style.font->height*2.1, render_width() - margin, 1);
591 if (nk_group_begin(context, name, NK_WINDOW_TITLE|NK_WINDOW_NO_SCROLLBAR)) {
592 nk_layout_row_static(context, context->style.font->height, (render_width() - margin - context->style.font->height) / 3, 3);
593 for (int i = 0; i < num_options; i++)
594 {
595 if (nk_button_label(context, translate_binding_option(options[i]))) {
596 *current_bind_dest = options[i];
597 pop_view();
598 }
599 }
600 nk_group_end(context);
601 }
602 }
603
604 static void view_button_binding(struct nk_context *context)
605 {
606 static const char *pad_opts[] = {
607 "gamepads.n.up",
608 "gamepads.n.down",
609 "gamepads.n.left",
610 "gamepads.n.right",
611 "gamepads.n.a",
612 "gamepads.n.b",
613 "gamepads.n.c",
614 "gamepads.n.x",
615 "gamepads.n.y",
616 "gamepads.n.z",
617 "gamepads.n.start",
618 "gamepads.n.mode"
619 };
620 static const char *system_buttons[] = {
621 "ui.soft_reset",
622 "ui.reload",
623 "ui.sms_pause"
624 };
625 static const char *emu_control[] = {
626 "ui.save_state",
627 "ui.exit",
628 "ui.toggle_fullscreen",
629 "ui.screenshot",
630 "ui.release_mouse",
631 "ui.toggle_keyboard_captured"
632 };
633 static const char *debugger[] = {
634 "ui.vdp_debug_mode",
635 "ui.vdp_debug_pal",
636 "ui.enter_debugger"
637 };
638 static const char *speeds[] = {
639 "ui.next_speed",
640 "ui.prev_speed",
641 "ui.set_speed.0",
642 "ui.set_speed.1",
643 "ui.set_speed.2",
644 "ui.set_speed.3",
645 "ui.set_speed.4",
646 "ui.set_speed.5",
647 "ui.set_speed.6",
648 "ui.set_speed.7",
649 "ui.set_speed.8",
650 "ui.set_speed.9"
651 };
652
653 if (nk_begin(context, "Button Binding", nk_rect(0, 0, render_width(), render_height()), 0)) {
654 bind_option_group(context, "Controller Buttons", pad_opts, sizeof(pad_opts)/sizeof(*pad_opts));
655 bind_option_group(context, "System Buttons", system_buttons, sizeof(system_buttons)/sizeof(*system_buttons));
656 bind_option_group(context, "Emulator Control", emu_control, sizeof(emu_control)/sizeof(*emu_control));
657 bind_option_group(context, "Debugging", debugger, sizeof(debugger)/sizeof(*debugger));
658 bind_option_group(context, "Speed Control", speeds, sizeof(speeds)/sizeof(*speeds));
659
660 nk_layout_row_static(context, context->style.font->height, (render_width() - 80)/4, 1);
661 if (nk_button_label(context, "Back")) {
662 pop_view();
663 }
664 nk_end(context);
665 }
666 }
667
668 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)
669 {
670 const struct nk_user_font *font = context->style.font;
671 float row_height = font->height * 2;
672
673 char const **labels = calloc(sizeof(char *), num_binds);
674 char const ***conf_vals = calloc(sizeof(char *), num_binds);
675 float max_width = 0.0f;
676
677 int skipped = 0;
678 for (int i = 0; i < num_binds; i++)
679 {
680 if (binds[i] & AXIS) {
681 labels[i] = get_axis_label(&selected_controller_info, binds[i] & ~AXIS);
682 conf_vals[i] = &bindings->triggers[(binds[i] & ~AXIS) - SDL_CONTROLLER_AXIS_TRIGGERLEFT];
683 } else if (binds[i] & STICKDIR) {
684 static char const * dirs[] = {"Up", "Down", "Right", "Left"};
685 labels[i] = dirs[binds[i] & 3];
686 conf_vals[i] = &(binds[i] & LEFTSTICK ? bindings->left_stick : bindings->right_stick)[binds[i] & 3];
687 } else {
688 labels[i] = get_button_label(&selected_controller_info, binds[i]);
689 conf_vals[i] = &bindings->button_binds[binds[i]];
690 }
691 if (!labels[i]) {
692 skipped++;
693 continue;
694 }
695 float lb_width = font->width(font->userdata, font->height, labels[i], strlen(labels[i]));
696 max_width = max_width < lb_width ? lb_width : max_width;
697 }
698 nk_layout_space_push(context, nk_rect(x, y, width, (num_binds - skipped) * (row_height + 4) + 4));
699 nk_group_begin(context, name, NK_WINDOW_BORDER | NK_WINDOW_NO_SCROLLBAR);
613 700
614 float widths[] = {max_width + 3, width - (max_width + 6)}; 701 float widths[] = {max_width + 3, width - (max_width + 6)};
615 nk_layout_row(context, NK_STATIC, row_height, 2, widths); 702 nk_layout_row(context, NK_STATIC, row_height, 2, widths);
616 for (int i = 0; i < num_binds; i++) 703 for (int i = 0; i < num_binds; i++)
617 { 704 {
618 if (!labels[i]) { 705 if (!labels[i]) {
619 continue; 706 continue;
620 } 707 }
621 nk_label(context, labels[i], NK_TEXT_LEFT); 708 nk_label(context, labels[i], NK_TEXT_LEFT);
622 char *name = conf_vals[i] ? tern_find_ptr(conf_names, conf_vals[i]) : NULL; 709 const char *name = *conf_vals[i] ? translate_binding_option(*conf_vals[i]) : "None";
623 nk_button_label(context, name ? name : conf_vals[i] ? conf_vals[i] : "None"); 710 if (nk_button_label(context, name)) {
711 current_bind_dest = conf_vals[i];
712 push_view(view_button_binding);
713 }
624 } 714 }
625 free(labels); 715 free(labels);
626 free(conf_vals); 716 free(conf_vals);
627 nk_group_end(context); 717 nk_group_end(context);
628 } 718 }