Mercurial > repos > blastem
comparison nuklear_ui/blastem_nuklear.c @ 2202:ee6d30c56eeb
Add separate model/IO selection settings for SMS/GG
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Mon, 22 Aug 2022 22:56:05 -0700 |
parents | 1270fe86eb89 |
children | ff700f50541c |
comparison
equal
deleted
inserted
replaced
2201:2f8984ff5c85 | 2202:ee6d30c56eeb |
---|---|
29 uint32_t *image_data; | 29 uint32_t *image_data; |
30 uint32_t width, height; | 30 uint32_t width, height; |
31 struct nk_image ui; | 31 struct nk_image ui; |
32 } ui_image; | 32 } ui_image; |
33 | 33 |
34 static ui_image **ui_images, *controller_360, *controller_ps4, | 34 static ui_image **ui_images, *controller_360, *controller_ps4, |
35 *controller_ps4_6b, *controller_wiiu, *controller_gen_6b; | 35 *controller_ps4_6b, *controller_wiiu, *controller_gen_6b; |
36 static uint32_t num_ui_images, ui_image_storage; | 36 static uint32_t num_ui_images, ui_image_storage; |
37 | 37 |
38 typedef void (*view_fun)(struct nk_context *); | 38 typedef void (*view_fun)(struct nk_context *); |
39 static view_fun current_view; | 39 static view_fun current_view; |
67 num_prev = 0; | 67 num_prev = 0; |
68 } | 68 } |
69 | 69 |
70 void view_play(struct nk_context *context) | 70 void view_play(struct nk_context *context) |
71 { | 71 { |
72 | 72 |
73 } | 73 } |
74 | 74 |
75 static char *browser_cur_path; | 75 static char *browser_cur_path; |
76 static const char *browser_label; | 76 static const char *browser_label; |
77 static const char *browser_setting_path; | 77 static const char *browser_setting_path; |
161 current_system->request_exit(current_system); | 161 current_system->request_exit(current_system); |
162 } else { | 162 } else { |
163 init_system_with_media(full_path, SYSTEM_UNKNOWN); | 163 init_system_with_media(full_path, SYSTEM_UNKNOWN); |
164 free(full_path); | 164 free(full_path); |
165 } | 165 } |
166 | 166 |
167 clear_view_stack(); | 167 clear_view_stack(); |
168 show_play_view(); | 168 show_play_view(); |
169 } else if (browser_setting_path) { | 169 } else if (browser_setting_path) { |
170 config = tern_insert_path(config, browser_setting_path, (tern_val){.ptrval = full_path}, TVAL_PTR); | 170 config = tern_insert_path(config, browser_setting_path, (tern_val){.ptrval = full_path}, TVAL_PTR); |
171 config_dirty = 1; | 171 config_dirty = 1; |
172 browser_ext_list = NULL; | 172 browser_ext_list = NULL; |
173 pop_view(); | 173 pop_view(); |
174 } else { | 174 } else { |
175 lockon_media(full_path); | 175 lockon_media(full_path); |
176 free(full_path); | 176 free(full_path); |
177 | 177 |
178 clear_view_stack(); | 178 clear_view_stack(); |
179 show_play_view(); | 179 show_play_view(); |
180 } | 180 } |
181 } | 181 } |
182 selected_entry = -1; | 182 selected_entry = -1; |
320 static void menu(struct nk_context *context, uint32_t num_entries, const menu_item *items, menu_handler handler) | 320 static void menu(struct nk_context *context, uint32_t num_entries, const menu_item *items, menu_handler handler) |
321 { | 321 { |
322 const uint32_t button_height = context->style.font->height * 1.75; | 322 const uint32_t button_height = context->style.font->height * 1.75; |
323 const uint32_t ideal_button_width = context->style.font->height * 10; | 323 const uint32_t ideal_button_width = context->style.font->height * 10; |
324 const uint32_t button_space = 6; | 324 const uint32_t button_space = 6; |
325 | 325 |
326 uint32_t width = render_width(); | 326 uint32_t width = render_width(); |
327 uint32_t height = render_height(); | 327 uint32_t height = render_height(); |
328 uint32_t top = height/2 - (button_height * num_entries)/2; | 328 uint32_t top = height/2 - (button_height * num_entries)/2; |
329 uint32_t button_width = width > ideal_button_width ? ideal_button_width : width; | 329 uint32_t button_width = width > ideal_button_width ? ideal_button_width : width; |
330 uint32_t left = width/2 - button_width/2; | 330 uint32_t left = width/2 - button_width/2; |
331 | 331 |
332 nk_layout_space_begin(context, NK_STATIC, top + button_height * num_entries, num_entries); | 332 nk_layout_space_begin(context, NK_STATIC, top + button_height * num_entries, num_entries); |
333 for (uint32_t i = 0; i < num_entries; i++) | 333 for (uint32_t i = 0; i < num_entries; i++) |
334 { | 334 { |
335 nk_layout_space_push(context, nk_rect(left, top + i * button_height, button_width, button_height-button_space)); | 335 nk_layout_space_push(context, nk_rect(left, top + i * button_height, button_width, button_height-button_space)); |
336 if (nk_button_label(context, items[i].title)) { | 336 if (nk_button_label(context, items[i].title)) { |
367 void binding_group(struct nk_context *context, char *name, const char **binds, const char **bind_names, uint32_t num_binds, tern_node *binding_lookup) | 367 void binding_group(struct nk_context *context, char *name, const char **binds, const char **bind_names, uint32_t num_binds, tern_node *binding_lookup) |
368 { | 368 { |
369 nk_layout_row_static(context, (context->style.font->height + 4)*num_binds+context->style.font->height+30, render_width() - 80, 1); | 369 nk_layout_row_static(context, (context->style.font->height + 4)*num_binds+context->style.font->height+30, render_width() - 80, 1); |
370 if (nk_group_begin(context, name, NK_WINDOW_TITLE)) { | 370 if (nk_group_begin(context, name, NK_WINDOW_TITLE)) { |
371 nk_layout_row_static(context, context->style.font->height, render_width()/2 - 80, 2); | 371 nk_layout_row_static(context, context->style.font->height, render_width()/2 - 80, 2); |
372 | 372 |
373 for (int i = 0; i < num_binds; i++) | 373 for (int i = 0; i < num_binds; i++) |
374 { | 374 { |
375 char *label_alloc = bind_names ? NULL : path_extension(binds[i]); | 375 char *label_alloc = bind_names ? NULL : path_extension(binds[i]); |
376 const char *label = label_alloc; | 376 const char *label = label_alloc; |
377 if (!label) { | 377 if (!label) { |
498 static const char *debug_binds[] = { | 498 static const char *debug_binds[] = { |
499 "ui.enter_debugger", "ui.plane_debug", "ui.vram_debug", "ui.cram_debug", | 499 "ui.enter_debugger", "ui.plane_debug", "ui.vram_debug", "ui.cram_debug", |
500 "ui.compositing_debug", "ui.vdp_debug_mode" | 500 "ui.compositing_debug", "ui.vdp_debug_mode" |
501 }; | 501 }; |
502 const char *debug_names[] = { | 502 const char *debug_names[] = { |
503 "CPU Debugger", "Plane Debugger", "VRAM Debugger", "CRAM Debugger", | 503 "CPU Debugger", "Plane Debugger", "VRAM Debugger", "CRAM Debugger", |
504 "Layer Debugger", "Cycle Mode/Pal" | 504 "Layer Debugger", "Cycle Mode/Pal" |
505 }; | 505 }; |
506 const uint32_t NUM_C1_BINDS = sizeof(controller1_binds)/sizeof(*controller1_binds); | 506 const uint32_t NUM_C1_BINDS = sizeof(controller1_binds)/sizeof(*controller1_binds); |
507 const uint32_t NUM_C2_BINDS = sizeof(controller2_binds)/sizeof(*controller2_binds); | 507 const uint32_t NUM_C2_BINDS = sizeof(controller2_binds)/sizeof(*controller2_binds); |
508 const uint32_t NUM_SPEED_BINDS = sizeof(speed_binds)/sizeof(*speed_binds); | 508 const uint32_t NUM_SPEED_BINDS = sizeof(speed_binds)/sizeof(*speed_binds); |
555 uint32_t suffix_len = strlen(name) + 1; | 555 uint32_t suffix_len = strlen(name) + 1; |
556 char *path = malloc(prefix_len + suffix_len + 1); | 556 char *path = malloc(prefix_len + suffix_len + 1); |
557 memcpy(path, "bindings\0keys\0", prefix_len); | 557 memcpy(path, "bindings\0keys\0", prefix_len); |
558 memcpy(path + prefix_len, name, suffix_len); | 558 memcpy(path + prefix_len, name, suffix_len); |
559 path[prefix_len + suffix_len] = 0; | 559 path[prefix_len + suffix_len] = 0; |
560 | 560 |
561 config_dirty = 1; | 561 config_dirty = 1; |
562 config = tern_insert_path(config, path, (tern_val){.ptrval = strdup(set_binding)}, TVAL_PTR); | 562 config = tern_insert_path(config, path, (tern_val){.ptrval = strdup(set_binding)}, TVAL_PTR); |
563 free(path); | 563 free(path); |
564 free(name); | 564 free(name); |
565 tern_free(binding_lookup); | 565 tern_free(binding_lookup); |
598 [SDL_CONTROLLER_BUTTON_RIGHTSHOULDER] = "r1", | 598 [SDL_CONTROLLER_BUTTON_RIGHTSHOULDER] = "r1", |
599 [SDL_CONTROLLER_BUTTON_LEFTSTICK] = "l3", | 599 [SDL_CONTROLLER_BUTTON_LEFTSTICK] = "l3", |
600 [SDL_CONTROLLER_BUTTON_RIGHTSTICK] = "r3", | 600 [SDL_CONTROLLER_BUTTON_RIGHTSTICK] = "r3", |
601 }; | 601 }; |
602 | 602 |
603 typedef struct { | 603 typedef struct { |
604 const char *button_binds[SDL_CONTROLLER_BUTTON_MAX]; | 604 const char *button_binds[SDL_CONTROLLER_BUTTON_MAX]; |
605 const char *left_stick[NUM_AXIS_DIRS]; | 605 const char *left_stick[NUM_AXIS_DIRS]; |
606 const char *right_stick[NUM_AXIS_DIRS]; | 606 const char *right_stick[NUM_AXIS_DIRS]; |
607 const char *triggers[2]; | 607 const char *triggers[2]; |
608 } pad_bind_config; | 608 } pad_bind_config; |
721 "ui.set_speed.6", | 721 "ui.set_speed.6", |
722 "ui.set_speed.7", | 722 "ui.set_speed.7", |
723 "ui.set_speed.8", | 723 "ui.set_speed.8", |
724 "ui.set_speed.9" | 724 "ui.set_speed.9" |
725 }; | 725 }; |
726 | 726 |
727 if (nk_begin(context, "Button Binding", nk_rect(0, 0, render_width(), render_height()), 0)) { | 727 if (nk_begin(context, "Button Binding", nk_rect(0, 0, render_width(), render_height()), 0)) { |
728 bind_option_group(context, "Controller Buttons", pad_opts, sizeof(pad_opts)/sizeof(*pad_opts)); | 728 bind_option_group(context, "Controller Buttons", pad_opts, sizeof(pad_opts)/sizeof(*pad_opts)); |
729 bind_option_group(context, "System Buttons", system_buttons, sizeof(system_buttons)/sizeof(*system_buttons)); | 729 bind_option_group(context, "System Buttons", system_buttons, sizeof(system_buttons)/sizeof(*system_buttons)); |
730 bind_option_group(context, "Emulator Control", emu_control, sizeof(emu_control)/sizeof(*emu_control)); | 730 bind_option_group(context, "Emulator Control", emu_control, sizeof(emu_control)/sizeof(*emu_control)); |
731 bind_option_group(context, "Debugging", debugger, sizeof(debugger)/sizeof(*debugger)); | 731 bind_option_group(context, "Debugging", debugger, sizeof(debugger)/sizeof(*debugger)); |
732 bind_option_group(context, "Speed Control", speeds, sizeof(speeds)/sizeof(*speeds)); | 732 bind_option_group(context, "Speed Control", speeds, sizeof(speeds)/sizeof(*speeds)); |
733 | 733 |
734 nk_layout_row_static(context, context->style.font->height, (render_width() - 80)/4, 1); | 734 nk_layout_row_static(context, context->style.font->height, (render_width() - 80)/4, 1); |
735 if (nk_button_label(context, "Back")) { | 735 if (nk_button_label(context, "Back")) { |
736 pop_view(); | 736 pop_view(); |
737 } | 737 } |
738 nk_end(context); | 738 nk_end(context); |
741 | 741 |
742 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) | 742 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) |
743 { | 743 { |
744 const struct nk_user_font *font = context->style.font; | 744 const struct nk_user_font *font = context->style.font; |
745 float row_height = font->height * 2; | 745 float row_height = font->height * 2; |
746 | 746 |
747 char const **labels = calloc(sizeof(char *), num_binds); | 747 char const **labels = calloc(sizeof(char *), num_binds); |
748 char const ***conf_vals = calloc(sizeof(char *), num_binds); | 748 char const ***conf_vals = calloc(sizeof(char *), num_binds); |
749 float max_width = 0.0f; | 749 float max_width = 0.0f; |
750 | 750 |
751 int skipped = 0; | 751 int skipped = 0; |
752 for (int i = 0; i < num_binds; i++) | 752 for (int i = 0; i < num_binds; i++) |
753 { | 753 { |
754 if (binds[i] & AXIS) { | 754 if (binds[i] & AXIS) { |
755 labels[i] = get_axis_label(&selected_controller_info, binds[i] & ~AXIS); | 755 labels[i] = get_axis_label(&selected_controller_info, binds[i] & ~AXIS); |
769 float lb_width = font->width(font->userdata, font->height, labels[i], strlen(labels[i])); | 769 float lb_width = font->width(font->userdata, font->height, labels[i], strlen(labels[i])); |
770 max_width = max_width < lb_width ? lb_width : max_width; | 770 max_width = max_width < lb_width ? lb_width : max_width; |
771 } | 771 } |
772 nk_layout_space_push(context, nk_rect(x, y, width, (num_binds - skipped) * (row_height + 4) + 4)); | 772 nk_layout_space_push(context, nk_rect(x, y, width, (num_binds - skipped) * (row_height + 4) + 4)); |
773 nk_group_begin(context, name, NK_WINDOW_BORDER | NK_WINDOW_NO_SCROLLBAR); | 773 nk_group_begin(context, name, NK_WINDOW_BORDER | NK_WINDOW_NO_SCROLLBAR); |
774 | 774 |
775 float widths[] = {max_width + 3, width - (max_width + 6)}; | 775 float widths[] = {max_width + 3, width - (max_width + 6)}; |
776 nk_layout_row(context, NK_STATIC, row_height, 2, widths); | 776 nk_layout_row(context, NK_STATIC, row_height, 2, widths); |
777 for (int i = 0; i < num_binds; i++) | 777 for (int i = 0; i < num_binds; i++) |
778 { | 778 { |
779 if (!labels[i]) { | 779 if (!labels[i]) { |
872 memcpy(full_key, axes_key, axes_key_size); | 872 memcpy(full_key, axes_key, axes_key_size); |
873 memcpy(full_key + axes_key_size, prefix, prefix_len); | 873 memcpy(full_key + axes_key_size, prefix, prefix_len); |
874 full_key[axes_key_size+prefix_len] = axis; | 874 full_key[axes_key_size+prefix_len] = axis; |
875 memcpy(full_key + axes_key_size + prefix_len + 1, suffix, suffix_len +1); | 875 memcpy(full_key + axes_key_size + prefix_len + 1, suffix, suffix_len +1); |
876 full_key[axes_key_size + prefix_len + 1 + suffix_len + 1] = 0; | 876 full_key[axes_key_size + prefix_len + 1 + suffix_len + 1] = 0; |
877 | 877 |
878 if (bindings[i]) { | 878 if (bindings[i]) { |
879 tern_insert_path(config, full_key, (tern_val){.ptrval = strdup(bindings[i])}, TVAL_PTR); | 879 tern_insert_path(config, full_key, (tern_val){.ptrval = strdup(bindings[i])}, TVAL_PTR); |
880 } else { | 880 } else { |
881 tern_val prev_val; | 881 tern_val prev_val; |
882 uint8_t prev_type = tern_delete_path(&config, full_key, &prev_val); | 882 uint8_t prev_type = tern_delete_path(&config, full_key, &prev_val); |
883 if (prev_type == TVAL_PTR) { | 883 if (prev_type == TVAL_PTR) { |
884 free(prev_val.ptrval); | 884 free(prev_val.ptrval); |
885 } | 885 } |
886 } | 886 } |
887 | 887 |
888 free(full_key); | 888 free(full_key); |
889 } | 889 } |
890 } | 890 } |
891 | 891 |
892 static pad_bind_config *bindings; | 892 static pad_bind_config *bindings; |
923 static const char button_base[] = "buttons"; | 923 static const char button_base[] = "buttons"; |
924 size_t button_key_size = pad_key_size + sizeof(button_base); | 924 size_t button_key_size = pad_key_size + sizeof(button_base); |
925 char *button_key = malloc(button_key_size); | 925 char *button_key = malloc(button_key_size); |
926 memcpy(button_key, pad_key, pad_key_size); | 926 memcpy(button_key, pad_key, pad_key_size); |
927 memcpy(button_key + pad_key_size, button_base, sizeof(button_base)); | 927 memcpy(button_key + pad_key_size, button_base, sizeof(button_base)); |
928 | 928 |
929 char *final_key; | 929 char *final_key; |
930 for (int i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++) | 930 for (int i = 0; i < SDL_CONTROLLER_BUTTON_MAX; i++) |
931 { | 931 { |
932 char *base; | 932 char *base; |
933 const char *suffix; | 933 const char *suffix; |
934 size_t base_key_len; | 934 size_t base_key_len; |
935 if ( i < SDL_CONTROLLER_BUTTON_DPAD_UP) { | 935 if ( i < SDL_CONTROLLER_BUTTON_DPAD_UP) { |
936 suffix = SDL_GameControllerGetStringForButton(i); | 936 suffix = SDL_GameControllerGetStringForButton(i); |
937 base_key_len = button_key_size; | 937 base_key_len = button_key_size; |
938 base = button_key; | 938 base = button_key; |
939 | 939 |
940 | 940 |
941 } else { | 941 } else { |
942 static const char *dir_keys[] = {"up", "down", "left", "right"}; | 942 static const char *dir_keys[] = {"up", "down", "left", "right"}; |
943 suffix = dir_keys[i - SDL_CONTROLLER_BUTTON_DPAD_UP]; | 943 suffix = dir_keys[i - SDL_CONTROLLER_BUTTON_DPAD_UP]; |
944 base = dpad_key; | 944 base = dpad_key; |
945 base_key_len = dpad_key_size; | 945 base_key_len = dpad_key_size; |
960 } | 960 } |
961 free(final_key); | 961 free(final_key); |
962 } | 962 } |
963 free(button_key); | 963 free(button_key); |
964 free(dpad_key); | 964 free(dpad_key); |
965 | 965 |
966 static const char axes_base[] = "axes"; | 966 static const char axes_base[] = "axes"; |
967 size_t axes_key_size = pad_key_size + sizeof(axes_base); | 967 size_t axes_key_size = pad_key_size + sizeof(axes_base); |
968 char *axes_key = malloc(axes_key_size); | 968 char *axes_key = malloc(axes_key_size); |
969 memcpy(axes_key, pad_key, pad_key_size); | 969 memcpy(axes_key, pad_key, pad_key_size); |
970 memcpy(axes_key + pad_key_size, axes_base, sizeof(axes_base)); | 970 memcpy(axes_key + pad_key_size, axes_base, sizeof(axes_base)); |
971 | 971 |
972 save_stick_binds(axes_key, axes_key_size,bindings->left_stick, "left"); | 972 save_stick_binds(axes_key, axes_key_size,bindings->left_stick, "left"); |
973 save_stick_binds(axes_key, axes_key_size,bindings->right_stick, "right"); | 973 save_stick_binds(axes_key, axes_key_size,bindings->right_stick, "right"); |
974 for (int i = SDL_CONTROLLER_AXIS_TRIGGERLEFT; i < SDL_CONTROLLER_AXIS_MAX; i++) | 974 for (int i = SDL_CONTROLLER_AXIS_TRIGGERLEFT; i < SDL_CONTROLLER_AXIS_MAX; i++) |
975 { | 975 { |
976 const char *suffix = SDL_GameControllerGetStringForAxis(i); | 976 const char *suffix = SDL_GameControllerGetStringForAxis(i); |
989 } | 989 } |
990 } | 990 } |
991 free(final_key); | 991 free(final_key); |
992 } | 992 } |
993 free(axes_key); | 993 free(axes_key); |
994 | 994 |
995 free(pad_key); | 995 free(pad_key); |
996 if (dest == SIMILAR_CONTROLLERS) { | 996 if (dest == SIMILAR_CONTROLLERS) { |
997 free(key); | 997 free(key); |
998 } | 998 } |
999 pop_view(); | 999 pop_view(); |
1005 static menu_item options[NUM_DEST_TYPES]; | 1005 static menu_item options[NUM_DEST_TYPES]; |
1006 options[IDENTICAL_CONTROLLERS].title = "Use for identical controllers"; | 1006 options[IDENTICAL_CONTROLLERS].title = "Use for identical controllers"; |
1007 options[DEFAULT].title = "Use as default"; | 1007 options[DEFAULT].title = "Use as default"; |
1008 options[BY_INDEX].title = by_index_names[selected_controller]; | 1008 options[BY_INDEX].title = by_index_names[selected_controller]; |
1009 options[SIMILAR_CONTROLLERS].title = make_human_readable_type_name(&selected_controller_info); | 1009 options[SIMILAR_CONTROLLERS].title = make_human_readable_type_name(&selected_controller_info); |
1010 | 1010 |
1011 if (nk_begin(context, "Select Binding Dest", nk_rect(0, 0, render_width(), render_height()), NK_WINDOW_NO_SCROLLBAR)) { | 1011 if (nk_begin(context, "Select Binding Dest", nk_rect(0, 0, render_width(), render_height()), NK_WINDOW_NO_SCROLLBAR)) { |
1012 menu(context, NUM_DEST_TYPES, options, handle_dest_clicked); | 1012 menu(context, NUM_DEST_TYPES, options, handle_dest_clicked); |
1013 nk_end(context); | 1013 nk_end(context); |
1014 } | 1014 } |
1015 free((char *)options[SIMILAR_CONTROLLERS].title); | 1015 free((char *)options[SIMILAR_CONTROLLERS].title); |
1048 { | 1048 { |
1049 bindings->button_binds[button_idx[i]] = tern_find_ptr(dpad, dir_keys[i]); | 1049 bindings->button_binds[button_idx[i]] = tern_find_ptr(dpad, dir_keys[i]); |
1050 } | 1050 } |
1051 } | 1051 } |
1052 } | 1052 } |
1053 | 1053 |
1054 float orig_height = def_font->handle.height; | 1054 float orig_height = def_font->handle.height; |
1055 def_font->handle.height *= 0.5f; | 1055 def_font->handle.height *= 0.5f; |
1056 | 1056 |
1057 uint32_t avail_height = render_height() - 2 * orig_height; | 1057 uint32_t avail_height = render_height() - 2 * orig_height; |
1058 float desired_width = render_width() * 0.5f, desired_height = avail_height * 0.5f; | 1058 float desired_width = render_width() * 0.5f, desired_height = avail_height * 0.5f; |
1059 ui_image *controller_image = select_best_image(&selected_controller_info); | 1059 ui_image *controller_image = select_best_image(&selected_controller_info); |
1060 | 1060 |
1061 float controller_ratio = (float)controller_image->width / (float)controller_image->height; | 1061 float controller_ratio = (float)controller_image->width / (float)controller_image->height; |
1062 | 1062 |
1063 const struct nk_user_font *font = context->style.font; | 1063 const struct nk_user_font *font = context->style.font; |
1064 int MIN_BIND_BOX_WIDTH = font->width(font->userdata, font->height, "Right", strlen("Right")) | 1064 int MIN_BIND_BOX_WIDTH = font->width(font->userdata, font->height, "Right", strlen("Right")) |
1065 + def_font->handle.width(font->userdata, font->height, "Internal Screenshot", strlen("Internal Screenshot")); | 1065 + def_font->handle.width(font->userdata, font->height, "Internal Screenshot", strlen("Internal Screenshot")); |
1066 | 1066 |
1067 if (render_width() - desired_width < 2.5f*MIN_BIND_BOX_WIDTH) { | 1067 if (render_width() - desired_width < 2.5f*MIN_BIND_BOX_WIDTH) { |
1068 desired_width = render_width() - 2.5f*MIN_BIND_BOX_WIDTH; | 1068 desired_width = render_width() - 2.5f*MIN_BIND_BOX_WIDTH; |
1069 } | 1069 } |
1070 | 1070 |
1071 if (desired_width / desired_height > controller_ratio) { | 1071 if (desired_width / desired_height > controller_ratio) { |
1072 desired_width = desired_height * controller_ratio; | 1072 desired_width = desired_height * controller_ratio; |
1073 } else { | 1073 } else { |
1074 desired_height = desired_width / controller_ratio; | 1074 desired_height = desired_width / controller_ratio; |
1075 } | 1075 } |
1078 float img_right = img_left + desired_width; | 1078 float img_right = img_left + desired_width; |
1079 float img_bot = img_top + desired_height; | 1079 float img_bot = img_top + desired_height; |
1080 nk_layout_space_begin(context, NK_STATIC, avail_height, INT_MAX); | 1080 nk_layout_space_begin(context, NK_STATIC, avail_height, INT_MAX); |
1081 nk_layout_space_push(context, nk_rect(img_left, img_top, desired_width, desired_height)); | 1081 nk_layout_space_push(context, nk_rect(img_left, img_top, desired_width, desired_height)); |
1082 nk_image(context, controller_image->ui); | 1082 nk_image(context, controller_image->ui); |
1083 | 1083 |
1084 float bind_box_width = (render_width() - img_right) * 0.8f; | 1084 float bind_box_width = (render_width() - img_right) * 0.8f; |
1085 if (bind_box_width < MIN_BIND_BOX_WIDTH) { | 1085 if (bind_box_width < MIN_BIND_BOX_WIDTH) { |
1086 bind_box_width = render_width() - img_right; | 1086 bind_box_width = render_width() - img_right; |
1087 if (bind_box_width > MIN_BIND_BOX_WIDTH) { | 1087 if (bind_box_width > MIN_BIND_BOX_WIDTH) { |
1088 bind_box_width = MIN_BIND_BOX_WIDTH; | 1088 bind_box_width = MIN_BIND_BOX_WIDTH; |
1094 if (bind_box_width >= (render_width() - img_right)) { | 1094 if (bind_box_width >= (render_width() - img_right)) { |
1095 bind_box_left = img_right; | 1095 bind_box_left = img_right; |
1096 } else { | 1096 } else { |
1097 bind_box_left = img_right + (render_width() - img_right) / 2.0f - bind_box_width / 2.0f; | 1097 bind_box_left = img_right + (render_width() - img_right) / 2.0f - bind_box_width / 2.0f; |
1098 } | 1098 } |
1099 | 1099 |
1100 if (selected_controller_info.variant == VARIANT_NORMAL) { | 1100 if (selected_controller_info.variant == VARIANT_NORMAL) { |
1101 binding_box(context, bindings, "Action Buttons", bind_box_left, img_top, bind_box_width, 4, (int[]){ | 1101 binding_box(context, bindings, "Action Buttons", bind_box_left, img_top, bind_box_width, 4, (int[]){ |
1102 SDL_CONTROLLER_BUTTON_A, | 1102 SDL_CONTROLLER_BUTTON_A, |
1103 SDL_CONTROLLER_BUTTON_B, | 1103 SDL_CONTROLLER_BUTTON_B, |
1104 SDL_CONTROLLER_BUTTON_X, | 1104 SDL_CONTROLLER_BUTTON_X, |
1112 SDL_CONTROLLER_BUTTON_X, | 1112 SDL_CONTROLLER_BUTTON_X, |
1113 SDL_CONTROLLER_BUTTON_Y, | 1113 SDL_CONTROLLER_BUTTON_Y, |
1114 selected_controller_info.variant == VARIANT_6B_RIGHT ? SDL_CONTROLLER_BUTTON_RIGHTSHOULDER : SDL_CONTROLLER_BUTTON_LEFTSHOULDER, | 1114 selected_controller_info.variant == VARIANT_6B_RIGHT ? SDL_CONTROLLER_BUTTON_RIGHTSHOULDER : SDL_CONTROLLER_BUTTON_LEFTSHOULDER, |
1115 }); | 1115 }); |
1116 } | 1116 } |
1117 | 1117 |
1118 if (selected_controller_info.variant == VARIANT_NORMAL) { | 1118 if (selected_controller_info.variant == VARIANT_NORMAL) { |
1119 binding_box(context, bindings, "Right Shoulder", bind_box_left, font->height/2, bind_box_width, 2, (int[]){ | 1119 binding_box(context, bindings, "Right Shoulder", bind_box_left, font->height/2, bind_box_width, 2, (int[]){ |
1120 SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, | 1120 SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, |
1121 AXIS | SDL_CONTROLLER_AXIS_TRIGGERRIGHT | 1121 AXIS | SDL_CONTROLLER_AXIS_TRIGGERRIGHT |
1122 }); | 1122 }); |
1123 } else { | 1123 } else { |
1124 binding_box(context, bindings, "Right Shoulder", bind_box_left, font->height/2, bind_box_width, | 1124 binding_box(context, bindings, "Right Shoulder", bind_box_left, font->height/2, bind_box_width, |
1125 selected_controller_info.variant == VARIANT_6B_BUMPERS ? 1 : 2, | 1125 selected_controller_info.variant == VARIANT_6B_BUMPERS ? 1 : 2, |
1126 (int[]){ | 1126 (int[]){ |
1127 selected_controller_info.variant == VARIANT_6B_RIGHT ? SDL_CONTROLLER_BUTTON_LEFTSHOULDER : AXIS | SDL_CONTROLLER_AXIS_TRIGGERRIGHT, | 1127 selected_controller_info.variant == VARIANT_6B_RIGHT ? SDL_CONTROLLER_BUTTON_LEFTSHOULDER : AXIS | SDL_CONTROLLER_AXIS_TRIGGERRIGHT, |
1128 AXIS | SDL_CONTROLLER_AXIS_TRIGGERLEFT | 1128 AXIS | SDL_CONTROLLER_AXIS_TRIGGERLEFT |
1129 }); | 1129 }); |
1130 } | 1130 } |
1131 | 1131 |
1132 binding_box(context, bindings, "Misc Buttons", (render_width() - bind_box_width) / 2, font->height/2, bind_box_width, 3, (int[]){ | 1132 binding_box(context, bindings, "Misc Buttons", (render_width() - bind_box_width) / 2, font->height/2, bind_box_width, 3, (int[]){ |
1133 SDL_CONTROLLER_BUTTON_BACK, | 1133 SDL_CONTROLLER_BUTTON_BACK, |
1134 SDL_CONTROLLER_BUTTON_GUIDE, | 1134 SDL_CONTROLLER_BUTTON_GUIDE, |
1135 SDL_CONTROLLER_BUTTON_START | 1135 SDL_CONTROLLER_BUTTON_START |
1136 }); | 1136 }); |
1137 | 1137 |
1138 if (selected_controller_info.variant == VARIANT_NORMAL) | 1138 if (selected_controller_info.variant == VARIANT_NORMAL) |
1139 { | 1139 { |
1140 binding_box(context, bindings, "Right Stick", img_right - desired_width/3, img_bot, bind_box_width, 5, (int[]){ | 1140 binding_box(context, bindings, "Right Stick", img_right - desired_width/3, img_bot, bind_box_width, 5, (int[]){ |
1141 RIGHTSTICK | UP, | 1141 RIGHTSTICK | UP, |
1142 RIGHTSTICK | DOWN, | 1142 RIGHTSTICK | DOWN, |
1143 RIGHTSTICK | LEFT, | 1143 RIGHTSTICK | LEFT, |
1144 RIGHTSTICK | RIGHT, | 1144 RIGHTSTICK | RIGHT, |
1145 SDL_CONTROLLER_BUTTON_RIGHTSTICK | 1145 SDL_CONTROLLER_BUTTON_RIGHTSTICK |
1146 }); | 1146 }); |
1147 } | 1147 } |
1148 | 1148 |
1149 bind_box_left -= img_right; | 1149 bind_box_left -= img_right; |
1150 float dpad_left, dpad_top; | 1150 float dpad_left, dpad_top; |
1151 if (selected_controller_info.variant == VARIANT_NORMAL) | 1151 if (selected_controller_info.variant == VARIANT_NORMAL) |
1152 { | 1152 { |
1153 binding_box(context, bindings, "Left Stick", bind_box_left, img_top, bind_box_width, 5, (int[]){ | 1153 binding_box(context, bindings, "Left Stick", bind_box_left, img_top, bind_box_width, 5, (int[]){ |
1161 dpad_top = img_bot + font->height * 1.5; | 1161 dpad_top = img_bot + font->height * 1.5; |
1162 } else { | 1162 } else { |
1163 dpad_left = bind_box_left; | 1163 dpad_left = bind_box_left; |
1164 dpad_top = img_top; | 1164 dpad_top = img_top; |
1165 } | 1165 } |
1166 | 1166 |
1167 if (selected_controller_info.variant == VARIANT_NORMAL) { | 1167 if (selected_controller_info.variant == VARIANT_NORMAL) { |
1168 binding_box(context, bindings, "Left Shoulder", bind_box_left, font->height/2, bind_box_width, 2, (int[]){ | 1168 binding_box(context, bindings, "Left Shoulder", bind_box_left, font->height/2, bind_box_width, 2, (int[]){ |
1169 SDL_CONTROLLER_BUTTON_LEFTSHOULDER, | 1169 SDL_CONTROLLER_BUTTON_LEFTSHOULDER, |
1170 AXIS | SDL_CONTROLLER_AXIS_TRIGGERLEFT | 1170 AXIS | SDL_CONTROLLER_AXIS_TRIGGERLEFT |
1171 }); | 1171 }); |
1172 } else { | 1172 } else { |
1173 binding_box(context, bindings, "Left Shoulder", bind_box_left, font->height/2, bind_box_width, | 1173 binding_box(context, bindings, "Left Shoulder", bind_box_left, font->height/2, bind_box_width, |
1174 selected_controller_info.variant == VARIANT_6B_BUMPERS ? 1 : 2, | 1174 selected_controller_info.variant == VARIANT_6B_BUMPERS ? 1 : 2, |
1175 (int[]){ | 1175 (int[]){ |
1176 selected_controller_info.variant == VARIANT_6B_RIGHT ? SDL_CONTROLLER_BUTTON_LEFTSTICK : AXIS | SDL_CONTROLLER_AXIS_TRIGGERLEFT, | 1176 selected_controller_info.variant == VARIANT_6B_RIGHT ? SDL_CONTROLLER_BUTTON_LEFTSTICK : AXIS | SDL_CONTROLLER_AXIS_TRIGGERLEFT, |
1177 SDL_CONTROLLER_BUTTON_RIGHTSTICK | 1177 SDL_CONTROLLER_BUTTON_RIGHTSTICK |
1178 }); | 1178 }); |
1179 } | 1179 } |
1180 | 1180 |
1181 binding_box(context, bindings, "D-pad", dpad_left, dpad_top, bind_box_width, 4, (int[]){ | 1181 binding_box(context, bindings, "D-pad", dpad_left, dpad_top, bind_box_width, 4, (int[]){ |
1182 SDL_CONTROLLER_BUTTON_DPAD_UP, | 1182 SDL_CONTROLLER_BUTTON_DPAD_UP, |
1183 SDL_CONTROLLER_BUTTON_DPAD_DOWN, | 1183 SDL_CONTROLLER_BUTTON_DPAD_DOWN, |
1184 SDL_CONTROLLER_BUTTON_DPAD_LEFT, | 1184 SDL_CONTROLLER_BUTTON_DPAD_LEFT, |
1185 SDL_CONTROLLER_BUTTON_DPAD_RIGHT | 1185 SDL_CONTROLLER_BUTTON_DPAD_RIGHT |
1186 }); | 1186 }); |
1187 | 1187 |
1188 nk_layout_space_end(context); | 1188 nk_layout_space_end(context); |
1189 | 1189 |
1190 def_font->handle.height = orig_height; | 1190 def_font->handle.height = orig_height; |
1191 nk_layout_row_static(context, orig_height + 4, (render_width() - 2*orig_height) / 4, 1); | 1191 nk_layout_row_static(context, orig_height + 4, (render_width() - 2*orig_height) / 4, 1); |
1192 if (nk_button_label(context, controller_binding_changed ? "Save" : "Back")) { | 1192 if (nk_button_label(context, controller_binding_changed ? "Save" : "Back")) { |
1193 pop_view(); | 1193 pop_view(); |
1194 if (controller_binding_changed) { | 1194 if (controller_binding_changed) { |
1228 { | 1228 { |
1229 char buffer[512]; | 1229 char buffer[512]; |
1230 static int quiet, button_a = -1, button_a_axis = -1; | 1230 static int quiet, button_a = -1, button_a_axis = -1; |
1231 uint8_t added_mapping = 0; | 1231 uint8_t added_mapping = 0; |
1232 if (nk_begin(context, "Controllers", nk_rect(0, 0, render_width(), render_height()), NK_WINDOW_NO_SCROLLBAR)) { | 1232 if (nk_begin(context, "Controllers", nk_rect(0, 0, render_width(), render_height()), NK_WINDOW_NO_SCROLLBAR)) { |
1233 | 1233 |
1234 nk_layout_space_begin(context, NK_STATIC, render_height() - context->style.font->height, 3); | 1234 nk_layout_space_begin(context, NK_STATIC, render_height() - context->style.font->height, 3); |
1235 | 1235 |
1236 if (current_button < SDL_CONTROLLER_BUTTON_MAX) { | 1236 if (current_button < SDL_CONTROLLER_BUTTON_MAX) { |
1237 snprintf(buffer, sizeof(buffer), "Press Button %s", get_button_label(&selected_controller_info, current_button)); | 1237 snprintf(buffer, sizeof(buffer), "Press Button %s", get_button_label(&selected_controller_info, current_button)); |
1238 } else { | 1238 } else { |
1239 snprintf(buffer, sizeof(buffer), "Move Axis %s", get_axis_label(&selected_controller_info, current_axis)); | 1239 snprintf(buffer, sizeof(buffer), "Move Axis %s", get_axis_label(&selected_controller_info, current_axis)); |
1240 } | 1240 } |
1241 | 1241 |
1242 float height = context->style.font->height * 1.25; | 1242 float height = context->style.font->height * 1.25; |
1243 float top = render_height()/2 - 1.5 * height; | 1243 float top = render_height()/2 - 1.5 * height; |
1244 float width = render_width() - context->style.font->height; | 1244 float width = render_width() - context->style.font->height; |
1245 | 1245 |
1246 nk_layout_space_push(context, nk_rect(0, top, width, height)); | 1246 nk_layout_space_push(context, nk_rect(0, top, width, height)); |
1247 nk_label(context, buffer, NK_TEXT_CENTERED); | 1247 nk_label(context, buffer, NK_TEXT_CENTERED); |
1248 if (current_button > SDL_CONTROLLER_BUTTON_B) { | 1248 if (current_button > SDL_CONTROLLER_BUTTON_B) { |
1249 nk_layout_space_push(context, nk_rect(0, top + height, width, height)); | 1249 nk_layout_space_push(context, nk_rect(0, top + height, width, height)); |
1250 nk_label(context, "OR", NK_TEXT_CENTERED); | 1250 nk_label(context, "OR", NK_TEXT_CENTERED); |
1251 | 1251 |
1252 nk_layout_space_push(context, nk_rect(0, top + 2.0 * height, width, height)); | 1252 nk_layout_space_push(context, nk_rect(0, top + 2.0 * height, width, height)); |
1253 snprintf(buffer, sizeof(buffer), "Press Button %s to skip", get_button_label(&selected_controller_info, SDL_CONTROLLER_BUTTON_A)); | 1253 snprintf(buffer, sizeof(buffer), "Press Button %s to skip", get_button_label(&selected_controller_info, SDL_CONTROLLER_BUTTON_A)); |
1254 nk_label(context, buffer, NK_TEXT_CENTERED); | 1254 nk_label(context, buffer, NK_TEXT_CENTERED); |
1255 } | 1255 } |
1256 | 1256 |
1257 nk_layout_space_end(context); | 1257 nk_layout_space_end(context); |
1258 if (quiet) { | 1258 if (quiet) { |
1259 --quiet; | 1259 --quiet; |
1260 } else { | 1260 } else { |
1261 if (button_pressed >= 0 && button_pressed != last_button) { | 1261 if (button_pressed >= 0 && button_pressed != last_button) { |
1277 mapping_string[mapping_pos++] = 'h'; | 1277 mapping_string[mapping_pos++] = 'h'; |
1278 mapping_string[mapping_pos++] = '0' + hat_moved; | 1278 mapping_string[mapping_pos++] = '0' + hat_moved; |
1279 mapping_string[mapping_pos++] = '.'; | 1279 mapping_string[mapping_pos++] = '.'; |
1280 mapping_string[mapping_pos++] = '0' + hat_value; | 1280 mapping_string[mapping_pos++] = '0' + hat_value; |
1281 added_mapping = 1; | 1281 added_mapping = 1; |
1282 | 1282 |
1283 last_hat = hat_moved; | 1283 last_hat = hat_moved; |
1284 last_hat_value = hat_value; | 1284 last_hat_value = hat_value; |
1285 } else if (axis_moved >= 0 && abs(axis_value) > 1000 && ( | 1285 } else if (axis_moved >= 0 && abs(axis_value) > 1000 && ( |
1286 axis_moved != last_axis || ( | 1286 axis_moved != last_axis || ( |
1287 axis_value/abs(axis_value) != last_axis_value/abs(axis_value) && current_button >= SDL_CONTROLLER_BUTTON_DPAD_UP | 1287 axis_value/abs(axis_value) != last_axis_value/abs(axis_value) && current_button >= SDL_CONTROLLER_BUTTON_DPAD_UP |
1301 last_axis_value = axis_value; | 1301 last_axis_value = axis_value; |
1302 } | 1302 } |
1303 added_mapping = 1; | 1303 added_mapping = 1; |
1304 } | 1304 } |
1305 } | 1305 } |
1306 | 1306 |
1307 while (added_mapping) { | 1307 while (added_mapping) { |
1308 quiet = QUIET_FRAMES; | 1308 quiet = QUIET_FRAMES; |
1309 if (current_button < SDL_CONTROLLER_BUTTON_MAX) { | 1309 if (current_button < SDL_CONTROLLER_BUTTON_MAX) { |
1310 current_button++; | 1310 current_button++; |
1311 if (current_button == SDL_CONTROLLER_BUTTON_MAX) { | 1311 if (current_button == SDL_CONTROLLER_BUTTON_MAX) { |
1361 if (c == ',' || c == '\n' || c == '\r') { | 1361 if (c == ',' || c == '\n' || c == '\r') { |
1362 c = ' '; | 1362 c = ' '; |
1363 } | 1363 } |
1364 mapping_string[mapping_pos] = c; | 1364 mapping_string[mapping_pos] = c; |
1365 } | 1365 } |
1366 | 1366 |
1367 push_view(view_controller_mappings); | 1367 push_view(view_controller_mappings); |
1368 } | 1368 } |
1369 | 1369 |
1370 static void view_controller_variant(struct nk_context *context) | 1370 static void view_controller_variant(struct nk_context *context) |
1371 { | 1371 { |
1393 if (nk_button_label(context, "4 face buttons")) { | 1393 if (nk_button_label(context, "4 face buttons")) { |
1394 selected_controller_info.variant = VARIANT_NORMAL; | 1394 selected_controller_info.variant = VARIANT_NORMAL; |
1395 selected = 1; | 1395 selected = 1; |
1396 } | 1396 } |
1397 char buffer[512]; | 1397 char buffer[512]; |
1398 snprintf(buffer, sizeof(buffer), "6 face buttons including %s and %s", | 1398 snprintf(buffer, sizeof(buffer), "6 face buttons including %s and %s", |
1399 get_button_label(&selected_controller_info, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), | 1399 get_button_label(&selected_controller_info, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), |
1400 get_axis_label(&selected_controller_info, SDL_CONTROLLER_AXIS_TRIGGERRIGHT) | 1400 get_axis_label(&selected_controller_info, SDL_CONTROLLER_AXIS_TRIGGERRIGHT) |
1401 ); | 1401 ); |
1402 if (nk_button_label(context, buffer)) { | 1402 if (nk_button_label(context, buffer)) { |
1403 selected_controller_info.variant = VARIANT_6B_RIGHT; | 1403 selected_controller_info.variant = VARIANT_6B_RIGHT; |
1404 selected = 1; | 1404 selected = 1; |
1405 } | 1405 } |
1406 snprintf(buffer, sizeof(buffer), "6 face buttons including %s and %s", | 1406 snprintf(buffer, sizeof(buffer), "6 face buttons including %s and %s", |
1407 get_button_label(&selected_controller_info, SDL_CONTROLLER_BUTTON_LEFTSHOULDER), | 1407 get_button_label(&selected_controller_info, SDL_CONTROLLER_BUTTON_LEFTSHOULDER), |
1408 get_button_label(&selected_controller_info, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER) | 1408 get_button_label(&selected_controller_info, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER) |
1409 ); | 1409 ); |
1410 if (nk_button_label(context, buffer)) { | 1410 if (nk_button_label(context, buffer)) { |
1411 selected_controller_info.variant = VARIANT_6B_BUMPERS; | 1411 selected_controller_info.variant = VARIANT_6B_BUMPERS; |
1412 selected = 1; | 1412 selected = 1; |
1493 int change_type_width = font->width(font->userdata, font->height, "Change Type", strlen("Change Type")) + context->style.button.padding.x * 2; | 1493 int change_type_width = font->width(font->userdata, font->height, "Change Type", strlen("Change Type")) + context->style.button.padding.x * 2; |
1494 int total = bindings_width + remap_width + change_type_width; | 1494 int total = bindings_width + remap_width + change_type_width; |
1495 float bindings_ratio = (float)bindings_width / total; | 1495 float bindings_ratio = (float)bindings_width / total; |
1496 float remap_ratio = (float)remap_width / total; | 1496 float remap_ratio = (float)remap_width / total; |
1497 float change_type_ratio = (float)change_type_width / total; | 1497 float change_type_ratio = (float)change_type_width / total; |
1498 | 1498 |
1499 | 1499 |
1500 uint8_t found_controller = 0; | 1500 uint8_t found_controller = 0; |
1501 for (int i = 0; i < MAX_JOYSTICKS; i++) | 1501 for (int i = 0; i < MAX_JOYSTICKS; i++) |
1502 { | 1502 { |
1503 SDL_Joystick *joy = render_get_joystick(i); | 1503 SDL_Joystick *joy = render_get_joystick(i); |
1504 if (joy) { | 1504 if (joy) { |
1513 } else { | 1513 } else { |
1514 nk_image(context, controller_image->ui); | 1514 nk_image(context, controller_image->ui); |
1515 } | 1515 } |
1516 int button_start = image_width + context->style.font->height; | 1516 int button_start = image_width + context->style.font->height; |
1517 int button_area_width = render_width() - image_width - 2 * context->style.font->height; | 1517 int button_area_width = render_width() - image_width - 2 * context->style.font->height; |
1518 | 1518 |
1519 nk_layout_space_push(context, nk_rect(button_start, 0, button_area_width, inner_height/2)); | 1519 nk_layout_space_push(context, nk_rect(button_start, 0, button_area_width, inner_height/2)); |
1520 nk_label(context, info.name, NK_TEXT_CENTERED); | 1520 nk_label(context, info.name, NK_TEXT_CENTERED); |
1521 const struct nk_user_font *font = context->style.font; | 1521 const struct nk_user_font *font = context->style.font; |
1522 if (info.type == TYPE_UNKNOWN || info.type == TYPE_GENERIC_MAPPING) { | 1522 if (info.type == TYPE_UNKNOWN || info.type == TYPE_GENERIC_MAPPING) { |
1523 int button_width = font->width(font->userdata, font->height, "Configure", strlen("Configure")); | 1523 int button_width = font->width(font->userdata, font->height, "Configure", strlen("Configure")); |
1635 buffer[len] = 0; | 1635 buffer[len] = 0; |
1636 if (strcmp(buffer, curstr)) { | 1636 if (strcmp(buffer, curstr)) { |
1637 config_dirty = 1; | 1637 config_dirty = 1; |
1638 config = tern_insert_path(config, path, (tern_val){.ptrval = strdup(buffer)}, TVAL_PTR); | 1638 config = tern_insert_path(config, path, (tern_val){.ptrval = strdup(buffer)}, TVAL_PTR); |
1639 } | 1639 } |
1640 | 1640 |
1641 nk_spacing(context, 1); | 1641 nk_spacing(context, 1); |
1642 if (nk_button_label(context, "Browse")) { | 1642 if (nk_button_label(context, "Browse")) { |
1643 browser_label = label; | 1643 browser_label = label; |
1644 browser_setting_path = path; | 1644 browser_setting_path = path; |
1645 browser_ext_list = exts; | 1645 browser_ext_list = exts; |
1690 shader_prog *get_shader_progs(dir_entry *entries, size_t num_entries, shader_prog *progs, uint32_t *num_existing, uint32_t *storage) | 1690 shader_prog *get_shader_progs(dir_entry *entries, size_t num_entries, shader_prog *progs, uint32_t *num_existing, uint32_t *storage) |
1691 { | 1691 { |
1692 uint32_t num_progs = *num_existing; | 1692 uint32_t num_progs = *num_existing; |
1693 uint32_t prog_storage = *storage; | 1693 uint32_t prog_storage = *storage; |
1694 uint32_t starting = num_progs; | 1694 uint32_t starting = num_progs; |
1695 | 1695 |
1696 for (uint32_t i = 0; i < num_entries; i++) { | 1696 for (uint32_t i = 0; i < num_entries; i++) { |
1697 if (entries[i].is_dir) { | 1697 if (entries[i].is_dir) { |
1698 continue; | 1698 continue; |
1699 } | 1699 } |
1700 char *no_ext = basename_no_extension(entries[i].name); | 1700 char *no_ext = basename_no_extension(entries[i].name); |
1711 if (num_progs == prog_storage) { | 1711 if (num_progs == prog_storage) { |
1712 prog_storage = prog_storage ? prog_storage*2 : 4; | 1712 prog_storage = prog_storage ? prog_storage*2 : 4; |
1713 progs = realloc(progs, sizeof(*progs) * prog_storage); | 1713 progs = realloc(progs, sizeof(*progs) * prog_storage); |
1714 } | 1714 } |
1715 progs[num_progs].vertex = NULL; | 1715 progs[num_progs].vertex = NULL; |
1716 progs[num_progs++].fragment = strdup(entries[i].name); | 1716 progs[num_progs++].fragment = strdup(entries[i].name); |
1717 } | 1717 } |
1718 } | 1718 } |
1719 free(no_ext); | 1719 free(no_ext); |
1720 } | 1720 } |
1721 | 1721 |
1722 for (uint32_t i = 0; i < num_entries; i++) { | 1722 for (uint32_t i = 0; i < num_entries; i++) { |
1723 if (entries[i].is_dir) { | 1723 if (entries[i].is_dir) { |
1724 continue; | 1724 continue; |
1725 } | 1725 } |
1726 char *no_ext = basename_no_extension(entries[i].name); | 1726 char *no_ext = basename_no_extension(entries[i].name); |
1872 settings_int_property(context, "", "Right", "video\0ntsc\0overscan\0right\0", 14, 0, 32); | 1872 settings_int_property(context, "", "Right", "video\0ntsc\0overscan\0right\0", 14, 0, 32); |
1873 settings_int_property(context, "PAL Overscan", "Top", "video\0pal\0overscan\0top\0", 2, 0, 32); | 1873 settings_int_property(context, "PAL Overscan", "Top", "video\0pal\0overscan\0top\0", 2, 0, 32); |
1874 settings_int_property(context, "", "Bottom", "video\0pal\0overscan\0bottom\0", 17, 0, 32); | 1874 settings_int_property(context, "", "Bottom", "video\0pal\0overscan\0bottom\0", 17, 0, 32); |
1875 settings_int_property(context, "", "Left", "video\0pal\0overscan\0left\0", 13, 0, 32); | 1875 settings_int_property(context, "", "Left", "video\0pal\0overscan\0left\0", 13, 0, 32); |
1876 settings_int_property(context, "", "Right", "video\0pal\0overscan\0right\0", 14, 0, 32); | 1876 settings_int_property(context, "", "Right", "video\0pal\0overscan\0right\0", 14, 0, 32); |
1877 | 1877 |
1878 if (nk_button_label(context, "Back")) { | 1878 if (nk_button_label(context, "Back")) { |
1879 pop_view(); | 1879 pop_view(); |
1880 } | 1880 } |
1881 nk_end(context); | 1881 nk_end(context); |
1882 } | 1882 } |
1941 typedef struct { | 1941 typedef struct { |
1942 const char **models; | 1942 const char **models; |
1943 const char **names; | 1943 const char **names; |
1944 uint32_t num_models; | 1944 uint32_t num_models; |
1945 uint32_t storage; | 1945 uint32_t storage; |
1946 uint8_t genesis_only; | |
1946 } model_foreach_state; | 1947 } model_foreach_state; |
1947 void model_iter(char *key, tern_val val, uint8_t valtype, void *data) | 1948 void model_iter(char *key, tern_val val, uint8_t valtype, void *data) |
1948 { | 1949 { |
1949 if (valtype != TVAL_NODE) { | 1950 if (valtype != TVAL_NODE) { |
1950 return; | 1951 return; |
1951 } | 1952 } |
1953 if (!strcmp(tern_find_ptr_default(val.ptrval, "show", "yes"), "no")) { | |
1954 return; | |
1955 } | |
1952 model_foreach_state *state = data; | 1956 model_foreach_state *state = data; |
1957 if (state->genesis_only && strcmp(tern_find_ptr_default(val.ptrval, "vdp", "genesis"), "genesis")) { | |
1958 return; | |
1959 } | |
1953 if (state->num_models == state->storage) { | 1960 if (state->num_models == state->storage) { |
1954 state->storage *= 2; | 1961 state->storage *= 2; |
1955 state->models = realloc(state->models, state->storage * sizeof(char *)); | 1962 state->models = realloc(state->models, state->storage * sizeof(char *)); |
1956 state->names = realloc(state->names, state->storage * sizeof(char *)); | 1963 state->names = realloc(state->names, state->storage * sizeof(char *)); |
1957 } | 1964 } |
1963 typedef struct { | 1970 typedef struct { |
1964 const char **models; | 1971 const char **models; |
1965 const char **names; | 1972 const char **names; |
1966 } models; | 1973 } models; |
1967 | 1974 |
1968 models get_models(uint32_t *num_out) | 1975 models get_models(uint32_t *num_out, uint8_t genesis_only) |
1969 { | 1976 { |
1970 tern_node *systems = get_systems_config(); | 1977 tern_node *systems = get_systems_config(); |
1971 model_foreach_state state = { | 1978 model_foreach_state state = { |
1972 .models = calloc(4, sizeof(char *)), | 1979 .models = calloc(4, sizeof(char *)), |
1973 .names = calloc(4, sizeof(char *)), | 1980 .names = calloc(4, sizeof(char *)), |
1974 .num_models = 0, | 1981 .num_models = 0, |
1975 .storage = 4 | 1982 .storage = 4, |
1983 .genesis_only = genesis_only | |
1976 }; | 1984 }; |
1977 tern_foreach(systems, model_iter, &state); | 1985 tern_foreach(systems, model_iter, &state); |
1978 *num_out = state.num_models; | 1986 *num_out = state.num_models; |
1979 return (models){ | 1987 return (models){ |
1980 .models = state.models, | 1988 .models = state.models, |
2002 const uint32_t num_regions = sizeof(regions)/sizeof(*regions); | 2010 const uint32_t num_regions = sizeof(regions)/sizeof(*regions); |
2003 static int32_t selected_region = -1; | 2011 static int32_t selected_region = -1; |
2004 if (selected_region < 0) { | 2012 if (selected_region < 0) { |
2005 selected_region = find_match(region_codes, num_regions, "system\0default_region\0", "U"); | 2013 selected_region = find_match(region_codes, num_regions, "system\0default_region\0", "U"); |
2006 } | 2014 } |
2007 static const char **model_opts; | 2015 static const char **model_opts, **sms_model_opts; |
2008 static const char **model_names; | 2016 static const char **model_names, **sms_model_names; |
2009 static uint32_t num_models; | 2017 static uint32_t num_models, num_sms_models; |
2010 if (!model_opts) { | 2018 if (!model_opts) { |
2011 models m = get_models(&num_models); | 2019 models m = get_models(&num_models, 1); |
2012 model_opts = m.models; | 2020 model_opts = m.models; |
2013 model_names = m.names; | 2021 model_names = m.names; |
2014 } | 2022 m = get_models(&num_sms_models, 0); |
2023 sms_model_opts = m.models; | |
2024 sms_model_names = m.names; | |
2025 } | |
2026 static uint8_t old_show_sms; | |
2027 uint8_t show_sms = current_system && current_system->type == SYSTEM_SMS; | |
2028 | |
2015 static int32_t selected_model = -1; | 2029 static int32_t selected_model = -1; |
2016 if (selected_model < 0) { | 2030 if (selected_model < 0 || show_sms != old_show_sms) { |
2017 selected_model = find_match(model_opts, num_models, "system\0model\0", "md1va3"); | 2031 if (show_sms) { |
2018 } | 2032 selected_model = find_match(sms_model_opts, num_sms_models, "sms\0system\0model\0", "md1va3"); |
2019 | 2033 } else { |
2034 selected_model = find_match(model_opts, num_models, "system\0model\0", "md1va3"); | |
2035 } | |
2036 } | |
2037 | |
2020 const char *formats[] = { | 2038 const char *formats[] = { |
2021 "native", | 2039 "native", |
2022 "gst" | 2040 "gst" |
2023 }; | 2041 }; |
2024 const uint32_t num_formats = sizeof(formats)/sizeof(*formats); | 2042 const uint32_t num_formats = sizeof(formats)/sizeof(*formats); |
2054 "xband keyboard" | 2072 "xband keyboard" |
2055 }; | 2073 }; |
2056 static int32_t selected_io_1 = -1; | 2074 static int32_t selected_io_1 = -1; |
2057 static int32_t selected_io_2 = -1; | 2075 static int32_t selected_io_2 = -1; |
2058 const uint32_t num_io = sizeof(io_opts_1)/sizeof(*io_opts_1); | 2076 const uint32_t num_io = sizeof(io_opts_1)/sizeof(*io_opts_1); |
2059 if (selected_io_1 < 0 || selected_io_2 < 0) { | 2077 if (selected_io_1 < 0 || selected_io_2 < 0 || show_sms != old_show_sms) { |
2060 selected_io_1 = find_match(io_opts_1, num_io, "io\0devices\0""1\0", "gamepad6.1"); | 2078 if (show_sms) { |
2061 selected_io_2 = find_match(io_opts_2, num_io, "io\0devices\0""2\0", "gamepad6.2"); | 2079 selected_io_1 = find_match(io_opts_1, num_io, "sms\0io\0devices\0""1\0", "gamepad2.1"); |
2062 } | 2080 selected_io_2 = find_match(io_opts_2, num_io, "sms\0io\0devices\0""2\0", "gamepad2.2"); |
2063 | 2081 } else { |
2082 selected_io_1 = find_match(io_opts_1, num_io, "io\0devices\0""1\0", "gamepad6.1"); | |
2083 selected_io_2 = find_match(io_opts_2, num_io, "io\0devices\0""2\0", "gamepad6.2"); | |
2084 } | |
2085 } | |
2086 old_show_sms = show_sms; | |
2087 | |
2064 uint32_t width = render_width(); | 2088 uint32_t width = render_width(); |
2065 uint32_t height = render_height(); | 2089 uint32_t height = render_height(); |
2066 uint32_t desired_width = context->style.font->height * 10; | 2090 uint32_t desired_width = context->style.font->height * 10; |
2067 if (nk_begin(context, "System Settings", nk_rect(0, 0, width, height), 0)) { | 2091 if (nk_begin(context, "System Settings", nk_rect(0, 0, width, height), 0)) { |
2068 nk_layout_row_static(context, context->style.font->height, desired_width, 2); | 2092 nk_layout_row_static(context, context->style.font->height, desired_width, 2); |
2069 | 2093 |
2070 selected_model = settings_dropdown_ex(context, "Model", model_opts, model_names, num_models, selected_model, "system\0model\0"); | 2094 if (show_sms) { |
2071 selected_io_1 = settings_dropdown_ex(context, "IO Port 1 Device", io_opts_1, device_type_names, num_io, selected_io_1, "io\0devices\0""1\0"); | 2095 selected_model = settings_dropdown_ex(context, "Model", sms_model_opts, sms_model_names, num_sms_models, selected_model, "sms\0system\0model\0"); |
2072 selected_io_2 = settings_dropdown_ex(context, "IO Port 2 Device", io_opts_2, device_type_names, num_io, selected_io_2, "io\0devices\0""2\0"); | 2096 } else { |
2097 selected_model = settings_dropdown_ex(context, "Model", model_opts, model_names, num_models, selected_model, "system\0model\0"); | |
2098 } | |
2099 selected_io_1 = settings_dropdown_ex(context, "IO Port 1 Device", io_opts_1, device_type_names, num_io, selected_io_1, show_sms ? "sms\0io\0devices\0""1\0" : "io\0devices\0""1\0"); | |
2100 selected_io_2 = settings_dropdown_ex(context, "IO Port 2 Device", io_opts_2, device_type_names, num_io, selected_io_2, show_sms ? "sms\0io\0devices\0""2\0" : "io\0devices\0""2\0"); | |
2073 selected_region = settings_dropdown_ex(context, "Default Region", region_codes, regions, num_regions, selected_region, "system\0default_region\0"); | 2101 selected_region = settings_dropdown_ex(context, "Default Region", region_codes, regions, num_regions, selected_region, "system\0default_region\0"); |
2074 selected_sync = settings_dropdown(context, "Sync Source", sync_opts, num_sync_opts, selected_sync, "system\0sync_source\0"); | 2102 selected_sync = settings_dropdown(context, "Sync Source", sync_opts, num_sync_opts, selected_sync, "system\0sync_source\0"); |
2075 settings_int_property(context, "68000 Clock Divider", "", "clocks\0m68k_divider\0", 7, 1, 53); | 2103 if (!show_sms) { |
2076 selected_format = settings_dropdown(context, "Save State Format", formats, num_formats, selected_format, "ui\0state_format\0"); | 2104 settings_int_property(context, "68000 Clock Divider", "", "clocks\0m68k_divider\0", 7, 1, 53); |
2105 selected_format = settings_dropdown(context, "Save State Format", formats, num_formats, selected_format, "ui\0state_format\0"); | |
2106 } | |
2077 selected_init = settings_dropdown(context, "Initial RAM Value", ram_inits, num_inits, selected_init, "system\0ram_init\0"); | 2107 selected_init = settings_dropdown(context, "Initial RAM Value", ram_inits, num_inits, selected_init, "system\0ram_init\0"); |
2078 settings_toggle(context, "Remember ROM Path", "ui\0remember_path\0", 1); | 2108 settings_toggle(context, "Remember ROM Path", "ui\0remember_path\0", 1); |
2079 settings_toggle(context, "Save config with EXE", "ui\0config_in_exe_dir\0", 0); | 2109 settings_toggle(context, "Save config with EXE", "ui\0config_in_exe_dir\0", 0); |
2080 settings_string(context, "Game Save Path", "ui\0save_path\0", "$USERDATA/blastem/$ROMNAME"); | 2110 settings_string(context, "Game Save Path", "ui\0save_path\0", "$USERDATA/blastem/$ROMNAME"); |
2081 | 2111 |
2082 if (nk_button_label(context, "Back")) { | 2112 if (nk_button_label(context, "Back")) { |
2083 pop_view(); | 2113 pop_view(); |
2084 } | 2114 } |
2085 nk_end(context); | 2115 nk_end(context); |
2086 } | 2116 } |
2143 {"System", view_system_settings}, | 2173 {"System", view_system_settings}, |
2144 {"Firmware", view_bios_settings}, | 2174 {"Firmware", view_bios_settings}, |
2145 {"Reset to Defaults", view_confirm_reset}, | 2175 {"Reset to Defaults", view_confirm_reset}, |
2146 {"Back", view_back} | 2176 {"Back", view_back} |
2147 }; | 2177 }; |
2148 | 2178 |
2149 if (nk_begin(context, "Settings Menu", nk_rect(0, 0, render_width(), render_height()), 0)) { | 2179 if (nk_begin(context, "Settings Menu", nk_rect(0, 0, render_width(), render_height()), 0)) { |
2150 menu(context, sizeof(items)/sizeof(*items), items, NULL); | 2180 menu(context, sizeof(items)/sizeof(*items), items, NULL); |
2151 nk_end(context); | 2181 nk_end(context); |
2152 } | 2182 } |
2153 } | 2183 } |
2166 {"Save State", view_save_state}, | 2196 {"Save State", view_save_state}, |
2167 {"Load State", view_load_state}, | 2197 {"Load State", view_load_state}, |
2168 {"Settings", view_settings}, | 2198 {"Settings", view_settings}, |
2169 {"Exit", NULL} | 2199 {"Exit", NULL} |
2170 }; | 2200 }; |
2171 | 2201 |
2172 if (nk_begin(context, "Main Menu", nk_rect(0, 0, render_width(), render_height()), 0)) { | 2202 if (nk_begin(context, "Main Menu", nk_rect(0, 0, render_width(), render_height()), 0)) { |
2173 menu(context, sizeof(items)/sizeof(*items), items, exit_handler); | 2203 menu(context, sizeof(items)/sizeof(*items), items, exit_handler); |
2174 nk_end(context); | 2204 nk_end(context); |
2175 } | 2205 } |
2176 } | 2206 } |
2181 {"Load ROM", view_load}, | 2211 {"Load ROM", view_load}, |
2182 {"Settings", view_settings}, | 2212 {"Settings", view_settings}, |
2183 {"About", view_about}, | 2213 {"About", view_about}, |
2184 {"Exit", NULL} | 2214 {"Exit", NULL} |
2185 }; | 2215 }; |
2186 | 2216 |
2187 if (nk_begin(context, "Main Menu", nk_rect(0, 0, render_width(), render_height()), 0)) { | 2217 if (nk_begin(context, "Main Menu", nk_rect(0, 0, render_width(), render_height()), 0)) { |
2188 menu(context, sizeof(items)/sizeof(*items), items, exit_handler); | 2218 menu(context, sizeof(items)/sizeof(*items), items, exit_handler); |
2189 nk_end(context); | 2219 nk_end(context); |
2190 } | 2220 } |
2191 } | 2221 } |
2454 render_set_ui_fb_resize_handler(fb_resize); | 2484 render_set_ui_fb_resize_handler(fb_resize); |
2455 #ifndef DISABLE_OPENGL | 2485 #ifndef DISABLE_OPENGL |
2456 } | 2486 } |
2457 #endif | 2487 #endif |
2458 style_init(); | 2488 style_init(); |
2459 | 2489 |
2460 controller_360 = load_ui_image("images/360.png"); | 2490 controller_360 = load_ui_image("images/360.png"); |
2461 controller_ps4 = load_ui_image("images/ps4.png"); | 2491 controller_ps4 = load_ui_image("images/ps4.png"); |
2462 controller_ps4_6b = load_ui_image("images/ps4_6b.png"); | 2492 controller_ps4_6b = load_ui_image("images/ps4_6b.png"); |
2463 controller_wiiu = load_ui_image("images/wiiu.png"); | 2493 controller_wiiu = load_ui_image("images/wiiu.png"); |
2464 controller_gen_6b = load_ui_image("images/genesis_6b.png"); | 2494 controller_gen_6b = load_ui_image("images/genesis_6b.png"); |
2465 | 2495 |
2466 texture_init(); | 2496 texture_init(); |
2467 | 2497 |
2468 if (file_loaded) { | 2498 if (file_loaded) { |
2469 current_view = view_play; | 2499 current_view = view_play; |
2470 } else { | 2500 } else { |
2471 current_view = view_menu; | 2501 current_view = view_menu; |
2472 set_content_binding_state(0); | 2502 set_content_binding_state(0); |
2473 } | 2503 } |
2474 render_set_ui_render_fun(blastem_nuklear_render); | 2504 render_set_ui_render_fun(blastem_nuklear_render); |
2475 render_set_event_handler(handle_event); | 2505 render_set_event_handler(handle_event); |
2476 render_set_gl_context_handlers(context_destroyed, context_created); | 2506 render_set_gl_context_handlers(context_destroyed, context_created); |
2477 | 2507 |
2478 atexit(persist_config_exit); | 2508 atexit(persist_config_exit); |
2479 | 2509 |
2480 active = 1; | 2510 active = 1; |
2481 ui_idle_loop(); | 2511 ui_idle_loop(); |
2482 } | 2512 } |