From 8fcfa3659a80d9df90ae08a627321087510164cf Mon Sep 17 00:00:00 2001 From: radius Date: Wed, 23 Mar 2016 23:31:15 -0500 Subject: [PATCH] add gamepad POC panel --- menu/drivers/zr.c | 51 ++++++++- menu/drivers/zr_menu.c | 239 ++++++++++++++++++++++++++++++++++++++++- menu/drivers/zr_menu.h | 5 + 3 files changed, 293 insertions(+), 2 deletions(-) diff --git a/menu/drivers/zr.c b/menu/drivers/zr.c index 9add4472c5..9468d38e35 100644 --- a/menu/drivers/zr.c +++ b/menu/drivers/zr.c @@ -74,6 +74,32 @@ static void zrmenu_main(zrmenu_handle_t *zr) zr_buffer_info(&zr->status, &zr->ctx.memory); } +static void zrmenu_input_gamepad(zrmenu_handle_t *zr) +{ + switch (zr->action) + { + case MENU_ACTION_LEFT: + zr_input_key(&zr->ctx, ZR_KEY_LEFT, 1); + break; + case MENU_ACTION_RIGHT: + zr_input_key(&zr->ctx, ZR_KEY_RIGHT, 1); + break; + case MENU_ACTION_DOWN: + zr_input_key(&zr->ctx, ZR_KEY_DOWN, 1); + break; + case MENU_ACTION_UP: + zr_input_key(&zr->ctx, ZR_KEY_UP, 1); + break; + default: + zr_input_key(&zr->ctx, ZR_KEY_UP, 0); + zr_input_key(&zr->ctx, ZR_KEY_DOWN, 0); + zr_input_key(&zr->ctx, ZR_KEY_LEFT, 0); + zr_input_key(&zr->ctx, ZR_KEY_RIGHT, 0); + break; + } + +} + static void zrmenu_input_mouse_movement(struct zr_context *ctx) { int16_t mouse_x = menu_input_mouse_state(MENU_MOUSE_X_AXIS); @@ -197,6 +223,7 @@ static void zrmenu_frame(void *data) menu_display_ctl(MENU_DISPLAY_CTL_SET_VIEWPORT, NULL); zr_input_begin(&zr->ctx); + zrmenu_input_gamepad(zr); zrmenu_input_mouse_movement(&zr->ctx); zrmenu_input_mouse_button(&zr->ctx); zrmenu_input_keyboard(&zr->ctx); @@ -413,10 +440,32 @@ static bool zrmenu_init_list(void *data) return false; } +static int zrmenu_iterate(void *data, void *userdata, enum menu_action action) +{ + int ret; + size_t selection; + menu_entry_t entry; + zrmenu_handle_t *zr = (zrmenu_handle_t*)userdata; + + if (!zr) + return -1; + if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection)) + return 0; + + menu_entry_get(&entry, 0, selection, NULL, false); + + zr->action = action; + + ret = menu_entry_action(&entry, selection, action); + if (ret) + return -1; + return 0; +} + menu_ctx_driver_t menu_ctx_zr = { NULL, zrmenu_get_message, - generic_menu_iterate, + zrmenu_iterate, NULL, zrmenu_frame, zrmenu_init, diff --git a/menu/drivers/zr_menu.c b/menu/drivers/zr_menu.c index c4be34f1aa..99927af7c2 100644 --- a/menu/drivers/zr_menu.c +++ b/menu/drivers/zr_menu.c @@ -36,6 +36,228 @@ #include "../../configuration.h" #include "../../retroarch.h" + +#define LEN(a) (sizeof(a)/sizeof(a)[0]) + + +/* gamepad demo variables */ +enum widget_id +{ + WINDOW_MODE = 0, + MODEL_DETAIL, + TEXTURES, + SHADOWS, + LIGHTNING, + EFFECTS, + CONSOLE, + BRIGHTNESS, + VOLUME, + WIDGET_MAX +}; +enum display_settings { + WINDOWED = 0, FULLSCREEN}; +enum detail_settings {LOW, MEDIUM, HIGH, EXTRA_HIGH}; +enum state_settings {OFF, ON}; +const char *display[] = {"Windowed", "Fullscreen"}; +const char *state[] = {"Off", "On"}; +const char *detail[] = {"Low", "Medium", "High", "Extra High"}; + +static int window_mode = FULLSCREEN; +static int model_detail = HIGH; +static int texture_detail = EXTRA_HIGH; +static int shadow_detail = HIGH; +static int lighning_detail = LOW; +static int effects_detail = MEDIUM; +static int show_console = ON; +static int brightness = 90; +static int volume = 30; +static int active = WINDOW_MODE; +/* end of gamepad demo variables */ + + +static int ui_selector(struct zr_context *ctx, const char *title, int *selected, const char *items[], + int max, int active) +{ + struct zr_vec2 item_padding; + struct zr_rect bounds, label, content, tri, sel; + struct zr_window *win; + struct zr_panel *layout; + struct zr_command_buffer *out; + struct zr_color col; + struct zr_vec2 result[3]; + zr_size text_len, text_width; + + ZR_ASSERT(ctx); + ZR_ASSERT(ctx->current); + if (!ctx || !ctx->current) + return 0; + + win = ctx->current; + layout = zr_window_get_panel(ctx); + ZR_ASSERT(layout); + out = zr_window_get_canvas(ctx); + if (!zr_widget(&bounds, ctx)) + return 0; + + item_padding = zr_get_property(ctx, ZR_PROPERTY_ITEM_PADDING); + bounds.x += item_padding.x; + bounds.y += item_padding.y; + bounds.w -= 2 * item_padding.x; + bounds.h -= 2 * item_padding.y; + + label.h = bounds.h; + label.w = bounds.w / 2.0f; + label.x = bounds.x + item_padding.x; + label.y = bounds.y + label.h/2.0f - (float)ctx->style.font.height/2.0f; + + content.x = bounds.x + bounds.w/2.0f; + content.y = bounds.y; + content.w = bounds.w / 2.0f; + content.h = bounds.h; + + if (active) zr_draw_rect(out, bounds, 0, zr_rgba(220, 220, 220, 135)); + text_len = strlen(title); + col = (active) ? zr_rgba(0, 0, 0, 255): zr_rgba(220,220,220,220); + zr_draw_text(out, label, title, text_len, &ctx->style.font, zr_rgba(0,0,0,0), col); + + if (zr_input_is_key_pressed(&ctx->input, ZR_KEY_RIGHT) && active) + *selected = MIN(*selected+1, max-1); + else if (zr_input_is_key_pressed(&ctx->input, ZR_KEY_LEFT) && active) + *selected = MAX(0, *selected-1); + + tri.h = ctx->style.font.height - 2 * item_padding.y; + tri.w = tri.h/2.0f; + tri.x = content.x + item_padding.x; + tri.y = content.y + content.h/2 - tri.h/2.0f; + + sel.x = tri.x + item_padding.x; + sel.y = tri.y; + sel.h = content.h; + + if (*selected > 0) { + zr_triangle_from_direction(result, tri, 0, 0, ZR_LEFT); + zr_draw_triangle(out, result[0].x, result[0].y, result[1].x, result[1].y, + result[2].x, result[2].y, (active) ? zr_rgba(0, 0, 0, 255): + zr_rgba(100, 100, 100, 150)); + } + + tri.x = content.x + (content.w - item_padding.x) - tri.w; + sel.w = tri.x - sel.x; + + if (*selected < max-1) { + zr_triangle_from_direction(result, tri, 0, 0, ZR_RIGHT); + zr_draw_triangle(out, result[0].x, result[0].y, result[1].x, result[1].y, + result[2].x, result[2].y, (active) ? zr_rgba(0, 0, 0, 255): + zr_rgba(100, 100, 100, 150)); + } + + text_width = ctx->style.font.width(ctx->style.font.userdata, + ctx->style.font.height, items[*selected], strlen(items[*selected])); + + label.w = MAX(1, (float)text_width); + label.x = (sel.x + (sel.w - label.w) / 2); + label.x = MAX(sel.x, label.x); + label.w = MIN(sel.x + sel.w, label.x + label.w); + if (label.w >= label.x) label.w -= label.x; + zr_draw_text(out, label, items[*selected], strlen(items[*selected]), + &ctx->style.font, zr_rgba(0,0,0,0), col); + return 0; +} + +static void ui_slider(struct zr_context *ctx, const char *title, int *value, int max, int active) +{ + struct zr_vec2 item_padding; + struct zr_rect bounds, label, content, bar, cursor, tri; + struct zr_window *win; + struct zr_panel *layout; + struct zr_command_buffer *out; + struct zr_color col; + zr_size text_len, text_width; + float prog_scale = (float)*value / (float)max; + struct zr_vec2 result[3]; + + ZR_ASSERT(ctx); + ZR_ASSERT(ctx->current); + if (!ctx || !ctx->current) + return; + + win = ctx->current; + layout = zr_window_get_panel(ctx); + ZR_ASSERT(layout); + out = zr_window_get_canvas(ctx); + if (!zr_widget(&bounds, ctx)) + return; + + item_padding = zr_get_property(ctx, ZR_PROPERTY_ITEM_PADDING); + bounds.x += item_padding.x; + bounds.y += item_padding.y; + bounds.w -= 2 * item_padding.x; + bounds.h -= 2 * item_padding.y; + + label.h = bounds.h; + label.w = bounds.w / 2.0f; + label.x = bounds.x + item_padding.x; + label.y = bounds.y + label.h/2.0f - (float)ctx->style.font.height/2.0f; + + content.x = bounds.x + bounds.w/2.0f; + content.y = bounds.y; + content.w = bounds.w / 2.0f; + content.h = bounds.h; + + if (active) zr_draw_rect(out, bounds, 0, zr_rgba(220, 220, 220, 135)); + text_len = strlen(title); + col = (active) ? zr_rgba(0, 0, 0, 255): zr_rgba(220,220,220,220); + zr_draw_text(out, label, title, text_len, &ctx->style.font, zr_rgba(0,0,0,0), col); + + if (zr_input_is_key_pressed(&ctx->input, ZR_KEY_LEFT) && active) + *value = MAX(0, *value - 10); + if (zr_input_is_key_pressed(&ctx->input, ZR_KEY_RIGHT) && active) + *value = MIN(*value + 10, max); + + tri.h = ctx->style.font.height - 2 * item_padding.y; + tri.w = tri.h/2.0f; + tri.x = content.x + item_padding.x; + tri.y = content.y + content.h/2 - tri.h/2.0f; + + bar.x = tri.x + 4 * item_padding.x + tri.w; + bar.h = tri.h / 4.0f; + bar.y = tri.y + tri.h/2.0f - bar.h/2.0f; + + if (*value > 0) { + zr_triangle_from_direction(result, tri, 0, 0, ZR_LEFT); + zr_draw_triangle(out, result[0].x, result[0].y, result[1].x, result[1].y, + result[2].x, result[2].y, (active) ? zr_rgba(0, 0, 0, 255): + zr_rgba(100, 100, 100, 150)); + } + + tri.x = content.x + (content.w - item_padding.x) - tri.w; + bar.w = (tri.x - bar.x) - 4 * item_padding.x; + + if (*value < max) + { + zr_triangle_from_direction(result, tri, 0, 0, ZR_RIGHT); + zr_draw_triangle(out, result[0].x, result[0].y, result[1].x, result[1].y, + result[2].x, result[2].y, (active) ? zr_rgba(0, 0, 0, 255): + zr_rgba(100, 100, 100, 150)); + } + + bar.w = (bar.w - tri.h/2.0f); + if (active) + { + zr_draw_rect(out, bar, 0, zr_rgba(0, 0, 0, 135)); + bar.w = bar.w * prog_scale; + bar.y = tri.y; bar.x = bar.x + bar.w; bar.w = tri.h; bar.h = tri.h; + zr_draw_circle(out, bar, zr_rgba(220, 220, 220, 255)); + } + else + { + zr_draw_rect(out, bar, 0, zr_rgba(220, 220, 220, 135)); + bar.w = bar.w * prog_scale; + bar.y = tri.y; bar.x = bar.x + bar.w; bar.w = tri.h; bar.h = tri.h; + zr_draw_circle(out, bar, zr_rgba(190, 190, 190, 255)); + } +} + bool zr_checkbox_bool(struct zr_context* cx, const char* text, bool *active) { int x = *active; @@ -447,7 +669,6 @@ void zrmenu_wnd_main(zrmenu_handle_t *zr) } zr_layout_row_push(ctx, 60); zr_menubar_end(ctx); - } @@ -564,6 +785,22 @@ void zrmenu_wnd_wizard(zrmenu_handle_t *zr) if (zr_button_text(ctx, "Next", ZR_BUTTON_DEFAULT)) panel++; break; + case 2: + if (zr_input_is_key_pressed(&ctx->input, ZR_KEY_UP)) + active = MAX(0, active-1); + if (zr_input_is_key_pressed(&ctx->input, ZR_KEY_DOWN)) + active = MIN(active+1, WIDGET_MAX-1); + zr_layout_row_dynamic(ctx, 50, 1); + ui_selector(ctx, "Windowed Mode", &window_mode, display, LEN(display), WINDOW_MODE == active); + ui_selector(ctx, "Model Detail", &model_detail, detail, LEN(detail), MODEL_DETAIL == active); + ui_selector(ctx, "Textures", &texture_detail, detail, LEN(detail), TEXTURES == active); + ui_selector(ctx, "Shadows", &shadow_detail, detail, LEN(detail), SHADOWS == active); + ui_selector(ctx, "Lighting", &lighning_detail, detail, LEN(detail), LIGHTNING == active); + ui_selector(ctx, "Effects", &effects_detail, detail, LEN(detail), EFFECTS == active); + ui_selector(ctx, "Console", &show_console, state, LEN(state), CONSOLE == active); + ui_slider(ctx, "Brightness", &brightness, 100, BRIGHTNESS == active); + ui_slider(ctx, "Volume", &volume, 100, VOLUME == active); + break; default: zr_layout_row_begin(ctx, ZR_DYNAMIC, height * 0.80f, 2); zr_layout_row_push(ctx, 0.15f); diff --git a/menu/drivers/zr_menu.h b/menu/drivers/zr_menu.h index 94da59819e..1fb3c0f09c 100644 --- a/menu/drivers/zr_menu.h +++ b/menu/drivers/zr_menu.h @@ -17,6 +17,7 @@ #include "zr_common.h" #include "../menu_display.h" +#include "../menu_input.h" enum { @@ -62,6 +63,7 @@ typedef struct zrmenu_handle void *memory; struct zr_context ctx; struct zr_memory_status status; + enum menu_action action; /* window control variables */ struct zr_vec2 size; @@ -93,3 +95,6 @@ void zrmenu_wnd_shader_parameters(zrmenu_handle_t *zr); void zrmenu_wnd_control(zrmenu_handle_t *zr); void zrmenu_wnd_test(zrmenu_handle_t *zr); void zrmenu_wnd_main(zrmenu_handle_t *zr); + +static void ui_slider(struct zr_context *ctx, const char *title, int *value, int max, int active); +static int ui_selector(struct zr_context *ctx, const char *title, int *selected, const char *items[], int max, int active); \ No newline at end of file