diff --git a/menu/cbs/menu_cbs_get_value.c b/menu/cbs/menu_cbs_get_value.c index 02394a4721..2616d4ce73 100644 --- a/menu/cbs/menu_cbs_get_value.c +++ b/menu/cbs/menu_cbs_get_value.c @@ -451,16 +451,13 @@ static void general_disp_set_label_perf_counters( const char *path, unsigned *w ) { - menu_animation_t *anim = menu_animation_get_ptr(); - *s = '\0'; *w = 19; strlcpy(s2, path, len2); menu_action_setting_disp_set_label_perf_counters_common( counters, offset, s, len); - - menu_animation_set_active(anim); + menu_animation_set_active(); } static void menu_action_setting_disp_set_label_perf_counters( diff --git a/menu/drivers/glui.c b/menu/drivers/glui.c index e5e336511b..064a332e9b 100644 --- a/menu/drivers/glui.c +++ b/menu/drivers/glui.c @@ -222,8 +222,8 @@ static void glui_render(void) glui = (glui_handle_t*)menu->userdata; - menu_animation_update(disp->animation, - menu_animation_get_delta_time(disp->animation) / IDEAL_DT); + menu_animation_update( + menu_animation_get_delta_time() / IDEAL_DT); menu_display_ctl(MENU_DISPLAY_CTL_SET_WIDTH, &width); menu_display_ctl(MENU_DISPLAY_CTL_SET_HEIGHT, &height); @@ -379,7 +379,6 @@ static void glui_frame(void) const struct font_renderer *font_driver = NULL; driver_t *driver = driver_get_ptr(); menu_handle_t *menu = menu_driver_get_ptr(); - menu_animation_t *anim = menu_animation_get_ptr(); settings_t *settings = config_get_ptr(); uint64_t *frame_count = video_driver_get_frame_count(); const uint32_t normal_color = FONT_COLOR_ARGB_TO_RGBA( @@ -453,7 +452,7 @@ static void glui_frame(void) width, height, &highlight_bg[0]); - menu_animation_set_active(anim); + menu_animation_set_active(); glui_render_quad(gl, 0, 0, width, header_height, @@ -741,7 +740,7 @@ static void glui_navigation_set(bool scroll) if (!menu || !disp || !scroll) return; - menu_animation_push(disp->animation, 10, scroll_pos, + menu_animation_push(10, scroll_pos, &menu->scroll_y, EASING_IN_OUT_QUAD, -1, NULL); } diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index c17d3ec4b6..87e52484c9 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -411,7 +411,6 @@ static void rgui_render(void) menu_display_t *disp = menu_display_get_ptr(); driver_t *driver = driver_get_ptr(); settings_t *settings = config_get_ptr(); - menu_animation_t *anim = menu_animation_get_ptr(); uint64_t *frame_count = video_driver_get_frame_count(); rgui_t *rgui = NULL; @@ -455,7 +454,7 @@ static void rgui_render(void) menu_display_ctl(MENU_DISPLAY_CTL_SET_FRAMEBUFFER_DIRTY_FLAG, NULL); - menu_animation_clear_active(anim); + menu_animation_clear_active(); rgui->force_redraw = false; diff --git a/menu/drivers/rmenu.c b/menu/drivers/rmenu.c index 2d5c01b532..ae4f13916c 100644 --- a/menu/drivers/rmenu.c +++ b/menu/drivers/rmenu.c @@ -130,7 +130,6 @@ static void rmenu_render(void) char title_msg[64] = {0}; menu_handle_t *menu = menu_driver_get_ptr(); menu_display_t *disp = menu_display_get_ptr(); - menu_animation_t *anim = menu_animation_get_ptr(); menu_list_t *menu_list = menu_list_get_ptr(); uint64_t *frame_count = video_driver_get_frame_count(); size_t entries_end = menu_entries_get_end(); @@ -152,7 +151,7 @@ static void rmenu_render(void) return; menu_display_fb_unset_dirty(); - menu_animation_clear_active(anim); + menu_animation_clear_active(); if (!menu_list->selection_buf) return; diff --git a/menu/drivers/rmenu_xui.cpp b/menu/drivers/rmenu_xui.cpp index 97099bc905..ca7b57c245 100644 --- a/menu/drivers/rmenu_xui.cpp +++ b/menu/drivers/rmenu_xui.cpp @@ -537,7 +537,6 @@ static void rmenu_xui_render(void) const char *label = NULL; unsigned menu_type = 0; menu_handle_t *menu = menu_driver_get_ptr(); - menu_animation_t *anim = menu_animation_get_ptr(); menu_display_t *disp = menu_display_get_ptr(); uint64_t frame_count = video_driver_get_frame_count(); @@ -553,7 +552,7 @@ static void rmenu_xui_render(void) return; menu_display_fb_unset_dirty(); - menu_animation_clear_active(anim); + menu_animation_clear_active(); rmenu_xui_render_background(); diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index 82b29adacf..ab0043a8b0 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -590,7 +590,7 @@ static void xmb_selection_pointer_changed(bool allow_animations) video_driver_get_size(NULL, &height); - menu_animation_kill_by_tag(disp->animation, tag); + menu_animation_kill_by_tag(tag); menu_entries_set_start(0); skip = 0; @@ -628,14 +628,10 @@ static void xmb_selection_pointer_changed(bool allow_animations) } else { - menu_animation_push(disp->animation, - XMB_DELAY, ia, &node->alpha, EASING_IN_OUT_QUAD, tag, NULL); - menu_animation_push(disp->animation, - XMB_DELAY, ia, &node->label_alpha, EASING_IN_OUT_QUAD, tag, NULL); - menu_animation_push(disp->animation, - XMB_DELAY, iz, &node->zoom, EASING_IN_OUT_QUAD, tag, NULL); - menu_animation_push(disp->animation, - XMB_DELAY, iy, &node->y, EASING_IN_OUT_QUAD, tag, NULL); + menu_animation_push(XMB_DELAY, ia, &node->alpha, EASING_IN_OUT_QUAD, tag, NULL); + menu_animation_push(XMB_DELAY, ia, &node->label_alpha, EASING_IN_OUT_QUAD, tag, NULL); + menu_animation_push(XMB_DELAY, iz, &node->zoom, EASING_IN_OUT_QUAD, tag, NULL); + menu_animation_push(XMB_DELAY, iy, &node->y, EASING_IN_OUT_QUAD, tag, NULL); } } @@ -681,11 +677,11 @@ static void xmb_list_open_old(xmb_handle_t *xmb, } else { - menu_animation_push(disp->animation, + menu_animation_push( XMB_DELAY, ia, &node->alpha, EASING_IN_OUT_QUAD, -1, NULL); - menu_animation_push(disp->animation, + menu_animation_push( XMB_DELAY, 0, &node->label_alpha, EASING_IN_OUT_QUAD, -1, NULL); - menu_animation_push(disp->animation, + menu_animation_push( XMB_DELAY, xmb->icon.size * dir * -2, &node->x, EASING_IN_OUT_QUAD, -1, NULL); } @@ -738,11 +734,11 @@ static void xmb_list_open_new(xmb_handle_t *xmb, } else { - menu_animation_push(disp->animation, + menu_animation_push( XMB_DELAY, ia, &node->alpha, EASING_IN_OUT_QUAD, -1, NULL); - menu_animation_push(disp->animation, + menu_animation_push( XMB_DELAY, ia, &node->label_alpha, EASING_IN_OUT_QUAD, -1, NULL); - menu_animation_push(disp->animation, + menu_animation_push( XMB_DELAY, 0, &node->x, EASING_IN_OUT_QUAD, -1, NULL); } } @@ -784,15 +780,11 @@ static xmb_node_t* xmb_get_userdata_from_horizontal_list( static void xmb_push_animations(xmb_node_t *node, float ia, float ix) { - menu_display_t *disp = menu_display_get_ptr(); - if (!disp) - return; - - menu_animation_push(disp->animation, + menu_animation_push( XMB_DELAY, ia, &node->alpha, EASING_IN_OUT_QUAD, -1, NULL); - menu_animation_push(disp->animation, + menu_animation_push( XMB_DELAY, ia, &node->label_alpha, EASING_IN_OUT_QUAD, -1, NULL); - menu_animation_push(disp->animation, + menu_animation_push( XMB_DELAY, ix, &node->x, EASING_IN_OUT_QUAD, -1, NULL); } @@ -907,9 +899,9 @@ static void xmb_list_switch_horizontal_list(xmb_handle_t *xmb, menu_handle_t *me iz = xmb->categories.active.zoom; } - menu_animation_push(menu->display.animation, + menu_animation_push( XMB_DELAY, ia, &node->alpha, EASING_IN_OUT_QUAD, -1, NULL); - menu_animation_push(menu->display.animation, + menu_animation_push( XMB_DELAY, iz, &node->zoom, EASING_IN_OUT_QUAD, -1, NULL); } } @@ -935,7 +927,7 @@ static void xmb_list_switch(xmb_handle_t *xmb) xmb_list_switch_horizontal_list(xmb, menu); - menu_animation_push(disp->animation, XMB_DELAY, + menu_animation_push(XMB_DELAY, xmb->icon.spacing.horizontal * -(float)xmb->categories.selection_ptr, &xmb->categories.x_pos, EASING_IN_OUT_QUAD, -1, NULL); @@ -973,7 +965,7 @@ static void xmb_list_open_horizontal_list(xmb_handle_t *xmb, menu_handle_t *menu else if (xmb->depth <= 1) ia = xmb->categories.passive.alpha; - menu_animation_push(menu->display.animation, XMB_DELAY, ia, + menu_animation_push(XMB_DELAY, ia, &node->alpha, EASING_IN_OUT_QUAD, -1, NULL); } } @@ -1051,18 +1043,18 @@ static void xmb_list_open(xmb_handle_t *xmb) switch (xmb->depth) { case 1: - menu_animation_push(disp->animation, + menu_animation_push( XMB_DELAY, xmb->icon.size * -(xmb->depth*2-2), &xmb->x, EASING_IN_OUT_QUAD, -1, NULL); - menu_animation_push(disp->animation, + menu_animation_push( XMB_DELAY, 0, &xmb->textures.arrow.alpha, EASING_IN_OUT_QUAD, -1, NULL); break; case 2: - menu_animation_push(disp->animation, + menu_animation_push( XMB_DELAY, xmb->icon.size * -(xmb->depth*2-2), &xmb->x, EASING_IN_OUT_QUAD, -1, NULL); - menu_animation_push(disp->animation, + menu_animation_push( XMB_DELAY, 1, &xmb->textures.arrow.alpha, EASING_IN_OUT_QUAD, -1, NULL); break; @@ -1414,7 +1406,6 @@ static void xmb_render(void) settings_t *settings = config_get_ptr(); menu_handle_t *menu = menu_driver_get_ptr(); menu_display_t *disp = menu_display_get_ptr(); - menu_animation_t *anim = menu_animation_get_ptr(); menu_list_t *menu_list = menu_list_get_ptr(); if (!menu) @@ -1425,7 +1416,7 @@ static void xmb_render(void) if (!xmb) return; - menu_animation_update(disp->animation, menu_animation_get_delta_time(disp->animation) / IDEAL_DT); + menu_animation_update(menu_animation_get_delta_time() / IDEAL_DT); video_driver_get_size(NULL, &height); @@ -1460,7 +1451,7 @@ static void xmb_render(void) if (menu_entries_get_start() >= end) menu_entries_set_start(0); - menu_animation_clear_active(anim); + menu_animation_clear_active(); } static void xmb_frame_horizontal_list(xmb_handle_t *xmb, @@ -2322,7 +2313,7 @@ static void xmb_list_clear(file_list_t *list) subjects[3] = &node->x; subjects[4] = &node->y; - menu_animation_kill_by_subject(disp->animation, 5, subjects); + menu_animation_kill_by_subject(5, subjects); file_list_free_userdata(list, i); } @@ -2346,7 +2337,7 @@ static void xmb_list_deep_copy(menu_handle_t *menu, const file_list_t *src, file subjects[3] = &node->x; subjects[4] = &node->y; - menu_animation_kill_by_subject(menu->display.animation, 5, subjects); + menu_animation_kill_by_subject(5, subjects); } file_list_free_userdata(dst, i); @@ -2508,7 +2499,7 @@ static void xmb_toggle(bool menu_on) return; } - menu_animation_push(disp->animation, XMB_DELAY, 1.0f, + menu_animation_push(XMB_DELAY, 1.0f, &xmb->alpha, EASING_IN_OUT_QUAD, -1, NULL); xmb->prevent_populate = !menu_entries_needs_refresh(); diff --git a/menu/menu_animation.c b/menu/menu_animation.c index 0433ea2f25..a6dd53e8cf 100644 --- a/menu/menu_animation.c +++ b/menu/menu_animation.c @@ -51,12 +51,11 @@ struct menu_animation retro_time_t old_time; }; +static menu_animation_t menu_animation_state; + menu_animation_t *menu_animation_get_ptr(void) { - menu_display_t *disp = menu_display_get_ptr(); - if (!disp) - return NULL; - return disp->animation; + return &menu_animation_state; } /* from https://github.com/kikito/tween.lua/blob/master/tween.lua */ @@ -287,9 +286,10 @@ static float easing_out_in_bounce(float t, float b, float c, float d) return easing_in_bounce((t * 2) - d, b + c / 2, c / 2, d); } -void menu_animation_free(menu_animation_t *anim) +void menu_animation_free(void) { size_t i; + menu_animation_t *anim = menu_animation_get_ptr(); if (!anim) return; @@ -301,14 +301,15 @@ void menu_animation_free(menu_animation_t *anim) } free(anim->list); - free(anim); + + memset(&menu_animation_state, 0, sizeof(menu_animation_t)); } -void menu_animation_kill_by_subject(menu_animation_t *anim, - size_t count, const void *subjects) +void menu_animation_kill_by_subject(size_t count, const void *subjects) { unsigned i, j, killed = 0; float **sub = (float**)subjects; + menu_animation_t *anim = menu_animation_get_ptr(); for (i = 0; i < anim->size; ++i) { @@ -332,9 +333,10 @@ void menu_animation_kill_by_subject(menu_animation_t *anim, } } -void menu_animation_kill_by_tag(menu_animation_t *anim, int tag) +void menu_animation_kill_by_tag(int tag) { unsigned i; + menu_animation_t *anim = menu_animation_get_ptr(); if (tag == -1) return; @@ -352,9 +354,10 @@ void menu_animation_kill_by_tag(menu_animation_t *anim, int tag) } } -static void menu_animation_push_internal(menu_animation_t *anim, const struct tween *t) +static void menu_animation_push_internal(const struct tween *t) { struct tween *target = NULL; + menu_animation_t *anim = menu_animation_get_ptr(); if (anim->first_dead < anim->size && !anim->list[anim->first_dead].alive) target = &anim->list[anim->first_dead++]; @@ -373,13 +376,11 @@ static void menu_animation_push_internal(menu_animation_t *anim, const struct tw *target = *t; } -bool menu_animation_push(menu_animation_t *anim, - float duration, - float target_value, float* subject, - enum menu_animation_easing_type easing_enum, - int tag, tween_cb cb) +bool menu_animation_push(float duration, float target_value, float* subject, + enum menu_animation_easing_type easing_enum, int tag, tween_cb cb) { struct tween t; + menu_animation_t *anim = menu_animation_get_ptr(); if (!subject) return false; @@ -511,18 +512,17 @@ bool menu_animation_push(menu_animation_t *anim, if (!t.easing || t.duration == 0 || t.initial_value == t.target_value) return false; - menu_animation_push_internal(anim, &t); + menu_animation_push_internal(&t); return true; } -static int menu_animation_iterate( - menu_animation_t *anim, unsigned idx, - float dt, unsigned *active_tweens) +static int menu_animation_iterate(unsigned idx, float dt, unsigned *active_tweens) { - struct tween *tween = &anim->list[idx]; + menu_animation_t *anim = menu_animation_get_ptr(); + struct tween *tween = anim ? &anim->list[idx] : NULL; - if (!tween->alive) + if (!tween || !tween->alive) return -1; tween->running_since += dt; @@ -551,13 +551,14 @@ static int menu_animation_iterate( return 0; } -bool menu_animation_update(menu_animation_t *anim, float dt) +bool menu_animation_update(float dt) { unsigned i; unsigned active_tweens = 0; + menu_animation_t *anim = menu_animation_get_ptr(); for(i = 0; i < anim->size; i++) - menu_animation_iterate(anim, i, dt, &active_tweens); + menu_animation_iterate(i, dt, &active_tweens); if (!active_tweens) { @@ -647,7 +648,7 @@ void menu_animation_update_time(void) { static retro_time_t last_clock_update = 0; menu_display_t *disp = menu_display_get_ptr(); - menu_animation_t *anim = disp->animation; + menu_animation_t *anim = menu_animation_get_ptr(); settings_t *settings = config_get_ptr(); anim->cur_time = retro_get_time_usec(); @@ -667,37 +668,33 @@ void menu_animation_update_time(void) } } -void menu_animation_set_active(menu_animation_t *anim) +void menu_animation_set_active(void) { + menu_animation_t *anim = menu_animation_get_ptr(); if (!anim) return; anim->is_active = true; } -void menu_animation_clear_active(menu_animation_t *anim) +void menu_animation_clear_active(void) { + menu_animation_t *anim = menu_animation_get_ptr(); if (!anim) return; anim->is_active = false; } -float menu_animation_get_delta_time(menu_animation_t *anim) +float menu_animation_get_delta_time(void) { + menu_animation_t *anim = menu_animation_get_ptr(); if (!anim) return 0.0f; return anim->delta_time; } -menu_animation_t *menu_animation_init(void) -{ - menu_animation_t *anim = (menu_animation_t*)calloc(1, sizeof(*anim)); - if (!anim) - return NULL; - return (menu_animation_t*)anim; -} - -bool menu_animation_is_active(menu_animation_t *anim) +bool menu_animation_is_active(void) { + menu_animation_t *anim = menu_animation_get_ptr(); if (!anim) return false; return anim->is_active; diff --git a/menu/menu_animation.h b/menu/menu_animation.h index fec271c9ba..fb833fa7ec 100644 --- a/menu/menu_animation.h +++ b/menu/menu_animation.h @@ -81,24 +81,17 @@ enum menu_animation_easing_type EASING_OUT_IN_BOUNCE }; -void menu_animation_free(menu_animation_t *animation); +void menu_animation_free(void); -void menu_animation_kill_by_subject( - menu_animation_t *animation, - size_t count, - const void *subjects); +void menu_animation_kill_by_subject(size_t count, const void *subjects); -void menu_animation_kill_by_tag(menu_animation_t *anim, int tag); +void menu_animation_kill_by_tag(int tag); /* Use -1 for untagged */ -bool menu_animation_push( - menu_animation_t *animation, - float duration, - float target_value, float* subject, - enum menu_animation_easing_type easing_enum, - int tag, tween_cb cb); +bool menu_animation_push(float duration, float target_value, float* subject, + enum menu_animation_easing_type easing_enum, int tag, tween_cb cb); -bool menu_animation_update(menu_animation_t *animation, float dt); +bool menu_animation_update(float dt); /** * menu_animation_ticker_str: @@ -118,15 +111,13 @@ menu_animation_t *menu_animation_get_ptr(void); void menu_animation_update_time(void); -void menu_animation_set_active(menu_animation_t *anim); +void menu_animation_set_active(void); -void menu_animation_clear_active(menu_animation_t *anim); +void menu_animation_clear_active(void); -float menu_animation_get_delta_time(menu_animation_t *anim); +float menu_animation_get_delta_time(void); -bool menu_animation_is_active(menu_animation_t *anim); - -menu_animation_t *menu_animation_init(void); +bool menu_animation_is_active(void); #ifdef __cplusplus } diff --git a/menu/menu_display.c b/menu/menu_display.c index 84452fe67c..59b249ce17 100644 --- a/menu/menu_display.c +++ b/menu/menu_display.c @@ -97,8 +97,7 @@ void menu_display_free(void *data) msg_queue_free(disp->msg_queue); disp->msg_queue = NULL; - menu_animation_free(disp->animation); - disp->animation = NULL; + menu_animation_free(); menu_display_fb_free(&frame_buf_state); memset(&frame_buf_state, 0, sizeof(menu_framebuf_t)); @@ -110,11 +109,6 @@ bool menu_display_init(void *data) if (!menu) return false; - menu->display.animation = menu_animation_init(); - - if (!menu->display.animation) - return false; - rarch_assert(menu->display.msg_queue = msg_queue_new(8)); return true; @@ -300,12 +294,8 @@ bool menu_display_ctl(enum menu_display_ctl_state state, void *data) } return true; case MENU_DISPLAY_CTL_UPDATE_PENDING: - { - menu_animation_t *anim = menu_animation_get_ptr(); - - if (menu_animation_is_active(anim) || (frame_buf && frame_buf->dirty)) - return true; - } + if (menu_animation_is_active() || (frame_buf && frame_buf->dirty)) + return true; return false; case MENU_DISPLAY_CTL_SET_VIEWPORT: video_driver_get_size(&width, &height); diff --git a/menu/menu_display.h b/menu/menu_display.h index 078fef1d5d..3b093d096f 100644 --- a/menu/menu_display.h +++ b/menu/menu_display.h @@ -53,8 +53,6 @@ typedef struct menu_display { bool msg_force; - menu_animation_t *animation; - struct { void *buf; diff --git a/menu/menu_input.c b/menu/menu_input.c index 7add652161..aff7782e01 100644 --- a/menu/menu_input.c +++ b/menu/menu_input.c @@ -759,7 +759,6 @@ static int menu_input_mouse(unsigned *action) unsigned fb_width, fb_height; video_viewport_t vp; const struct retro_keybind *binds[MAX_USERS]; - menu_animation_t *anim = menu_animation_get_ptr(); menu_input_t *menu_input = menu_input_get_ptr(); settings_t *settings = config_get_ptr(); @@ -839,7 +838,7 @@ static int menu_input_mouse(unsigned *action) menu_input->mouse.scrollup || menu_input->mouse.scrolldown ) - menu_animation_set_active(anim); + menu_animation_set_active(); return 0; } @@ -850,7 +849,6 @@ static int menu_input_pointer(unsigned *action) int pointer_device, pointer_x, pointer_y; const struct retro_keybind *binds[MAX_USERS] = {NULL}; menu_input_t *menu_input = menu_input_get_ptr(); - menu_animation_t *anim = menu_animation_get_ptr(); settings_t *settings = config_get_ptr(); driver_t *driver = driver_get_ptr(); @@ -887,7 +885,7 @@ static int menu_input_pointer(unsigned *action) (menu_input->pointer.dy != 0) || (menu_input->pointer.dx != 0) ) - menu_animation_set_active(anim); + menu_animation_set_active(); return 0; } @@ -1126,7 +1124,7 @@ static int menu_input_pointer_post_iterate(menu_file_list_cbs_t *cbs, menu_input->pointer.old_x = pointer_x; menu_input->pointer.old_y = pointer_y; - s = menu_input->pointer.dy / menu_animation_get_delta_time(disp->animation) * 1000000.0; + s = menu_input->pointer.dy / menu_animation_get_delta_time() * 1000000.0; menu_input->pointer.accel = (menu_input->pointer.accel0 + menu_input->pointer.accel1 + s) / 3; menu_input->pointer.accel0 = menu_input->pointer.accel1; menu_input->pointer.accel1 = menu_input->pointer.accel; @@ -1273,7 +1271,7 @@ unsigned menu_input_frame(retro_input_t input, retro_input_t trigger_input) menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SCROLL_ACCEL, &new_scroll_accel); - menu_input->delay.count += menu_animation_get_delta_time(disp->animation) / IDEAL_DT; + menu_input->delay.count += menu_animation_get_delta_time() / IDEAL_DT; if (menu_input->keyboard.display) { diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 8a904673b8..e4d1d422c5 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -1183,12 +1183,9 @@ static void setting_get_string_representation_st_float_video_refresh_rate_auto(v if (video_monitor_fps_statistics(&video_refresh_rate, &deviation, &sample_points)) { - menu_animation_t *anim = menu_animation_get_ptr(); - snprintf(s, len, "%.3f Hz (%.1f%% dev, %u samples)", video_refresh_rate, 100.0 * deviation, sample_points); - - menu_animation_set_active(anim); + menu_animation_set_active(); } else strlcpy(s, menu_hash_to_str(MENU_VALUE_NOT_AVAILABLE), len);