# HG changeset patch # User Michael Pavone # Date 1700211932 28800 # Node ID 1c09f5be285b6bad3adc496e215130af86a37cc5 # Parent 02c04196c2da017a2569b6b0960f1d48814d25b6 Very basic UI for media player diff -r 02c04196c2da -r 1c09f5be285b mediaplayer.c --- a/mediaplayer.c Fri Nov 17 00:30:46 2023 -0800 +++ b/mediaplayer.c Fri Nov 17 01:05:32 2023 -0800 @@ -21,11 +21,6 @@ MEDIA_UNKNOWN }; -enum { - STATE_PLAY, - STATE_PAUSED -}; - uint32_t cycles_to_samples(uint32_t clock_rate, uint32_t cycles) { return ((uint64_t)cycles) * ((uint64_t)44100) / ((uint64_t)clock_rate); @@ -464,6 +459,7 @@ if (sample_size > player->media->size || player->current_offset > player->media->size - sample_size) { player->current_offset = player->wave->format_header.size + offsetof(wave_header, audio_format); player->state = STATE_PAUSED; + player->playback_time = 0; return; } if (player->wave->bits_per_sample == 16) { @@ -498,6 +494,7 @@ render_put_stereo_sample(player->audio, samples[0], samples[1]); } else { player->state = STATE_PAUSED; + player->playback_time = 0; return; } } @@ -654,6 +651,7 @@ switch (player->state) { case STATE_PLAY: + player->playback_time++; switch(player->media_type) { case AUDIO_VGM: diff -r 02c04196c2da -r 1c09f5be285b mediaplayer.h --- a/mediaplayer.h Fri Nov 17 00:30:46 2023 -0800 +++ b/mediaplayer.h Fri Nov 17 01:05:32 2023 -0800 @@ -28,6 +28,11 @@ uint8_t data_type; }; +enum { + STATE_PLAY, + STATE_PAUSED +}; + typedef struct { system_header header; system_media *media; diff -r 02c04196c2da -r 1c09f5be285b nuklear_ui/blastem_nuklear.c --- a/nuklear_ui/blastem_nuklear.c Fri Nov 17 00:30:46 2023 -0800 +++ b/nuklear_ui/blastem_nuklear.c Fri Nov 17 01:05:32 2023 -0800 @@ -21,6 +21,7 @@ #include "../png.h" #include "../controller_info.h" #include "../bindings.h" +#include "../mediaplayer.h" static struct nk_context *context; static struct rawfb_context *fb_context; @@ -70,7 +71,32 @@ void view_play(struct nk_context *context) { + if (current_system && current_system->type == SYSTEM_MEDIA_PLAYER) { + media_player *player = (media_player *)current_system; + if (nk_begin(context, "Media Player", nk_rect(0, 0, render_width(), render_height()), 0)) { + uint32_t desired_width = context->style.font->height * 10; + nk_layout_row_static(context, context->style.font->height * 1.25f, render_width() - 4 * context->style.font->height, 1); + nk_label(context, current_media()->name, NK_TEXT_LEFT); + uint32_t seconds = player->playback_time / 60; + uint32_t minutes = seconds / 60; + seconds %= 60; + uint32_t hours = minutes / 60; + minutes %= 60; + char buffer[10]; + sprintf(buffer, "%02d:%02d:%02d", hours, minutes, seconds); + nk_label(context, buffer, NK_TEXT_LEFT); + + nk_layout_row_static(context, context->style.font->height * 1.25f, desired_width, 1); + if (nk_button_label(context, player->state == STATE_PLAY ? "Pause" : "Play")) { + uint8_t old_state = player->button_state[BUTTON_A]; + player->button_state[BUTTON_A] = 0; + current_system->gamepad_down(current_system, 1, BUTTON_A); + player->button_state[BUTTON_A] = old_state; + } + nk_end(context); + } + } } static char *browser_cur_path; @@ -1035,7 +1061,7 @@ options[BY_INDEX].title = by_index_names[selected_controller]; options[SIMILAR_CONTROLLERS].title = make_human_readable_type_name(&selected_controller_info); - if (nk_begin(context, "Select Binding Dest", nk_rect(0, 0, render_width(), render_height()), NK_WINDOW_NO_SCROLLBAR)) { + if ((context, "Select Binding Dest", nk_rect(0, 0, render_width(), render_height()), NK_WINDOW_NO_SCROLLBAR)) { menu(context, NUM_DEST_TYPES, options, handle_dest_clicked); nk_end(context); } @@ -1061,7 +1087,7 @@ void view_controller_bindings(struct nk_context *context) { - if (nk_begin(context, "Controller Bindings", nk_rect(0, 0, render_width(), render_height()), NK_WINDOW_NO_SCROLLBAR)) { + if ((context, "Controller Bindings", nk_rect(0, 0, render_width(), render_height()), NK_WINDOW_NO_SCROLLBAR)) { if (!bindings) { bindings = calloc(1, sizeof(*bindings)); tern_node *pad = get_binding_node_for_pad(selected_controller, &selected_controller_info); @@ -1256,7 +1282,7 @@ char buffer[512]; static int quiet, button_a = -1, button_a_axis = -1; uint8_t added_mapping = 0; - if (nk_begin(context, "Controllers", nk_rect(0, 0, render_width(), render_height()), NK_WINDOW_NO_SCROLLBAR)) { + if ((context, "Controllers", nk_rect(0, 0, render_width(), render_height()), NK_WINDOW_NO_SCROLLBAR)) { nk_layout_space_begin(context, NK_STATIC, render_height() - context->style.font->height, 3); @@ -1397,7 +1423,7 @@ static void view_controller_variant(struct nk_context *context) { uint8_t selected = 0; - if (nk_begin(context, "Controller Type", nk_rect(0, 0, render_width(), render_height()), 0)) { + if ((context, "Controller Type", nk_rect(0, 0, render_width(), render_height()), 0)) { nk_layout_row_static(context, context->style.font->height*1.25, render_width() - context->style.font->height * 2, 1); nk_label(context, "", NK_TEXT_CENTERED); nk_label(context, "Select the layout that", NK_TEXT_CENTERED); @@ -1492,7 +1518,7 @@ void view_controller_type(struct nk_context *context) { - if (nk_begin(context, "Controller Type", nk_rect(0, 0, render_width(), render_height()), 0)) { + if ((context, "Controller Type", nk_rect(0, 0, render_width(), render_height()), 0)) { controller_type_group(context, "Xbox", TYPE_XBOX, SUBTYPE_XBOX, (const char *[]){ "Original", "Xbox 360", "Xbox One/Series", "Xbox Elite" }, 4); @@ -1578,7 +1604,7 @@ void view_deadzones(struct nk_context *context) { - if (nk_begin(context, "Deadzones", nk_rect(0, 0, render_width(), render_height()), NK_WINDOW_NO_SCROLLBAR)) { + if ((context, "Deadzones", nk_rect(0, 0, render_width(), render_height()), NK_WINDOW_NO_SCROLLBAR)) { nk_layout_space_begin(context, NK_STATIC, render_height() - 3 * context->style.font->height, 4); float left = render_width() / 8.0f, top = render_height() / 8.0f; @@ -1628,7 +1654,7 @@ void view_controllers(struct nk_context *context) { - if (nk_begin(context, "Controllers", nk_rect(0, 0, render_width(), render_height()), NK_WINDOW_NO_SCROLLBAR)) { + if ((context, "Controllers", nk_rect(0, 0, render_width(), render_height()), NK_WINDOW_NO_SCROLLBAR)) { int height = (render_height() - 2*context->style.font->height) / 5; int inner_height = height - context->style.window.spacing.y; const struct nk_user_font *font = context->style.font; @@ -2008,7 +2034,7 @@ if (desired_width > width) { desired_width = width; } - if (nk_begin(context, "Video Settings", nk_rect(0, 0, width, height), 0)) { + if ((context, "Video Settings", nk_rect(0, 0, width, height), 0)) { nk_layout_row_static(context, context->style.font->height, desired_width, 2); settings_toggle(context, "Fullscreen", "video\0fullscreen\0", 0); settings_toggle(context, "Open GL", "video\0gl\0", 1); @@ -2418,7 +2444,7 @@ void blastem_nuklear_render(void) { - if (current_view != view_play) { + if (current_view != view_play || (current_system && current_system->type == SYSTEM_MEDIA_PLAYER)) { nk_input_end(context); current_view(context); if (fb_context) { diff -r 02c04196c2da -r 1c09f5be285b render_sdl.c --- a/render_sdl.c Fri Nov 17 00:30:46 2023 -0800 +++ b/render_sdl.c Fri Nov 17 01:05:32 2023 -0800 @@ -1865,6 +1865,7 @@ { #ifndef DISABLE_OPENGL if (render_gl) { + SDL_GL_MakeCurrent(main_window, main_context); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT);