comparison nuklear_ui/blastem_nuklear.c @ 1931:374a5ae694e8 mame_interp

Merge from default
author Michael Pavone <pavone@retrodev.com>
date Sat, 18 Apr 2020 11:42:53 -0700
parents ee178f08611b
children 81df9aa2de9b
comparison
equal deleted inserted replaced
1843:13abdc98379e 1931:374a5ae694e8
48 view_storage = view_storage ? 2*view_storage : 2; 48 view_storage = view_storage ? 2*view_storage : 2;
49 previous_views = realloc(previous_views, view_storage*sizeof(view_fun)); 49 previous_views = realloc(previous_views, view_storage*sizeof(view_fun));
50 } 50 }
51 previous_views[num_prev++] = current_view; 51 previous_views[num_prev++] = current_view;
52 current_view = new_view; 52 current_view = new_view;
53 context->input.selected_widget = 0;
53 } 54 }
54 55
55 static void pop_view() 56 static void pop_view()
56 { 57 {
57 if (num_prev) { 58 if (num_prev) {
58 current_view = previous_views[--num_prev]; 59 current_view = previous_views[--num_prev];
60 context->input.selected_widget = 0;
59 } 61 }
60 } 62 }
61 63
62 static void clear_view_stack() 64 static void clear_view_stack()
63 { 65 {
437 "gamepads.2.x", "gamepads.2.y", "gamepads.2.z", 439 "gamepads.2.x", "gamepads.2.y", "gamepads.2.z",
438 "gamepads.2.start", "gamepads.2.mode" 440 "gamepads.2.start", "gamepads.2.mode"
439 }; 441 };
440 const char *general_binds[] = { 442 const char *general_binds[] = {
441 "ui.exit", "ui.save_state", "ui.toggle_fullscreen", "ui.soft_reset", "ui.reload", 443 "ui.exit", "ui.save_state", "ui.toggle_fullscreen", "ui.soft_reset", "ui.reload",
442 "ui.screenshot", "ui.sms_pause", "ui.toggle_keyboard_cpatured", "ui.release_mouse" 444 "ui.screenshot", "ui.vgm_log", "ui.sms_pause", "ui.toggle_keyboard_cpatured", "ui.release_mouse"
443 }; 445 };
444 const char *general_names[] = { 446 const char *general_names[] = {
445 "Show Menu", "Quick Save", "Toggle Fullscreen", "Soft Reset", "Reload Media", 447 "Show Menu", "Quick Save", "Toggle Fullscreen", "Soft Reset", "Reload Media",
446 "Internal Screenshot", "SMS Pause", "Capture Keyboard", "Release Mouse" 448 "Internal Screenshot", "Toggle VGM Log", "SMS Pause", "Capture Keyboard", "Release Mouse"
447 }; 449 };
448 const char *speed_binds[] = { 450 const char *speed_binds[] = {
449 "ui.next_speed", "ui.prev_speed", 451 "ui.next_speed", "ui.prev_speed",
450 "ui.set_speed.0", "ui.set_speed.1", "ui.set_speed.2" ,"ui.set_speed.3", "ui.set_speed.4", 452 "ui.set_speed.0", "ui.set_speed.1", "ui.set_speed.2" ,"ui.set_speed.3", "ui.set_speed.4",
451 "ui.set_speed.5", "ui.set_speed.6", "ui.set_speed.7" ,"ui.set_speed.8", "ui.set_speed.9", 453 "ui.set_speed.5", "ui.set_speed.6", "ui.set_speed.7" ,"ui.set_speed.8", "ui.set_speed.9",
588 conf_names = tern_insert_ptr(conf_names, "ui.release_mouse", "Release Mouse"); 590 conf_names = tern_insert_ptr(conf_names, "ui.release_mouse", "Release Mouse");
589 conf_names = tern_insert_ptr(conf_names, "ui.vdp_debug_mode", "VDP Debug Mode"); 591 conf_names = tern_insert_ptr(conf_names, "ui.vdp_debug_mode", "VDP Debug Mode");
590 conf_names = tern_insert_ptr(conf_names, "ui.vdp_debug_pal", "VDP Debug Palette"); 592 conf_names = tern_insert_ptr(conf_names, "ui.vdp_debug_pal", "VDP Debug Palette");
591 conf_names = tern_insert_ptr(conf_names, "ui.enter_debugger", "Enter CPU Debugger"); 593 conf_names = tern_insert_ptr(conf_names, "ui.enter_debugger", "Enter CPU Debugger");
592 conf_names = tern_insert_ptr(conf_names, "ui.screenshot", "Take Screenshot"); 594 conf_names = tern_insert_ptr(conf_names, "ui.screenshot", "Take Screenshot");
595 conf_names = tern_insert_ptr(conf_names, "ui.vgm_log", "Toggle VGM Log");
593 conf_names = tern_insert_ptr(conf_names, "ui.exit", "Show Menu"); 596 conf_names = tern_insert_ptr(conf_names, "ui.exit", "Show Menu");
594 conf_names = tern_insert_ptr(conf_names, "ui.save_state", "Quick Save"); 597 conf_names = tern_insert_ptr(conf_names, "ui.save_state", "Quick Save");
595 conf_names = tern_insert_ptr(conf_names, "ui.set_speed.0", "Set Speed 0"); 598 conf_names = tern_insert_ptr(conf_names, "ui.set_speed.0", "Set Speed 0");
596 conf_names = tern_insert_ptr(conf_names, "ui.set_speed.1", "Set Speed 1"); 599 conf_names = tern_insert_ptr(conf_names, "ui.set_speed.1", "Set Speed 1");
597 conf_names = tern_insert_ptr(conf_names, "ui.set_speed.2", "Set Speed 2"); 600 conf_names = tern_insert_ptr(conf_names, "ui.set_speed.2", "Set Speed 2");
1171 memcpy(mapping_string + mapping_pos, name, namesz); 1174 memcpy(mapping_string + mapping_pos, name, namesz);
1172 mapping_pos += namesz; 1175 mapping_pos += namesz;
1173 mapping_string[mapping_pos++] = ':'; 1176 mapping_string[mapping_pos++] = ':';
1174 } 1177 }
1175 1178
1179 static uint8_t initial_controller_config;
1176 #define QUIET_FRAMES 9 1180 #define QUIET_FRAMES 9
1177 static void view_controller_mappings(struct nk_context *context) 1181 static void view_controller_mappings(struct nk_context *context)
1178 { 1182 {
1179 char buffer[512]; 1183 char buffer[512];
1180 static int quiet, button_a = -1, button_a_axis = -1; 1184 static int quiet, button_a = -1, button_a_axis = -1;
1273 button_a_axis = -1; 1277 button_a_axis = -1;
1274 mapping_string[mapping_pos] = 0; 1278 mapping_string[mapping_pos] = 0;
1275 save_controller_mapping(selected_controller, mapping_string); 1279 save_controller_mapping(selected_controller, mapping_string);
1276 free(mapping_string); 1280 free(mapping_string);
1277 pop_view(); 1281 pop_view();
1278 push_view(view_controller_bindings); 1282 if (initial_controller_config) {
1279 controller_binding_changed = 0; 1283 push_view(view_controller_bindings);
1284 controller_binding_changed = 0;
1285 }
1280 added_mapping = 0; 1286 added_mapping = 0;
1281 } else if (get_axis_label(&selected_controller_info, current_axis)) { 1287 } else if (get_axis_label(&selected_controller_info, current_axis)) {
1282 added_mapping = 0; 1288 added_mapping = 0;
1283 } 1289 }
1284 } 1290 }
1286 button_pressed = -1; 1292 button_pressed = -1;
1287 hat_moved = -1; 1293 hat_moved = -1;
1288 axis_moved = -1; 1294 axis_moved = -1;
1289 nk_end(context); 1295 nk_end(context);
1290 } 1296 }
1297 }
1298
1299 static void show_mapping_view(void)
1300 {
1301 current_button = SDL_CONTROLLER_BUTTON_A;
1302 button_pressed = -1;
1303 last_button = -1;
1304 last_hat = -1;
1305 axis_moved = -1;
1306 last_axis = -1;
1307 last_axis_value = 0;
1308 SDL_Joystick *joy = render_get_joystick(selected_controller);
1309 const char *name = SDL_JoystickName(joy);
1310 size_t namesz = strlen(name);
1311 mapping_string = malloc(512 + namesz);
1312 for (mapping_pos = 0; mapping_pos < namesz; mapping_pos++)
1313 {
1314 char c = name[mapping_pos];
1315 if (c == ',' || c == '\n' || c == '\r') {
1316 c = ' ';
1317 }
1318 mapping_string[mapping_pos] = c;
1319 }
1320
1321 push_view(view_controller_mappings);
1291 } 1322 }
1292 1323
1293 static void view_controller_variant(struct nk_context *context) 1324 static void view_controller_variant(struct nk_context *context)
1294 { 1325 {
1295 uint8_t selected = 0; 1326 uint8_t selected = 0;
1323 nk_end(context); 1354 nk_end(context);
1324 } 1355 }
1325 if (selected) { 1356 if (selected) {
1326 save_controller_info(selected_controller, &selected_controller_info); 1357 save_controller_info(selected_controller, &selected_controller_info);
1327 pop_view(); 1358 pop_view();
1328 SDL_GameController *controller = render_get_controller(selected_controller); 1359 if (initial_controller_config) {
1329 if (controller) { 1360 SDL_GameController *controller = render_get_controller(selected_controller);
1330 push_view(view_controller_bindings); 1361 if (controller) {
1331 controller_binding_changed = 0; 1362 push_view(view_controller_bindings);
1332 SDL_GameControllerClose(controller); 1363 controller_binding_changed = 0;
1333 } else { 1364 SDL_GameControllerClose(controller);
1334 current_button = SDL_CONTROLLER_BUTTON_A; 1365 } else {
1335 button_pressed = -1; 1366 show_mapping_view();
1336 last_button = -1; 1367 }
1337 last_hat = -1;
1338 axis_moved = -1;
1339 last_axis = -1;
1340 last_axis_value = 0;
1341 SDL_Joystick *joy = render_get_joystick(selected_controller);
1342 const char *name = SDL_JoystickName(joy);
1343 size_t namesz = strlen(name);
1344 mapping_string = malloc(512 + namesz);
1345 for (mapping_pos = 0; mapping_pos < namesz; mapping_pos++)
1346 {
1347 char c = name[mapping_pos];
1348 if (c == ',' || c == '\n' || c == '\r') {
1349 c = ' ';
1350 }
1351 mapping_string[mapping_pos] = c;
1352 }
1353
1354 push_view(view_controller_mappings);
1355 } 1368 }
1356 } 1369 }
1357 } 1370 }
1358 1371
1359 static void controller_type_group(struct nk_context *context, char *name, int type_id, int first_subtype_id, const char **types, uint32_t num_types) 1372 static void controller_type_group(struct nk_context *context, char *name, int type_id, int first_subtype_id, const char **types, uint32_t num_types)
1394 } 1407 }
1395 1408
1396 void view_controllers(struct nk_context *context) 1409 void view_controllers(struct nk_context *context)
1397 { 1410 {
1398 if (nk_begin(context, "Controllers", nk_rect(0, 0, render_width(), render_height()), NK_WINDOW_NO_SCROLLBAR)) { 1411 if (nk_begin(context, "Controllers", nk_rect(0, 0, render_width(), render_height()), NK_WINDOW_NO_SCROLLBAR)) {
1399 int height = (render_width() - 2*context->style.font->height) / MAX_JOYSTICKS; 1412 int height = (render_height() - 2*context->style.font->height) / 5;
1413 int inner_height = height - context->style.window.spacing.y;
1414 const struct nk_user_font *font = context->style.font;
1415 int bindings_width = font->width(font->userdata, font->height, "Bindings", strlen("Bindings")) + context->style.button.padding.x * 2;
1416 int remap_width = font->width(font->userdata, font->height, "Remap", strlen("Remap")) + context->style.button.padding.x * 2;
1417 int change_type_width = font->width(font->userdata, font->height, "Change Type", strlen("Change Type")) + context->style.button.padding.x * 2;
1418 int total = bindings_width + remap_width + change_type_width;
1419 float bindings_ratio = (float)bindings_width / total;
1420 float remap_ratio = (float)remap_width / total;
1421 float change_type_ratio = (float)change_type_width / total;
1422
1423
1424 uint8_t found_controller = 0;
1400 for (int i = 0; i < MAX_JOYSTICKS; i++) 1425 for (int i = 0; i < MAX_JOYSTICKS; i++)
1401 { 1426 {
1402 SDL_Joystick *joy = render_get_joystick(i); 1427 SDL_Joystick *joy = render_get_joystick(i);
1403 if (joy) { 1428 if (joy) {
1429 found_controller = 1;
1404 controller_info info = get_controller_info(i); 1430 controller_info info = get_controller_info(i);
1405 ui_image *controller_image = select_best_image(&info); 1431 ui_image *controller_image = select_best_image(&info);
1406 int image_width = height * controller_image->width / controller_image->height; 1432 int image_width = inner_height * controller_image->width / controller_image->height;
1407 nk_layout_row_begin(context, NK_STATIC, height, 2); 1433 nk_layout_space_begin(context, NK_STATIC, height, INT_MAX);
1408 nk_layout_row_push(context, image_width); 1434 nk_layout_space_push(context, nk_rect(context->style.font->height / 2, 0, image_width, inner_height));
1409 if (info.type == TYPE_UNKNOWN || info.type == TYPE_GENERIC_MAPPING) { 1435 if (info.type == TYPE_UNKNOWN || info.type == TYPE_GENERIC_MAPPING) {
1410 nk_label(context, "?", NK_TEXT_CENTERED); 1436 nk_label(context, "?", NK_TEXT_CENTERED);
1411 } else { 1437 } else {
1412 nk_image(context, controller_image->ui); 1438 nk_image(context, controller_image->ui);
1413 } 1439 }
1414 nk_layout_row_push(context, render_width() - image_width - 2 * context->style.font->height); 1440 int button_start = image_width + context->style.font->height;
1415 if (nk_button_label(context, info.name)) { 1441 int button_area_width = render_width() - image_width - 2 * context->style.font->height;
1416 selected_controller = i; 1442
1417 selected_controller_info = info; 1443 nk_layout_space_push(context, nk_rect(button_start, 0, button_area_width, inner_height/2));
1418 if (info.type == TYPE_UNKNOWN || info.type == TYPE_GENERIC_MAPPING) { 1444 nk_label(context, info.name, NK_TEXT_CENTERED);
1445 const struct nk_user_font *font = context->style.font;
1446 if (info.type == TYPE_UNKNOWN || info.type == TYPE_GENERIC_MAPPING) {
1447 int button_width = font->width(font->userdata, font->height, "Configure", strlen("Configure"));
1448 nk_layout_space_push(context, nk_rect(button_start, height/2, button_width, inner_height/2));
1449 if (nk_button_label(context, "Configure")) {
1450 selected_controller = i;
1451 selected_controller_info = info;
1452 initial_controller_config = 1;
1419 push_view(view_controller_type); 1453 push_view(view_controller_type);
1420 } else { 1454 }
1455 } else {
1456 button_area_width -= 2 * context->style.window.spacing.x;
1457 bindings_width = bindings_ratio * button_area_width;
1458 nk_layout_space_push(context, nk_rect(button_start, height/2, bindings_width, inner_height/2));
1459 if (nk_button_label(context, "Bindings")) {
1460 selected_controller = i;
1461 selected_controller_info = info;
1421 push_view(view_controller_bindings); 1462 push_view(view_controller_bindings);
1422 controller_binding_changed = 0; 1463 controller_binding_changed = 0;
1423 } 1464 }
1424 1465 button_start += bindings_width + context->style.window.spacing.x;
1466 remap_width = remap_ratio * button_area_width;
1467 nk_layout_space_push(context, nk_rect(button_start, height/2, remap_width, inner_height/2));
1468 if (nk_button_label(context, "Remap")) {
1469 selected_controller = i;
1470 selected_controller_info = info;
1471 initial_controller_config = 0;
1472 show_mapping_view();
1473 }
1474 button_start += remap_width + context->style.window.spacing.x;
1475 change_type_width = change_type_ratio * button_area_width;
1476 nk_layout_space_push(context, nk_rect(button_start, height/2, change_type_width, inner_height/2));
1477 if (nk_button_label(context, "Change Type")) {
1478 selected_controller = i;
1479 selected_controller_info = info;
1480 initial_controller_config = 0;
1481 push_view(view_controller_type);
1482 }
1425 } 1483 }
1426 nk_layout_row_end(context); 1484 //nk_layout_row_end(context);
1427 } 1485 }
1486 }
1487 if (!found_controller) {
1488 nk_layout_row_static(context, context->style.font->height, render_width() - 2 * context->style.font->height, 1);
1489 nk_label(context, "No controllers detected", NK_TEXT_CENTERED);
1428 } 1490 }
1429 nk_layout_row_static(context, context->style.font->height, (render_width() - 2 * context->style.font->height) / 2, 2); 1491 nk_layout_row_static(context, context->style.font->height, (render_width() - 2 * context->style.font->height) / 2, 2);
1430 nk_label(context, "", NK_TEXT_LEFT); 1492 nk_label(context, "", NK_TEXT_LEFT);
1431 if (nk_button_label(context, "Back")) { 1493 if (nk_button_label(context, "Back")) {
1432 pop_view(); 1494 pop_view();
1462 buffer[len] = 0; 1524 buffer[len] = 0;
1463 if (strcmp(buffer, curstr)) { 1525 if (strcmp(buffer, curstr)) {
1464 config_dirty = 1; 1526 config_dirty = 1;
1465 config = tern_insert_path(config, path, (tern_val){.ptrval = strdup(buffer)}, TVAL_PTR); 1527 config = tern_insert_path(config, path, (tern_val){.ptrval = strdup(buffer)}, TVAL_PTR);
1466 } 1528 }
1529 }
1530
1531 void settings_string(struct nk_context *context, char *label, char *path, char *def)
1532 {
1533 nk_label(context, label, NK_TEXT_LEFT);
1534 char *curstr = tern_find_path_default(config, path, (tern_val){.ptrval = def}, TVAL_PTR).ptrval;
1535 uint32_t len = strlen(curstr);
1536 uint32_t buffer_len = len > 100 ? len + 1 : 101;
1537 char *buffer = malloc(buffer_len);
1538 memcpy(buffer, curstr, len);
1539 memset(buffer+len, 0, buffer_len-len);
1540 nk_edit_string(context, NK_EDIT_SIMPLE, buffer, &len, buffer_len-1, nk_filter_default);
1541 buffer[len] = 0;
1542 if (strcmp(buffer, curstr)) {
1543 config_dirty = 1;
1544 config = tern_insert_path(config, path, (tern_val){.ptrval = strdup(buffer)}, TVAL_PTR);
1545 }
1546 free(buffer);
1467 } 1547 }
1468 1548
1469 void settings_int_property(struct nk_context *context, char *label, char *name, char *path, int def, int min, int max) 1549 void settings_int_property(struct nk_context *context, char *label, char *name, char *path, int def, int min, int max)
1470 { 1550 {
1471 char *curstr = tern_find_path(config, path, TVAL_PTR).ptrval; 1551 char *curstr = tern_find_path(config, path, TVAL_PTR).ptrval;
1522 } 1602 }
1523 } 1603 }
1524 if (!dupe) { 1604 if (!dupe) {
1525 if (num_progs == prog_storage) { 1605 if (num_progs == prog_storage) {
1526 prog_storage = prog_storage ? prog_storage*2 : 4; 1606 prog_storage = prog_storage ? prog_storage*2 : 4;
1527 progs = realloc(progs, sizeof(progs) * prog_storage); 1607 progs = realloc(progs, sizeof(*progs) * prog_storage);
1528 } 1608 }
1529 progs[num_progs].vertex = NULL; 1609 progs[num_progs].vertex = NULL;
1530 progs[num_progs++].fragment = strdup(entries[i].name); 1610 progs[num_progs++].fragment = strdup(entries[i].name);
1531 } 1611 }
1532 } 1612 }
1574 shader_dir = path_append(DATA_PATH, "shaders"); 1654 shader_dir = path_append(DATA_PATH, "shaders");
1575 #else 1655 #else
1576 shader_dir = path_append(get_exe_dir(), "shaders"); 1656 shader_dir = path_append(get_exe_dir(), "shaders");
1577 #endif 1657 #endif
1578 entries = get_dir_list(shader_dir, &num_entries); 1658 entries = get_dir_list(shader_dir, &num_entries);
1659 free(shader_dir);
1579 progs = get_shader_progs(entries, num_entries, progs, &num_progs, &prog_storage); 1660 progs = get_shader_progs(entries, num_entries, progs, &num_progs, &prog_storage);
1580 *num_out = num_progs; 1661 *num_out = num_progs;
1581 return progs; 1662 return progs;
1582 } 1663 }
1583 1664
1749 pop_view(); 1830 pop_view();
1750 } 1831 }
1751 nk_end(context); 1832 nk_end(context);
1752 } 1833 }
1753 } 1834 }
1835 typedef struct {
1836 const char **models;
1837 const char **names;
1838 uint32_t num_models;
1839 uint32_t storage;
1840 } model_foreach_state;
1841 void model_iter(char *key, tern_val val, uint8_t valtype, void *data)
1842 {
1843 if (valtype != TVAL_NODE) {
1844 return;
1845 }
1846 model_foreach_state *state = data;
1847 if (state->num_models == state->storage) {
1848 state->storage *= 2;
1849 state->models = realloc(state->models, state->storage * sizeof(char *));
1850 state->names = realloc(state->names, state->storage * sizeof(char *));
1851 }
1852 char *def = strdup(key);
1853 state->models[state->num_models] = def;
1854 state->names[state->num_models++] = tern_find_ptr_default(val.ptrval, "name", def);
1855 }
1856
1857 typedef struct {
1858 const char **models;
1859 const char **names;
1860 } models;
1861
1862 models get_models(uint32_t *num_out)
1863 {
1864 tern_node *systems = get_systems_config();
1865 model_foreach_state state = {
1866 .models = calloc(4, sizeof(char *)),
1867 .names = calloc(4, sizeof(char *)),
1868 .num_models = 0,
1869 .storage = 4
1870 };
1871 tern_foreach(systems, model_iter, &state);
1872 *num_out = state.num_models;
1873 return (models){
1874 .models = state.models,
1875 .names = state.names
1876 };
1877 }
1878
1754 void view_system_settings(struct nk_context *context) 1879 void view_system_settings(struct nk_context *context)
1755 { 1880 {
1756 const char *sync_opts[] = { 1881 const char *sync_opts[] = {
1757 "video", 1882 "video",
1758 "audio" 1883 "audio"
1771 const uint32_t num_regions = sizeof(regions)/sizeof(*regions); 1896 const uint32_t num_regions = sizeof(regions)/sizeof(*regions);
1772 static int32_t selected_region = -1; 1897 static int32_t selected_region = -1;
1773 if (selected_region < 0) { 1898 if (selected_region < 0) {
1774 selected_region = find_match(region_codes, num_regions, "system\0default_region\0", "U"); 1899 selected_region = find_match(region_codes, num_regions, "system\0default_region\0", "U");
1775 } 1900 }
1901 static const char **model_opts;
1902 static const char **model_names;
1903 static uint32_t num_models;
1904 if (!model_opts) {
1905 models m = get_models(&num_models);
1906 model_opts = m.models;
1907 model_names = m.names;
1908 }
1909 static int32_t selected_model = -1;
1910 if (selected_model < 0) {
1911 selected_model = find_match(model_opts, num_models, "system\0model\0", "md1va3");
1912 }
1913
1776 const char *formats[] = { 1914 const char *formats[] = {
1777 "native", 1915 "native",
1778 "gst" 1916 "gst"
1779 }; 1917 };
1780 const uint32_t num_formats = sizeof(formats)/sizeof(*formats); 1918 const uint32_t num_formats = sizeof(formats)/sizeof(*formats);
1781 int32_t selected_format = -1; 1919 static int32_t selected_format = -1;
1782 if (selected_format < 0) { 1920 if (selected_format < 0) {
1783 selected_format = find_match(formats, num_formats, "ui\0state_format\0", "native"); 1921 selected_format = find_match(formats, num_formats, "ui\0state_format\0", "native");
1784 } 1922 }
1785 const char *ram_inits[] = { 1923 const char *ram_inits[] = {
1786 "zero", 1924 "zero",
1823 if (nk_begin(context, "System Settings", nk_rect(0, 0, width, height), 0)) { 1961 if (nk_begin(context, "System Settings", nk_rect(0, 0, width, height), 0)) {
1824 nk_layout_row_static(context, context->style.font->height, desired_width, 2); 1962 nk_layout_row_static(context, context->style.font->height, desired_width, 2);
1825 selected_sync = settings_dropdown(context, "Sync Source", sync_opts, num_sync_opts, selected_sync, "system\0sync_source\0"); 1963 selected_sync = settings_dropdown(context, "Sync Source", sync_opts, num_sync_opts, selected_sync, "system\0sync_source\0");
1826 settings_int_property(context, "68000 Clock Divider", "", "clocks\0m68k_divider\0", 7, 1, 53); 1964 settings_int_property(context, "68000 Clock Divider", "", "clocks\0m68k_divider\0", 7, 1, 53);
1827 settings_toggle(context, "Remember ROM Path", "ui\0remember_path\0", 1); 1965 settings_toggle(context, "Remember ROM Path", "ui\0remember_path\0", 1);
1966 settings_toggle(context, "Save config with EXE", "ui\0config_in_exe_dir\0", 0);
1967 settings_string(context, "Game Save Path", "ui\0save_path\0", "$USERDATA/blastem/$ROMNAME");
1828 selected_region = settings_dropdown_ex(context, "Default Region", region_codes, regions, num_regions, selected_region, "system\0default_region\0"); 1968 selected_region = settings_dropdown_ex(context, "Default Region", region_codes, regions, num_regions, selected_region, "system\0default_region\0");
1969 selected_model = settings_dropdown_ex(context, "Model", model_opts, model_names, num_models, selected_model, "system\0model\0");
1829 selected_format = settings_dropdown(context, "Save State Format", formats, num_formats, selected_format, "ui\0state_format\0"); 1970 selected_format = settings_dropdown(context, "Save State Format", formats, num_formats, selected_format, "ui\0state_format\0");
1830 selected_init = settings_dropdown(context, "Initial RAM Value", ram_inits, num_inits, selected_init, "system\0ram_init\0"); 1971 selected_init = settings_dropdown(context, "Initial RAM Value", ram_inits, num_inits, selected_init, "system\0ram_init\0");
1831 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"); 1972 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");
1832 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"); 1973 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");
1833 if (nk_button_label(context, "Back")) { 1974 if (nk_button_label(context, "Back")) {
1917 } 2058 }
1918 } 2059 }
1919 2060
1920 void ui_idle_loop(void) 2061 void ui_idle_loop(void)
1921 { 2062 {
2063 render_enable_gamepad_events(1);
1922 const uint32_t MIN_UI_DELAY = 15; 2064 const uint32_t MIN_UI_DELAY = 15;
1923 static uint32_t last; 2065 static uint32_t last;
1924 while (current_view != view_play) 2066 while (current_view != view_play)
1925 { 2067 {
1926 uint32_t current = render_elapsed_ms(); 2068 uint32_t current = render_elapsed_ms();
1933 if (config_dirty) { 2075 if (config_dirty) {
1934 apply_updated_config(); 2076 apply_updated_config();
1935 persist_config(config); 2077 persist_config(config);
1936 config_dirty = 0; 2078 config_dirty = 0;
1937 } 2079 }
2080 render_enable_gamepad_events(0);
1938 } 2081 }
1939 static void handle_event(SDL_Event *event) 2082 static void handle_event(SDL_Event *event)
1940 { 2083 {
1941 if (event->type == SDL_KEYDOWN) { 2084 if (event->type == SDL_KEYDOWN) {
1942 keycode = event->key.keysym.sym; 2085 keycode = event->key.keysym.sym;
2052 context->style.checkbox.cursor_normal.type = NK_STYLE_ITEM_COLOR; 2195 context->style.checkbox.cursor_normal.type = NK_STYLE_ITEM_COLOR;
2053 context->style.checkbox.cursor_normal.data.color = (struct nk_color){ 2196 context->style.checkbox.cursor_normal.data.color = (struct nk_color){
2054 .r = 255, .g = 128, .b = 0, .a = 255 2197 .r = 255, .g = 128, .b = 0, .a = 255
2055 }; 2198 };
2056 context->style.checkbox.cursor_hover = context->style.checkbox.cursor_normal; 2199 context->style.checkbox.cursor_hover = context->style.checkbox.cursor_normal;
2200 context->style.property.inc_button.text_hover = (struct nk_color){
2201 .r = 255, .g = 128, .b = 0, .a = 255
2202 };
2203 context->style.property.dec_button.text_hover = context->style.property.inc_button.text_hover;
2204 context->style.combo.button.text_hover = context->style.property.inc_button.text_hover;
2057 } 2205 }
2058 2206
2059 static void context_created(void) 2207 static void context_created(void)
2060 { 2208 {
2061 context = nk_sdl_init(render_get_window()); 2209 context = nk_sdl_init(render_get_window());
2069 if (current_view == view_play) { 2217 if (current_view == view_play) {
2070 set_content_binding_state(0); 2218 set_content_binding_state(0);
2071 context->style.window.background = nk_rgba(0, 0, 0, 128); 2219 context->style.window.background = nk_rgba(0, 0, 0, 128);
2072 context->style.window.fixed_background = nk_style_item_color(nk_rgba(0, 0, 0, 128)); 2220 context->style.window.fixed_background = nk_style_item_color(nk_rgba(0, 0, 0, 128));
2073 current_view = view_pause; 2221 current_view = view_pause;
2222 context->input.selected_widget = 0;
2074 current_system->request_exit(current_system); 2223 current_system->request_exit(current_system);
2075 } else if (current_system && !set_binding) { 2224 } else if (current_system && !set_binding) {
2076 clear_view_stack(); 2225 clear_view_stack();
2077 show_play_view(); 2226 show_play_view();
2078 } 2227 }
2080 2229
2081 void show_play_view(void) 2230 void show_play_view(void)
2082 { 2231 {
2083 set_content_binding_state(1); 2232 set_content_binding_state(1);
2084 current_view = view_play; 2233 current_view = view_play;
2234 context->input.selected_widget = 0;
2085 } 2235 }
2086 2236
2087 static uint8_t active; 2237 static uint8_t active;
2088 uint8_t is_nuklear_active(void) 2238 uint8_t is_nuklear_active(void)
2089 { 2239 {