mirror of
https://github.com/libretro/RetroArch
synced 2025-01-30 21:32:45 +00:00
Merge pull request #11406 from natinusala/ozone-cursor-wiggle
ozone: add cursor wiggle animation
This commit is contained in:
commit
1496fda9bf
@ -3,7 +3,7 @@
|
|||||||
* Copyright (C) 2014-2017 - Jean-André Santoni
|
* Copyright (C) 2014-2017 - Jean-André Santoni
|
||||||
* Copyright (C) 2016-2019 - Brad Parker
|
* Copyright (C) 2016-2019 - Brad Parker
|
||||||
* Copyright (C) 2018 - Alfredo Monclús
|
* Copyright (C) 2018 - Alfredo Monclús
|
||||||
* Copyright (C) 2018 - natinusala
|
* Copyright (C) 2018-2020 - natinusala
|
||||||
* Copyright (C) 2019 - Patrick Scheurenbrand
|
* Copyright (C) 2019 - Patrick Scheurenbrand
|
||||||
*
|
*
|
||||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||||
@ -303,13 +303,13 @@ static enum menu_action ozone_parse_menu_entry_action(
|
|||||||
{
|
{
|
||||||
/* If cursor is active, ensure we target
|
/* If cursor is active, ensure we target
|
||||||
* an on screen category */
|
* an on screen category */
|
||||||
size_t selection = (ozone->cursor_mode)
|
size_t selection = (ozone->cursor_mode)
|
||||||
? ozone_get_onscreen_category_selection(ozone)
|
? ozone_get_onscreen_category_selection(ozone)
|
||||||
: ozone->categories_selection_ptr;
|
: ozone->categories_selection_ptr;
|
||||||
|
|
||||||
new_selection = (int)(selection + 1);
|
new_selection = (int)(selection + 1);
|
||||||
|
|
||||||
if (new_selection >= (int)(ozone->system_tab_end
|
if (new_selection >= (int)(ozone->system_tab_end
|
||||||
+ horizontal_list_size + 1))
|
+ horizontal_list_size + 1))
|
||||||
new_selection = 0;
|
new_selection = 0;
|
||||||
|
|
||||||
@ -360,6 +360,8 @@ static enum menu_action ozone_parse_menu_entry_action(
|
|||||||
if (ozone->cursor_in_sidebar)
|
if (ozone->cursor_in_sidebar)
|
||||||
{
|
{
|
||||||
new_action = MENU_ACTION_ACCESSIBILITY_SPEAK_TITLE;
|
new_action = MENU_ACTION_ACCESSIBILITY_SPEAK_TITLE;
|
||||||
|
ozone_start_cursor_wiggle(ozone, MENU_ACTION_LEFT);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (ozone->depth > 1)
|
else if (ozone->depth > 1)
|
||||||
@ -374,7 +376,11 @@ static enum menu_action ozone_parse_menu_entry_action(
|
|||||||
if (!ozone->cursor_in_sidebar)
|
if (!ozone->cursor_in_sidebar)
|
||||||
{
|
{
|
||||||
if (ozone->depth == 1)
|
if (ozone->depth == 1)
|
||||||
|
{
|
||||||
new_action = MENU_ACTION_NOOP;
|
new_action = MENU_ACTION_NOOP;
|
||||||
|
ozone_start_cursor_wiggle(ozone, MENU_ACTION_RIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -607,6 +613,8 @@ static void *ozone_init(void **userdata, bool video_is_threaded)
|
|||||||
|
|
||||||
ozone->num_search_terms_old = 0;
|
ozone->num_search_terms_old = 0;
|
||||||
|
|
||||||
|
ozone->cursor_wiggle_state.wiggling = false;
|
||||||
|
|
||||||
ozone->thumbnail_path_data = gfx_thumbnail_path_init();
|
ozone->thumbnail_path_data = gfx_thumbnail_path_init();
|
||||||
if (!ozone->thumbnail_path_data)
|
if (!ozone->thumbnail_path_data)
|
||||||
goto error;
|
goto error;
|
||||||
@ -1175,6 +1183,8 @@ static void ozone_context_reset(void *data, bool is_threaded)
|
|||||||
ozone->messagebox_state = false;
|
ozone->messagebox_state = false;
|
||||||
ozone->messagebox_state_old = false;
|
ozone->messagebox_state_old = false;
|
||||||
|
|
||||||
|
ozone->cursor_wiggle_state.wiggling = false;
|
||||||
|
|
||||||
/* Animations */
|
/* Animations */
|
||||||
ozone->animations.cursor_alpha = 1.0f;
|
ozone->animations.cursor_alpha = 1.0f;
|
||||||
ozone->animations.scroll_y = 0.0f;
|
ozone->animations.scroll_y = 0.0f;
|
||||||
@ -3957,6 +3967,76 @@ void ozone_toggle_metadata_override(ozone_handle_t *ozone)
|
|||||||
gfx_animation_push(&animation_entry);
|
gfx_animation_push(&animation_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ozone_start_cursor_wiggle(ozone_handle_t* ozone, enum menu_action direction)
|
||||||
|
{
|
||||||
|
/* Don't start another wiggle animation on top of another */
|
||||||
|
if (!ozone || ozone->cursor_wiggle_state.wiggling)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Don't allow wiggling in invalid directions */
|
||||||
|
if (!(
|
||||||
|
direction == MENU_ACTION_UP ||
|
||||||
|
direction == MENU_ACTION_DOWN ||
|
||||||
|
direction == MENU_ACTION_LEFT ||
|
||||||
|
direction == MENU_ACTION_RIGHT
|
||||||
|
))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Start wiggling */
|
||||||
|
ozone->cursor_wiggle_state.start_time = menu_driver_get_current_time() / 1000;
|
||||||
|
ozone->cursor_wiggle_state.direction = direction;
|
||||||
|
ozone->cursor_wiggle_state.amplitude = rand() % 15 + 10;
|
||||||
|
ozone->cursor_wiggle_state.wiggling = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ozone_wiggle(ozone_handle_t* ozone, float t)
|
||||||
|
{
|
||||||
|
float a = ozone->cursor_wiggle_state.amplitude;
|
||||||
|
|
||||||
|
/* Damped sine wave */
|
||||||
|
float w = 0.8f; /* period */
|
||||||
|
float c = 0.35f; /* damp factor */
|
||||||
|
return roundf(a * exp(-(c * t)) * sin(w * t));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ozone_apply_cursor_wiggle_offset(ozone_handle_t* ozone, int* x, size_t* y)
|
||||||
|
{
|
||||||
|
retro_time_t cur_time;
|
||||||
|
retro_time_t t;
|
||||||
|
|
||||||
|
/* Don't do anything if we are not wiggling */
|
||||||
|
if (!ozone || !ozone->cursor_wiggle_state.wiggling)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cur_time = menu_driver_get_current_time() / 1000;
|
||||||
|
t = (cur_time - ozone->cursor_wiggle_state.start_time) / 10;
|
||||||
|
|
||||||
|
/* Has the animation ended? */
|
||||||
|
if (t >= OZONE_WIGGLE_DURATION)
|
||||||
|
{
|
||||||
|
ozone->cursor_wiggle_state.wiggling = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Change cursor position depending on wiggle direction */
|
||||||
|
switch (ozone->cursor_wiggle_state.direction)
|
||||||
|
{
|
||||||
|
case MENU_ACTION_RIGHT:
|
||||||
|
*x += ozone_wiggle(ozone, t);
|
||||||
|
break;
|
||||||
|
case MENU_ACTION_LEFT:
|
||||||
|
*x -= ozone_wiggle(ozone, t);
|
||||||
|
break;
|
||||||
|
case MENU_ACTION_DOWN:
|
||||||
|
*y += ozone_wiggle(ozone, t);
|
||||||
|
break;
|
||||||
|
case MENU_ACTION_UP:
|
||||||
|
*y -= ozone_wiggle(ozone, t);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
menu_ctx_driver_t menu_ctx_ozone = {
|
menu_ctx_driver_t menu_ctx_ozone = {
|
||||||
NULL, /* set_texture */
|
NULL, /* set_texture */
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* RetroArch - A frontend for libretro.
|
/* RetroArch - A frontend for libretro.
|
||||||
* Copyright (C) 2018 - natinusala
|
* Copyright (C) 2018-2020 - natinusala
|
||||||
* Copyright (C) 2019 - Patrick Scheurenbrand
|
* Copyright (C) 2019 - Patrick Scheurenbrand
|
||||||
*
|
*
|
||||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||||
@ -295,6 +295,14 @@ struct ozone_handle
|
|||||||
bool is_file_list;
|
bool is_file_list;
|
||||||
bool is_quick_menu;
|
bool is_quick_menu;
|
||||||
bool first_frame;
|
bool first_frame;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
retro_time_t start_time;
|
||||||
|
float amplitude;
|
||||||
|
enum menu_action direction;
|
||||||
|
bool wiggling;
|
||||||
|
} cursor_wiggle_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* If you change this struct, also
|
/* If you change this struct, also
|
||||||
@ -394,7 +402,6 @@ static INLINE unsigned ozone_count_lines(const char *str)
|
|||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ozone_update_content_metadata(ozone_handle_t *ozone);
|
void ozone_update_content_metadata(ozone_handle_t *ozone);
|
||||||
|
|
||||||
void ozone_font_flush(
|
void ozone_font_flush(
|
||||||
@ -403,4 +410,18 @@ void ozone_font_flush(
|
|||||||
|
|
||||||
void ozone_toggle_metadata_override(ozone_handle_t *ozone);
|
void ozone_toggle_metadata_override(ozone_handle_t *ozone);
|
||||||
|
|
||||||
|
#define OZONE_WIGGLE_DURATION 15
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the cursor wiggle animation in the given direction
|
||||||
|
* Use ozone_get_cursor_wiggle_offset to read the animation
|
||||||
|
* once it has started
|
||||||
|
*/
|
||||||
|
void ozone_start_cursor_wiggle(ozone_handle_t* ozone, enum menu_action direction);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes x and y to the current offset of the cursor wiggle animation
|
||||||
|
*/
|
||||||
|
void ozone_apply_cursor_wiggle_offset(ozone_handle_t* ozone, int* x, size_t* y);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Copyright (C) 2014-2017 - Jean-André Santoni
|
* Copyright (C) 2014-2017 - Jean-André Santoni
|
||||||
* Copyright (C) 2016-2019 - Brad Parker
|
* Copyright (C) 2016-2019 - Brad Parker
|
||||||
* Copyright (C) 2018 - Alfredo Monclús
|
* Copyright (C) 2018 - Alfredo Monclús
|
||||||
* Copyright (C) 2018 - natinusala
|
* Copyright (C) 2018-2020 - natinusala
|
||||||
*
|
*
|
||||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||||
* of the GNU General Public License as published by the Free Software Found-
|
* of the GNU General Public License as published by the Free Software Found-
|
||||||
@ -260,16 +260,24 @@ void ozone_draw_cursor(
|
|||||||
unsigned width, unsigned height,
|
unsigned width, unsigned height,
|
||||||
size_t y, float alpha)
|
size_t y, float alpha)
|
||||||
{
|
{
|
||||||
|
int new_x = x_offset;
|
||||||
|
size_t new_y = y;
|
||||||
|
|
||||||
|
/* Apply wiggle animation if needed */
|
||||||
|
if (ozone->cursor_wiggle_state.wiggling)
|
||||||
|
ozone_apply_cursor_wiggle_offset(ozone, &new_x, &new_y);
|
||||||
|
|
||||||
|
/* Draw the cursor */
|
||||||
if (ozone->has_all_assets)
|
if (ozone->has_all_assets)
|
||||||
ozone_draw_cursor_slice(ozone, userdata,
|
ozone_draw_cursor_slice(ozone, userdata,
|
||||||
video_width, video_height,
|
video_width, video_height,
|
||||||
x_offset, width, height, y, alpha);
|
new_x, width, height, new_y, alpha);
|
||||||
else
|
else
|
||||||
ozone_draw_cursor_fallback(ozone,
|
ozone_draw_cursor_fallback(ozone,
|
||||||
userdata,
|
userdata,
|
||||||
video_width,
|
video_width,
|
||||||
video_height,
|
video_height,
|
||||||
x_offset, width, height, y, alpha);
|
new_x, width, height, new_y, alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ozone_draw_icon(
|
void ozone_draw_icon(
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Copyright (C) 2014-2017 - Jean-André Santoni
|
* Copyright (C) 2014-2017 - Jean-André Santoni
|
||||||
* Copyright (C) 2016-2019 - Brad Parker
|
* Copyright (C) 2016-2019 - Brad Parker
|
||||||
* Copyright (C) 2018 - Alfredo Monclús
|
* Copyright (C) 2018 - Alfredo Monclús
|
||||||
* Copyright (C) 2018 - natinusala
|
* Copyright (C) 2018-2020 - natinusala
|
||||||
* Copyright (C) 2019 - Patrick Scheurenbrand
|
* Copyright (C) 2019 - Patrick Scheurenbrand
|
||||||
*
|
*
|
||||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||||
@ -128,19 +128,19 @@ static void ozone_sidebar_collapse_end(void *userdata)
|
|||||||
static float ozone_sidebar_get_scroll_y(
|
static float ozone_sidebar_get_scroll_y(
|
||||||
ozone_handle_t *ozone, unsigned video_height)
|
ozone_handle_t *ozone, unsigned video_height)
|
||||||
{
|
{
|
||||||
float scroll_y =
|
float scroll_y =
|
||||||
ozone->animations.scroll_y_sidebar;
|
ozone->animations.scroll_y_sidebar;
|
||||||
float selected_position_y =
|
float selected_position_y =
|
||||||
ozone_get_selected_sidebar_y_position(ozone);
|
ozone_get_selected_sidebar_y_position(ozone);
|
||||||
float current_selection_middle_onscreen =
|
float current_selection_middle_onscreen =
|
||||||
ozone->dimensions.header_height
|
ozone->dimensions.header_height
|
||||||
+ ozone->dimensions.spacer_1px
|
+ ozone->dimensions.spacer_1px
|
||||||
+ ozone->animations.scroll_y_sidebar
|
+ ozone->animations.scroll_y_sidebar
|
||||||
+ selected_position_y
|
+ selected_position_y
|
||||||
+ ozone->dimensions.sidebar_entry_height / 2.0f;
|
+ ozone->dimensions.sidebar_entry_height / 2.0f;
|
||||||
float bottom_boundary =
|
float bottom_boundary =
|
||||||
(float)video_height
|
(float)video_height
|
||||||
- (ozone->dimensions.header_height + ozone->dimensions.spacer_1px)
|
- (ozone->dimensions.header_height + ozone->dimensions.spacer_1px)
|
||||||
- ozone->dimensions.footer_height;
|
- ozone->dimensions.footer_height;
|
||||||
float entries_middle = (float)video_height / 2.0f;
|
float entries_middle = (float)video_height / 2.0f;
|
||||||
float entries_height = ozone_get_sidebar_height(ozone);
|
float entries_height = ozone_get_sidebar_height(ozone);
|
||||||
@ -171,7 +171,7 @@ void ozone_draw_sidebar(
|
|||||||
unsigned i, sidebar_height;
|
unsigned i, sidebar_height;
|
||||||
gfx_animation_ctx_ticker_t ticker;
|
gfx_animation_ctx_ticker_t ticker;
|
||||||
gfx_animation_ctx_ticker_smooth_t ticker_smooth;
|
gfx_animation_ctx_ticker_smooth_t ticker_smooth;
|
||||||
static const char* const
|
static const char* const
|
||||||
ticker_spacer = OZONE_TICKER_SPACER;
|
ticker_spacer = OZONE_TICKER_SPACER;
|
||||||
unsigned ticker_x_offset = 0;
|
unsigned ticker_x_offset = 0;
|
||||||
settings_t *settings = config_get_ptr();
|
settings_t *settings = config_get_ptr();
|
||||||
@ -305,10 +305,10 @@ void ozone_draw_sidebar(
|
|||||||
video_width,
|
video_width,
|
||||||
video_height,
|
video_height,
|
||||||
ozone->sidebar_offset + ozone->dimensions.sidebar_padding_horizontal + ozone->dimensions.spacer_3px,
|
ozone->sidebar_offset + ozone->dimensions.sidebar_padding_horizontal + ozone->dimensions.spacer_3px,
|
||||||
entry_width - ozone->dimensions.spacer_5px,
|
entry_width - ozone->dimensions.spacer_5px,
|
||||||
ozone->dimensions.sidebar_entry_height + ozone->dimensions.spacer_1px,
|
ozone->dimensions.sidebar_entry_height + ozone->dimensions.spacer_1px,
|
||||||
selection_old_y + ozone->animations.scroll_y_sidebar,
|
selection_old_y + ozone->animations.scroll_y_sidebar,
|
||||||
1-ozone->animations.cursor_alpha);
|
1-ozone->animations.cursor_alpha);
|
||||||
|
|
||||||
/* Menu tabs */
|
/* Menu tabs */
|
||||||
y = ozone->dimensions.header_height + ozone->dimensions.spacer_1px + ozone->dimensions.sidebar_padding_vertical;
|
y = ozone->dimensions.header_height + ozone->dimensions.spacer_1px + ozone->dimensions.sidebar_padding_vertical;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user