From 2ef80983d5d11aec60c4a4fbe0958a261e42fb6b Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Tue, 21 Nov 2017 19:07:43 -0800 Subject: Initial work on Nuklear-based UI --HG-- branch : nuklear_ui --- nuklear_ui/blastem_nuklear.c | 158 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 nuklear_ui/blastem_nuklear.c (limited to 'nuklear_ui/blastem_nuklear.c') diff --git a/nuklear_ui/blastem_nuklear.c b/nuklear_ui/blastem_nuklear.c new file mode 100644 index 0000000..9085b38 --- /dev/null +++ b/nuklear_ui/blastem_nuklear.c @@ -0,0 +1,158 @@ +#define NK_IMPLEMENTATION +#define NK_SDL_GLES2_IMPLEMENTATION + +#include +#include "blastem_nuklear.h" +#include "font.h" +#include "../render.h" +#include "../render_sdl.h" +#include "../util.h" +#include "../paths.h" +#include "../blastem.h" + +static struct nk_context *context; + +typedef void (*view_fun)(struct nk_context *); +static view_fun current_view; + +void view_play(struct nk_context *context) +{ + +} + +void view_load(struct nk_context *context) +{ + static char *current_path; + static dir_entry *entries; + static size_t num_entries; + static uint32_t selected_entry; + get_initial_browse_path(¤t_path); + if (!entries) { + entries = get_dir_list(current_path, &num_entries); + } + uint32_t width = render_width(); + uint32_t height = render_height(); + if (nk_begin(context, "Load ROM", nk_rect(0, 0, width, height), 0)) { + nk_layout_row_static(context, height - 100, width - 60, 1); + if (nk_group_begin(context, "Select ROM", NK_WINDOW_BORDER | NK_WINDOW_TITLE)) { + nk_layout_row_static(context, 28, width-100, 1); + for (uint32_t i = 0; i < num_entries; i++) + { + int selected = i == selected_entry; + nk_selectable_label(context, entries[i].name, NK_TEXT_ALIGN_LEFT, &selected); + if (selected) { + selected_entry = i; + } + } + nk_group_end(context); + } + nk_layout_row_static(context, 52, 300, 1); + if (nk_button_label(context, "Open")) { + if (entries[selected_entry].is_dir) { + char *old = current_path; + char const *pieces[] = {old, PATH_SEP, entries[selected_entry].name}; + current_path = alloc_concat_m(3, pieces); + free(old); + free_dir_list(entries, num_entries); + entries = NULL; + } else { + //TODO: load ROM + current_view = view_play; + } + } + nk_end(context); + } +} + +void view_about(struct nk_context *context) +{ +} + +typedef struct { + const char *title; + view_fun next_view; +} menu_item; + +static void menu(struct nk_context *context, uint32_t num_entries, const menu_item *items) +{ + const uint32_t button_height = 52; + const uint32_t ideal_button_width = 300; + const uint32_t button_space = 6; + + uint32_t width = render_width(); + uint32_t height = render_height(); + uint32_t top = height/2 - (button_height * num_entries)/2; + uint32_t button_width = width > ideal_button_width ? ideal_button_width : width; + uint32_t left = width/2 - button_width/2; + + nk_layout_space_begin(context, NK_STATIC, top + button_height * num_entries, num_entries); + for (uint32_t i = 0; i < num_entries; i++) + { + nk_layout_space_push(context, nk_rect(left, top + i * button_height, button_width, button_height-button_space)); + if (nk_button_label(context, items[i].title)) { + current_view = items[i].next_view; + if (!current_view) { + exit(0); + } + } + } + nk_layout_space_end(context); +} + +void view_menu(struct nk_context *context) +{ + static menu_item items[] = { + {"Load ROM", view_load}, + {"About", view_about}, + {"Exit", NULL} + }; + + const uint32_t num_buttons = 3; + if (nk_begin(context, "Main Menu", nk_rect(0, 0, render_width(), render_height()), 0)) { + menu(context, sizeof(items)/sizeof(*items), items); + nk_end(context); + } +} + +void blastem_nuklear_render(void) +{ + nk_input_end(context); + current_view(context); + glViewport(0, 0, render_width(), render_height()); +/* glClear(GL_COLOR_BUFFER_BIT); + glClearColor(0, 0, 0, 0);*/ + nk_sdl_render(NK_ANTI_ALIASING_ON, 512 * 1024, 128 * 1024); + //SDL_GL_SwapWindow(render_get_window()); + nk_input_begin(context); +} + +void idle_loop(void) +{ + while (current_view != view_play) + { + render_update_display(); + } +} +static void handle_event(SDL_Event *event) +{ + nk_sdl_handle_event(event); +} + +void blastem_nuklear_init(uint8_t file_loaded) +{ + context = nk_sdl_init(render_get_window()); + + struct nk_font_atlas *atlas; + nk_sdl_font_stash_begin(&atlas); + char *font = default_font_path(); + if (!font) { + fatal_error("Failed to find default font path\n"); + } + struct nk_font *def_font = nk_font_atlas_add_from_file(atlas, font, 30, NULL); + nk_sdl_font_stash_end(); + nk_style_set_font(context, &def_font->handle); + current_view = file_loaded ? view_play : view_menu; + render_set_ui_render_fun(blastem_nuklear_render); + render_set_event_handler(handle_event); + idle_loop(); +} -- cgit v1.2.3 From 4f5d059cb030c530fa5042256a64223526be405b Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Tue, 21 Nov 2017 23:11:11 -0800 Subject: Basic support for loading ROMs via Nuklear UI --HG-- branch : nuklear_ui --- nuklear_ui/blastem_nuklear.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'nuklear_ui/blastem_nuklear.c') diff --git a/nuklear_ui/blastem_nuklear.c b/nuklear_ui/blastem_nuklear.c index 9085b38..80d6474 100644 --- a/nuklear_ui/blastem_nuklear.c +++ b/nuklear_ui/blastem_nuklear.c @@ -48,15 +48,16 @@ void view_load(struct nk_context *context) } nk_layout_row_static(context, 52, 300, 1); if (nk_button_label(context, "Open")) { + char const *pieces[] = {current_path, PATH_SEP, entries[selected_entry].name}; if (entries[selected_entry].is_dir) { char *old = current_path; - char const *pieces[] = {old, PATH_SEP, entries[selected_entry].name}; current_path = alloc_concat_m(3, pieces); free(old); free_dir_list(entries, num_entries); entries = NULL; } else { - //TODO: load ROM + current_system->next_rom = alloc_concat_m(3, pieces); + current_system->request_exit(current_system); current_view = view_play; } } -- cgit v1.2.3 From 6895070c631340809829e0c20c085b231b0fcadd Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Wed, 22 Nov 2017 10:54:27 -0800 Subject: Fix UI rendering in fullscreen and wome initial work on the "pause" menu --HG-- branch : nuklear_ui --- nuklear_ui/blastem_nuklear.c | 62 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 5 deletions(-) (limited to 'nuklear_ui/blastem_nuklear.c') diff --git a/nuklear_ui/blastem_nuklear.c b/nuklear_ui/blastem_nuklear.c index 80d6474..e63d9cf 100644 --- a/nuklear_ui/blastem_nuklear.c +++ b/nuklear_ui/blastem_nuklear.c @@ -14,6 +14,7 @@ static struct nk_context *context; typedef void (*view_fun)(struct nk_context *); static view_fun current_view; +static view_fun previous_view; void view_play(struct nk_context *context) { @@ -46,7 +47,10 @@ void view_load(struct nk_context *context) } nk_group_end(context); } - nk_layout_row_static(context, 52, 300, 1); + nk_layout_row_static(context, 52, width > 600 ? 300 : width / 2, 2); + if (nk_button_label(context, "Back")) { + current_view = previous_view; + } if (nk_button_label(context, "Open")) { char const *pieces[] = {current_path, PATH_SEP, entries[selected_entry].name}; if (entries[selected_entry].is_dir) { @@ -91,6 +95,7 @@ static void menu(struct nk_context *context, uint32_t num_entries, const menu_it { nk_layout_space_push(context, nk_rect(left, top + i * button_height, button_width, button_height-button_space)); if (nk_button_label(context, items[i].title)) { + previous_view = current_view; current_view = items[i].next_view; if (!current_view) { exit(0); @@ -100,6 +105,38 @@ static void menu(struct nk_context *context, uint32_t num_entries, const menu_it nk_layout_space_end(context); } +void view_choose_state(struct nk_context *context, uint8_t is_load) +{ + +} + +void view_save_state(struct nk_context *context) +{ + view_choose_state(context, 0); +} + +void view_load_state(struct nk_context *context) +{ + view_choose_state(context, 1); +} + +void view_pause(struct nk_context *context) +{ + static menu_item items[] = { + {"Resume", view_play}, + {"Load ROM", view_load}, + {"Save State", view_save_state}, + {"Load State", view_load_state}, + {"Exit", NULL} + }; + + const uint32_t num_buttons = 3; + if (nk_begin(context, "Main Menu", nk_rect(0, 0, render_width(), render_height()), 0)) { + menu(context, sizeof(items)/sizeof(*items), items); + nk_end(context); + } +} + void view_menu(struct nk_context *context) { static menu_item items[] = { @@ -119,11 +156,7 @@ void blastem_nuklear_render(void) { nk_input_end(context); current_view(context); - glViewport(0, 0, render_width(), render_height()); -/* glClear(GL_COLOR_BUFFER_BIT); - glClearColor(0, 0, 0, 0);*/ nk_sdl_render(NK_ANTI_ALIASING_ON, 512 * 1024, 128 * 1024); - //SDL_GL_SwapWindow(render_get_window()); nk_input_begin(context); } @@ -139,6 +172,24 @@ static void handle_event(SDL_Event *event) nk_sdl_handle_event(event); } +static void context_destroyed(void) +{ + nk_sdl_device_destroy(); +} +static void context_created(void) +{ + nk_sdl_device_create(); + struct nk_font_atlas *atlas; + nk_sdl_font_stash_begin(&atlas); + char *font = default_font_path(); + if (!font) { + fatal_error("Failed to find default font path\n"); + } + struct nk_font *def_font = nk_font_atlas_add_from_file(atlas, font, 30, NULL); + nk_sdl_font_stash_end(); + nk_style_set_font(context, &def_font->handle); +} + void blastem_nuklear_init(uint8_t file_loaded) { context = nk_sdl_init(render_get_window()); @@ -155,5 +206,6 @@ void blastem_nuklear_init(uint8_t file_loaded) current_view = file_loaded ? view_play : view_menu; render_set_ui_render_fun(blastem_nuklear_render); render_set_event_handler(handle_event); + render_set_gl_context_handlers(context_destroyed, context_created); idle_loop(); } -- cgit v1.2.3 From b21ebe75d412c72441be8a63c202641cc5ff4dfa Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Wed, 22 Nov 2017 11:18:36 -0800 Subject: Pause menu now triggered on ui.exit event --HG-- branch : nuklear_ui --- nuklear_ui/blastem_nuklear.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'nuklear_ui/blastem_nuklear.c') diff --git a/nuklear_ui/blastem_nuklear.c b/nuklear_ui/blastem_nuklear.c index e63d9cf..2042402 100644 --- a/nuklear_ui/blastem_nuklear.c +++ b/nuklear_ui/blastem_nuklear.c @@ -190,6 +190,19 @@ static void context_created(void) nk_style_set_font(context, &def_font->handle); } +void show_pause_menu(void) +{ + context->style.window.background = nk_rgba(0, 0, 0, 128); + context->style.window.fixed_background = nk_style_item_color(nk_rgba(0, 0, 0, 128)); + current_view = view_pause; +} + +static uint8_t active; +uint8_t is_nuklear_active(void) +{ + return active; +} + void blastem_nuklear_init(uint8_t file_loaded) { context = nk_sdl_init(render_get_window()); @@ -207,5 +220,6 @@ void blastem_nuklear_init(uint8_t file_loaded) render_set_ui_render_fun(blastem_nuklear_render); render_set_event_handler(handle_event); render_set_gl_context_handlers(context_destroyed, context_created); + active = 1; idle_loop(); } -- cgit v1.2.3 From 27b829ffc447758832cbd7ab2f9b7e427928d687 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Fri, 24 Nov 2017 12:04:02 -0800 Subject: Refactored save slot related logic to reduce duplication and allow reuse in new UI. Get state loading/saving mostly working in new UI --HG-- branch : nuklear_ui --- nuklear_ui/blastem_nuklear.c | 73 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 58 insertions(+), 15 deletions(-) (limited to 'nuklear_ui/blastem_nuklear.c') diff --git a/nuklear_ui/blastem_nuklear.c b/nuklear_ui/blastem_nuklear.c index 2042402..a486a64 100644 --- a/nuklear_ui/blastem_nuklear.c +++ b/nuklear_ui/blastem_nuklear.c @@ -8,6 +8,7 @@ #include "../render_sdl.h" #include "../util.h" #include "../paths.h" +#include "../saves.h" #include "../blastem.h" static struct nk_context *context; @@ -78,6 +79,59 @@ typedef struct { view_fun next_view; } menu_item; +static save_slot_info *slots; +static uint32_t num_slots, selected_slot; + +void view_choose_state(struct nk_context *context, uint8_t is_load) +{ + uint32_t width = render_width(); + uint32_t height = render_height(); + if (nk_begin(context, "Slot Picker", nk_rect(0, 0, width, height), 0)) { + nk_layout_row_static(context, height - 100, width - 60, 1); + if (nk_group_begin(context, "Select Save Slot", NK_WINDOW_BORDER | NK_WINDOW_TITLE)) { + nk_layout_row_static(context, 28, width-100, 1); + if (!slots) { + slots = get_slot_info(current_system, &num_slots); + } + for (uint32_t i = 0; i < num_slots; i++) + { + int selected = i == selected_slot; + nk_selectable_label(context, slots[i].desc, NK_TEXT_ALIGN_LEFT, &selected); + if (selected && (slots[i].modification_time || !is_load)) { + selected_slot = i; + } + } + nk_group_end(context); + } + nk_layout_row_static(context, 52, width > 600 ? 300 : width / 2, 2); + if (nk_button_label(context, "Back")) { + current_view = previous_view; + } + if (is_load) { + if (nk_button_label(context, "Load")) { + current_system->load_state(current_system, selected_slot); + current_view = view_play; + } + } else { + if (nk_button_label(context, "Save")) { + current_system->save_state = selected_slot + 1; + current_view = view_play; + } + } + nk_end(context); + } +} + +void view_save_state(struct nk_context *context) +{ + view_choose_state(context, 0); +} + +void view_load_state(struct nk_context *context) +{ + view_choose_state(context, 1); +} + static void menu(struct nk_context *context, uint32_t num_entries, const menu_item *items) { const uint32_t button_height = 52; @@ -100,26 +154,15 @@ static void menu(struct nk_context *context, uint32_t num_entries, const menu_it if (!current_view) { exit(0); } + if (current_view == view_save_state || current_view == view_load_state) { + free_slot_info(slots); + slots = NULL; + } } } nk_layout_space_end(context); } -void view_choose_state(struct nk_context *context, uint8_t is_load) -{ - -} - -void view_save_state(struct nk_context *context) -{ - view_choose_state(context, 0); -} - -void view_load_state(struct nk_context *context) -{ - view_choose_state(context, 1); -} - void view_pause(struct nk_context *context) { static menu_item items[] = { -- cgit v1.2.3 From 2900092e4e06be77108ed6b8a66c7aa673d0b494 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Sat, 25 Nov 2017 13:57:38 -0800 Subject: Fix directory navigation in ROM file chooser in Nuklear UI --HG-- branch : nuklear_ui --- nuklear_ui/blastem_nuklear.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'nuklear_ui/blastem_nuklear.c') diff --git a/nuklear_ui/blastem_nuklear.c b/nuklear_ui/blastem_nuklear.c index a486a64..bcff610 100644 --- a/nuklear_ui/blastem_nuklear.c +++ b/nuklear_ui/blastem_nuklear.c @@ -28,7 +28,9 @@ void view_load(struct nk_context *context) static dir_entry *entries; static size_t num_entries; static uint32_t selected_entry; - get_initial_browse_path(¤t_path); + if (!current_path) { + get_initial_browse_path(¤t_path); + } if (!entries) { entries = get_dir_list(current_path, &num_entries); } @@ -53,15 +55,14 @@ void view_load(struct nk_context *context) current_view = previous_view; } if (nk_button_label(context, "Open")) { - char const *pieces[] = {current_path, PATH_SEP, entries[selected_entry].name}; + char *full_path = path_append(current_path, entries[selected_entry].name); if (entries[selected_entry].is_dir) { - char *old = current_path; - current_path = alloc_concat_m(3, pieces); - free(old); + free(current_path); + current_path = full_path; free_dir_list(entries, num_entries); entries = NULL; } else { - current_system->next_rom = alloc_concat_m(3, pieces); + current_system->next_rom = full_path; current_system->request_exit(current_system); current_view = view_play; } -- cgit v1.2.3 From c6edea8bbaceda316375019344f4e7ffbf6da57e Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Sat, 25 Nov 2017 14:42:38 -0800 Subject: Avoid burning a huge amount of CPU in the menu when emulation is not running and vsync is disabled --HG-- branch : nuklear_ui --- nuklear_ui/blastem_nuklear.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'nuklear_ui/blastem_nuklear.c') diff --git a/nuklear_ui/blastem_nuklear.c b/nuklear_ui/blastem_nuklear.c index bcff610..4785de6 100644 --- a/nuklear_ui/blastem_nuklear.c +++ b/nuklear_ui/blastem_nuklear.c @@ -206,8 +206,15 @@ void blastem_nuklear_render(void) void idle_loop(void) { + const uint32_t MIN_UI_DELAY = 15; + static uint32_t last; while (current_view != view_play) { + uint32_t current = render_elapsed_ms(); + if ((current - last) < MIN_UI_DELAY) { + render_sleep_ms(MIN_UI_DELAY - (current - last) - 1); + } + last = current; render_update_display(); } } -- cgit v1.2.3 From f4767bb05392fa4a04d72969fa35aa91b688c8cb Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Sat, 25 Nov 2017 20:43:20 -0800 Subject: Skip loading menu ROM if Nuklear UI is enabled. Allow disabling Nuklear UI in favor of old menu ROM both at compile time and in config. Fall back to ROM UI if GL is unavailable --HG-- branch : nuklear_ui --- nuklear_ui/blastem_nuklear.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'nuklear_ui/blastem_nuklear.c') diff --git a/nuklear_ui/blastem_nuklear.c b/nuklear_ui/blastem_nuklear.c index 4785de6..96f8a5d 100644 --- a/nuklear_ui/blastem_nuklear.c +++ b/nuklear_ui/blastem_nuklear.c @@ -62,8 +62,13 @@ void view_load(struct nk_context *context) free_dir_list(entries, num_entries); entries = NULL; } else { - current_system->next_rom = full_path; - current_system->request_exit(current_system); + if (current_system) { + current_system->next_rom = full_path; + current_system->request_exit(current_system); + } else { + init_system_with_media(full_path, SYSTEM_UNKNOWN); + free(full_path); + } current_view = view_play; } } @@ -254,6 +259,19 @@ uint8_t is_nuklear_active(void) return active; } +uint8_t is_nuklear_available(void) +{ + if (!render_has_gl()) { + //currently no fallback if GL2 unavailable + return 0; + } + char *style = tern_find_path(config, "ui\0style\0", TVAL_PTR).ptrval; + if (!style) { + return 1; + } + return strcmp(style, "rom") != 0; +} + void blastem_nuklear_init(uint8_t file_loaded) { context = nk_sdl_init(render_get_window()); -- cgit v1.2.3 From 3c9268353c943b32ca517945c42dfb8c0b8484f8 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Sun, 26 Nov 2017 17:33:39 -0800 Subject: Sort directory listing in Nuklear UI file browser --HG-- branch : nuklear_ui --- nuklear_ui/blastem_nuklear.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'nuklear_ui/blastem_nuklear.c') diff --git a/nuklear_ui/blastem_nuklear.c b/nuklear_ui/blastem_nuklear.c index 96f8a5d..44861d9 100644 --- a/nuklear_ui/blastem_nuklear.c +++ b/nuklear_ui/blastem_nuklear.c @@ -33,6 +33,9 @@ void view_load(struct nk_context *context) } if (!entries) { entries = get_dir_list(current_path, &num_entries); + if (entries) { + sort_dir_list(entries, num_entries); + } } uint32_t width = render_width(); uint32_t height = render_height(); -- cgit v1.2.3 From c9b253c58788376865cc8768ba342a67b4758bcf Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Sun, 26 Nov 2017 18:33:36 -0800 Subject: Filter file list in Nuklear UI --HG-- branch : nuklear_ui --- nuklear_ui/blastem_nuklear.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'nuklear_ui/blastem_nuklear.c') diff --git a/nuklear_ui/blastem_nuklear.c b/nuklear_ui/blastem_nuklear.c index 44861d9..850f70e 100644 --- a/nuklear_ui/blastem_nuklear.c +++ b/nuklear_ui/blastem_nuklear.c @@ -10,6 +10,7 @@ #include "../paths.h" #include "../saves.h" #include "../blastem.h" +#include "../config.h" static struct nk_context *context; @@ -28,6 +29,9 @@ void view_load(struct nk_context *context) static dir_entry *entries; static size_t num_entries; static uint32_t selected_entry; + static char **ext_list; + static uint32_t num_exts; + static uint8_t got_ext_list; if (!current_path) { get_initial_browse_path(¤t_path); } @@ -37,6 +41,10 @@ void view_load(struct nk_context *context) sort_dir_list(entries, num_entries); } } + if (!got_ext_list) { + ext_list = get_extension_list(config, &num_exts); + got_ext_list = 1; + } uint32_t width = render_width(); uint32_t height = render_height(); if (nk_begin(context, "Load ROM", nk_rect(0, 0, width, height), 0)) { @@ -45,6 +53,12 @@ void view_load(struct nk_context *context) nk_layout_row_static(context, 28, width-100, 1); for (uint32_t i = 0; i < num_entries; i++) { + if (entries[i].name[0] == '.' && entries[i].name[1] != '.') { + continue; + } + if (num_exts && !entries[i].is_dir && !path_matches_extensions(entries[i].name, ext_list, num_exts)) { + continue; + } int selected = i == selected_entry; nk_selectable_label(context, entries[i].name, NK_TEXT_ALIGN_LEFT, &selected); if (selected) { -- cgit v1.2.3 From 3b2e343a1088abc7fe1cf1dffcf6a20aa97b0918 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Sun, 26 Nov 2017 19:22:09 -0800 Subject: Pause game execution when in the new UI pause menu --HG-- branch : nuklear_ui --- nuklear_ui/blastem_nuklear.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'nuklear_ui/blastem_nuklear.c') diff --git a/nuklear_ui/blastem_nuklear.c b/nuklear_ui/blastem_nuklear.c index 850f70e..8ff1821 100644 --- a/nuklear_ui/blastem_nuklear.c +++ b/nuklear_ui/blastem_nuklear.c @@ -226,7 +226,7 @@ void blastem_nuklear_render(void) nk_input_begin(context); } -void idle_loop(void) +void ui_idle_loop(void) { const uint32_t MIN_UI_DELAY = 15; static uint32_t last; @@ -268,6 +268,7 @@ void show_pause_menu(void) context->style.window.background = nk_rgba(0, 0, 0, 128); context->style.window.fixed_background = nk_style_item_color(nk_rgba(0, 0, 0, 128)); current_view = view_pause; + current_system->request_exit(current_system); } static uint8_t active; @@ -307,5 +308,5 @@ void blastem_nuklear_init(uint8_t file_loaded) render_set_event_handler(handle_event); render_set_gl_context_handlers(context_destroyed, context_created); active = 1; - idle_loop(); + ui_idle_loop(); } -- cgit v1.2.3 From 4a9e985267f3c88b480f9f3b3d07e4a0c70716ae Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Sun, 26 Nov 2017 20:17:22 -0800 Subject: Enable lock-on in Nuklear UI --HG-- branch : nuklear_ui --- nuklear_ui/blastem_nuklear.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'nuklear_ui/blastem_nuklear.c') diff --git a/nuklear_ui/blastem_nuklear.c b/nuklear_ui/blastem_nuklear.c index 8ff1821..694ba7b 100644 --- a/nuklear_ui/blastem_nuklear.c +++ b/nuklear_ui/blastem_nuklear.c @@ -23,7 +23,7 @@ void view_play(struct nk_context *context) } -void view_load(struct nk_context *context) +void view_file_browser(struct nk_context *context, uint8_t normal_open) { static char *current_path; static dir_entry *entries; @@ -79,11 +79,16 @@ void view_load(struct nk_context *context) free_dir_list(entries, num_entries); entries = NULL; } else { - if (current_system) { - current_system->next_rom = full_path; - current_system->request_exit(current_system); + if(normal_open) { + if (current_system) { + current_system->next_rom = full_path; + current_system->request_exit(current_system); + } else { + init_system_with_media(full_path, SYSTEM_UNKNOWN); + free(full_path); + } } else { - init_system_with_media(full_path, SYSTEM_UNKNOWN); + lockon_media(full_path); free(full_path); } current_view = view_play; @@ -93,6 +98,16 @@ void view_load(struct nk_context *context) } } +void view_load(struct nk_context *context) +{ + view_file_browser(context, 1); +} + +void view_lock_on(struct nk_context *context) +{ + view_file_browser(context, 0); +} + void view_about(struct nk_context *context) { } @@ -191,6 +206,7 @@ void view_pause(struct nk_context *context) static menu_item items[] = { {"Resume", view_play}, {"Load ROM", view_load}, + {"Lock On", view_lock_on}, {"Save State", view_save_state}, {"Load State", view_load_state}, {"Exit", NULL} -- cgit v1.2.3 From dbe1d84613796c610b65236d6bbe673fe952c2c8 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Wed, 29 Nov 2017 08:53:47 -0800 Subject: Initial work on settings menu --HG-- branch : nuklear_ui --- nuklear_ui/blastem_nuklear.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'nuklear_ui/blastem_nuklear.c') diff --git a/nuklear_ui/blastem_nuklear.c b/nuklear_ui/blastem_nuklear.c index 694ba7b..e301fbd 100644 --- a/nuklear_ui/blastem_nuklear.c +++ b/nuklear_ui/blastem_nuklear.c @@ -201,6 +201,46 @@ static void menu(struct nk_context *context, uint32_t num_entries, const menu_it nk_layout_space_end(context); } +void view_key_bindings(struct nk_context *context) +{ + +} +void view_controllers(struct nk_context *context) +{ + +} +void view_video_settings(struct nk_context *context) +{ + +} +void view_audio_settings(struct nk_context *context) +{ + +} +void view_system_settings(struct nk_context *context) +{ + +} + +void view_settings(struct nk_context *context) +{ + static menu_item items[] = { + {"Key Bindings", view_key_bindings}, + {"Controllers", view_controllers}, + {"Video", view_video_settings}, + {"Audio", view_audio_settings}, + {"System", view_system_settings}, + {"Back", NULL} + }; + + const uint32_t num_buttons = 6; + items[num_buttons-1].next_view = previous_view; + if (nk_begin(context, "Settings Menu", nk_rect(0, 0, render_width(), render_height()), 0)) { + menu(context, sizeof(items)/sizeof(*items), items); + nk_end(context); + } +} + void view_pause(struct nk_context *context) { static menu_item items[] = { @@ -209,6 +249,7 @@ void view_pause(struct nk_context *context) {"Lock On", view_lock_on}, {"Save State", view_save_state}, {"Load State", view_load_state}, + {"Settings", view_settings}, {"Exit", NULL} }; @@ -223,6 +264,7 @@ void view_menu(struct nk_context *context) { static menu_item items[] = { {"Load ROM", view_load}, + {"Settings", view_settings}, {"About", view_about}, {"Exit", NULL} }; -- cgit v1.2.3 From 670252dd0d070daa2b63c6846f4705157a620b94 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Fri, 1 Dec 2017 09:22:43 -0800 Subject: Somewhat fleshed out video settings view --HG-- branch : nuklear_ui --- nuklear_ui/blastem_nuklear.c | 109 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 101 insertions(+), 8 deletions(-) (limited to 'nuklear_ui/blastem_nuklear.c') diff --git a/nuklear_ui/blastem_nuklear.c b/nuklear_ui/blastem_nuklear.c index e301fbd..95a3161 100644 --- a/nuklear_ui/blastem_nuklear.c +++ b/nuklear_ui/blastem_nuklear.c @@ -16,7 +16,31 @@ static struct nk_context *context; typedef void (*view_fun)(struct nk_context *); static view_fun current_view; -static view_fun previous_view; +static view_fun *previous_views; +static uint32_t view_storage; +static uint32_t num_prev; + +static void push_view(view_fun new_view) +{ + if (num_prev == view_storage) { + view_storage = view_storage ? 2*view_storage : 2; + previous_views = realloc(previous_views, view_storage*sizeof(view_fun)); + } + previous_views[num_prev++] = current_view; + current_view = new_view; +} + +static void pop_view() +{ + if (num_prev) { + current_view = previous_views[--num_prev]; + } +} + +static void clear_view_stack() +{ + num_prev = 0; +} void view_play(struct nk_context *context) { @@ -69,7 +93,7 @@ void view_file_browser(struct nk_context *context, uint8_t normal_open) } nk_layout_row_static(context, 52, width > 600 ? 300 : width / 2, 2); if (nk_button_label(context, "Back")) { - current_view = previous_view; + pop_view(); } if (nk_button_label(context, "Open")) { char *full_path = path_append(current_path, entries[selected_entry].name); @@ -91,6 +115,7 @@ void view_file_browser(struct nk_context *context, uint8_t normal_open) lockon_media(full_path); free(full_path); } + clear_view_stack(); current_view = view_play; } } @@ -143,7 +168,7 @@ void view_choose_state(struct nk_context *context, uint8_t is_load) } nk_layout_row_static(context, 52, width > 600 ? 300 : width / 2, 2); if (nk_button_label(context, "Back")) { - current_view = previous_view; + pop_view(); } if (is_load) { if (nk_button_label(context, "Load")) { @@ -187,8 +212,7 @@ static void menu(struct nk_context *context, uint32_t num_entries, const menu_it { nk_layout_space_push(context, nk_rect(left, top + i * button_height, button_width, button_height-button_space)); if (nk_button_label(context, items[i].title)) { - previous_view = current_view; - current_view = items[i].next_view; + push_view(items[i].next_view); if (!current_view) { exit(0); } @@ -209,9 +233,72 @@ void view_controllers(struct nk_context *context) { } + +void settings_toggle(struct nk_context *context, char *label, char *path, uint8_t def) +{ + uint8_t curval = !strcmp("on", tern_find_path_default(config, path, (tern_val){.ptrval = def ? "on": "off"}, TVAL_PTR).ptrval); + nk_label(context, label, NK_TEXT_LEFT); + uint8_t newval = nk_check_label(context, "", curval); + if (newval != curval) { + config = tern_insert_path(config, path, (tern_val){.ptrval = strdup(newval ? "on" : "off")}, TVAL_PTR); + } +} + +void settings_int_input(struct nk_context *context, char *label, char *path, char *def) +{ + char buffer[12]; + nk_label(context, label, NK_TEXT_LEFT); + uint32_t curval; + char *curstr = tern_find_path_default(config, path, (tern_val){.ptrval = def}, TVAL_PTR).ptrval; + uint32_t len = strlen(curstr); + if (len > 11) { + len = 11; + } + memcpy(buffer, curstr, len); + nk_edit_string(context, NK_EDIT_SIMPLE, buffer, &len, sizeof(buffer)-1, nk_filter_decimal); + buffer[len] = 0; + if (strcmp(buffer, curstr)) { + config = tern_insert_path(config, path, (tern_val){.ptrval = strdup(buffer)}, TVAL_PTR); + } +} + +void settings_int_property(struct nk_context *context, char *label, char *name, char *path, int def, int min, int max) +{ + char *curstr = tern_find_path(config, path, TVAL_PTR).ptrval; + int curval = curstr ? atoi(curstr) : def; + nk_label(context, label, NK_TEXT_LEFT); + int val = curval; + nk_property_int(context, name, min, &val, max, 1, 1.0f); + if (val != curval) { + char buffer[12]; + sprintf(buffer, "%d", val); + config = tern_insert_path(config, path, (tern_val){.ptrval = strdup(buffer)}, TVAL_PTR); + } +} + void view_video_settings(struct nk_context *context) { - + uint32_t width = render_width(); + uint32_t height = render_height(); + if (nk_begin(context, "Video Settings", nk_rect(0, 0, width, height), 0)) { + nk_layout_row_static(context, 30, width > 300 ? 300 : width, 2); + settings_toggle(context, "Fullscreen", "video\0fullscreen\0", 0); + settings_toggle(context, "Open GL", "video\0gl\0", 1); + settings_toggle(context, "Scanlines", "video\0scanlines\0", 0); + settings_int_input(context, "Windowed Width", "video\0width\0", "640"); + settings_int_property(context, "NTSC Overscan", "Top", "video\0ntsc\0overscan\0top\0", 2, 0, 32); + settings_int_property(context, "", "Bottom", "video\0ntsc\0overscan\0bottom\0", 17, 0, 32); + settings_int_property(context, "", "Left", "video\0ntsc\0overscan\0left\0", 13, 0, 32); + settings_int_property(context, "", "Right", "video\0ntsc\0overscan\0right\0", 14, 0, 32); + settings_int_property(context, "PAL Overscan", "Top", "video\0pal\0overscan\0top\0", 2, 0, 32); + settings_int_property(context, "", "Bottom", "video\0pal\0overscan\0bottom\0", 17, 0, 32); + settings_int_property(context, "", "Left", "video\0pal\0overscan\0left\0", 13, 0, 32); + settings_int_property(context, "", "Right", "video\0pal\0overscan\0right\0", 14, 0, 32); + if (nk_button_label(context, "Back")) { + pop_view(); + } + nk_end(context); + } } void view_audio_settings(struct nk_context *context) { @@ -222,6 +309,13 @@ void view_system_settings(struct nk_context *context) } +void view_back(struct nk_context *context) +{ + pop_view(); + pop_view(); + current_view(context); +} + void view_settings(struct nk_context *context) { static menu_item items[] = { @@ -230,11 +324,10 @@ void view_settings(struct nk_context *context) {"Video", view_video_settings}, {"Audio", view_audio_settings}, {"System", view_system_settings}, - {"Back", NULL} + {"Back", view_back} }; const uint32_t num_buttons = 6; - items[num_buttons-1].next_view = previous_view; if (nk_begin(context, "Settings Menu", nk_rect(0, 0, render_width(), render_height()), 0)) { menu(context, sizeof(items)/sizeof(*items), items); nk_end(context); -- cgit v1.2.3 From 3f85894b41ecdaf90394327e8013978cdcc18159 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Fri, 1 Dec 2017 23:16:07 -0800 Subject: Add shader selector to video settings --HG-- branch : nuklear_ui --- nuklear_ui/blastem_nuklear.c | 114 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) (limited to 'nuklear_ui/blastem_nuklear.c') diff --git a/nuklear_ui/blastem_nuklear.c b/nuklear_ui/blastem_nuklear.c index 95a3161..47a6e33 100644 --- a/nuklear_ui/blastem_nuklear.c +++ b/nuklear_ui/blastem_nuklear.c @@ -276,8 +276,114 @@ void settings_int_property(struct nk_context *context, char *label, char *name, } } +typedef struct { + char *fragment; + char *vertex; +} shader_prog; + +shader_prog *get_shader_progs(dir_entry *entries, size_t num_entries, shader_prog *progs, uint32_t *num_existing, uint32_t *storage) +{ + uint32_t num_progs = *num_existing; + uint32_t prog_storage = *storage; + uint32_t starting = num_progs; + + for (uint32_t i = 0; i < num_entries; i++) { + if (entries[i].is_dir) { + continue; + } + char *no_ext = basename_no_extension(entries[i].name); + uint32_t len = strlen(no_ext); + if (no_ext[len-1] == 'f' && no_ext[len-2] == '.') { + uint8_t dupe = 0;; + for (uint32_t j = 0; j < starting; j++) { + if (!strcmp(entries[i].name, progs[j].fragment)) { + dupe = 1; + break; + } + } + if (!dupe) { + if (num_progs == prog_storage) { + prog_storage *= 2; + progs = realloc(progs, sizeof(progs) * prog_storage); + } + progs[num_progs].vertex = NULL; + progs[num_progs++].fragment = strdup(entries[i].name); + } + } + free(no_ext); + } + + for (uint32_t i = 0; i < num_entries; i++) { + if (entries[i].is_dir) { + continue; + } + char *no_ext = basename_no_extension(entries[i].name); + uint32_t len = strlen(no_ext); + if (no_ext[len-1] == 'v' && no_ext[len-2] == '.') { + for (uint32_t j = 0; j < num_progs; j++) { + if (!strncmp(no_ext, progs[j].fragment, len-1) && progs[j].fragment[len-1] == 'f' && progs[j].fragment[len] == '.') { + progs[j].vertex = strdup(entries[i].name); + } + } + } + free(no_ext); + } + free_dir_list(entries, num_entries); + *num_existing = num_progs; + *storage = prog_storage; + return progs; +} + +shader_prog *get_shader_list(uint32_t *num_out) +{ + char *shader_dir = path_append(get_config_dir(), "shaders"); + size_t num_entries; + dir_entry *entries = get_dir_list(shader_dir, &num_entries); + free(shader_dir); + shader_prog *progs; + uint32_t num_progs = 0, prog_storage; + if (num_entries) { + progs = calloc(num_entries, sizeof(shader_prog)); + prog_storage = num_entries; + progs = get_shader_progs(entries, num_entries, progs, &num_progs, &prog_storage); + } else { + progs = NULL; + prog_storage = 0; + } + shader_dir = path_append(get_exe_dir(), "shaders"); + entries = get_dir_list(shader_dir, &num_entries); + progs = get_shader_progs(entries, num_entries, progs, &num_progs, &prog_storage); + *num_out = num_progs; + return progs; +} + void view_video_settings(struct nk_context *context) { + static shader_prog *progs; + static char **prog_names; + static uint32_t num_progs; + static uint32_t selected_prog; + if(!progs) { + progs = get_shader_list(&num_progs); + prog_names = calloc(num_progs, sizeof(char*)); + for (uint32_t i = 0; i < num_progs; i++) + { + prog_names[i] = basename_no_extension(progs[i].fragment);; + uint32_t len = strlen(prog_names[i]); + if (len > 2) { + prog_names[i][len-2] = 0; + } + if (!progs[i].vertex) { + progs[i].vertex = strdup("default.v.glsl"); + } + if (!strcmp( + progs[i].fragment, + tern_find_path_default(config, "video\0fragment_shader\0", (tern_val){.ptrval = "default.f.glsl"}, TVAL_PTR).ptrval + )) { + selected_prog = i; + } + } + } uint32_t width = render_width(); uint32_t height = render_height(); if (nk_begin(context, "Video Settings", nk_rect(0, 0, width, height), 0)) { @@ -286,6 +392,13 @@ void view_video_settings(struct nk_context *context) settings_toggle(context, "Open GL", "video\0gl\0", 1); settings_toggle(context, "Scanlines", "video\0scanlines\0", 0); settings_int_input(context, "Windowed Width", "video\0width\0", "640"); + nk_label(context, "Shader", NK_TEXT_LEFT); + uint32_t next_selected = nk_combo(context, (const char **)prog_names, num_progs, selected_prog, 30, nk_vec2(300, 300)); + if (next_selected != selected_prog) { + selected_prog = next_selected; + config = tern_insert_path(config, "video\0fragment_shader\0", (tern_val){.ptrval = strdup(progs[next_selected].fragment)}, TVAL_PTR); + config = tern_insert_path(config, "video\0vertex_shader\0", (tern_val){.ptrval = strdup(progs[next_selected].vertex)}, TVAL_PTR); + } settings_int_property(context, "NTSC Overscan", "Top", "video\0ntsc\0overscan\0top\0", 2, 0, 32); settings_int_property(context, "", "Bottom", "video\0ntsc\0overscan\0bottom\0", 17, 0, 32); settings_int_property(context, "", "Left", "video\0ntsc\0overscan\0left\0", 13, 0, 32); @@ -294,6 +407,7 @@ void view_video_settings(struct nk_context *context) settings_int_property(context, "", "Bottom", "video\0pal\0overscan\0bottom\0", 17, 0, 32); settings_int_property(context, "", "Left", "video\0pal\0overscan\0left\0", 13, 0, 32); settings_int_property(context, "", "Right", "video\0pal\0overscan\0right\0", 14, 0, 32); + if (nk_button_label(context, "Back")) { pop_view(); } -- cgit v1.2.3 From 3dd1634466078dab5cc65fdd0f78215a2cbea591 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Mon, 4 Dec 2017 21:38:26 -0800 Subject: Fix buffer overrun in video settings menu --HG-- branch : nuklear_ui --- nuklear_ui/blastem_nuklear.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nuklear_ui/blastem_nuklear.c') diff --git a/nuklear_ui/blastem_nuklear.c b/nuklear_ui/blastem_nuklear.c index 47a6e33..7087d42 100644 --- a/nuklear_ui/blastem_nuklear.c +++ b/nuklear_ui/blastem_nuklear.c @@ -303,7 +303,7 @@ shader_prog *get_shader_progs(dir_entry *entries, size_t num_entries, shader_pro } if (!dupe) { if (num_progs == prog_storage) { - prog_storage *= 2; + prog_storage = prog_storage ? prog_storage*2 : 4; progs = realloc(progs, sizeof(progs) * prog_storage); } progs[num_progs].vertex = NULL; -- cgit v1.2.3 From 1cfa6057ad6cd25422c68132584a948c1ae7c05c Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Wed, 6 Dec 2017 19:29:16 -0800 Subject: Fleshed out audio settings menu --HG-- branch : nuklear_ui --- nuklear_ui/blastem_nuklear.c | 67 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) (limited to 'nuklear_ui/blastem_nuklear.c') diff --git a/nuklear_ui/blastem_nuklear.c b/nuklear_ui/blastem_nuklear.c index 7087d42..5eb75f2 100644 --- a/nuklear_ui/blastem_nuklear.c +++ b/nuklear_ui/blastem_nuklear.c @@ -416,7 +416,72 @@ void view_video_settings(struct nk_context *context) } void view_audio_settings(struct nk_context *context) { - + const char *rates[] = { + "192000", + "96000", + "48000", + "44100", + "22050" + }; + const char *sizes[] = { + "1024", + "512", + "256", + "128", + "64" + }; + const uint32_t num_rates = sizeof(rates)/sizeof(*rates); + const uint32_t num_sizes = sizeof(sizes)/sizeof(*sizes); + static int32_t selected_rate = -1; + static int32_t selected_size = -1; + if (selected_rate < 0 || selected_size < 0) { + char *rate = tern_find_path_default(config, "audio\0rate\0", (tern_val){.ptrval = "48000"}, TVAL_PTR).ptrval; + for (uint32_t i = 0; i < num_rates; i++) + { + if (!strcmp(rate, rates[i])) { + selected_rate = i; + break; + } + } + if (selected_rate < 0) { + //better solution would be to add the custom rate to the rate list, but this is probably sufficient for now + selected_rate = 2; + } + char *size = tern_find_path_default(config, "audio\0buffer\0", (tern_val){.ptrval = "512"}, TVAL_PTR).ptrval; + for (uint32_t i = 0; i < num_sizes; i++) + { + if (!strcmp(size, sizes[i])) { + selected_size = i; + break; + } + } + if (selected_size < 0) { + //better solution would be to add the custom rate to the rate list, but this is probably sufficient for now + selected_size = 2; + } + } + uint32_t width = render_width(); + uint32_t height = render_height(); + if (nk_begin(context, "Audio Settings", nk_rect(0, 0, width, height), 0)) { + nk_layout_row_static(context, 30, width > 300 ? 300 : width, 2); + nk_label(context, "Rate in Hz", NK_TEXT_LEFT); + int32_t next_selected = nk_combo(context, rates, num_rates, selected_rate, 30, nk_vec2(300, 300)); + if (next_selected != selected_rate) { + config = tern_insert_path(config, "audio\0rate\0", (tern_val){.ptrval = strdup(rates[next_selected])}, TVAL_PTR); + selected_rate = next_selected; + } + nk_label(context, "Buffer Samples", NK_TEXT_LEFT); + next_selected = nk_combo(context, sizes, num_sizes, selected_size, 30, nk_vec2(300, 300)); + if (next_selected != selected_size) { + config = tern_insert_path(config, "audio\0buffer\0", (tern_val){.ptrval = strdup(sizes[next_selected])}, TVAL_PTR); + selected_size = next_selected; + } + settings_int_input(context, "Lowpass Cutoff Hz", "audio\0lowpass_cutoff\0", "3390"); + if (nk_button_label(context, "Back")) { + pop_view(); + } + nk_end(context); + } } void view_system_settings(struct nk_context *context) { -- cgit v1.2.3 From 2b3257dd11dd84b57d5a3a78e9e27a2d041da664 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Fri, 8 Dec 2017 09:43:05 -0800 Subject: Initial work on system menu --HG-- branch : nuklear_ui --- nuklear_ui/blastem_nuklear.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'nuklear_ui/blastem_nuklear.c') diff --git a/nuklear_ui/blastem_nuklear.c b/nuklear_ui/blastem_nuklear.c index 5eb75f2..beab37a 100644 --- a/nuklear_ui/blastem_nuklear.c +++ b/nuklear_ui/blastem_nuklear.c @@ -485,7 +485,17 @@ void view_audio_settings(struct nk_context *context) } void view_system_settings(struct nk_context *context) { - + uint32_t width = render_width(); + uint32_t height = render_height(); + if (nk_begin(context, "System Settings", nk_rect(0, 0, width, height), 0)) { + nk_layout_row_static(context, 30, width > 300 ? 300 : width, 2); + settings_int_property(context, "68000 Clock Divider", "", "clocks\0m68k_divider\0", 7, 1, 53); + settings_toggle(context, "Remember ROM Path", "ui\0remember_path\0", 1); + if (nk_button_label(context, "Back")) { + pop_view(); + } + nk_end(context); + } } void view_back(struct nk_context *context) -- cgit v1.2.3 From 8a5b965d6034a2a7fae6087e334fbf334ca7671a Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Fri, 8 Dec 2017 23:24:21 -0800 Subject: Refactor basic settings dropdowns --HG-- branch : nuklear_ui --- nuklear_ui/blastem_nuklear.c | 74 +++++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 36 deletions(-) (limited to 'nuklear_ui/blastem_nuklear.c') diff --git a/nuklear_ui/blastem_nuklear.c b/nuklear_ui/blastem_nuklear.c index beab37a..5d47d23 100644 --- a/nuklear_ui/blastem_nuklear.c +++ b/nuklear_ui/blastem_nuklear.c @@ -414,6 +414,40 @@ void view_video_settings(struct nk_context *context) nk_end(context); } } + +int32_t find_match(const char **options, uint32_t num_options, char *path, char *def) +{ + char *setting = tern_find_path_default(config, path, (tern_val){.ptrval = def}, TVAL_PTR).ptrval; + int32_t selected = -1; + for (uint32_t i = 0; i < num_options; i++) + { + if (!strcmp(setting, options[i])) { + selected = i; + break; + } + } + if (selected == -1) { + for (uint32_t i = 0; i < num_options; i++) + { + if (!strcmp(def, options[i])) { + selected = i; + break; + } + } + } + return selected; +} + +int32_t settings_dropdown(struct nk_context *context, char *label, const char **options, uint32_t num_options, int32_t current, char *path) +{ + nk_label(context, label, NK_TEXT_LEFT); + int32_t next = nk_combo(context, options, num_options, current, 30, nk_vec2(300, 300)); + if (next != current) { + config = tern_insert_path(config, path, (tern_val){.ptrval = strdup(options[next])}, TVAL_PTR); + } + return next; +} + void view_audio_settings(struct nk_context *context) { const char *rates[] = { @@ -435,47 +469,15 @@ void view_audio_settings(struct nk_context *context) static int32_t selected_rate = -1; static int32_t selected_size = -1; if (selected_rate < 0 || selected_size < 0) { - char *rate = tern_find_path_default(config, "audio\0rate\0", (tern_val){.ptrval = "48000"}, TVAL_PTR).ptrval; - for (uint32_t i = 0; i < num_rates; i++) - { - if (!strcmp(rate, rates[i])) { - selected_rate = i; - break; - } - } - if (selected_rate < 0) { - //better solution would be to add the custom rate to the rate list, but this is probably sufficient for now - selected_rate = 2; - } - char *size = tern_find_path_default(config, "audio\0buffer\0", (tern_val){.ptrval = "512"}, TVAL_PTR).ptrval; - for (uint32_t i = 0; i < num_sizes; i++) - { - if (!strcmp(size, sizes[i])) { - selected_size = i; - break; - } - } - if (selected_size < 0) { - //better solution would be to add the custom rate to the rate list, but this is probably sufficient for now - selected_size = 2; - } + selected_rate = find_match(rates, num_rates, "autio\0rate\0", "48000"); + selected_size = find_match(sizes, num_sizes, "audio\0buffer\0", "512"); } uint32_t width = render_width(); uint32_t height = render_height(); if (nk_begin(context, "Audio Settings", nk_rect(0, 0, width, height), 0)) { nk_layout_row_static(context, 30, width > 300 ? 300 : width, 2); - nk_label(context, "Rate in Hz", NK_TEXT_LEFT); - int32_t next_selected = nk_combo(context, rates, num_rates, selected_rate, 30, nk_vec2(300, 300)); - if (next_selected != selected_rate) { - config = tern_insert_path(config, "audio\0rate\0", (tern_val){.ptrval = strdup(rates[next_selected])}, TVAL_PTR); - selected_rate = next_selected; - } - nk_label(context, "Buffer Samples", NK_TEXT_LEFT); - next_selected = nk_combo(context, sizes, num_sizes, selected_size, 30, nk_vec2(300, 300)); - if (next_selected != selected_size) { - config = tern_insert_path(config, "audio\0buffer\0", (tern_val){.ptrval = strdup(sizes[next_selected])}, TVAL_PTR); - selected_size = next_selected; - } + selected_rate = settings_dropdown(context, "Rate in Hz", rates, num_rates, selected_rate, "audio\0rate\0"); + selected_size = settings_dropdown(context, "Buffer Samples", sizes, num_sizes, selected_size, "audio\0buffer\0"); settings_int_input(context, "Lowpass Cutoff Hz", "audio\0lowpass_cutoff\0", "3390"); if (nk_button_label(context, "Back")) { pop_view(); -- cgit v1.2.3 From 0ebcc8530372444c34f906eddc1614fa6731f865 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Mon, 11 Dec 2017 09:50:47 -0800 Subject: Added dropdowns for default region and savestate format --HG-- branch : nuklear_ui --- nuklear_ui/blastem_nuklear.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) (limited to 'nuklear_ui/blastem_nuklear.c') diff --git a/nuklear_ui/blastem_nuklear.c b/nuklear_ui/blastem_nuklear.c index 5d47d23..6b6ccea 100644 --- a/nuklear_ui/blastem_nuklear.c +++ b/nuklear_ui/blastem_nuklear.c @@ -438,16 +438,21 @@ int32_t find_match(const char **options, uint32_t num_options, char *path, char return selected; } -int32_t settings_dropdown(struct nk_context *context, char *label, const char **options, uint32_t num_options, int32_t current, char *path) +int32_t settings_dropdown_ex(struct nk_context *context, char *label, const char **options, const char **opt_display, uint32_t num_options, int32_t current, char *path) { nk_label(context, label, NK_TEXT_LEFT); - int32_t next = nk_combo(context, options, num_options, current, 30, nk_vec2(300, 300)); + int32_t next = nk_combo(context, opt_display, num_options, current, 30, nk_vec2(300, 300)); if (next != current) { config = tern_insert_path(config, path, (tern_val){.ptrval = strdup(options[next])}, TVAL_PTR); } return next; } +int32_t settings_dropdown(struct nk_context *context, char *label, const char **options, uint32_t num_options, int32_t current, char *path) +{ + return settings_dropdown_ex(context, label, options, options, num_options, current, path); +} + void view_audio_settings(struct nk_context *context) { const char *rates[] = { @@ -487,12 +492,34 @@ void view_audio_settings(struct nk_context *context) } void view_system_settings(struct nk_context *context) { + const char *regions[] = { + "J - Japan", + "U - Americas", + "E - Europe" + }; + const char *region_codes[] = {"J", "U", "E"}; + const uint32_t num_regions = sizeof(regions)/sizeof(*regions); + static int32_t selected_region = -1; + if (selected_region < 0) { + selected_region = find_match(region_codes, num_regions, "system\0default_region\0", "U"); + } + const char *formats[] = { + "native", + "gst" + }; + const uint32_t num_formats = sizeof(formats)/sizeof(*formats); + int32_t selected_format = -1; + if (selected_format < 0) { + selected_format = find_match(formats, num_formats, "ui\0state_format\0", "native"); + } uint32_t width = render_width(); uint32_t height = render_height(); if (nk_begin(context, "System Settings", nk_rect(0, 0, width, height), 0)) { nk_layout_row_static(context, 30, width > 300 ? 300 : width, 2); settings_int_property(context, "68000 Clock Divider", "", "clocks\0m68k_divider\0", 7, 1, 53); settings_toggle(context, "Remember ROM Path", "ui\0remember_path\0", 1); + selected_region = settings_dropdown_ex(context, "Default Region", region_codes, regions, num_regions, selected_region, "system\0default_region\0"); + selected_format = settings_dropdown(context, "Save State Format", formats, num_formats, selected_format, "ui\0state_format\0"); if (nk_button_label(context, "Back")) { pop_view(); } -- cgit v1.2.3 From 96791e9a31aaf086b972a80783c8a2ffc2abc8eb Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Mon, 11 Dec 2017 19:16:44 -0800 Subject: Added RAM init and IO port config to system settings menu --HG-- branch : nuklear_ui --- nuklear_ui/blastem_nuklear.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'nuklear_ui/blastem_nuklear.c') diff --git a/nuklear_ui/blastem_nuklear.c b/nuklear_ui/blastem_nuklear.c index 6b6ccea..3304c17 100644 --- a/nuklear_ui/blastem_nuklear.c +++ b/nuklear_ui/blastem_nuklear.c @@ -11,6 +11,7 @@ #include "../saves.h" #include "../blastem.h" #include "../config.h" +#include "../io.h" static struct nk_context *context; @@ -512,6 +513,39 @@ void view_system_settings(struct nk_context *context) if (selected_format < 0) { selected_format = find_match(formats, num_formats, "ui\0state_format\0", "native"); } + const char *ram_inits[] = { + "zero", + "random" + }; + const uint32_t num_inits = sizeof(ram_inits)/sizeof(*ram_inits); + static int32_t selected_init = -1; + if (selected_init < 0) { + selected_init = find_match(ram_inits, num_inits, "system\0ram_init\0", "zero"); + } + const char *io_opts_1[] = { + "gamepad2.1", + "gamepad3.1", + "gamepad6.1", + "mouse", + "saturn keyboard", + "xband keyboard" + }; + const char *io_opts_2[] = { + "gamepad2.2", + "gamepad3.2", + "gamepad6.2", + "mouse", + "saturn keyboard", + "xband keyboard" + }; + static int32_t selected_io_1 = -1; + static int32_t selected_io_2 = -1; + const uint32_t num_io = sizeof(io_opts_1)/sizeof(*io_opts_1); + if (selected_io_1 < 0 || selected_io_2 < 0) { + selected_io_1 = find_match(io_opts_1, num_io, "io\0devices\0""1\0", "gamepad6.1"); + selected_io_2 = find_match(io_opts_2, num_io, "io\0devices\0""2\0", "gamepad6.2"); + } + uint32_t width = render_width(); uint32_t height = render_height(); if (nk_begin(context, "System Settings", nk_rect(0, 0, width, height), 0)) { @@ -520,6 +554,9 @@ void view_system_settings(struct nk_context *context) settings_toggle(context, "Remember ROM Path", "ui\0remember_path\0", 1); selected_region = settings_dropdown_ex(context, "Default Region", region_codes, regions, num_regions, selected_region, "system\0default_region\0"); selected_format = settings_dropdown(context, "Save State Format", formats, num_formats, selected_format, "ui\0state_format\0"); + selected_init = settings_dropdown(context, "Initial RAM Value", ram_inits, num_inits, selected_init, "system\0ram_init\0"); + 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"); + 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"); if (nk_button_label(context, "Back")) { pop_view(); } -- cgit v1.2.3 From 248f437b959b5e901ed9ff1ee59ba9a610ed4765 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Fri, 2 Feb 2018 09:24:01 -0800 Subject: Initial work on keyboard binding settings view --HG-- branch : nuklear_ui --- nuklear_ui/blastem_nuklear.c | 69 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) (limited to 'nuklear_ui/blastem_nuklear.c') diff --git a/nuklear_ui/blastem_nuklear.c b/nuklear_ui/blastem_nuklear.c index 3304c17..f494ad8 100644 --- a/nuklear_ui/blastem_nuklear.c +++ b/nuklear_ui/blastem_nuklear.c @@ -226,9 +226,76 @@ static void menu(struct nk_context *context, uint32_t num_entries, const menu_it nk_layout_space_end(context); } +void binding_loop(char *key, tern_val val, uint8_t valtype, void *data) +{ + if (valtype != TVAL_PTR) { + return; + } + tern_node **binding_lookup = data; + *binding_lookup = tern_insert_ptr(*binding_lookup, val.ptrval, strdup(key)); +} + +void binding_group(struct nk_context *context, char *name, const char **binds, uint32_t num_binds, tern_node *binding_lookup) +{ + nk_layout_row_static(context, 34*num_binds+30, render_width() - 80, 1); + if (nk_group_begin(context, name, NK_WINDOW_TITLE)) { + nk_layout_row_static(context, 30, render_width()/2 - 80, 2); + + for (int i = 0; i < num_binds; i++) + { + char *label_alloc = path_extension(binds[i]); + const char *label = label_alloc; + if (!label) { + label = binds[i]; + } + nk_label(context, label, NK_TEXT_LEFT); + if (label_alloc) { + free(label_alloc); + } + nk_button_label(context, tern_find_ptr_default(binding_lookup, binds[i], "Not Set")); + } + nk_group_end(context); + } +} + void view_key_bindings(struct nk_context *context) { - + const char *controller1_binds[] = { + "gamepads.1.up", "gamepads.1.down", "gamepads.1.left", "gamepads.1.right" + "gamepads.1.a", "gamepads.1.b", "gamepads.1.c", + "gamepads.1.x", "gamepads.1.y", "gamepads.1.z", + "gamepads.1.start", "gamepads.1.mode" + }; + const char *controller2_binds[] = { + "gamepads.2.up", "gamepads.2.down", "gamepads.2.left", "gamepads.2.right" + "gamepads.2.a", "gamepads.2.b", "gamepads.2.c", + "gamepads.2.x", "gamepads.2.y", "gamepads.2.z", + "gamepads.2.start", "gamepads.2.mode" + }; + const char *speed_binds[] = { + "ui.next_speed", "ui.prev_speed", + "ui.set_speed.0", "ui.set_speed.1", "ui.set_speed.2" ,"ui.set_speed.3", "ui.set_speed.4", + "ui.set_speed.5", "ui.set_speed.6", "ui.set_speed.7" ,"ui.set_speed.8", "ui.set_speed.9", + }; + const uint32_t NUM_C1_BINDS = sizeof(controller1_binds)/sizeof(*controller1_binds); + const uint32_t NUM_C2_BINDS = sizeof(controller2_binds)/sizeof(*controller2_binds); + const uint32_t NUM_SPEED_BINDS = sizeof(speed_binds)/sizeof(*speed_binds); + static tern_node *binding_lookup; + if (!binding_lookup) { + tern_node *bindings = tern_find_path(config, "bindings\0keys\0", TVAL_NODE).ptrval; + if (bindings) { + tern_foreach(bindings, binding_loop, &binding_lookup); + } + } + uint32_t width = render_width(); + uint32_t height = render_height(); + if (nk_begin(context, "Keyboard Bindings", nk_rect(0, 0, width, height), 0)) { + binding_group(context, "Controller 1", controller1_binds, NUM_C1_BINDS, binding_lookup); + binding_group(context, "Controller 2", controller2_binds, NUM_C2_BINDS, binding_lookup); + binding_group(context, "Speed Control", speed_binds, NUM_SPEED_BINDS, binding_lookup); + + nk_end(context); + } } void view_controllers(struct nk_context *context) { -- cgit v1.2.3 From b1f354708009f7c79c1f4b31783cdd67893d7c20 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Mon, 5 Feb 2018 23:39:14 -0800 Subject: More fleshed out keyboard bindings view --HG-- branch : nuklear_ui --- nuklear_ui/blastem_nuklear.c | 58 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 10 deletions(-) (limited to 'nuklear_ui/blastem_nuklear.c') diff --git a/nuklear_ui/blastem_nuklear.c b/nuklear_ui/blastem_nuklear.c index f494ad8..eba99d0 100644 --- a/nuklear_ui/blastem_nuklear.c +++ b/nuklear_ui/blastem_nuklear.c @@ -235,24 +235,29 @@ void binding_loop(char *key, tern_val val, uint8_t valtype, void *data) *binding_lookup = tern_insert_ptr(*binding_lookup, val.ptrval, strdup(key)); } -void binding_group(struct nk_context *context, char *name, const char **binds, uint32_t num_binds, tern_node *binding_lookup) +static const char *set_binding; +char *set_label; +void binding_group(struct nk_context *context, char *name, const char **binds, const char **bind_names, uint32_t num_binds, tern_node *binding_lookup) { - nk_layout_row_static(context, 34*num_binds+30, render_width() - 80, 1); + nk_layout_row_static(context, 34*num_binds+60, render_width() - 80, 1); if (nk_group_begin(context, name, NK_WINDOW_TITLE)) { nk_layout_row_static(context, 30, render_width()/2 - 80, 2); for (int i = 0; i < num_binds; i++) { - char *label_alloc = path_extension(binds[i]); + char *label_alloc = bind_names ? NULL : path_extension(binds[i]); const char *label = label_alloc; if (!label) { - label = binds[i]; + label = bind_names ? bind_names[i] : binds[i]; } nk_label(context, label, NK_TEXT_LEFT); + if (nk_button_label(context, tern_find_ptr_default(binding_lookup, binds[i], "Not Set"))) { + set_binding = binds[i]; + set_label = strdup(label); + } if (label_alloc) { free(label_alloc); } - nk_button_label(context, tern_find_ptr_default(binding_lookup, binds[i], "Not Set")); } nk_group_end(context); } @@ -261,25 +266,46 @@ void binding_group(struct nk_context *context, char *name, const char **binds, u void view_key_bindings(struct nk_context *context) { const char *controller1_binds[] = { - "gamepads.1.up", "gamepads.1.down", "gamepads.1.left", "gamepads.1.right" + "gamepads.1.up", "gamepads.1.down", "gamepads.1.left", "gamepads.1.right", "gamepads.1.a", "gamepads.1.b", "gamepads.1.c", "gamepads.1.x", "gamepads.1.y", "gamepads.1.z", "gamepads.1.start", "gamepads.1.mode" }; const char *controller2_binds[] = { - "gamepads.2.up", "gamepads.2.down", "gamepads.2.left", "gamepads.2.right" + "gamepads.2.up", "gamepads.2.down", "gamepads.2.left", "gamepads.2.right", "gamepads.2.a", "gamepads.2.b", "gamepads.2.c", "gamepads.2.x", "gamepads.2.y", "gamepads.2.z", "gamepads.2.start", "gamepads.2.mode" }; + const char *general_binds[] = { + "ui.exit", "ui.save_state", "ui.toggle_fullscreen", "ui.soft_reset", "ui.reload", + "ui.screenshot", "ui.sms_pause", "ui.toggle_keyboard_cpatured", "ui.release_mouse" + }; + const char *general_names[] = { + "Show Menu", "Quick Save", "Toggle Fullscreen", "Soft Reset", "Reload Media" + "Internal Screenshot", "SMS Pause", "Capture Keyboard", "Release Mouse" + }; const char *speed_binds[] = { "ui.next_speed", "ui.prev_speed", "ui.set_speed.0", "ui.set_speed.1", "ui.set_speed.2" ,"ui.set_speed.3", "ui.set_speed.4", "ui.set_speed.5", "ui.set_speed.6", "ui.set_speed.7" ,"ui.set_speed.8", "ui.set_speed.9", }; + const char *speed_names[] = { + "Next", "Previous", + "Default Speed", "Set Speed 1", "Set Speed 2", "Set Speed 3", "Set Speed 4", + "Set Speed 5", "Set Speed 6", "Set Speed 7", "Set Speed 8", "Set Speed 9" + }; + const char *debug_binds[] = { + "ui.enter_debugger", "ui.vdp_debug_mode", "ui.vdp_debug_pal" + }; + const char *debug_names[] = { + "Enter Debugger", "VDP Debug Mode", "Debug Palette" + }; const uint32_t NUM_C1_BINDS = sizeof(controller1_binds)/sizeof(*controller1_binds); const uint32_t NUM_C2_BINDS = sizeof(controller2_binds)/sizeof(*controller2_binds); const uint32_t NUM_SPEED_BINDS = sizeof(speed_binds)/sizeof(*speed_binds); + const uint32_t NUM_GEN_BINDS = sizeof(general_binds)/sizeof(*general_binds); + const uint32_t NUM_DBG_BINDS = sizeof(debug_binds)/sizeof(*debug_binds); static tern_node *binding_lookup; if (!binding_lookup) { tern_node *bindings = tern_find_path(config, "bindings\0keys\0", TVAL_NODE).ptrval; @@ -290,12 +316,24 @@ void view_key_bindings(struct nk_context *context) uint32_t width = render_width(); uint32_t height = render_height(); if (nk_begin(context, "Keyboard Bindings", nk_rect(0, 0, width, height), 0)) { - binding_group(context, "Controller 1", controller1_binds, NUM_C1_BINDS, binding_lookup); - binding_group(context, "Controller 2", controller2_binds, NUM_C2_BINDS, binding_lookup); - binding_group(context, "Speed Control", speed_binds, NUM_SPEED_BINDS, binding_lookup); + binding_group(context, "Controller 1", controller1_binds, NULL, NUM_C1_BINDS, binding_lookup); + binding_group(context, "Controller 2", controller2_binds, NULL, NUM_C2_BINDS, binding_lookup); + binding_group(context, "General", general_binds, general_names, NUM_GEN_BINDS, binding_lookup); + binding_group(context, "Speed Control", speed_binds, speed_names, NUM_SPEED_BINDS, binding_lookup); + binding_group(context, "Debug", debug_binds, debug_names, NUM_DBG_BINDS, binding_lookup); nk_end(context); } + if (set_binding && nk_begin(context, "Set Binding", nk_rect(width/4, height/4, width/2/*width*3/4*/, height/2), NK_WINDOW_TITLE | NK_WINDOW_BORDER)) { + nk_layout_row_static(context, 30, width/2-30, 1); + nk_label(context, "Press new key for", NK_TEXT_CENTERED); + nk_label(context, set_label, NK_TEXT_CENTERED); + if (nk_button_label(context, "Cancel")) { + free(set_label); + set_binding = set_label = NULL; + } + nk_end(context); + } } void view_controllers(struct nk_context *context) { -- cgit v1.2.3 From d728432b713702b6a564e3532930e380dd5d3f28 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Tue, 6 Feb 2018 22:42:16 -0800 Subject: Key binding menu is now functional --HG-- branch : nuklear_ui --- nuklear_ui/blastem_nuklear.c | 92 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) (limited to 'nuklear_ui/blastem_nuklear.c') diff --git a/nuklear_ui/blastem_nuklear.c b/nuklear_ui/blastem_nuklear.c index eba99d0..367893d 100644 --- a/nuklear_ui/blastem_nuklear.c +++ b/nuklear_ui/blastem_nuklear.c @@ -235,6 +235,7 @@ void binding_loop(char *key, tern_val val, uint8_t valtype, void *data) *binding_lookup = tern_insert_ptr(*binding_lookup, val.ptrval, strdup(key)); } +static int32_t keycode; static const char *set_binding; char *set_label; void binding_group(struct nk_context *context, char *name, const char **binds, const char **bind_names, uint32_t num_binds, tern_node *binding_lookup) @@ -254,6 +255,7 @@ void binding_group(struct nk_context *context, char *name, const char **binds, c if (nk_button_label(context, tern_find_ptr_default(binding_lookup, binds[i], "Not Set"))) { set_binding = binds[i]; set_label = strdup(label); + keycode = 0; } if (label_alloc) { free(label_alloc); @@ -263,6 +265,61 @@ void binding_group(struct nk_context *context, char *name, const char **binds, c } } +static char *get_key_name(int32_t keycode) +{ + char *name = NULL; + if (keycode > ' ' && keycode < 0x80) { + //key corresponds to a printable non-whitespace character + name = malloc(2); + name[0] = keycode; + name[1] = 0; + } else { + switch (keycode) + { + case RENDERKEY_UP: name = "up"; break; + case RENDERKEY_DOWN: name = "down"; break; + case RENDERKEY_LEFT: name = "left"; break; + case RENDERKEY_RIGHT: name = "right"; break; + case '\r': name = "enter"; break; + case ' ': name = "space"; break; + case '\t': name = "tab"; break; + case '\b': name = "backspace"; break; + case RENDERKEY_ESC: name = "esc"; break; + case RENDERKEY_DEL: name = "delete"; break; + case RENDERKEY_LSHIFT: name = "lshift"; break; + case RENDERKEY_RSHIFT: name = "rshift"; break; + case RENDERKEY_LCTRL: name = "lctrl"; break; + case RENDERKEY_RCTRL: name = "rctrl"; break; + case RENDERKEY_LALT: name = "lalt"; break; + case RENDERKEY_RALT: name = "ralt"; break; + case RENDERKEY_HOME: name = "home"; break; + case RENDERKEY_END: name = "end"; break; + case RENDERKEY_PAGEUP: name = "pageup"; break; + case RENDERKEY_PAGEDOWN: name = "pagedown"; break; + case RENDERKEY_F1: name = "f1"; break; + case RENDERKEY_F2: name = "f2"; break; + case RENDERKEY_F3: name = "f3"; break; + case RENDERKEY_F4: name = "f4"; break; + case RENDERKEY_F5: name = "f5"; break; + case RENDERKEY_F6: name = "f6"; break; + case RENDERKEY_F7: name = "f7"; break; + case RENDERKEY_F8: name = "f8"; break; + case RENDERKEY_F9: name = "f9"; break; + case RENDERKEY_F10: name = "f10"; break; + case RENDERKEY_F11: name = "f11"; break; + case RENDERKEY_F12: name = "f12"; break; + case RENDERKEY_SELECT: name = "select"; break; + case RENDERKEY_PLAY: name = "play"; break; + case RENDERKEY_SEARCH: name = "search"; break; + case RENDERKEY_BACK: name = "back"; break; + } + if (name) { + name = strdup(name); + } + } + return name; +} + void view_key_bindings(struct nk_context *context) { const char *controller1_binds[] = { @@ -282,7 +339,7 @@ void view_key_bindings(struct nk_context *context) "ui.screenshot", "ui.sms_pause", "ui.toggle_keyboard_cpatured", "ui.release_mouse" }; const char *general_names[] = { - "Show Menu", "Quick Save", "Toggle Fullscreen", "Soft Reset", "Reload Media" + "Show Menu", "Quick Save", "Toggle Fullscreen", "Soft Reset", "Reload Media", "Internal Screenshot", "SMS Pause", "Capture Keyboard", "Release Mouse" }; const char *speed_binds[] = { @@ -331,6 +388,36 @@ void view_key_bindings(struct nk_context *context) if (nk_button_label(context, "Cancel")) { free(set_label); set_binding = set_label = NULL; + } else if (keycode) { + char *name = get_key_name(keycode); + if (name) { + uint32_t prefix_len = strlen("bindings") + strlen("keys") + 2; + char * old = tern_find_ptr(binding_lookup, set_binding); + if (old) { + uint32_t suffix_len = strlen(old) + 1; + char *old_path = malloc(prefix_len + suffix_len + 1); + memcpy(old_path, "bindings\0keys\0", prefix_len); + memcpy(old_path + prefix_len, old, suffix_len); + old_path[prefix_len + suffix_len] = 0; + tern_val old_val; + if (tern_delete_path(&config, old_path, &old_val) == TVAL_PTR) { + free(old_val.ptrval); + } + } + uint32_t suffix_len = strlen(name) + 1; + char *path = malloc(prefix_len + suffix_len + 1); + memcpy(path, "bindings\0keys\0", prefix_len); + memcpy(path + prefix_len, name, suffix_len); + path[prefix_len + suffix_len] = 0; + + config = tern_insert_path(config, path, (tern_val){.ptrval = strdup(set_binding)}, TVAL_PTR); + free(path); + free(name); + tern_free(binding_lookup); + binding_lookup = NULL; + } + free(set_label); + set_binding = set_label = NULL; } nk_end(context); } @@ -753,6 +840,9 @@ void ui_idle_loop(void) } static void handle_event(SDL_Event *event) { + if (event->type == SDL_KEYDOWN) { + keycode = event->key.keysym.sym; + } nk_sdl_handle_event(event); } -- cgit v1.2.3 From 94b11b186fa4cf46c64bc3fad55f74c7b5096ffe Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Wed, 7 Feb 2018 19:21:44 -0800 Subject: Filled in About view --HG-- branch : nuklear_ui --- nuklear_ui/blastem_nuklear.c | 47 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'nuklear_ui/blastem_nuklear.c') diff --git a/nuklear_ui/blastem_nuklear.c b/nuklear_ui/blastem_nuklear.c index 367893d..715eb9f 100644 --- a/nuklear_ui/blastem_nuklear.c +++ b/nuklear_ui/blastem_nuklear.c @@ -136,6 +136,53 @@ void view_lock_on(struct nk_context *context) void view_about(struct nk_context *context) { + const char *lines[] = { + "BlastEm v0.6.0", + "Copyright 2012-2017 Michael Pavone", + "", + "BlastEm is a high performance open source", + "(GPLv3) Genesis/Megadrive emulator", + }; + const uint32_t NUM_LINES = sizeof(lines)/sizeof(*lines); + const char *thanks[] = { + "Nemesis: Documentatino and test ROMs", + "Charles MacDonald: Documentation", + "Eke-Eke: Documentation", + "Bart Trzynadlowski: Documentation", + "KanedaFR: Hosting the best Sega forum", + "Titan: Awesome demos and documentation", + "micky: Testing", + "Sasha: Testing", + "lol-frank: Testing", + "Sik: Testing", + "Tim Lawrence : Testing", + "ComradeOj: Testing", + "Vladikcomper: Testing" + }; + const uint32_t NUM_THANKS = sizeof(thanks)/sizeof(*thanks); + uint32_t width = render_width(); + uint32_t height = render_height(); + if (nk_begin(context, "About", nk_rect(0, 0, width, height), 0)) { + nk_layout_row_static(context, 30, width-40, 1); + for (uint32_t i = 0; i < NUM_LINES; i++) + { + nk_label(context, lines[i], NK_TEXT_LEFT); + } + nk_layout_row_static(context, height - 80 - 34*NUM_LINES, width-40, 1); + if (nk_group_begin(context, "Special Thanks", NK_WINDOW_TITLE)) { + nk_layout_row_static(context, 30, width - 80, 1); + for (uint32_t i = 0; i < NUM_THANKS; i++) + { + nk_label(context, thanks[i], NK_TEXT_LEFT); + } + nk_group_end(context); + } + nk_layout_row_static(context, 52, width/3, 1); + if (nk_button_label(context, "Back")) { + pop_view(); + } + nk_end(context); + } } typedef struct { -- cgit v1.2.3 From d738c30dec8a7c9f351094851c00a4623f339084 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Tue, 6 Mar 2018 21:27:12 -0800 Subject: Added support for TTC and dfont format true type fonts. More robust font selection on Windows --HG-- branch : nuklear_ui --- nuklear_ui/blastem_nuklear.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'nuklear_ui/blastem_nuklear.c') diff --git a/nuklear_ui/blastem_nuklear.c b/nuklear_ui/blastem_nuklear.c index 715eb9f..59d5a3b 100644 --- a/nuklear_ui/blastem_nuklear.c +++ b/nuklear_ui/blastem_nuklear.c @@ -902,11 +902,12 @@ static void context_created(void) nk_sdl_device_create(); struct nk_font_atlas *atlas; nk_sdl_font_stash_begin(&atlas); - char *font = default_font_path(); + uint32_t font_size; + uint8_t *font = default_font(&font_size); if (!font) { fatal_error("Failed to find default font path\n"); } - struct nk_font *def_font = nk_font_atlas_add_from_file(atlas, font, 30, NULL); + struct nk_font *def_font = nk_font_atlas_add_from_memory(atlas, font, font_size, 30, NULL); nk_sdl_font_stash_end(); nk_style_set_font(context, &def_font->handle); } @@ -944,11 +945,14 @@ void blastem_nuklear_init(uint8_t file_loaded) struct nk_font_atlas *atlas; nk_sdl_font_stash_begin(&atlas); - char *font = default_font_path(); + //char *font = default_font_path(); + uint32_t font_size; + uint8_t *font = default_font(&font_size); if (!font) { fatal_error("Failed to find default font path\n"); } - struct nk_font *def_font = nk_font_atlas_add_from_file(atlas, font, 30, NULL); + //struct nk_font *def_font = nk_font_atlas_add_from_file(atlas, font, 30, NULL); + struct nk_font *def_font = nk_font_atlas_add_from_memory(atlas, font, font_size, 30, NULL); nk_sdl_font_stash_end(); nk_style_set_font(context, &def_font->handle); current_view = file_loaded ? view_play : view_menu; -- cgit v1.2.3