mirror of
https://github.com/libretro/RetroArch
synced 2025-02-01 00:32:46 +00:00
Merge pull request #10203 from jdgleaver/line-ticker-fix
Fix smooth (vertical) line ticker scroll speed
This commit is contained in:
commit
f61621f753
@ -74,15 +74,16 @@ static const float ticker_pixel_period = (1.0f / 60.0f) * 1000.0f;
|
||||
|
||||
static const char ticker_spacer_default[] = TICKER_SPACER_DEFAULT;
|
||||
|
||||
static gfx_animation_t anim = {{0}};
|
||||
static retro_time_t cur_time = 0;
|
||||
static retro_time_t old_time = 0;
|
||||
static uint64_t ticker_idx = 0; /* updated every TICKER_SPEED us */
|
||||
static uint64_t ticker_slow_idx = 0; /* updated every TICKER_SLOW_SPEED us */
|
||||
static uint64_t ticker_pixel_idx = 0; /* updated every frame */
|
||||
static float delta_time = 0.0f;
|
||||
static bool animation_is_active = false;
|
||||
static bool ticker_is_active = false;
|
||||
static gfx_animation_t anim = {{0}};
|
||||
static retro_time_t cur_time = 0;
|
||||
static retro_time_t old_time = 0;
|
||||
static uint64_t ticker_idx = 0; /* updated every TICKER_SPEED us */
|
||||
static uint64_t ticker_slow_idx = 0; /* updated every TICKER_SLOW_SPEED us */
|
||||
static uint64_t ticker_pixel_idx = 0; /* updated every frame */
|
||||
static uint64_t ticker_pixel_line_idx = 0; /* updated every frame */
|
||||
static float delta_time = 0.0f;
|
||||
static bool animation_is_active = false;
|
||||
static bool ticker_is_active = false;
|
||||
|
||||
/* Forward declarations */
|
||||
static void gfx_animation_update_time_default(
|
||||
@ -1197,11 +1198,10 @@ bool gfx_animation_push(gfx_animation_ctx_entry_t *entry)
|
||||
}
|
||||
|
||||
static void gfx_animation_update_time_default(
|
||||
float *dst,
|
||||
float *ticker_pixel_increment,
|
||||
unsigned video_width, unsigned video_height)
|
||||
{
|
||||
if (video_width > 0)
|
||||
*(dst) *= ((float)video_width / 1920.0f);
|
||||
/* By default, this should be a NOOP */
|
||||
}
|
||||
|
||||
void gfx_animation_set_update_time_cb(update_time_cb cb)
|
||||
@ -1213,27 +1213,33 @@ void gfx_animation_unset_update_time_cb(void)
|
||||
{
|
||||
update_time_callback = gfx_animation_update_time_default;
|
||||
}
|
||||
|
||||
|
||||
static void gfx_animation_update_time(
|
||||
retro_time_t current_time,
|
||||
bool timedate_enable,
|
||||
unsigned video_width, unsigned video_height,
|
||||
float _ticker_speed)
|
||||
{
|
||||
static retro_time_t last_clock_update = 0;
|
||||
static retro_time_t last_ticker_update = 0;
|
||||
static retro_time_t
|
||||
last_ticker_slow_update = 0;
|
||||
static retro_time_t last_clock_update = 0;
|
||||
static retro_time_t last_ticker_update = 0;
|
||||
static retro_time_t last_ticker_slow_update = 0;
|
||||
|
||||
/* Horizontal smooth ticker parameters */
|
||||
static float ticker_pixel_accumulator = 0.0f;
|
||||
unsigned ticker_pixel_accumulator_uint = 0;
|
||||
float ticker_pixel_increment = 0.0f;
|
||||
|
||||
/* Vertical (line) smooth ticker parameters */
|
||||
static float ticker_pixel_line_accumulator = 0.0f;
|
||||
unsigned ticker_pixel_line_accumulator_uint = 0;
|
||||
float ticker_pixel_line_increment = 0.0f;
|
||||
|
||||
static float ticker_pixel_accumulator = 0.0f;
|
||||
unsigned ticker_pixel_accumulator_uint = 0;
|
||||
float ticker_pixel_increment = 0.0f;
|
||||
/* Adjust ticker speed */
|
||||
float speed_factor = (_ticker_speed > 0.0001f)
|
||||
? _ticker_speed : 1.0f;
|
||||
unsigned ticker_speed =
|
||||
float speed_factor =
|
||||
(_ticker_speed > 0.0001f) ? _ticker_speed : 1.0f;
|
||||
unsigned ticker_speed =
|
||||
(unsigned)(((float)TICKER_SPEED / speed_factor) + 0.5);
|
||||
unsigned ticker_slow_speed =
|
||||
unsigned ticker_slow_speed =
|
||||
(unsigned)(((float)TICKER_SLOW_SPEED / speed_factor) + 0.5);
|
||||
|
||||
/* Note: cur_time & old_time are in us (microseconds),
|
||||
@ -1251,6 +1257,7 @@ static void gfx_animation_update_time(
|
||||
|
||||
if (ticker_is_active)
|
||||
{
|
||||
/* Update non-smooth ticker indices */
|
||||
if (cur_time - last_ticker_update >= ticker_speed)
|
||||
{
|
||||
ticker_idx++;
|
||||
@ -1263,8 +1270,9 @@ static void gfx_animation_update_time(
|
||||
last_ticker_slow_update = cur_time;
|
||||
}
|
||||
|
||||
/* Pixel ticker updates every frame (regardless of time delta),
|
||||
* so requires special handling */
|
||||
/* Pixel tickers (horizontal + vertical/line) update
|
||||
* every frame (regardless of time delta), so require
|
||||
* special handling */
|
||||
|
||||
/* > Get base increment size (+1 every ticker_pixel_period ms) */
|
||||
ticker_pixel_increment = delta_time / ticker_pixel_period;
|
||||
@ -1272,39 +1280,43 @@ static void gfx_animation_update_time(
|
||||
/* > Apply ticker speed adjustment */
|
||||
ticker_pixel_increment *= speed_factor;
|
||||
|
||||
/* > Apply display resolution adjustment
|
||||
* (baseline resolution: 1920x1080)
|
||||
* Note 1: RGUI framebuffer size is independent of
|
||||
* display resolution, so have to use a fixed multiplier.
|
||||
* We choose a value such that text is scrolled
|
||||
* 1 pixel every 4 frames when ticker speed is 1x,
|
||||
* which matches almost exactly the scroll speed
|
||||
* of non-smooth ticker text (scrolling 1 pixel
|
||||
* every 2 frames is optimal, but may be too fast
|
||||
* for some users - so play it safe. Users can always
|
||||
* set ticker speed to 2x if they prefer)
|
||||
* Note 2: GLUI uses the new DPI scaling system,
|
||||
* so scaling multiplier is gfx_display_get_dpi_scale()
|
||||
* multiplied by a small correction factor (since the
|
||||
* default 1.0x speed is just a little faster than the
|
||||
* non-smooth ticker)
|
||||
* Note 3: Ozone now also uses the new DPI scaling
|
||||
* system. We therefore take the same approach as GLUI,
|
||||
* but with a different correction factor (expected
|
||||
* scroll speed is somewhat lower for Ozone) */
|
||||
/* At this point we diverge:
|
||||
* > Vertical (line) ticker is based upon text
|
||||
* characteristics (number of characters per
|
||||
* line) - it is therefore independent of display
|
||||
* size/scaling, so speed-adjusted pixel increment
|
||||
* is used directly */
|
||||
ticker_pixel_line_increment = ticker_pixel_increment;
|
||||
|
||||
/* > Horizontal ticker is based upon physical line
|
||||
* width - it is therefore very much dependent upon
|
||||
* display size/scaling. Each menu driver is free
|
||||
* to handle video scaling as it pleases - a callback
|
||||
* function set by the menu driver is thus used to
|
||||
* perform menu-specific scaling adjustments */
|
||||
update_time_callback(&ticker_pixel_increment,
|
||||
video_width, video_height);
|
||||
|
||||
/* > Update accumulator */
|
||||
/* > Update accumulators */
|
||||
ticker_pixel_accumulator += ticker_pixel_increment;
|
||||
ticker_pixel_accumulator_uint = (unsigned)ticker_pixel_accumulator;
|
||||
|
||||
/* > Check whether we've accumulated enough for an idx update */
|
||||
ticker_pixel_line_accumulator += ticker_pixel_line_increment;
|
||||
ticker_pixel_line_accumulator_uint = (unsigned)ticker_pixel_line_accumulator;
|
||||
|
||||
/* > Check whether we've accumulated enough
|
||||
* for an idx update */
|
||||
if (ticker_pixel_accumulator_uint > 0)
|
||||
{
|
||||
ticker_pixel_idx += ticker_pixel_accumulator_uint;
|
||||
ticker_pixel_accumulator -= (float)ticker_pixel_accumulator_uint;
|
||||
}
|
||||
|
||||
if (ticker_pixel_accumulator_uint > 0)
|
||||
{
|
||||
ticker_pixel_line_idx += ticker_pixel_line_accumulator_uint;
|
||||
ticker_pixel_line_accumulator -= (float)ticker_pixel_line_accumulator_uint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2347,3 +2359,8 @@ uint64_t gfx_animation_get_ticker_pixel_idx(void)
|
||||
{
|
||||
return ticker_pixel_idx;
|
||||
}
|
||||
|
||||
uint64_t gfx_animation_get_ticker_pixel_line_idx(void)
|
||||
{
|
||||
return ticker_pixel_line_idx;
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ RETRO_BEGIN_DECLS
|
||||
|
||||
typedef void (*tween_cb) (void*);
|
||||
|
||||
typedef void (*update_time_cb) (float *dst,
|
||||
typedef void (*update_time_cb) (float *ticker_pixel_increment,
|
||||
unsigned width, unsigned height);
|
||||
|
||||
enum gfx_animation_ctl_state
|
||||
@ -235,6 +235,8 @@ uint64_t gfx_animation_get_ticker_slow_idx(void);
|
||||
|
||||
uint64_t gfx_animation_get_ticker_pixel_idx(void);
|
||||
|
||||
uint64_t gfx_animation_get_ticker_pixel_line_idx(void);
|
||||
|
||||
void gfx_animation_set_update_time_cb(update_time_cb cb);
|
||||
|
||||
void gfx_animation_unset_update_time_cb(void);
|
||||
|
@ -5646,10 +5646,16 @@ static void materialui_init_nav_bar(materialui_handle_t *mui)
|
||||
}
|
||||
|
||||
static void materialui_menu_animation_update_time(
|
||||
float *dst,
|
||||
float *ticker_pixel_increment,
|
||||
unsigned video_width, unsigned video_height)
|
||||
{
|
||||
*(dst) *= gfx_display_get_dpi_scale(video_width, video_height) * 0.8f;
|
||||
/* MaterialUI uses DPI scaling
|
||||
* > Smooth ticker scaling multiplier is
|
||||
* gfx_display_get_dpi_scale() multiplied by
|
||||
* a small correction factor to achieve a
|
||||
* default scroll speed equal to that of the
|
||||
* non-smooth ticker */
|
||||
*(ticker_pixel_increment) *= gfx_display_get_dpi_scale(video_width, video_height) * 0.8f;
|
||||
}
|
||||
|
||||
static void *materialui_init(void **userdata, bool video_is_threaded)
|
||||
|
@ -123,13 +123,18 @@ void ozone_free_list_nodes(file_list_t *list, bool actiondata)
|
||||
}
|
||||
|
||||
static void ozone_menu_animation_update_time(
|
||||
float *dst,
|
||||
float *ticker_pixel_increment,
|
||||
unsigned video_width, unsigned video_height)
|
||||
{
|
||||
*(dst) *= gfx_display_get_dpi_scale(video_width, video_height) * 0.5f;
|
||||
/* Ozone uses DPI scaling
|
||||
* > Smooth ticker scaling multiplier is
|
||||
* gfx_display_get_dpi_scale() multiplied by
|
||||
* a small correction factor to achieve a
|
||||
* default scroll speed equal to that of the
|
||||
* non-smooth ticker */
|
||||
*(ticker_pixel_increment) *= gfx_display_get_dpi_scale(video_width, video_height) * 0.5f;
|
||||
}
|
||||
|
||||
|
||||
static void *ozone_init(void **userdata, bool video_is_threaded)
|
||||
{
|
||||
bool fallback_color_theme = false;
|
||||
|
@ -4296,10 +4296,20 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui, bool delay_update)
|
||||
}
|
||||
|
||||
static void rgui_menu_animation_update_time(
|
||||
float *dst,
|
||||
unsigned video_width, unsigned height)
|
||||
float *ticker_pixel_increment,
|
||||
unsigned video_width, unsigned video_height)
|
||||
{
|
||||
*(dst) *= 0.25f;
|
||||
/* RGUI framebuffer size is independent of
|
||||
* display resolution, so have to use a fixed
|
||||
* multiplier for smooth scrolling ticker text.
|
||||
* We choose a value such that text is scrolled
|
||||
* 1 pixel every 4 frames when ticker speed is 1x,
|
||||
* which matches almost exactly the scroll speed
|
||||
* of non-smooth ticker text (scrolling 1 pixel
|
||||
* every 2 frames is optimal, but may be too fast
|
||||
* for some users - so play it safe. Users can always
|
||||
* set ticker speed to 2x if they prefer) */
|
||||
*(ticker_pixel_increment) *= 0.25f;
|
||||
}
|
||||
|
||||
static void *rgui_init(void **userdata, bool video_is_threaded)
|
||||
|
@ -243,6 +243,7 @@ typedef struct xmb_handle
|
||||
{
|
||||
bool mouse_show;
|
||||
bool use_ps3_layout;
|
||||
bool last_use_ps3_layout;
|
||||
bool assets_missing;
|
||||
bool is_playlist;
|
||||
bool is_db_manager_list;
|
||||
@ -273,7 +274,7 @@ typedef struct xmb_handle
|
||||
float shadow_offset;
|
||||
float font_size;
|
||||
float font2_size;
|
||||
float previous_scale_factor;
|
||||
float last_scale_factor;
|
||||
|
||||
float margins_screen_left;
|
||||
float margins_screen_top;
|
||||
@ -3141,7 +3142,7 @@ static int xmb_draw_item(
|
||||
{
|
||||
line_ticker_smooth.fade_enabled = true;
|
||||
line_ticker_smooth.type_enum = menu_ticker_type;
|
||||
line_ticker_smooth.idx = gfx_animation_get_ticker_pixel_idx();
|
||||
line_ticker_smooth.idx = gfx_animation_get_ticker_pixel_line_idx();
|
||||
|
||||
line_ticker_smooth.font = xmb->font2;
|
||||
line_ticker_smooth.font_scale = 1.0f;
|
||||
@ -3401,6 +3402,48 @@ static void xmb_draw_items(
|
||||
gfx_display_blend_end(video_info);
|
||||
}
|
||||
|
||||
static INLINE bool xmb_use_ps3_layout(
|
||||
settings_t *settings, unsigned width, unsigned height)
|
||||
{
|
||||
unsigned menu_xmb_layout = settings->uints.menu_xmb_layout;
|
||||
|
||||
switch (menu_xmb_layout)
|
||||
{
|
||||
case 1:
|
||||
/* PS3 */
|
||||
return true;
|
||||
case 2:
|
||||
/* PSP */
|
||||
return false;
|
||||
case 0:
|
||||
default:
|
||||
/* Automatic
|
||||
* > Use PSP layout on tiny screens */
|
||||
return (width > 320) && (height > 240);
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE float xmb_get_scale_factor(
|
||||
settings_t *settings, bool use_ps3_layout, unsigned width)
|
||||
{
|
||||
float menu_scale_factor = settings->floats.menu_scale_factor;
|
||||
float scale_factor;
|
||||
|
||||
/* PS3 Layout */
|
||||
if (use_ps3_layout)
|
||||
scale_factor = (menu_scale_factor * (float)width) / 1920.0f;
|
||||
/* PSP Layout */
|
||||
else
|
||||
#ifdef _3DS
|
||||
scale_factor = menu_scale_factor / 4.0f;
|
||||
#else
|
||||
scale_factor = ((menu_scale_factor * (float)width) / 1920.0f) * 1.5f;
|
||||
#endif
|
||||
|
||||
/* Apply safety limit */
|
||||
return (scale_factor >= 0.1f) ? scale_factor : 0.1f;
|
||||
}
|
||||
|
||||
static void xmb_context_reset_internal(xmb_handle_t *xmb,
|
||||
bool is_threaded, bool reinit_textures);
|
||||
|
||||
@ -3410,21 +3453,25 @@ static void xmb_render(void *data,
|
||||
size_t i;
|
||||
float scale_factor;
|
||||
menu_input_pointer_t pointer;
|
||||
settings_t *settings = config_get_ptr();
|
||||
xmb_handle_t *xmb = (xmb_handle_t*)data;
|
||||
settings_t *settings = config_get_ptr();
|
||||
unsigned end = (unsigned)menu_entries_get_size();
|
||||
float menu_scale_factor = settings->floats.menu_scale_factor;
|
||||
|
||||
if (!xmb)
|
||||
return;
|
||||
|
||||
scale_factor = (menu_scale_factor * (float)width) / 1920.0f;
|
||||
xmb->use_ps3_layout = xmb_use_ps3_layout(settings, width, height);
|
||||
scale_factor = xmb_get_scale_factor(settings, xmb->use_ps3_layout, width);
|
||||
|
||||
if ((xmb->use_ps3_layout != xmb->last_use_ps3_layout) ||
|
||||
(scale_factor != xmb->last_scale_factor))
|
||||
{
|
||||
xmb->last_use_ps3_layout = xmb->use_ps3_layout;
|
||||
xmb->last_scale_factor = scale_factor;
|
||||
|
||||
if (scale_factor >= 0.1f && scale_factor != xmb->previous_scale_factor)
|
||||
xmb_context_reset_internal(xmb, video_driver_is_threaded(),
|
||||
false);
|
||||
|
||||
xmb->previous_scale_factor = scale_factor;
|
||||
}
|
||||
|
||||
menu_input_get_pointer_state(&pointer);
|
||||
|
||||
@ -4279,7 +4326,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info)
|
||||
/* Drop shadow for thumbnails needs to be larger
|
||||
* than for text/icons, and also needs to scale
|
||||
* with screen dimensions */
|
||||
float shadow_offset = xmb->shadow_offset * 1.5f * (menu_scale_factor * (float)width) / 1920.0f;
|
||||
float shadow_offset = xmb->shadow_offset * 1.5f * xmb->last_scale_factor;
|
||||
shadow_offset = (shadow_offset > xmb->shadow_offset)
|
||||
? shadow_offset
|
||||
: xmb->shadow_offset;
|
||||
@ -4841,10 +4888,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info)
|
||||
static void xmb_layout_ps3(xmb_handle_t *xmb, int width)
|
||||
{
|
||||
unsigned new_font_size, new_header_height;
|
||||
settings_t *settings = config_get_ptr();
|
||||
float menu_scale_factor = settings->floats.menu_scale_factor;
|
||||
float scale_factor =
|
||||
(menu_scale_factor * (float)width) / 1920.0f;
|
||||
float scale_factor = xmb->last_scale_factor;
|
||||
|
||||
xmb->above_subitem_offset = 1.5;
|
||||
xmb->above_item_offset = -1.0;
|
||||
@ -4896,13 +4940,7 @@ static void xmb_layout_ps3(xmb_handle_t *xmb, int width)
|
||||
static void xmb_layout_psp(xmb_handle_t *xmb, int width)
|
||||
{
|
||||
unsigned new_font_size, new_header_height;
|
||||
settings_t *settings = config_get_ptr();
|
||||
float menu_scale_factor = settings->floats.menu_scale_factor;
|
||||
float scale_factor =
|
||||
((menu_scale_factor * (float)width) / 1920.0f) * 1.5f;
|
||||
#ifdef _3DS
|
||||
scale_factor = menu_scale_factor / 4.0f;
|
||||
#endif
|
||||
float scale_factor = xmb->last_scale_factor;
|
||||
|
||||
xmb->above_subitem_offset = 1.5;
|
||||
xmb->above_item_offset = -1.0;
|
||||
@ -4951,37 +4989,13 @@ static void xmb_layout(xmb_handle_t *xmb)
|
||||
unsigned width, height, i, current, end;
|
||||
file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(0);
|
||||
size_t selection = menu_navigation_get_selection();
|
||||
settings_t *settings = config_get_ptr();
|
||||
unsigned menu_xmb_layout = settings->uints.menu_xmb_layout;
|
||||
|
||||
video_driver_get_size(&width, &height);
|
||||
|
||||
switch (menu_xmb_layout)
|
||||
{
|
||||
/* Automatic */
|
||||
case 0:
|
||||
{
|
||||
xmb->use_ps3_layout = false;
|
||||
xmb->use_ps3_layout = width > 320 && height > 240;
|
||||
|
||||
/* Mimic the layout of the PSP instead of the PS3 on tiny screens */
|
||||
if (xmb->use_ps3_layout)
|
||||
xmb_layout_ps3(xmb, width);
|
||||
else
|
||||
xmb_layout_psp(xmb, width);
|
||||
}
|
||||
break;
|
||||
/* PS3 */
|
||||
case 1:
|
||||
xmb->use_ps3_layout = true;
|
||||
xmb_layout_ps3(xmb, width);
|
||||
break;
|
||||
/* PSP */
|
||||
case 2:
|
||||
xmb->use_ps3_layout = false;
|
||||
xmb_layout_psp(xmb, width);
|
||||
break;
|
||||
}
|
||||
if (xmb->use_ps3_layout)
|
||||
xmb_layout_ps3(xmb, width);
|
||||
else
|
||||
xmb_layout_psp(xmb, width);
|
||||
|
||||
#ifdef XMB_DEBUG
|
||||
RARCH_LOG("[XMB] margin screen left: %.2f\n", xmb->margins_screen_left);
|
||||
@ -5093,6 +5107,24 @@ static void xmb_init_ribbon(xmb_handle_t * xmb)
|
||||
free(ribbon_verts);
|
||||
}
|
||||
|
||||
static void xmb_menu_animation_update_time(
|
||||
float *ticker_pixel_increment,
|
||||
unsigned video_width, unsigned video_height)
|
||||
{
|
||||
menu_handle_t *menu = menu_driver_get_ptr();
|
||||
xmb_handle_t *xmb = NULL;
|
||||
|
||||
if (!menu)
|
||||
return;
|
||||
|
||||
xmb = (xmb_handle_t*)menu->userdata;
|
||||
|
||||
if (!xmb)
|
||||
return;
|
||||
|
||||
*(ticker_pixel_increment) *= xmb->last_scale_factor;
|
||||
}
|
||||
|
||||
static void *xmb_init(void **userdata, bool video_is_threaded)
|
||||
{
|
||||
unsigned width, height;
|
||||
@ -5224,6 +5256,12 @@ static void *xmb_init(void **userdata, bool video_is_threaded)
|
||||
xmb->fullscreen_thumbnail_selection = 0;
|
||||
xmb->fullscreen_thumbnail_label[0] = '\0';
|
||||
|
||||
xmb->use_ps3_layout = xmb_use_ps3_layout(settings, width, height);
|
||||
xmb->last_use_ps3_layout = xmb->use_ps3_layout;
|
||||
xmb->last_scale_factor = xmb_get_scale_factor(settings, xmb->use_ps3_layout, width);
|
||||
|
||||
gfx_animation_set_update_time_cb(xmb_menu_animation_update_time);
|
||||
|
||||
return menu;
|
||||
|
||||
error:
|
||||
@ -5238,6 +5276,7 @@ error:
|
||||
file_list_free(xmb->horizontal_list);
|
||||
}
|
||||
xmb->horizontal_list = NULL;
|
||||
gfx_animation_unset_update_time_cb();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -5275,6 +5314,8 @@ static void xmb_free(void *data)
|
||||
}
|
||||
|
||||
font_driver_bind_block(NULL, NULL);
|
||||
|
||||
gfx_animation_unset_update_time_cb();
|
||||
}
|
||||
|
||||
static void xmb_context_bg_destroy(xmb_handle_t *xmb)
|
||||
|
Loading…
x
Reference in New Issue
Block a user