mirror of
https://github.com/libretro/RetroArch
synced 2025-03-28 19:20:35 +00:00
Merge branch 'master' into master
This commit is contained in:
commit
5cc89160e0
@ -180,6 +180,7 @@ error:
|
||||
#define BYTES_TO_FRAMES(bytes, frame_bits) ((bytes) * 8 / frame_bits)
|
||||
#define FRAMES_TO_BYTES(frames, frame_bits) ((frames) * frame_bits / 8)
|
||||
|
||||
static bool alsa_start(void *data, bool is_shutdown);
|
||||
static ssize_t alsa_write(void *data, const void *buf_, size_t size_)
|
||||
{
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
@ -188,6 +189,12 @@ static ssize_t alsa_write(void *data, const void *buf_, size_t size_)
|
||||
snd_pcm_sframes_t size = BYTES_TO_FRAMES(size_, alsa->frame_bits);
|
||||
size_t frames_size = alsa->has_float ? sizeof(float) : sizeof(int16_t);
|
||||
|
||||
/* Workaround buggy menu code.
|
||||
* If a write happens while we're paused, we might never progress. */
|
||||
if (alsa->is_paused)
|
||||
if (!alsa_start(alsa, false))
|
||||
return -1;
|
||||
|
||||
if (alsa->nonblock)
|
||||
{
|
||||
while (size)
|
||||
@ -269,6 +276,8 @@ static bool alsa_alive(void *data)
|
||||
static bool alsa_stop(void *data)
|
||||
{
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
if (alsa->is_paused)
|
||||
return true;
|
||||
|
||||
if (alsa->can_pause
|
||||
&& !alsa->is_paused)
|
||||
@ -293,6 +302,8 @@ static void alsa_set_nonblock_state(void *data, bool state)
|
||||
static bool alsa_start(void *data, bool is_shutdown)
|
||||
{
|
||||
alsa_t *alsa = (alsa_t*)data;
|
||||
if (!alsa->is_paused)
|
||||
return true;
|
||||
|
||||
if (alsa->can_pause
|
||||
&& alsa->is_paused)
|
||||
|
@ -237,12 +237,19 @@ error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool pulse_start(void *data, bool is_shutdown);
|
||||
static ssize_t pulse_write(void *data, const void *buf_, size_t size)
|
||||
{
|
||||
pa_t *pa = (pa_t*)data;
|
||||
const uint8_t *buf = (const uint8_t*)buf_;
|
||||
size_t written = 0;
|
||||
|
||||
/* Workaround buggy menu code.
|
||||
* If a write happens while we're paused, we might never progress. */
|
||||
if (pa->is_paused)
|
||||
if (!pulse_start(pa, false))
|
||||
return -1;
|
||||
|
||||
pa_threaded_mainloop_lock(pa->mainloop);
|
||||
while (size)
|
||||
{
|
||||
@ -270,6 +277,8 @@ static bool pulse_stop(void *data)
|
||||
{
|
||||
bool ret;
|
||||
pa_t *pa = (pa_t*)data;
|
||||
if (pa->is_paused)
|
||||
return true;
|
||||
|
||||
RARCH_LOG("[PulseAudio]: Pausing.\n");
|
||||
|
||||
@ -296,6 +305,8 @@ static bool pulse_start(void *data, bool is_shutdown)
|
||||
{
|
||||
bool ret;
|
||||
pa_t *pa = (pa_t*)data;
|
||||
if (!pa->is_paused)
|
||||
return true;
|
||||
|
||||
RARCH_LOG("[PulseAudio]: Unpausing.\n");
|
||||
|
||||
|
16
command.c
16
command.c
@ -1369,6 +1369,7 @@ static bool command_event_init_core(enum rarch_core_type *data)
|
||||
return false;
|
||||
|
||||
rarch_ctl(RARCH_CTL_SET_FRAME_LIMIT, NULL);
|
||||
rarch_ctl(RARCH_CTL_CONTENT_RUNTIME_LOG_INIT, NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2215,6 +2216,13 @@ TODO: Add a setting for these tweaks */
|
||||
}
|
||||
g_defaults.music_history = NULL;
|
||||
|
||||
if (g_defaults.content_runtime)
|
||||
{
|
||||
playlist_write_runtime_file(g_defaults.content_runtime);
|
||||
playlist_free(g_defaults.content_runtime);
|
||||
}
|
||||
g_defaults.content_runtime = NULL;
|
||||
|
||||
#if defined(HAVE_FFMPEG) || defined(HAVE_MPV)
|
||||
if (g_defaults.video_history)
|
||||
{
|
||||
@ -2265,6 +2273,13 @@ TODO: Add a setting for these tweaks */
|
||||
settings->paths.path_content_music_history,
|
||||
content_history_size);
|
||||
|
||||
RARCH_LOG("%s: [%s].\n",
|
||||
msg_hash_to_str(MSG_LOADING_HISTORY_FILE),
|
||||
settings->paths.path_content_runtime);
|
||||
g_defaults.content_runtime = playlist_init(
|
||||
settings->paths.path_content_runtime,
|
||||
content_history_size);
|
||||
|
||||
#if defined(HAVE_FFMPEG) || defined(HAVE_MPV)
|
||||
RARCH_LOG("%s: [%s].\n",
|
||||
msg_hash_to_str(MSG_LOADING_HISTORY_FILE),
|
||||
@ -2311,6 +2326,7 @@ TODO: Add a setting for these tweaks */
|
||||
case CMD_EVENT_CORE_DEINIT:
|
||||
{
|
||||
struct retro_hw_render_callback *hwr = NULL;
|
||||
rarch_ctl(RARCH_CTL_CONTENT_RUNTIME_LOG_DEINIT, NULL);
|
||||
content_reset_savestate_backups();
|
||||
hwr = video_driver_get_hw_context();
|
||||
command_event_deinit_core(true);
|
||||
|
@ -772,6 +772,9 @@ static const bool ui_companion_toggle = false;
|
||||
/* Only init the WIMP UI for this session if this is enabled */
|
||||
static const bool desktop_menu_enable = true;
|
||||
|
||||
/* Keep track of how long each core+content has been running for over time */
|
||||
static const bool content_runtime_log = false;
|
||||
|
||||
#if defined(__QNX__) || defined(_XBOX1) || defined(_XBOX360) || defined(__CELLOS_LV2__) || (defined(__MACH__) && defined(IOS)) || defined(ANDROID) || defined(WIIU) || defined(HAVE_NEON) || defined(GEKKO) || defined(__ARM_NEON__)
|
||||
static enum resampler_quality audio_resampler_quality_level = RESAMPLER_QUALITY_LOWER;
|
||||
#elif defined(PSP) || defined(_3DS) || defined(VITA) || defined(PS2)
|
||||
|
@ -1228,6 +1228,8 @@ static struct config_path_setting *populate_settings_path(settings_t *settings,
|
||||
settings->paths.path_content_video_history, false, NULL, true);
|
||||
SETTING_PATH("content_image_history_path",
|
||||
settings->paths.path_content_image_history, false, NULL, true);
|
||||
SETTING_PATH("content_runtime_path",
|
||||
settings->paths.path_content_runtime, false, NULL, true);
|
||||
#ifdef HAVE_OVERLAY
|
||||
SETTING_PATH("input_overlay",
|
||||
settings->paths.path_overlay, false, NULL, true);
|
||||
@ -1571,6 +1573,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings,
|
||||
#endif
|
||||
|
||||
SETTING_BOOL("playlist_use_old_format", &settings->bools.playlist_use_old_format, true, playlist_use_old_format, false);
|
||||
SETTING_BOOL("content_runtime_log", &settings->bools.content_runtime_log, true, content_runtime_log, false);
|
||||
|
||||
*size = count;
|
||||
|
||||
@ -2066,6 +2069,7 @@ void config_set_defaults(void)
|
||||
*settings->paths.path_content_music_history = '\0';
|
||||
*settings->paths.path_content_image_history = '\0';
|
||||
*settings->paths.path_content_video_history = '\0';
|
||||
*settings->paths.path_content_runtime = '\0';
|
||||
*settings->paths.path_cheat_settings = '\0';
|
||||
*settings->paths.path_shader = '\0';
|
||||
#ifndef IOS
|
||||
@ -3049,6 +3053,25 @@ static bool config_load_file(const char *path, bool set_defaults,
|
||||
}
|
||||
}
|
||||
|
||||
if (string_is_empty(settings->paths.path_content_runtime))
|
||||
{
|
||||
if (string_is_empty(settings->paths.directory_content_history))
|
||||
{
|
||||
fill_pathname_resolve_relative(
|
||||
settings->paths.path_content_runtime,
|
||||
path_config,
|
||||
file_path_str(FILE_PATH_CONTENT_RUNTIME),
|
||||
sizeof(settings->paths.path_content_runtime));
|
||||
}
|
||||
else
|
||||
{
|
||||
fill_pathname_join(settings->paths.path_content_runtime,
|
||||
settings->paths.directory_content_history,
|
||||
file_path_str(FILE_PATH_CONTENT_RUNTIME),
|
||||
sizeof(settings->paths.path_content_runtime));
|
||||
}
|
||||
}
|
||||
|
||||
if (!string_is_empty(settings->paths.directory_screenshot))
|
||||
{
|
||||
if (string_is_equal(settings->paths.directory_screenshot, "default"))
|
||||
|
@ -307,6 +307,7 @@ typedef struct settings
|
||||
|
||||
bool sustained_performance_mode;
|
||||
bool playlist_use_old_format;
|
||||
bool content_runtime_log;
|
||||
} bools;
|
||||
|
||||
struct
|
||||
@ -540,6 +541,7 @@ typedef struct settings
|
||||
char path_content_music_history[PATH_MAX_LENGTH];
|
||||
char path_content_image_history[PATH_MAX_LENGTH];
|
||||
char path_content_video_history[PATH_MAX_LENGTH];
|
||||
char path_content_runtime[PATH_MAX_LENGTH];
|
||||
char path_libretro_info[PATH_MAX_LENGTH];
|
||||
char path_cheat_settings[PATH_MAX_LENGTH];
|
||||
char path_shader[PATH_MAX_LENGTH];
|
||||
|
@ -103,6 +103,7 @@ struct defaults
|
||||
#ifndef IS_SALAMANDER
|
||||
playlist_t *content_history;
|
||||
playlist_t *content_favorites;
|
||||
playlist_t *content_runtime;
|
||||
#ifdef HAVE_IMAGEVIEWER
|
||||
playlist_t *image_history;
|
||||
#endif
|
||||
|
@ -38,6 +38,7 @@ enum file_path_enum
|
||||
FILE_PATH_LOG_ERROR,
|
||||
FILE_PATH_LOG_INFO,
|
||||
FILE_PATH_CONTENT_HISTORY,
|
||||
FILE_PATH_CONTENT_RUNTIME,
|
||||
FILE_PATH_CONTENT_FAVORITES,
|
||||
FILE_PATH_CONTENT_MUSIC_HISTORY,
|
||||
FILE_PATH_CONTENT_VIDEO_HISTORY,
|
||||
|
@ -200,6 +200,9 @@ const char *file_path_str(enum file_path_enum enum_idx)
|
||||
case FILE_PATH_CONTENT_HISTORY:
|
||||
str = "content_history.lpl";
|
||||
break;
|
||||
case FILE_PATH_CONTENT_RUNTIME:
|
||||
str = "content_runtime.lpl";
|
||||
break;
|
||||
case FILE_PATH_CONTENT_FAVORITES:
|
||||
str = "content_favorites.lpl";
|
||||
break;
|
||||
|
@ -251,8 +251,7 @@ int crt_compute_dynamic_width(int width)
|
||||
dynamic_width = (width*1.5)*i;
|
||||
if ((dynamic_width * min_height * ra_core_hz) > p_clock)
|
||||
break;
|
||||
|
||||
|
||||
|
||||
}
|
||||
return dynamic_width;
|
||||
}
|
||||
|
@ -1775,3 +1775,5 @@ MSG_HASH(MENU_ENUM_LABEL_MENU_SOUND_NOTICE,
|
||||
"menu_sound_notice")
|
||||
MSG_HASH(MENU_ENUM_LABEL_MENU_SOUND_BGM,
|
||||
"menu_sound_bgm")
|
||||
MSG_HASH(MENU_ENUM_LABEL_CONTENT_RUNTIME_LOG,
|
||||
"content_runtime_log")
|
||||
|
@ -8194,3 +8194,11 @@ MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_COREAUDIO3_SUPPORT,
|
||||
"CoreAudio V3 support"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_CONTENT_RUNTIME_LOG,
|
||||
"Save content runtime log"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_CONTENT_RUNTIME_LOG,
|
||||
"Keeps track of how long your content has been running over time."
|
||||
)
|
||||
|
@ -516,6 +516,7 @@ default_sublabel_macro(action_bind_sublabel_menu_rgui_lock_aspect,
|
||||
default_sublabel_macro(action_bind_sublabel_rgui_menu_color_theme, MENU_ENUM_SUBLABEL_RGUI_MENU_COLOR_THEME)
|
||||
default_sublabel_macro(action_bind_sublabel_rgui_menu_theme_preset, MENU_ENUM_SUBLABEL_RGUI_MENU_THEME_PRESET)
|
||||
default_sublabel_macro(action_bind_sublabel_menu_rgui_thumbnail_downscaler, MENU_ENUM_SUBLABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER)
|
||||
default_sublabel_macro(action_bind_sublabel_content_runtime_log, MENU_ENUM_SUBLABEL_CONTENT_RUNTIME_LOG)
|
||||
|
||||
static int action_bind_sublabel_systeminfo_controller_entry(
|
||||
file_list_t *list,
|
||||
@ -2248,6 +2249,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
|
||||
case MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_rgui_thumbnail_downscaler);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_CONTENT_RUNTIME_LOG:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_content_runtime_log);
|
||||
break;
|
||||
default:
|
||||
case MSG_UNKNOWN:
|
||||
return -1;
|
||||
|
@ -171,6 +171,8 @@ typedef struct materialui_handle
|
||||
|
||||
char *box_message;
|
||||
|
||||
char menu_title[255];
|
||||
|
||||
struct
|
||||
{
|
||||
menu_texture_item bg;
|
||||
@ -1063,7 +1065,6 @@ static void materialui_frame(void *data, video_frame_info_t *video_info)
|
||||
menu_animation_ctx_ticker_t ticker;
|
||||
menu_display_ctx_draw_t draw;
|
||||
char msg[255];
|
||||
char title[255];
|
||||
char title_buf[255];
|
||||
char title_msg[255];
|
||||
|
||||
@ -1168,7 +1169,7 @@ static void materialui_frame(void *data, video_frame_info_t *video_info)
|
||||
|
||||
mui->frame_count++;
|
||||
|
||||
msg[0] = title[0] = title_buf[0] = title_msg[0] = '\0';
|
||||
msg[0] = title_buf[0] = title_msg[0] = '\0';
|
||||
|
||||
switch (video_info->materialui_color_theme)
|
||||
{
|
||||
@ -1384,8 +1385,6 @@ static void materialui_frame(void *data, video_frame_info_t *video_info)
|
||||
}
|
||||
}
|
||||
|
||||
menu_entries_get_title(title, sizeof(title));
|
||||
|
||||
selection = menu_navigation_get_selection();
|
||||
|
||||
if (background_rendered || libretro_running)
|
||||
@ -1522,7 +1521,7 @@ static void materialui_frame(void *data, video_frame_info_t *video_info)
|
||||
ticker.s = title_buf;
|
||||
ticker.len = ticker_limit;
|
||||
ticker.idx = mui->frame_count / 100;
|
||||
ticker.str = title;
|
||||
ticker.str = mui->menu_title;
|
||||
ticker.selected = true;
|
||||
|
||||
menu_animation_ticker(&ticker);
|
||||
@ -1685,6 +1684,8 @@ static void *materialui_init(void **userdata, bool video_is_threaded)
|
||||
mui->cursor_size = scale_factor / 3;
|
||||
mui->need_compute = false;
|
||||
|
||||
mui->menu_title[0] = '\0';
|
||||
|
||||
return menu;
|
||||
error:
|
||||
if (menu)
|
||||
@ -1845,6 +1846,7 @@ static void materialui_populate_entries(
|
||||
if (!mui)
|
||||
return;
|
||||
|
||||
menu_entries_get_title(mui->menu_title, sizeof(mui->menu_title));
|
||||
mui->need_compute = true;
|
||||
mui->scroll_y = materialui_get_scroll(mui);
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
* Copyright (C) 2016-2017 - Brad Parker
|
||||
* Copyright (C) 2018 - Alfredo Monclús
|
||||
* Copyright (C) 2018 - natinusala
|
||||
* Copyright (C) 2019 - Patrick Scheurenbrand
|
||||
*
|
||||
* 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-
|
||||
@ -333,6 +334,8 @@ static void ozone_context_reset(void *data, bool is_threaded)
|
||||
unsigned size;
|
||||
char font_path[PATH_MAX_LENGTH];
|
||||
|
||||
float scale = 1;
|
||||
|
||||
ozone_handle_t *ozone = (ozone_handle_t*) data;
|
||||
|
||||
if (ozone)
|
||||
@ -365,6 +368,7 @@ static void ozone_context_reset(void *data, bool is_threaded)
|
||||
ozone->title_font_glyph_width = FONT_SIZE_TITLE * 3/4;
|
||||
ozone->entry_font_glyph_width = FONT_SIZE_ENTRIES_LABEL * 3/4;
|
||||
ozone->sublabel_font_glyph_width = FONT_SIZE_ENTRIES_SUBLABEL * 3/4;
|
||||
ozone->sidebar_font_glyph_width = FONT_SIZE_SIDEBAR * 3/4;
|
||||
|
||||
/* More realistic font size */
|
||||
size = font_driver_get_message_width(ozone->fonts.title, "a", 1, 1);
|
||||
@ -376,6 +380,9 @@ static void ozone_context_reset(void *data, bool is_threaded)
|
||||
size = font_driver_get_message_width(ozone->fonts.entries_sublabel, "a", 1, 1);
|
||||
if (size)
|
||||
ozone->sublabel_font_glyph_width = size;
|
||||
size = font_driver_get_message_width(ozone->fonts.sidebar, "a", 1, 1);
|
||||
if (size)
|
||||
ozone->sidebar_font_glyph_width = size;
|
||||
|
||||
/* Textures init */
|
||||
for (i = 0; i < OZONE_TEXTURE_LAST; i++)
|
||||
@ -468,6 +475,26 @@ static void ozone_context_reset(void *data, bool is_threaded)
|
||||
}
|
||||
|
||||
ozone_restart_cursor_animation(ozone);
|
||||
|
||||
/* UI dimensions */
|
||||
ozone->dimensions.header_height = HEADER_HEIGHT * scale;
|
||||
ozone->dimensions.footer_height = FOOTER_HEIGHT * scale;
|
||||
|
||||
ozone->dimensions.entry_padding_horizontal_half = ENTRY_PADDING_HORIZONTAL_HALF * scale;
|
||||
ozone->dimensions.entry_padding_horizontal_full = ENTRY_PADDING_HORIZONTAL_FULL * scale;
|
||||
ozone->dimensions.entry_padding_vertical = ENTRY_PADDING_VERTRICAL * scale;
|
||||
ozone->dimensions.entry_height = ENTRY_HEIGHT * scale;
|
||||
ozone->dimensions.entry_padding = ENTRY_PADDING * scale;
|
||||
ozone->dimensions.entry_icon_size = ENTRY_ICON_SIZE * scale;
|
||||
ozone->dimensions.entry_icon_padding = ENTRY_ICON_PADDING * scale;
|
||||
|
||||
ozone->dimensions.sidebar_width = SIDEBAR_WIDTH * scale;
|
||||
ozone->dimensions.sidebar_entry_height = SIDEBAR_ENTRY_HEIGHT * scale;
|
||||
ozone->dimensions.sidebar_padding_horizontal = SIDEBAR_X_PADDING * scale;
|
||||
ozone->dimensions.sidebar_padding_vertical = SIDEBAR_Y_PADDING * scale;
|
||||
ozone->dimensions.sidebar_entry_padding_vertical = SIDEBAR_ENTRY_Y_PADDING * scale;
|
||||
ozone->dimensions.sidebar_entry_icon_size = SIDEBAR_ENTRY_ICON_SIZE * scale;
|
||||
ozone->dimensions.sidebar_entry_icon_padding = SIDEBAR_ENTRY_ICON_PADDING * scale;
|
||||
}
|
||||
}
|
||||
|
||||
@ -796,14 +823,14 @@ static void ozone_update_scroll(ozone_handle_t *ozone, bool allow_animation, ozo
|
||||
|
||||
video_driver_get_size(NULL, &video_info_height);
|
||||
|
||||
current_selection_middle_onscreen = ENTRIES_START_Y + ozone->animations.scroll_y + node->position_y + node->height / 2;
|
||||
bottom_boundary = video_info_height - 87 - 78;
|
||||
current_selection_middle_onscreen = ozone->dimensions.header_height + ozone->dimensions.entry_padding_vertical + ozone->animations.scroll_y + node->position_y + node->height / 2;
|
||||
bottom_boundary = video_info_height - ozone->dimensions.header_height - 1 - ozone->dimensions.footer_height;
|
||||
entries_middle = video_info_height/2;
|
||||
|
||||
new_scroll = ozone->animations.scroll_y - (current_selection_middle_onscreen - entries_middle);
|
||||
|
||||
if (new_scroll + ozone->entries_height < bottom_boundary)
|
||||
new_scroll = -(78 + ozone->entries_height - bottom_boundary);
|
||||
new_scroll = bottom_boundary - ozone->entries_height - ozone->dimensions.entry_padding_vertical * 2;
|
||||
|
||||
if (new_scroll > 0)
|
||||
new_scroll = 0;
|
||||
@ -897,14 +924,16 @@ static void ozone_compute_entries_position(ozone_handle_t *ozone)
|
||||
if (!node)
|
||||
continue;
|
||||
|
||||
node->height = (entry.sublabel ? 100 : 60-8);
|
||||
node->height = ozone->dimensions.entry_height + ozone->dimensions.entry_padding + (entry.sublabel ? 40 : 0);
|
||||
node->wrap = false;
|
||||
|
||||
if (entry.sublabel)
|
||||
{
|
||||
char *sublabel_str = menu_entry_get_sublabel(&entry);
|
||||
|
||||
word_wrap(sublabel_str, sublabel_str, (video_info_width - 548) / ozone->sublabel_font_glyph_width, false);
|
||||
int sublable_max_width = video_info_width - ozone->dimensions.sidebar_width -
|
||||
ozone->dimensions.entry_padding_horizontal_half * 2 - ozone->dimensions.entry_icon_padding * 2;
|
||||
word_wrap(sublabel_str, sublabel_str, sublable_max_width / ozone->sublabel_font_glyph_width, false);
|
||||
|
||||
lines = ozone_count_lines(sublabel_str);
|
||||
|
||||
@ -966,7 +995,7 @@ static void ozone_draw_header(ozone_handle_t *ozone, video_frame_info_t *video_i
|
||||
unsigned timedate_offset = 0;
|
||||
|
||||
/* Separator */
|
||||
menu_display_draw_quad(video_info, 30, 87, video_info->width - 60, 1, video_info->width, video_info->height, ozone->theme->header_footer_separator);
|
||||
menu_display_draw_quad(video_info, 30, ozone->dimensions.header_height, video_info->width - 60, 1, video_info->width, video_info->height, ozone->theme->header_footer_separator);
|
||||
|
||||
/* Title */
|
||||
ticker.s = title;
|
||||
@ -977,7 +1006,7 @@ static void ozone_draw_header(ozone_handle_t *ozone, video_frame_info_t *video_i
|
||||
|
||||
menu_animation_ticker(&ticker);
|
||||
|
||||
ozone_draw_text(video_info, ozone, title, 128, 20 + FONT_SIZE_TITLE, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.title, ozone->theme->text_rgba, false);
|
||||
ozone_draw_text(video_info, ozone, title, 128, ozone->dimensions.header_height / 2 + FONT_SIZE_TITLE * 3/8, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.title, ozone->theme->text_rgba, false);
|
||||
|
||||
/* Icon */
|
||||
menu_display_blend_begin(video_info);
|
||||
@ -986,7 +1015,7 @@ static void ozone_draw_header(ozone_handle_t *ozone, video_frame_info_t *video_i
|
||||
ozone_draw_icon(video_info, 60, 60, ozone->textures[OZONE_TEXTURE_DISCORD_OWN_AVATAR], 47, 14, video_info->width, video_info->height, 0, 1, ozone->theme->entries_icon);
|
||||
else
|
||||
#endif
|
||||
ozone_draw_icon(video_info, 60, 60, ozone->textures[OZONE_TEXTURE_RETROARCH], 47, 14, video_info->width, video_info->height, 0, 1, ozone->theme->entries_icon);
|
||||
ozone_draw_icon(video_info, 60, 60, ozone->textures[OZONE_TEXTURE_RETROARCH], 47, (ozone->dimensions.header_height - 60) / 2, video_info->width, video_info->height, 0, 1, ozone->theme->entries_icon);
|
||||
menu_display_blend_end(video_info);
|
||||
|
||||
/* Battery */
|
||||
@ -1016,10 +1045,10 @@ static void ozone_draw_header(ozone_handle_t *ozone, video_frame_info_t *video_i
|
||||
|
||||
snprintf(msg, sizeof(msg), "%d%%", percent);
|
||||
|
||||
ozone_draw_text(video_info, ozone, msg, video_info->width - 85, 30 + FONT_SIZE_TIME, TEXT_ALIGN_RIGHT, video_info->width, video_info->height, ozone->fonts.time, ozone->theme->text_rgba, false);
|
||||
ozone_draw_text(video_info, ozone, msg, video_info->width - 85, ozone->dimensions.header_height / 2 + FONT_SIZE_TIME * 3/8, TEXT_ALIGN_RIGHT, video_info->width, video_info->height, ozone->fonts.time, ozone->theme->text_rgba, false);
|
||||
|
||||
menu_display_blend_begin(video_info);
|
||||
ozone_draw_icon(video_info, 92, 92, ozone->icons_textures[charging ? OZONE_ENTRIES_ICONS_TEXTURE_BATTERY_CHARGING : OZONE_ENTRIES_ICONS_TEXTURE_BATTERY_FULL], video_info->width - 60 - 56, 30 - 28, video_info->width, video_info->height, 0, 1, ozone->theme->entries_icon);
|
||||
ozone_draw_icon(video_info, 92, 92, ozone->icons_textures[charging ? OZONE_ENTRIES_ICONS_TEXTURE_BATTERY_CHARGING : OZONE_ENTRIES_ICONS_TEXTURE_BATTERY_FULL], video_info->width - 60 - 56, ozone->dimensions.header_height / 2 - 42, video_info->width, video_info->height, 0, 1, ozone->theme->entries_icon);
|
||||
menu_display_blend_end(video_info);
|
||||
}
|
||||
}
|
||||
@ -1038,10 +1067,10 @@ static void ozone_draw_header(ozone_handle_t *ozone, video_frame_info_t *video_i
|
||||
|
||||
menu_display_timedate(&datetime);
|
||||
|
||||
ozone_draw_text(video_info, ozone, timedate, video_info->width - 87 - timedate_offset, 30 + FONT_SIZE_TIME, TEXT_ALIGN_RIGHT, video_info->width, video_info->height, ozone->fonts.time, ozone->theme->text_rgba, false);
|
||||
ozone_draw_text(video_info, ozone, timedate, video_info->width - 85 - timedate_offset, ozone->dimensions.header_height / 2 + FONT_SIZE_TIME * 3/8, TEXT_ALIGN_RIGHT, video_info->width, video_info->height, ozone->fonts.time, ozone->theme->text_rgba, false);
|
||||
|
||||
menu_display_blend_begin(video_info);
|
||||
ozone_draw_icon(video_info, 92, 92, ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_CLOCK], video_info->width - 60 - 56 - timedate_offset, 30 - 28, video_info->width, video_info->height, 0, 1, ozone->theme->entries_icon);
|
||||
ozone_draw_icon(video_info, 92, 92, ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_CLOCK], video_info->width - 60 - 56 - timedate_offset, ozone->dimensions.header_height / 2 - 42, video_info->width, video_info->height, 0, 1, ozone->theme->entries_icon);
|
||||
menu_display_blend_end(video_info);
|
||||
}
|
||||
}
|
||||
@ -1050,42 +1079,37 @@ static void ozone_draw_footer(ozone_handle_t *ozone, video_frame_info_t *video_i
|
||||
{
|
||||
char core_title[255];
|
||||
/* Separator */
|
||||
menu_display_draw_quad(video_info, 23, video_info->height - 78, video_info->width - 60, 1, video_info->width, video_info->height, ozone->theme->header_footer_separator);
|
||||
menu_display_draw_quad(video_info, 23, video_info->height - ozone->dimensions.footer_height, video_info->width - 60, 1, video_info->width, video_info->height, ozone->theme->header_footer_separator);
|
||||
|
||||
/* Core title or Switch icon */
|
||||
if (settings->bools.menu_core_enable && menu_entries_get_core_title(core_title, sizeof(core_title)) == 0)
|
||||
ozone_draw_text(video_info, ozone, core_title, 59, video_info->height - 49 + FONT_SIZE_FOOTER, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.footer, ozone->theme->text_rgba, false);
|
||||
ozone_draw_text(video_info, ozone, core_title, 59, video_info->height - ozone->dimensions.footer_height / 2 + FONT_SIZE_FOOTER * 3/8, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.footer, ozone->theme->text_rgba, false);
|
||||
else
|
||||
ozone_draw_icon(video_info, 69, 30, ozone->theme->textures[OZONE_THEME_TEXTURE_SWITCH], 59, video_info->height - 52, video_info->width,video_info->height, 0, 1, NULL);
|
||||
ozone_draw_icon(video_info, 69, 30, ozone->theme->textures[OZONE_THEME_TEXTURE_SWITCH], 59, video_info->height - ozone->dimensions.footer_height / 2 - 15, video_info->width,video_info->height, 0, 1, NULL);
|
||||
|
||||
/* Buttons */
|
||||
|
||||
{
|
||||
unsigned back_width = 215;
|
||||
unsigned back_height = 49;
|
||||
unsigned ok_width = 96;
|
||||
unsigned ok_height = 49;
|
||||
bool do_swap = video_info->input_menu_swap_ok_cancel_buttons;
|
||||
|
||||
if (do_swap)
|
||||
{
|
||||
back_width = 96;
|
||||
back_height = 49;
|
||||
ok_width = 215;
|
||||
ok_height = 49;
|
||||
}
|
||||
|
||||
menu_display_blend_begin(video_info);
|
||||
|
||||
if (do_swap)
|
||||
{
|
||||
ozone_draw_icon(video_info, 25, 25, ozone->theme->textures[OZONE_THEME_TEXTURE_BUTTON_B], video_info->width - 133, video_info->height - 49, video_info->width,video_info->height, 0, 1, NULL);
|
||||
ozone_draw_icon(video_info, 25, 25, ozone->theme->textures[OZONE_THEME_TEXTURE_BUTTON_A], video_info->width - 251, video_info->height - 49, video_info->width,video_info->height, 0, 1, NULL);
|
||||
ozone_draw_icon(video_info, 25, 25, ozone->theme->textures[OZONE_THEME_TEXTURE_BUTTON_B], video_info->width - 133, video_info->height - ozone->dimensions.footer_height / 2 - 12, video_info->width,video_info->height, 0, 1, NULL);
|
||||
ozone_draw_icon(video_info, 25, 25, ozone->theme->textures[OZONE_THEME_TEXTURE_BUTTON_A], video_info->width - 251, video_info->height - ozone->dimensions.footer_height / 2 - 12, video_info->width,video_info->height, 0, 1, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
ozone_draw_icon(video_info, 25, 25, ozone->theme->textures[OZONE_THEME_TEXTURE_BUTTON_B], video_info->width - 251, video_info->height - 49, video_info->width,video_info->height, 0, 1, NULL);
|
||||
ozone_draw_icon(video_info, 25, 25, ozone->theme->textures[OZONE_THEME_TEXTURE_BUTTON_A], video_info->width - 133, video_info->height - 49, video_info->width,video_info->height, 0, 1, NULL);
|
||||
ozone_draw_icon(video_info, 25, 25, ozone->theme->textures[OZONE_THEME_TEXTURE_BUTTON_B], video_info->width - 251, video_info->height - ozone->dimensions.footer_height / 2 - 12, video_info->width,video_info->height, 0, 1, NULL);
|
||||
ozone_draw_icon(video_info, 25, 25, ozone->theme->textures[OZONE_THEME_TEXTURE_BUTTON_A], video_info->width - 133, video_info->height - ozone->dimensions.footer_height / 2 - 12, video_info->width,video_info->height, 0, 1, NULL);
|
||||
}
|
||||
|
||||
menu_display_blend_end(video_info);
|
||||
@ -1094,12 +1118,12 @@ static void ozone_draw_footer(ozone_handle_t *ozone, video_frame_info_t *video_i
|
||||
do_swap ?
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_OK) :
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_BACK),
|
||||
video_info->width - back_width, video_info->height - back_height + FONT_SIZE_FOOTER, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.footer, ozone->theme->text_rgba, false);
|
||||
video_info->width - back_width, video_info->height - ozone->dimensions.footer_height / 2 + FONT_SIZE_FOOTER * 3/8, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.footer, ozone->theme->text_rgba, false);
|
||||
ozone_draw_text(video_info, ozone,
|
||||
do_swap ?
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_BACK) :
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_OK),
|
||||
video_info->width - ok_width, video_info->height - ok_height + FONT_SIZE_FOOTER, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.footer, ozone->theme->text_rgba, false);
|
||||
video_info->width - ok_width, video_info->height - ozone->dimensions.footer_height / 2 + FONT_SIZE_FOOTER * 3/8, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.footer, ozone->theme->text_rgba, false);
|
||||
}
|
||||
|
||||
menu_display_blend_end(video_info);
|
||||
@ -1249,7 +1273,7 @@ static void ozone_frame(void *data, video_frame_info_t *video_info)
|
||||
ozone_draw_sidebar(ozone, video_info);
|
||||
|
||||
/* Menu entries */
|
||||
menu_display_scissor_begin(video_info, ozone->sidebar_offset + 408, 87, video_info->width - 408 + (-ozone->sidebar_offset), video_info->height - 87 - 78);
|
||||
menu_display_scissor_begin(video_info, ozone->sidebar_offset + ozone->dimensions.sidebar_width, ozone->dimensions.header_height, video_info->width - ozone->dimensions.sidebar_width + (-ozone->sidebar_offset), video_info->height - ozone->dimensions.header_height - ozone->dimensions.footer_height);
|
||||
|
||||
/* Current list */
|
||||
ozone_draw_entries(ozone,
|
||||
@ -1415,7 +1439,7 @@ static void ozone_list_open(ozone_handle_t *ozone)
|
||||
entry.easing_enum = EASING_OUT_QUAD;
|
||||
entry.subject = &ozone->sidebar_offset;
|
||||
entry.tag = (uintptr_t) NULL;
|
||||
entry.target_value = -408.0f;
|
||||
entry.target_value = -ozone->dimensions.sidebar_width;
|
||||
entry.userdata = (void*) ozone;
|
||||
|
||||
menu_animation_push(&entry);
|
||||
@ -1738,10 +1762,10 @@ static void ozone_list_cache(void *data,
|
||||
|
||||
/* Deep copy visible elements */
|
||||
video_driver_get_size(NULL, &video_info_height);
|
||||
y = ENTRIES_START_Y;
|
||||
y = ozone->dimensions.header_height + ozone->dimensions.entry_padding_vertical;
|
||||
entries_end = menu_entries_get_size();
|
||||
selection_buf = menu_entries_get_selection_buf_ptr(0);
|
||||
bottom_boundary = video_info_height - 87 - 78;
|
||||
bottom_boundary = video_info_height - ozone->dimensions.header_height - ozone->dimensions.footer_height;
|
||||
|
||||
for (i = 0; i < entries_end; i++)
|
||||
{
|
||||
@ -1750,7 +1774,7 @@ static void ozone_list_cache(void *data,
|
||||
if (!node)
|
||||
continue;
|
||||
|
||||
if (y + ozone->animations.scroll_y + node->height + 20 < ENTRIES_START_Y)
|
||||
if (y + ozone->animations.scroll_y + node->height + 20 < ozone->dimensions.header_height + ozone->dimensions.entry_padding_vertical)
|
||||
{
|
||||
first++;
|
||||
goto text_iterate;
|
||||
|
@ -1,5 +1,6 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2018 - natinusala
|
||||
* Copyright (C) 2019 - Patrick Scheurenbrand
|
||||
*
|
||||
* 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-
|
||||
@ -37,7 +38,24 @@ typedef struct ozone_handle ozone_handle_t;
|
||||
#define ANIMATION_CURSOR_DURATION 8
|
||||
#define ANIMATION_CURSOR_PULSE 30
|
||||
|
||||
#define ENTRIES_START_Y 127
|
||||
#define HEADER_HEIGHT 87
|
||||
#define FOOTER_HEIGHT 78
|
||||
|
||||
#define ENTRY_PADDING_HORIZONTAL_HALF 60
|
||||
#define ENTRY_PADDING_HORIZONTAL_FULL 100
|
||||
#define ENTRY_PADDING_VERTRICAL 20
|
||||
#define ENTRY_HEIGHT 50
|
||||
#define ENTRY_PADDING 0
|
||||
#define ENTRY_ICON_SIZE 46
|
||||
#define ENTRY_ICON_PADDING 15
|
||||
|
||||
#define SIDEBAR_WIDTH 408
|
||||
#define SIDEBAR_X_PADDING 40
|
||||
#define SIDEBAR_Y_PADDING 20
|
||||
#define SIDEBAR_ENTRY_HEIGHT 50
|
||||
#define SIDEBAR_ENTRY_Y_PADDING 10
|
||||
#define SIDEBAR_ENTRY_ICON_SIZE 40
|
||||
#define SIDEBAR_ENTRY_ICON_PADDING 15
|
||||
|
||||
#define INTERVAL_BATTERY_LEVEL_CHECK (30 * 1000000)
|
||||
#define INTERVAL_OSK_CURSOR (0.5f * 1000000)
|
||||
@ -113,7 +131,8 @@ struct ozone_handle
|
||||
unsigned title_font_glyph_width;
|
||||
unsigned entry_font_glyph_width;
|
||||
unsigned sublabel_font_glyph_width;
|
||||
|
||||
unsigned sidebar_font_glyph_width;
|
||||
|
||||
ozone_theme_t *theme;
|
||||
|
||||
struct {
|
||||
@ -152,6 +171,27 @@ struct ozone_handle
|
||||
unsigned old_list_offset_y;
|
||||
|
||||
file_list_t *horizontal_list; /* console tabs */
|
||||
|
||||
struct {
|
||||
int header_height;
|
||||
int footer_height;
|
||||
|
||||
int entry_padding_horizontal_half;
|
||||
int entry_padding_horizontal_full; /* todo when sidebar is not visible */
|
||||
int entry_padding_vertical;
|
||||
int entry_height;
|
||||
int entry_padding;
|
||||
int entry_icon_size;
|
||||
int entry_icon_padding;
|
||||
|
||||
int sidebar_width;
|
||||
int sidebar_padding_horizontal;
|
||||
int sidebar_padding_vertical;
|
||||
int sidebar_entry_padding_vertical;
|
||||
int sidebar_entry_height;
|
||||
int sidebar_entry_icon_size;
|
||||
int sidebar_entry_icon_padding;
|
||||
} dimensions;
|
||||
};
|
||||
|
||||
/* If you change this struct, also
|
||||
|
@ -4,6 +4,7 @@
|
||||
* Copyright (C) 2016-2017 - Brad Parker
|
||||
* Copyright (C) 2018 - Alfredo Monclús
|
||||
* Copyright (C) 2018 - natinusala
|
||||
* Copyright (C) 2019 - Patrick Scheurenbrand
|
||||
*
|
||||
* 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-
|
||||
@ -113,7 +114,7 @@ void ozone_draw_entries(ozone_handle_t *ozone, video_frame_info_t *video_info,
|
||||
size_t i, y, entries_end;
|
||||
float sidebar_offset, bottom_boundary, invert, alpha_anim;
|
||||
unsigned video_info_height, video_info_width, entry_width, button_height;
|
||||
int x_offset = 22;
|
||||
int x_offset = 0;
|
||||
size_t selection_y = 0;
|
||||
size_t old_selection_y = 0;
|
||||
|
||||
@ -121,14 +122,14 @@ void ozone_draw_entries(ozone_handle_t *ozone, video_frame_info_t *video_info,
|
||||
|
||||
entries_end = file_list_get_size(selection_buf);
|
||||
old_list = selection_buf == ozone->selection_buf_old;
|
||||
y = ENTRIES_START_Y;
|
||||
sidebar_offset = ozone->sidebar_offset / 2.0f;
|
||||
entry_width = video_info->width - 548;
|
||||
button_height = 52; /* height of the button (entry minus sublabel) */
|
||||
y = ozone->dimensions.header_height + 1 + ozone->dimensions.entry_padding_vertical;
|
||||
sidebar_offset = ozone->sidebar_offset;
|
||||
entry_width = video_info->width - ozone->dimensions.sidebar_width - ozone->sidebar_offset - ozone->dimensions.entry_padding_horizontal_half * 2;
|
||||
button_height = ozone->dimensions.entry_height; /* height of the button (entry minus sublabel) */
|
||||
|
||||
video_driver_get_size(&video_info_width, &video_info_height);
|
||||
|
||||
bottom_boundary = video_info_height - 87 - 78;
|
||||
bottom_boundary = video_info_height - ozone->dimensions.header_height - ozone->dimensions.footer_height;
|
||||
invert = (ozone->fade_direction) ? -1 : 1;
|
||||
alpha_anim = old_list ? alpha : 1.0f - alpha;
|
||||
|
||||
@ -163,7 +164,7 @@ void ozone_draw_entries(ozone_handle_t *ozone, video_frame_info_t *video_info,
|
||||
if (!node || ozone->empty_playlist)
|
||||
goto border_iterate;
|
||||
|
||||
if (y + scroll_y + node->height + 20 < ENTRIES_START_Y)
|
||||
if (y + scroll_y + node->height + 20 < ozone->dimensions.header_height + ozone->dimensions.entry_padding_vertical)
|
||||
goto border_iterate;
|
||||
else if (y + scroll_y - node->height - 20 > bottom_boundary)
|
||||
goto border_iterate;
|
||||
@ -172,8 +173,10 @@ void ozone_draw_entries(ozone_handle_t *ozone, video_frame_info_t *video_info,
|
||||
ozone_color_alpha(ozone->theme_dynamic.entries_checkmark, alpha);
|
||||
|
||||
/* Borders */
|
||||
menu_display_draw_quad(video_info, x_offset + 456-3, y - 3 + scroll_y, entry_width + 10 - 3 -1, 1, video_info->width, video_info->height, ozone->theme_dynamic.entries_border);
|
||||
menu_display_draw_quad(video_info, x_offset + 456-3, y - 3 + button_height + scroll_y, entry_width + 10 - 3-1, 1, video_info->width, video_info->height, ozone->theme_dynamic.entries_border);
|
||||
menu_display_draw_quad(video_info, ozone->dimensions.sidebar_width + x_offset + ozone->dimensions.entry_padding_horizontal_half,
|
||||
y + scroll_y, entry_width, 1, video_info->width, video_info->height, ozone->theme_dynamic.entries_border);
|
||||
menu_display_draw_quad(video_info, ozone->dimensions.sidebar_width + x_offset + ozone->dimensions.entry_padding_horizontal_half,
|
||||
y + button_height + scroll_y, entry_width, 1, video_info->width, video_info->height, ozone->theme_dynamic.entries_border);
|
||||
|
||||
border_iterate:
|
||||
y += node->height;
|
||||
@ -181,14 +184,16 @@ border_iterate:
|
||||
|
||||
/* Cursor(s) layer - current */
|
||||
if (!ozone->cursor_in_sidebar)
|
||||
ozone_draw_cursor(ozone, video_info, x_offset + 456, entry_width, button_height, selection_y + scroll_y, ozone->animations.cursor_alpha * alpha);
|
||||
ozone_draw_cursor(ozone, video_info, ozone->dimensions.sidebar_width + x_offset + ozone->dimensions.entry_padding_horizontal_half + 3,
|
||||
entry_width - 5, button_height + 2, selection_y + scroll_y + 1, ozone->animations.cursor_alpha * alpha);
|
||||
|
||||
/* Old*/
|
||||
if (!ozone->cursor_in_sidebar_old)
|
||||
ozone_draw_cursor(ozone, video_info, x_offset + 456, entry_width, button_height, old_selection_y + scroll_y, (1-ozone->animations.cursor_alpha) * alpha);
|
||||
ozone_draw_cursor(ozone, video_info, ozone->dimensions.sidebar_width + x_offset + ozone->dimensions.entry_padding_horizontal_half + 3,
|
||||
entry_width - 5, button_height + 2, old_selection_y + scroll_y + 1, (1-ozone->animations.cursor_alpha) * alpha);
|
||||
|
||||
/* Icons + text */
|
||||
y = ENTRIES_START_Y;
|
||||
y = ozone->dimensions.header_height + 1 + ozone->dimensions.entry_padding_vertical;
|
||||
|
||||
if (old_list)
|
||||
y += ozone->old_list_offset_y;
|
||||
@ -205,7 +210,7 @@ border_iterate:
|
||||
ozone_node_t *node = NULL;
|
||||
char *entry_rich_label = NULL;
|
||||
bool entry_selected = false;
|
||||
int text_offset = -40;
|
||||
int text_offset = -ozone->dimensions.entry_icon_padding - ozone->dimensions.entry_icon_size;
|
||||
float *icon_color = NULL;
|
||||
|
||||
entry_value[0] = '\0';
|
||||
@ -219,7 +224,7 @@ border_iterate:
|
||||
if (!node)
|
||||
continue;
|
||||
|
||||
if (y + scroll_y + node->height + 20 < ENTRIES_START_Y)
|
||||
if (y + scroll_y + node->height + 20 < ozone->dimensions.header_height + ozone->dimensions.entry_padding_vertical)
|
||||
goto icons_iterate;
|
||||
else if (y + scroll_y - node->height - 20 > bottom_boundary)
|
||||
goto icons_iterate;
|
||||
@ -238,15 +243,19 @@ border_iterate:
|
||||
if (ozone->empty_playlist)
|
||||
{
|
||||
unsigned text_width = font_driver_get_message_width(ozone->fonts.entries_label, rich_label, (unsigned)strlen(rich_label), 1);
|
||||
x_offset = (video_info_width - 408 - 162)/2 - text_width/2;
|
||||
y = video_info_height/2 - 60;
|
||||
x_offset = (video_info_width - ozone->dimensions.sidebar_width - ozone->dimensions.entry_padding_horizontal_half * 2) / 2 - text_width / 2 - 60;
|
||||
y = video_info_height / 2 - 60;
|
||||
}
|
||||
|
||||
sublabel_str = menu_entry_get_sublabel(&entry);
|
||||
|
||||
if (node->wrap && sublabel_str)
|
||||
word_wrap(sublabel_str, sublabel_str, (video_info->width - 548) / ozone->sublabel_font_glyph_width, false);
|
||||
|
||||
{
|
||||
int sublable_max_width = video_info_width - ozone->dimensions.sidebar_width -
|
||||
ozone->dimensions.entry_padding_horizontal_half * 2 - ozone->dimensions.entry_icon_padding * 2;
|
||||
word_wrap(sublabel_str, sublabel_str, sublable_max_width / ozone->sublabel_font_glyph_width, false);
|
||||
}
|
||||
|
||||
/* Icon */
|
||||
tex = ozone_entries_icon_get_texture(ozone, entry.enum_idx, entry.type, entry_selected);
|
||||
if (tex != ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_SUBSETTING])
|
||||
@ -280,7 +289,9 @@ border_iterate:
|
||||
ozone_color_alpha(icon_color, alpha);
|
||||
|
||||
menu_display_blend_begin(video_info);
|
||||
ozone_draw_icon(video_info, 46, 46, texture, x_offset + 451+5+10, y + scroll_y, video_info->width, video_info->height, 0, 1, icon_color);
|
||||
ozone_draw_icon(video_info, ozone->dimensions.entry_icon_size, ozone->dimensions.entry_icon_size, texture,
|
||||
ozone->dimensions.sidebar_width + x_offset + ozone->dimensions.entry_padding_horizontal_half + ozone->dimensions.entry_icon_padding,
|
||||
y + scroll_y + ozone->dimensions.entry_height / 2 - ozone->dimensions.entry_icon_size / 2, video_info->width, video_info->height, 0, 1, icon_color);
|
||||
menu_display_blend_end(video_info);
|
||||
|
||||
if (icon_color == ozone_pure_white)
|
||||
@ -290,20 +301,24 @@ border_iterate:
|
||||
}
|
||||
|
||||
/* Draw text */
|
||||
ozone_draw_text(video_info, ozone, rich_label, text_offset + x_offset + 521, y + FONT_SIZE_ENTRIES_LABEL + 8 - 1 + scroll_y, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.entries_label, COLOR_TEXT_ALPHA(ozone->theme->text_rgba, alpha_uint32), false);
|
||||
ozone_draw_text(video_info, ozone, rich_label, text_offset + ozone->dimensions.sidebar_width + x_offset + ozone->dimensions.entry_padding_horizontal_half + ozone->dimensions.entry_icon_size + ozone->dimensions.entry_icon_padding * 2,
|
||||
y + ozone->dimensions.entry_height / 2 + FONT_SIZE_ENTRIES_LABEL * 3/8 + scroll_y, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.entries_label, COLOR_TEXT_ALPHA(ozone->theme->text_rgba, alpha_uint32), false);
|
||||
if (sublabel_str)
|
||||
ozone_draw_text(video_info, ozone, sublabel_str, x_offset + 470, y + FONT_SIZE_ENTRIES_SUBLABEL + 80 - 20 - 3 + scroll_y, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.entries_sublabel, COLOR_TEXT_ALPHA(ozone->theme->text_sublabel_rgba, alpha_uint32), false);
|
||||
ozone_draw_text(video_info, ozone, sublabel_str, ozone->dimensions.sidebar_width + x_offset + ozone->dimensions.entry_padding_horizontal_half + ozone->dimensions.entry_icon_padding,
|
||||
y + ozone->dimensions.entry_height + 1 + 5 + FONT_SIZE_ENTRIES_SUBLABEL + scroll_y, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.entries_sublabel, COLOR_TEXT_ALPHA(ozone->theme->text_sublabel_rgba, alpha_uint32), false);
|
||||
|
||||
/* Value */
|
||||
ticker.idx = ozone->frame_count / 20;
|
||||
ticker.s = entry_value_ticker;
|
||||
ticker.str = entry_value;
|
||||
ticker.selected = entry_selected && !ozone->cursor_in_sidebar;
|
||||
ticker.len = (entry_width - 60 - ((int)utf8len(entry_rich_label) * ozone->entry_font_glyph_width)) / ozone->entry_font_glyph_width;
|
||||
ticker.len = (entry_width - ozone->dimensions.entry_icon_size - ozone->dimensions.entry_icon_padding * 2 -
|
||||
((int)utf8len(entry_rich_label) * ozone->entry_font_glyph_width)) / ozone->entry_font_glyph_width;
|
||||
|
||||
menu_animation_ticker(&ticker);
|
||||
|
||||
ozone_draw_entry_value(ozone, video_info, entry_value_ticker, x_offset + 426 + entry_width, y + FONT_SIZE_ENTRIES_LABEL + 8 - 1 + scroll_y,alpha_uint32, &entry);
|
||||
ozone_draw_entry_value(ozone, video_info, entry_value_ticker, ozone->dimensions.sidebar_width + ozone->dimensions.entry_padding_horizontal_half + x_offset + entry_width - ozone->dimensions.entry_icon_padding,
|
||||
y + ozone->dimensions.entry_height / 2 + FONT_SIZE_ENTRIES_LABEL * 3/8 + scroll_y, alpha_uint32, &entry);
|
||||
|
||||
free(entry_rich_label);
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
* Copyright (C) 2016-2017 - Brad Parker
|
||||
* Copyright (C) 2018 - Alfredo Monclús
|
||||
* Copyright (C) 2018 - natinusala
|
||||
* Copyright (C) 2019 - Patrick Scheurenbrand
|
||||
*
|
||||
* 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-
|
||||
@ -17,8 +18,6 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* TODO Fluid sidebar width ? */
|
||||
|
||||
#include "ozone.h"
|
||||
#include "ozone_theme.h"
|
||||
#include "ozone_display.h"
|
||||
@ -115,55 +114,61 @@ void ozone_draw_sidebar(ozone_handle_t *ozone, video_frame_info_t *video_info)
|
||||
unsigned selection_old_y = 0;
|
||||
unsigned horizontal_list_size = 0;
|
||||
|
||||
int entry_width = 0;
|
||||
|
||||
if (!ozone->draw_sidebar)
|
||||
return;
|
||||
|
||||
if (ozone->horizontal_list)
|
||||
horizontal_list_size = ozone->horizontal_list->size;
|
||||
|
||||
menu_display_scissor_begin(video_info, 0, 87, 408, video_info->height - 87 - 78);
|
||||
menu_display_scissor_begin(video_info, 0, ozone->dimensions.header_height, ozone->dimensions.sidebar_width, video_info->height - ozone->dimensions.header_height - ozone->dimensions.footer_height);
|
||||
|
||||
/* Background */
|
||||
sidebar_height = video_info->height - 87 - 55 - 78;
|
||||
sidebar_height = video_info->height - ozone->dimensions.header_height - 55 - ozone->dimensions.footer_height;
|
||||
|
||||
if (!video_info->libretro_running)
|
||||
{
|
||||
menu_display_draw_quad(video_info, ozone->sidebar_offset, 88, 408, 55/2, video_info->width, video_info->height, ozone->theme->sidebar_top_gradient);
|
||||
menu_display_draw_quad(video_info, ozone->sidebar_offset, 88 + 55/2, 408, sidebar_height, video_info->width, video_info->height, ozone->theme->sidebar_background);
|
||||
menu_display_draw_quad(video_info, ozone->sidebar_offset, 55*2 + sidebar_height, 408, 55/2 + 1, video_info->width, video_info->height, ozone->theme->sidebar_bottom_gradient);
|
||||
menu_display_draw_quad(video_info, ozone->sidebar_offset, ozone->dimensions.header_height + 1, ozone->dimensions.sidebar_width, 55/2, video_info->width, video_info->height, ozone->theme->sidebar_top_gradient);
|
||||
menu_display_draw_quad(video_info, ozone->sidebar_offset, ozone->dimensions.header_height + 1 + 55/2, ozone->dimensions.sidebar_width, sidebar_height, video_info->width, video_info->height, ozone->theme->sidebar_background);
|
||||
menu_display_draw_quad(video_info, ozone->sidebar_offset, video_info->height - ozone->dimensions.footer_height - 55/2 - 1, ozone->dimensions.sidebar_width, 55/2 + 1, video_info->width, video_info->height, ozone->theme->sidebar_bottom_gradient);
|
||||
}
|
||||
|
||||
/* Tabs */
|
||||
/* y offset computation */
|
||||
y = ENTRIES_START_Y - 10;
|
||||
y = ozone->dimensions.header_height + 1 + ozone->dimensions.sidebar_padding_vertical;
|
||||
for (i = 0; i < ozone->system_tab_end + horizontal_list_size + 1; i++)
|
||||
{
|
||||
if (i == ozone->categories_selection_ptr)
|
||||
{
|
||||
selection_y = y;
|
||||
if (ozone->categories_selection_ptr > ozone->system_tab_end)
|
||||
selection_y += 30;
|
||||
selection_y += ozone->dimensions.sidebar_entry_padding_vertical + 1;
|
||||
}
|
||||
|
||||
if (i == ozone->categories_active_idx_old)
|
||||
{
|
||||
selection_old_y = y;
|
||||
if (ozone->categories_active_idx_old > ozone->system_tab_end)
|
||||
selection_old_y += 30;
|
||||
selection_old_y += ozone->dimensions.sidebar_entry_padding_vertical + 1;
|
||||
}
|
||||
|
||||
y += 65;
|
||||
y += ozone->dimensions.sidebar_entry_height + ozone->dimensions.sidebar_entry_padding_vertical;
|
||||
}
|
||||
|
||||
entry_width = ozone->dimensions.sidebar_width - ozone->dimensions.sidebar_padding_horizontal * 2;
|
||||
|
||||
/* Cursor */
|
||||
if (ozone->cursor_in_sidebar)
|
||||
ozone_draw_cursor(ozone, video_info, ozone->sidebar_offset + 41, 408 - 81, 52, selection_y-8 + ozone->animations.scroll_y_sidebar, ozone->animations.cursor_alpha);
|
||||
ozone_draw_cursor(ozone, video_info, ozone->sidebar_offset + ozone->dimensions.sidebar_padding_horizontal + 3,
|
||||
entry_width - 5, ozone->dimensions.sidebar_entry_height + 2, selection_y + 1 + ozone->animations.scroll_y_sidebar, ozone->animations.cursor_alpha);
|
||||
|
||||
if (ozone->cursor_in_sidebar_old)
|
||||
ozone_draw_cursor(ozone, video_info, ozone->sidebar_offset + 41, 408 - 81, 52, selection_old_y-8 + ozone->animations.scroll_y_sidebar, 1-ozone->animations.cursor_alpha);
|
||||
ozone_draw_cursor(ozone, video_info, ozone->sidebar_offset + ozone->dimensions.sidebar_padding_horizontal + 3,
|
||||
entry_width - 5, ozone->dimensions.sidebar_entry_height + 2, selection_old_y + 1 + ozone->animations.scroll_y_sidebar, 1-ozone->animations.cursor_alpha);
|
||||
|
||||
/* Menu tabs */
|
||||
y = ENTRIES_START_Y - 10;
|
||||
y = ozone->dimensions.header_height + 1 + ozone->dimensions.sidebar_padding_vertical;
|
||||
menu_display_blend_begin(video_info);
|
||||
|
||||
for (i = 0; i < (unsigned)(ozone->system_tab_end+1); i++)
|
||||
@ -174,15 +179,18 @@ void ozone_draw_sidebar(ozone_handle_t *ozone, video_frame_info_t *video_info)
|
||||
unsigned icon = ozone_system_tabs_icons[ozone->tabs[i]];
|
||||
|
||||
/* Icon */
|
||||
ozone_draw_icon(video_info, 40, 40, ozone->tab_textures[icon], ozone->sidebar_offset + 41 + 10, y - 5 + ozone->animations.scroll_y_sidebar, video_info->width, video_info->height, 0, 1, (selected ? ozone->theme->text_selected : ozone->theme->entries_icon));
|
||||
ozone_draw_icon(video_info, ozone->dimensions.sidebar_entry_icon_size, ozone->dimensions.sidebar_entry_icon_size,
|
||||
ozone->tab_textures[icon], ozone->sidebar_offset + ozone->dimensions.sidebar_padding_horizontal + ozone->dimensions.sidebar_entry_icon_padding,
|
||||
y + ozone->dimensions.sidebar_entry_height / 2 - ozone->dimensions.sidebar_entry_icon_size / 2 + ozone->animations.scroll_y_sidebar, video_info->width, video_info->height, 0, 1, (selected ? ozone->theme->text_selected : ozone->theme->entries_icon));
|
||||
|
||||
value_idx = ozone_system_tabs_value[ozone->tabs[i]];
|
||||
title = msg_hash_to_str(value_idx);
|
||||
|
||||
/* Text */
|
||||
ozone_draw_text(video_info, ozone, title, ozone->sidebar_offset + 115 - 10, y + FONT_SIZE_SIDEBAR + ozone->animations.scroll_y_sidebar, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.sidebar, (selected ? ozone->theme->text_selected_rgba : ozone->theme->text_rgba), true);
|
||||
ozone_draw_text(video_info, ozone, title, ozone->sidebar_offset + ozone->dimensions.sidebar_padding_horizontal + ozone->dimensions.sidebar_entry_icon_padding * 2 + ozone->dimensions.sidebar_entry_icon_size,
|
||||
y + ozone->dimensions.sidebar_entry_height / 2 + FONT_SIZE_SIDEBAR * 3/8 + ozone->animations.scroll_y_sidebar, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.sidebar, (selected ? ozone->theme->text_selected_rgba : ozone->theme->text_rgba), true);
|
||||
|
||||
y += 65;
|
||||
y += ozone->dimensions.sidebar_entry_height + ozone->dimensions.sidebar_entry_padding_vertical;
|
||||
}
|
||||
|
||||
menu_display_blend_end(video_info);
|
||||
@ -190,9 +198,9 @@ void ozone_draw_sidebar(ozone_handle_t *ozone, video_frame_info_t *video_info)
|
||||
/* Console tabs */
|
||||
if (horizontal_list_size > 0)
|
||||
{
|
||||
menu_display_draw_quad(video_info, ozone->sidebar_offset + 41 + 10, y - 5 + ozone->animations.scroll_y_sidebar, 408-81, 1, video_info->width, video_info->height, ozone->theme->entries_border);
|
||||
menu_display_draw_quad(video_info, ozone->sidebar_offset + ozone->dimensions.sidebar_padding_horizontal, y + ozone->animations.scroll_y_sidebar, entry_width, 1, video_info->width, video_info->height, ozone->theme->entries_border);
|
||||
|
||||
y += 30;
|
||||
y += ozone->dimensions.sidebar_entry_padding_vertical + 1;
|
||||
|
||||
menu_display_blend_begin(video_info);
|
||||
|
||||
@ -206,21 +214,26 @@ void ozone_draw_sidebar(ozone_handle_t *ozone, video_frame_info_t *video_info)
|
||||
goto console_iterate;
|
||||
|
||||
/* Icon */
|
||||
ozone_draw_icon(video_info, 40, 40, node->icon, ozone->sidebar_offset + 41 + 10 - 3, y - 5 - 3 + ozone->animations.scroll_y_sidebar, video_info->width, video_info->height, 0, 1, (selected ? ozone->theme->text_selected : ozone->theme->entries_icon));
|
||||
ozone_draw_icon(video_info, ozone->dimensions.sidebar_entry_icon_size, ozone->dimensions.sidebar_entry_icon_size,
|
||||
node->icon, ozone->sidebar_offset + ozone->dimensions.sidebar_padding_horizontal + ozone->dimensions.sidebar_entry_icon_padding,
|
||||
y + ozone->dimensions.sidebar_entry_height / 2 - ozone->dimensions.sidebar_entry_icon_size / 2 + ozone->animations.scroll_y_sidebar, video_info->width, video_info->height, 0, 1, (selected ? ozone->theme->text_selected : ozone->theme->entries_icon));
|
||||
|
||||
|
||||
/* Text */
|
||||
ticker.idx = ozone->frame_count / 20;
|
||||
ticker.len = 19;
|
||||
ticker.len = (entry_width - ozone->dimensions.sidebar_entry_icon_size - 35) / ozone->sidebar_font_glyph_width;
|
||||
ticker.s = console_title;
|
||||
ticker.selected = selected;
|
||||
ticker.str = node->console_name;
|
||||
|
||||
menu_animation_ticker(&ticker);
|
||||
|
||||
ozone_draw_text(video_info, ozone, console_title, ozone->sidebar_offset + 115 - 10, y + FONT_SIZE_SIDEBAR + ozone->animations.scroll_y_sidebar, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.sidebar, (selected ? ozone->theme->text_selected_rgba : ozone->theme->text_rgba), true);
|
||||
ozone_draw_text(video_info, ozone, console_title, ozone->sidebar_offset + ozone->dimensions.sidebar_padding_horizontal + ozone->dimensions.sidebar_entry_icon_padding * 2 + ozone->dimensions.sidebar_entry_icon_size,
|
||||
y + ozone->dimensions.sidebar_entry_height / 2 + FONT_SIZE_SIDEBAR * 3/8 + ozone->animations.scroll_y_sidebar, TEXT_ALIGN_LEFT,
|
||||
video_info->width, video_info->height, ozone->fonts.sidebar, (selected ? ozone->theme->text_selected_rgba : ozone->theme->text_rgba), true);
|
||||
|
||||
console_iterate:
|
||||
y += 65;
|
||||
y += ozone->dimensions.sidebar_entry_height + ozone->dimensions.sidebar_entry_padding_vertical;
|
||||
}
|
||||
|
||||
menu_display_blend_end(video_info);
|
||||
@ -281,13 +294,16 @@ void ozone_leave_sidebar(ozone_handle_t *ozone, uintptr_t tag)
|
||||
|
||||
unsigned ozone_get_selected_sidebar_y_position(ozone_handle_t *ozone)
|
||||
{
|
||||
return ozone->categories_selection_ptr * 65 + (ozone->categories_selection_ptr > ozone->system_tab_end ? 30 : 0);
|
||||
return ozone->categories_selection_ptr * ozone->dimensions.sidebar_entry_height +
|
||||
(ozone->categories_selection_ptr - 1) * ozone->dimensions.sidebar_entry_padding_vertical + ozone->dimensions.sidebar_padding_vertical +
|
||||
(ozone->categories_selection_ptr > ozone->system_tab_end ? ozone->dimensions.sidebar_entry_padding_vertical + 1 : 0);
|
||||
}
|
||||
|
||||
unsigned ozone_get_sidebar_height(ozone_handle_t *ozone)
|
||||
{
|
||||
return (ozone->system_tab_end + 1 + (ozone->horizontal_list ? ozone->horizontal_list->size : 0)) * 65
|
||||
+ (ozone->horizontal_list && ozone->horizontal_list->size > 0 ? 30 : 0);
|
||||
int entries = (ozone->system_tab_end + 1 + (ozone->horizontal_list ? ozone->horizontal_list->size : 0));
|
||||
return entries * ozone->dimensions.sidebar_entry_height + (entries - 1) * ozone->dimensions.sidebar_entry_padding_vertical + ozone->dimensions.sidebar_padding_vertical +
|
||||
(ozone->horizontal_list && ozone->horizontal_list->size > 0 ? ozone->dimensions.sidebar_entry_padding_vertical + 1 : 0);
|
||||
}
|
||||
|
||||
void ozone_sidebar_goto(ozone_handle_t *ozone, unsigned new_selection)
|
||||
@ -335,8 +351,8 @@ void ozone_sidebar_goto(ozone_handle_t *ozone, unsigned new_selection)
|
||||
/* Scroll animation */
|
||||
new_scroll = 0;
|
||||
selected_position_y = ozone_get_selected_sidebar_y_position(ozone);
|
||||
current_selection_middle_onscreen = ENTRIES_START_Y - 10 + ozone->animations.scroll_y_sidebar + selected_position_y + 65 / 2;
|
||||
bottom_boundary = video_info_height - 87 - 78;
|
||||
current_selection_middle_onscreen = ozone->dimensions.header_height + 1 + ozone->animations.scroll_y_sidebar + selected_position_y + ozone->dimensions.sidebar_entry_height / 2;
|
||||
bottom_boundary = video_info_height - (ozone->dimensions.header_height + 1) - ozone->dimensions.footer_height;
|
||||
entries_middle = video_info_height/2;
|
||||
entries_height = ozone_get_sidebar_height(ozone);
|
||||
|
||||
@ -344,7 +360,7 @@ void ozone_sidebar_goto(ozone_handle_t *ozone, unsigned new_selection)
|
||||
new_scroll = ozone->animations.scroll_y_sidebar - (current_selection_middle_onscreen - entries_middle);
|
||||
|
||||
if (new_scroll + entries_height < bottom_boundary)
|
||||
new_scroll = -(30 + entries_height - bottom_boundary);
|
||||
new_scroll = bottom_boundary - entries_height - ozone->dimensions.sidebar_padding_vertical;
|
||||
|
||||
if (new_scroll > 0)
|
||||
new_scroll = 0;
|
||||
|
@ -427,6 +427,7 @@ typedef struct
|
||||
uint32_t thumbnail_queue_size;
|
||||
bool show_wallpaper;
|
||||
char theme_preset_path[PATH_MAX_LENGTH]; /* Must be a fixed length array... */
|
||||
char menu_title[255]; /* Must be a fixed length array... */
|
||||
struct scaler_ctx image_scaler;
|
||||
} rgui_t;
|
||||
|
||||
@ -1616,20 +1617,17 @@ static void rgui_render(void *data, bool is_idle)
|
||||
else
|
||||
{
|
||||
/* No thumbnail - render usual text */
|
||||
char title[255];
|
||||
char title_buf[255];
|
||||
unsigned timedate_x = RGUI_TERM_WIDTH(fb_width) * FONT_WIDTH_STRIDE - RGUI_TERM_START_X(fb_width);
|
||||
unsigned core_name_len = ((timedate_x - RGUI_TERM_START_X(fb_width)) / FONT_WIDTH_STRIDE) - 3;
|
||||
bool show_core_name = settings->bools.menu_core_enable;
|
||||
|
||||
/* Print title */
|
||||
title[0] = title_buf[0] = '\0';
|
||||
|
||||
menu_entries_get_title(title, sizeof(title));
|
||||
title_buf[0] = '\0';
|
||||
|
||||
ticker.s = title_buf;
|
||||
ticker.len = RGUI_TERM_WIDTH(fb_width) - 10;
|
||||
ticker.str = title;
|
||||
ticker.str = rgui->menu_title;
|
||||
ticker.selected = true;
|
||||
|
||||
menu_animation_ticker(&ticker);
|
||||
@ -1844,6 +1842,8 @@ static void *rgui_init(void **userdata, bool video_is_threaded)
|
||||
|
||||
*userdata = rgui;
|
||||
|
||||
rgui->menu_title[0] = '\0';
|
||||
|
||||
/* Prepare RGUI colors, to improve performance */
|
||||
rgui->theme_preset_path[0] = '\0';
|
||||
prepare_rgui_colors(rgui, settings);
|
||||
@ -2081,7 +2081,6 @@ static void rgui_update_thumbnail_content(void *userdata)
|
||||
{
|
||||
rgui_t *rgui = (rgui_t*)userdata;
|
||||
playlist_t *playlist = NULL;
|
||||
char title[255];
|
||||
size_t selection = menu_navigation_get_selection();
|
||||
|
||||
if (!rgui)
|
||||
@ -2090,11 +2089,9 @@ static void rgui_update_thumbnail_content(void *userdata)
|
||||
/* Check whether current selection is a playlist entry
|
||||
* (i.e. whether we should be looking for a thumbnail image) */
|
||||
rgui->is_playlist_entry = false;
|
||||
title[0] = '\0';
|
||||
menu_entries_get_title(title, sizeof(title));
|
||||
if (!string_is_empty(rgui->thumbnail_playlist))
|
||||
{
|
||||
if (string_is_equal(path_basename(title), rgui->thumbnail_playlist))
|
||||
if (string_is_equal(path_basename(rgui->menu_title), rgui->thumbnail_playlist))
|
||||
{
|
||||
/* Get label of currently selected playlist entry
|
||||
* > This is pretty nasty, but I can't see any other way of doing
|
||||
@ -2212,6 +2209,12 @@ static void rgui_populate_entries(void *data,
|
||||
const char *path,
|
||||
const char *label, unsigned k)
|
||||
{
|
||||
rgui_t *rgui = (rgui_t*)data;
|
||||
|
||||
if (!rgui)
|
||||
return;
|
||||
|
||||
menu_entries_get_title(rgui->menu_title, sizeof(rgui->menu_title));
|
||||
rgui_navigation_set(data, true);
|
||||
}
|
||||
|
||||
|
@ -5397,6 +5397,9 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist
|
||||
menu_displaylist_parse_settings_enum(menu, info,
|
||||
MENU_ENUM_LABEL_SCREENSHOTS_IN_CONTENT_DIR_ENABLE,
|
||||
PARSE_ONLY_BOOL, false);
|
||||
menu_displaylist_parse_settings_enum(menu, info,
|
||||
MENU_ENUM_LABEL_CONTENT_RUNTIME_LOG,
|
||||
PARSE_ONLY_BOOL, false);
|
||||
|
||||
info->need_refresh = true;
|
||||
info->need_push = true;
|
||||
|
@ -531,6 +531,7 @@ bool menu_display_libretro(bool is_idle,
|
||||
input_driver_set_libretro_input_blocked();
|
||||
|
||||
core_run();
|
||||
rarch_core_runtime_tick();
|
||||
input_driver_unset_libretro_input_blocked();
|
||||
|
||||
return true;
|
||||
|
@ -4833,9 +4833,25 @@ static bool setting_append_list(
|
||||
&setting_get_string_representation_uint_autosave_interval;
|
||||
#endif
|
||||
|
||||
CONFIG_BOOL(
|
||||
list, list_info,
|
||||
&settings->bools.content_runtime_log,
|
||||
MENU_ENUM_LABEL_CONTENT_RUNTIME_LOG,
|
||||
MENU_ENUM_LABEL_VALUE_CONTENT_RUNTIME_LOG,
|
||||
content_runtime_log,
|
||||
MENU_ENUM_LABEL_VALUE_OFF,
|
||||
MENU_ENUM_LABEL_VALUE_ON,
|
||||
&group_info,
|
||||
&subgroup_info,
|
||||
parent_group,
|
||||
general_write_handler,
|
||||
general_read_handler,
|
||||
SD_FLAG_NONE);
|
||||
|
||||
END_SUB_GROUP(list, list_info, parent_group);
|
||||
END_GROUP(list, list_info, parent_group);
|
||||
}
|
||||
|
||||
break;
|
||||
case SETTINGS_LIST_REWIND:
|
||||
START_GROUP(list, list_info, &group_info, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_REWIND_SETTINGS), parent_group);
|
||||
|
@ -2253,6 +2253,7 @@ enum msg_hash_enums
|
||||
MENU_LABEL(MENU_SOUND_NOTICE),
|
||||
MENU_LABEL(MENU_SOUND_BGM),
|
||||
MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER_FALLBACK,
|
||||
MENU_LABEL(CONTENT_RUNTIME_LOG),
|
||||
|
||||
MSG_LAST
|
||||
};
|
||||
|
376
playlist.c
376
playlist.c
@ -45,6 +45,9 @@ struct playlist_entry
|
||||
char *core_name;
|
||||
char *db_name;
|
||||
char *crc32;
|
||||
unsigned runtime_hours;
|
||||
unsigned runtime_minutes;
|
||||
unsigned runtime_seconds;
|
||||
};
|
||||
|
||||
struct content_playlist
|
||||
@ -67,6 +70,8 @@ typedef struct
|
||||
unsigned array_depth;
|
||||
unsigned object_depth;
|
||||
char **current_entry_val;
|
||||
int *current_entry_int_val;
|
||||
unsigned *current_entry_uint_val;
|
||||
char *current_meta_string;
|
||||
bool in_items;
|
||||
} JSONContext;
|
||||
@ -125,6 +130,27 @@ void playlist_get_index(playlist_t *playlist,
|
||||
*crc32 = playlist->entries[idx].crc32;
|
||||
}
|
||||
|
||||
void playlist_get_runtime_index(playlist_t *playlist,
|
||||
size_t idx,
|
||||
const char **path, const char **core_path,
|
||||
unsigned *runtime_hours, unsigned *runtime_minutes,
|
||||
unsigned *runtime_seconds)
|
||||
{
|
||||
if (!playlist)
|
||||
return;
|
||||
|
||||
if (path)
|
||||
*path = playlist->entries[idx].path;
|
||||
if (core_path)
|
||||
*core_path = playlist->entries[idx].core_path;
|
||||
if (runtime_hours)
|
||||
*runtime_hours = playlist->entries[idx].runtime_hours;
|
||||
if (runtime_minutes)
|
||||
*runtime_minutes = playlist->entries[idx].runtime_minutes;
|
||||
if (runtime_seconds)
|
||||
*runtime_seconds = playlist->entries[idx].runtime_seconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* playlist_delete_index:
|
||||
* @playlist : Playlist handle.
|
||||
@ -223,6 +249,9 @@ static void playlist_free_entry(struct playlist_entry *entry)
|
||||
entry->core_name = NULL;
|
||||
entry->db_name = NULL;
|
||||
entry->crc32 = NULL;
|
||||
entry->runtime_hours = 0;
|
||||
entry->runtime_minutes = 0;
|
||||
entry->runtime_seconds = 0;
|
||||
}
|
||||
|
||||
void playlist_update(playlist_t *playlist, size_t idx,
|
||||
@ -288,6 +317,146 @@ void playlist_update(playlist_t *playlist, size_t idx,
|
||||
}
|
||||
}
|
||||
|
||||
void playlist_update_runtime(playlist_t *playlist, size_t idx,
|
||||
const char *path, const char *core_path,
|
||||
unsigned runtime_hours, unsigned runtime_minutes,
|
||||
unsigned runtime_seconds)
|
||||
{
|
||||
struct playlist_entry *entry = NULL;
|
||||
|
||||
if (!playlist || idx > playlist->size)
|
||||
return;
|
||||
|
||||
entry = &playlist->entries[idx];
|
||||
|
||||
if (path && (path != entry->path))
|
||||
{
|
||||
if (entry->path != NULL)
|
||||
free(entry->path);
|
||||
entry->path = strdup(path);
|
||||
playlist->modified = true;
|
||||
}
|
||||
|
||||
if (core_path && (core_path != entry->core_path))
|
||||
{
|
||||
if (entry->core_path != NULL)
|
||||
free(entry->core_path);
|
||||
entry->core_path = NULL;
|
||||
entry->core_path = strdup(core_path);
|
||||
playlist->modified = true;
|
||||
}
|
||||
|
||||
if (runtime_hours != entry->runtime_hours)
|
||||
{
|
||||
entry->runtime_hours = runtime_hours;
|
||||
playlist->modified = true;
|
||||
}
|
||||
|
||||
if (runtime_minutes != entry->runtime_minutes)
|
||||
{
|
||||
entry->runtime_minutes = runtime_minutes;
|
||||
playlist->modified = true;
|
||||
}
|
||||
|
||||
if (runtime_seconds != entry->runtime_seconds)
|
||||
{
|
||||
entry->runtime_seconds = runtime_seconds;
|
||||
playlist->modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool playlist_push_runtime(playlist_t *playlist,
|
||||
const char *path, const char *core_path,
|
||||
unsigned runtime_hours, unsigned runtime_minutes,
|
||||
unsigned runtime_seconds)
|
||||
{
|
||||
size_t i;
|
||||
bool core_path_empty = string_is_empty(core_path);
|
||||
|
||||
if (core_path_empty)
|
||||
{
|
||||
RARCH_ERR("cannot push NULL or empty core name into the playlist.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string_is_empty(path))
|
||||
path = NULL;
|
||||
|
||||
if (!playlist)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < playlist->size; i++)
|
||||
{
|
||||
struct playlist_entry tmp;
|
||||
bool equal_path;
|
||||
|
||||
equal_path = (!path && !playlist->entries[i].path) ||
|
||||
(path && playlist->entries[i].path &&
|
||||
#ifdef _WIN32
|
||||
/*prevent duplicates on case-insensitive operating systems*/
|
||||
string_is_equal_noncase(path,playlist->entries[i].path)
|
||||
#else
|
||||
string_is_equal(path,playlist->entries[i].path)
|
||||
#endif
|
||||
);
|
||||
|
||||
/* Core name can have changed while still being the same core.
|
||||
* Differentiate based on the core path only. */
|
||||
if (!equal_path)
|
||||
continue;
|
||||
|
||||
if (!string_is_equal(playlist->entries[i].core_path, core_path))
|
||||
continue;
|
||||
|
||||
/* If top entry, we don't want to push a new entry since
|
||||
* the top and the entry to be pushed are the same. */
|
||||
if (i == 0)
|
||||
return false;
|
||||
|
||||
/* Seen it before, bump to top. */
|
||||
tmp = playlist->entries[i];
|
||||
memmove(playlist->entries + 1, playlist->entries,
|
||||
i * sizeof(struct playlist_entry));
|
||||
playlist->entries[0] = tmp;
|
||||
|
||||
goto success;
|
||||
}
|
||||
|
||||
if (playlist->size == playlist->cap)
|
||||
{
|
||||
struct playlist_entry *entry = &playlist->entries[playlist->cap - 1];
|
||||
|
||||
if (entry)
|
||||
playlist_free_entry(entry);
|
||||
playlist->size--;
|
||||
}
|
||||
|
||||
if (playlist->entries)
|
||||
{
|
||||
memmove(playlist->entries + 1, playlist->entries,
|
||||
(playlist->cap - 1) * sizeof(struct playlist_entry));
|
||||
|
||||
playlist->entries[0].path = NULL;
|
||||
playlist->entries[0].core_path = NULL;
|
||||
|
||||
if (!string_is_empty(path))
|
||||
playlist->entries[0].path = strdup(path);
|
||||
if (!string_is_empty(core_path))
|
||||
playlist->entries[0].core_path = strdup(core_path);
|
||||
|
||||
playlist->entries[0].runtime_hours = runtime_hours;
|
||||
playlist->entries[0].runtime_minutes = runtime_minutes;
|
||||
playlist->entries[0].runtime_seconds = runtime_seconds;
|
||||
}
|
||||
|
||||
playlist->size++;
|
||||
|
||||
success:
|
||||
playlist->modified = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* playlist_push:
|
||||
* @playlist : Playlist handle.
|
||||
@ -380,12 +549,15 @@ bool playlist_push(playlist_t *playlist,
|
||||
memmove(playlist->entries + 1, playlist->entries,
|
||||
(playlist->cap - 1) * sizeof(struct playlist_entry));
|
||||
|
||||
playlist->entries[0].path = NULL;
|
||||
playlist->entries[0].label = NULL;
|
||||
playlist->entries[0].core_path = NULL;
|
||||
playlist->entries[0].core_name = NULL;
|
||||
playlist->entries[0].db_name = NULL;
|
||||
playlist->entries[0].crc32 = NULL;
|
||||
playlist->entries[0].path = NULL;
|
||||
playlist->entries[0].label = NULL;
|
||||
playlist->entries[0].core_path = NULL;
|
||||
playlist->entries[0].core_name = NULL;
|
||||
playlist->entries[0].db_name = NULL;
|
||||
playlist->entries[0].crc32 = NULL;
|
||||
playlist->entries[0].runtime_hours = 0;
|
||||
playlist->entries[0].runtime_minutes = 0;
|
||||
playlist->entries[0].runtime_seconds = 0;
|
||||
if (!string_is_empty(path))
|
||||
playlist->entries[0].path = strdup(path);
|
||||
if (!string_is_empty(label))
|
||||
@ -435,6 +607,136 @@ static void JSONLogError(JSONContext *pCtx)
|
||||
}
|
||||
}
|
||||
|
||||
void playlist_write_runtime_file(playlist_t *playlist)
|
||||
{
|
||||
size_t i;
|
||||
RFILE *file = NULL;
|
||||
settings_t *settings = config_get_ptr();
|
||||
JSONContext context = {0};
|
||||
|
||||
if (!playlist || !playlist->modified)
|
||||
return;
|
||||
|
||||
file = filestream_open(playlist->conf_path,
|
||||
RETRO_VFS_FILE_ACCESS_WRITE, RETRO_VFS_FILE_ACCESS_HINT_NONE);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
RARCH_ERR("Failed to write to playlist file: %s\n", playlist->conf_path);
|
||||
return;
|
||||
}
|
||||
|
||||
context.writer = JSON_Writer_Create(NULL);
|
||||
context.file = file;
|
||||
|
||||
if (!context.writer)
|
||||
{
|
||||
RARCH_ERR("Failed to create JSON writer\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
JSON_Writer_SetOutputEncoding(context.writer, JSON_UTF8);
|
||||
JSON_Writer_SetOutputHandler(context.writer, &JSONOutputHandler);
|
||||
JSON_Writer_SetUserData(context.writer, &context);
|
||||
|
||||
JSON_Writer_WriteStartObject(context.writer);
|
||||
JSON_Writer_WriteNewLine(context.writer);
|
||||
JSON_Writer_WriteSpace(context.writer, 2);
|
||||
JSON_Writer_WriteString(context.writer, "version", strlen("version"), JSON_UTF8);
|
||||
JSON_Writer_WriteColon(context.writer);
|
||||
JSON_Writer_WriteSpace(context.writer, 1);
|
||||
JSON_Writer_WriteString(context.writer, "1.0", strlen("1.0"), JSON_UTF8);
|
||||
JSON_Writer_WriteComma(context.writer);
|
||||
JSON_Writer_WriteNewLine(context.writer);
|
||||
JSON_Writer_WriteSpace(context.writer, 2);
|
||||
JSON_Writer_WriteString(context.writer, "items", strlen("items"), JSON_UTF8);
|
||||
JSON_Writer_WriteColon(context.writer);
|
||||
JSON_Writer_WriteSpace(context.writer, 1);
|
||||
JSON_Writer_WriteStartArray(context.writer);
|
||||
JSON_Writer_WriteNewLine(context.writer);
|
||||
|
||||
for (i = 0; i < playlist->size; i++)
|
||||
{
|
||||
JSON_Writer_WriteSpace(context.writer, 4);
|
||||
JSON_Writer_WriteStartObject(context.writer);
|
||||
|
||||
JSON_Writer_WriteNewLine(context.writer);
|
||||
JSON_Writer_WriteSpace(context.writer, 6);
|
||||
JSON_Writer_WriteString(context.writer, "path", strlen("path"), JSON_UTF8);
|
||||
JSON_Writer_WriteColon(context.writer);
|
||||
JSON_Writer_WriteSpace(context.writer, 1);
|
||||
JSON_Writer_WriteString(context.writer, playlist->entries[i].path ? playlist->entries[i].path : "", playlist->entries[i].path ? strlen(playlist->entries[i].path) : 0, JSON_UTF8);
|
||||
JSON_Writer_WriteComma(context.writer);
|
||||
|
||||
JSON_Writer_WriteNewLine(context.writer);
|
||||
JSON_Writer_WriteSpace(context.writer, 6);
|
||||
JSON_Writer_WriteString(context.writer, "core_path", strlen("core_path"), JSON_UTF8);
|
||||
JSON_Writer_WriteColon(context.writer);
|
||||
JSON_Writer_WriteSpace(context.writer, 1);
|
||||
JSON_Writer_WriteString(context.writer, playlist->entries[i].core_path, strlen(playlist->entries[i].core_path), JSON_UTF8);
|
||||
JSON_Writer_WriteComma(context.writer);
|
||||
JSON_Writer_WriteNewLine(context.writer);
|
||||
|
||||
{
|
||||
char tmp[32] = {0};
|
||||
|
||||
snprintf(tmp, sizeof(tmp), "%u", playlist->entries[i].runtime_hours);
|
||||
|
||||
JSON_Writer_WriteSpace(context.writer, 6);
|
||||
JSON_Writer_WriteString(context.writer, "runtime_hours", strlen("runtime_hours"), JSON_UTF8);
|
||||
JSON_Writer_WriteColon(context.writer);
|
||||
JSON_Writer_WriteSpace(context.writer, 1);
|
||||
JSON_Writer_WriteNumber(context.writer, tmp, strlen(tmp), JSON_UTF8);
|
||||
JSON_Writer_WriteComma(context.writer);
|
||||
JSON_Writer_WriteNewLine(context.writer);
|
||||
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
|
||||
snprintf(tmp, sizeof(tmp), "%u", playlist->entries[i].runtime_minutes);
|
||||
|
||||
JSON_Writer_WriteSpace(context.writer, 6);
|
||||
JSON_Writer_WriteString(context.writer, "runtime_minutes", strlen("runtime_minutes"), JSON_UTF8);
|
||||
JSON_Writer_WriteColon(context.writer);
|
||||
JSON_Writer_WriteSpace(context.writer, 1);
|
||||
JSON_Writer_WriteNumber(context.writer, tmp, strlen(tmp), JSON_UTF8);
|
||||
JSON_Writer_WriteComma(context.writer);
|
||||
JSON_Writer_WriteNewLine(context.writer);
|
||||
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
|
||||
snprintf(tmp, sizeof(tmp), "%u", playlist->entries[i].runtime_seconds);
|
||||
|
||||
JSON_Writer_WriteSpace(context.writer, 6);
|
||||
JSON_Writer_WriteString(context.writer, "runtime_seconds", strlen("runtime_seconds"), JSON_UTF8);
|
||||
JSON_Writer_WriteColon(context.writer);
|
||||
JSON_Writer_WriteSpace(context.writer, 1);
|
||||
JSON_Writer_WriteNumber(context.writer, tmp, strlen(tmp), JSON_UTF8);
|
||||
JSON_Writer_WriteNewLine(context.writer);
|
||||
}
|
||||
|
||||
JSON_Writer_WriteSpace(context.writer, 4);
|
||||
JSON_Writer_WriteEndObject(context.writer);
|
||||
|
||||
if (i < playlist->size - 1)
|
||||
JSON_Writer_WriteComma(context.writer);
|
||||
|
||||
JSON_Writer_WriteNewLine(context.writer);
|
||||
}
|
||||
|
||||
JSON_Writer_WriteSpace(context.writer, 2);
|
||||
JSON_Writer_WriteEndArray(context.writer);
|
||||
JSON_Writer_WriteNewLine(context.writer);
|
||||
JSON_Writer_WriteEndObject(context.writer);
|
||||
JSON_Writer_WriteNewLine(context.writer);
|
||||
JSON_Writer_Free(context.writer);
|
||||
|
||||
playlist->modified = false;
|
||||
|
||||
RARCH_LOG("Written to playlist file: %s\n", playlist->conf_path);
|
||||
end:
|
||||
filestream_close(file);
|
||||
}
|
||||
|
||||
void playlist_write_file(playlist_t *playlist)
|
||||
{
|
||||
size_t i;
|
||||
@ -735,6 +1037,9 @@ static JSON_Parser_HandlerResult JSONStringHandler(JSON_Parser parser, char *pVa
|
||||
{
|
||||
if (pCtx->current_entry_val && length && !string_is_empty(pValue))
|
||||
{
|
||||
if (*pCtx->current_entry_val)
|
||||
free(*pCtx->current_entry_val);
|
||||
|
||||
*pCtx->current_entry_val = strdup(pValue);
|
||||
}
|
||||
else
|
||||
@ -753,6 +1058,7 @@ static JSON_Parser_HandlerResult JSONStringHandler(JSON_Parser parser, char *pVa
|
||||
/*RARCH_LOG("found meta: %s = %s\n", pCtx->current_meta_string, pValue);*/
|
||||
|
||||
free(pCtx->current_meta_string);
|
||||
pCtx->current_meta_string = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -762,6 +1068,50 @@ static JSON_Parser_HandlerResult JSONStringHandler(JSON_Parser parser, char *pVa
|
||||
return JSON_Parser_Continue;
|
||||
}
|
||||
|
||||
static JSON_Parser_HandlerResult JSONNumberHandler(JSON_Parser parser, char *pValue, size_t length, JSON_StringAttributes attributes)
|
||||
{
|
||||
JSONContext *pCtx = (JSONContext*)JSON_Parser_GetUserData(parser);
|
||||
(void)attributes; /* unused */
|
||||
|
||||
if (pCtx->in_items && pCtx->object_depth == 2)
|
||||
{
|
||||
if (pCtx->array_depth == 1)
|
||||
{
|
||||
if (pCtx->current_entry_int_val && length && !string_is_empty(pValue))
|
||||
{
|
||||
*pCtx->current_entry_int_val = strtoul(pValue, NULL, 10);
|
||||
}
|
||||
else if (pCtx->current_entry_uint_val && length && !string_is_empty(pValue))
|
||||
{
|
||||
*pCtx->current_entry_uint_val = strtoul(pValue, NULL, 10);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* must be a value for an unknown member we aren't tracking, skip it */
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (pCtx->object_depth == 1)
|
||||
{
|
||||
if (pCtx->array_depth == 0)
|
||||
{
|
||||
if (pCtx->current_meta_string && length && !string_is_empty(pValue))
|
||||
{
|
||||
/* handle any top-level playlist metadata here */
|
||||
/*RARCH_LOG("found meta: %s = %s\n", pCtx->current_meta_string, pValue);*/
|
||||
|
||||
free(pCtx->current_meta_string);
|
||||
pCtx->current_meta_string = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pCtx->current_entry_int_val = NULL;
|
||||
pCtx->current_entry_uint_val = NULL;
|
||||
|
||||
return JSON_Parser_Continue;
|
||||
}
|
||||
|
||||
static JSON_Parser_HandlerResult JSONObjectMemberHandler(JSON_Parser parser, char *pValue, size_t length, JSON_StringAttributes attributes)
|
||||
{
|
||||
JSONContext *pCtx = (JSONContext*)JSON_Parser_GetUserData(parser);
|
||||
@ -792,6 +1142,12 @@ static JSON_Parser_HandlerResult JSONObjectMemberHandler(JSON_Parser parser, cha
|
||||
pCtx->current_entry_val = &pCtx->current_entry->crc32;
|
||||
else if (string_is_equal(pValue, "db_name"))
|
||||
pCtx->current_entry_val = &pCtx->current_entry->db_name;
|
||||
else if (string_is_equal(pValue, "runtime_hours"))
|
||||
pCtx->current_entry_uint_val = &pCtx->current_entry->runtime_hours;
|
||||
else if (string_is_equal(pValue, "runtime_minutes"))
|
||||
pCtx->current_entry_uint_val = &pCtx->current_entry->runtime_minutes;
|
||||
else if (string_is_equal(pValue, "runtime_seconds"))
|
||||
pCtx->current_entry_uint_val = &pCtx->current_entry->runtime_seconds;
|
||||
else
|
||||
{
|
||||
/* ignore unknown members */
|
||||
@ -805,6 +1161,9 @@ static JSON_Parser_HandlerResult JSONObjectMemberHandler(JSON_Parser parser, cha
|
||||
{
|
||||
if (length)
|
||||
{
|
||||
if (pCtx->current_meta_string)
|
||||
free(pCtx->current_meta_string);
|
||||
|
||||
pCtx->current_meta_string = strdup(pValue);
|
||||
}
|
||||
}
|
||||
@ -886,10 +1245,10 @@ static bool playlist_read_file(
|
||||
|
||||
/*JSON_Parser_SetNullHandler(context.parser, &JSONNullHandler);
|
||||
JSON_Parser_SetBooleanHandler(context.parser, &JSONBooleanHandler);
|
||||
JSON_Parser_SetNumberHandler(context.parser, &JSONNumberHandler);
|
||||
JSON_Parser_SetSpecialNumberHandler(context.parser, &JSONSpecialNumberHandler);
|
||||
JSON_Parser_SetArrayItemHandler(context.parser, &JSONArrayItemHandler);*/
|
||||
|
||||
JSON_Parser_SetNumberHandler(context.parser, &JSONNumberHandler);
|
||||
JSON_Parser_SetStringHandler(context.parser, &JSONStringHandler);
|
||||
JSON_Parser_SetStartObjectHandler(context.parser, &JSONStartObjectHandler);
|
||||
JSON_Parser_SetEndObjectHandler(context.parser, &JSONEndObjectHandler);
|
||||
@ -928,6 +1287,9 @@ static bool playlist_read_file(
|
||||
}
|
||||
|
||||
JSON_Parser_Free(context.parser);
|
||||
|
||||
if (context.current_meta_string)
|
||||
free(context.current_meta_string);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
18
playlist.h
18
playlist.h
@ -79,6 +79,12 @@ void playlist_get_index(playlist_t *playlist,
|
||||
const char **db_name,
|
||||
const char **crc32);
|
||||
|
||||
void playlist_get_runtime_index(playlist_t *playlist,
|
||||
size_t idx,
|
||||
const char **path, const char **core_path,
|
||||
unsigned *runtime_hours, unsigned *runtime_minutes,
|
||||
unsigned *runtime_seconds);
|
||||
|
||||
/**
|
||||
* playlist_delete_index:
|
||||
* @playlist : Playlist handle.
|
||||
@ -104,12 +110,22 @@ bool playlist_push(playlist_t *playlist,
|
||||
const char *crc32,
|
||||
const char *db_name);
|
||||
|
||||
bool playlist_push_runtime(playlist_t *playlist,
|
||||
const char *path, const char *core_path,
|
||||
unsigned runtime_hours, unsigned runtime_minutes,
|
||||
unsigned runtime_seconds);
|
||||
|
||||
void playlist_update(playlist_t *playlist, size_t idx,
|
||||
const char *path, const char *label,
|
||||
const char *core_path, const char *core_name,
|
||||
const char *crc32,
|
||||
const char *db_name);
|
||||
|
||||
void playlist_update_runtime(playlist_t *playlist, size_t idx,
|
||||
const char *path, const char *core_path,
|
||||
unsigned runtime_hours, unsigned runtime_minutes,
|
||||
unsigned runtime_seconds);
|
||||
|
||||
void playlist_get_index_by_path(playlist_t *playlist,
|
||||
const char *search_path,
|
||||
char **path, char **label,
|
||||
@ -127,6 +143,8 @@ uint32_t playlist_get_size(playlist_t *playlist);
|
||||
|
||||
void playlist_write_file(playlist_t *playlist);
|
||||
|
||||
void playlist_write_runtime_file(playlist_t *playlist);
|
||||
|
||||
void playlist_qsort(playlist_t *playlist);
|
||||
|
||||
void playlist_free_cached(void);
|
||||
|
95
retroarch.c
95
retroarch.c
@ -102,6 +102,8 @@
|
||||
#include "file_path_special.h"
|
||||
#include "ui/ui_companion_driver.h"
|
||||
#include "verbosity.h"
|
||||
#include "defaults.h"
|
||||
#include "playlist.h"
|
||||
|
||||
#include "frontend/frontend_driver.h"
|
||||
#include "audio/audio_driver.h"
|
||||
@ -263,11 +265,20 @@ static unsigned fastforward_after_frames = 0;
|
||||
static retro_usec_t runloop_frame_time_last = 0;
|
||||
static retro_time_t frame_limit_minimum_time = 0.0;
|
||||
static retro_time_t frame_limit_last_time = 0.0;
|
||||
static retro_time_t libretro_core_runtime_usec = 0;
|
||||
|
||||
extern bool input_driver_flushing_input;
|
||||
|
||||
static char launch_arguments[4096];
|
||||
|
||||
void rarch_core_runtime_tick(void)
|
||||
{
|
||||
struct retro_system_av_info *av_info = video_viewport_get_system_av_info();
|
||||
|
||||
if (av_info && av_info->timing.fps)
|
||||
libretro_core_runtime_usec += (1.0 / av_info->timing.fps) * 1000 * 1000;
|
||||
}
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
void runloop_msg_queue_lock(void)
|
||||
{
|
||||
@ -1813,6 +1824,82 @@ bool rarch_ctl(enum rarch_ctl_state state, void *data)
|
||||
/ (av_info->timing.fps * fastforward_ratio));
|
||||
}
|
||||
break;
|
||||
case RARCH_CTL_CONTENT_RUNTIME_LOG_INIT:
|
||||
libretro_core_runtime_usec = 0;
|
||||
break;
|
||||
case RARCH_CTL_CONTENT_RUNTIME_LOG_DEINIT:
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
unsigned seconds = libretro_core_runtime_usec / 1000 / 1000;
|
||||
unsigned minutes = seconds / 60;
|
||||
unsigned hours = minutes / 60;
|
||||
char log[PATH_MAX_LENGTH] = {0};
|
||||
size_t pos = 0;
|
||||
|
||||
seconds -= minutes * 60;
|
||||
seconds -= hours * 60 *60;
|
||||
|
||||
pos = strlcpy(log, "Content ran for a total of", sizeof(log));
|
||||
|
||||
if (hours > 0)
|
||||
pos += snprintf(log + pos, sizeof(log) - pos, ", %d hours", hours);
|
||||
|
||||
if (minutes > 0)
|
||||
pos += snprintf(log + pos, sizeof(log) - pos, ", %d minutes", minutes);
|
||||
|
||||
pos += snprintf(log + pos, sizeof(log) - pos, ", %d seconds", seconds);
|
||||
|
||||
if (pos < sizeof(log) - 2)
|
||||
{
|
||||
log[pos++] = '.';
|
||||
log[pos++] = '\n';
|
||||
}
|
||||
|
||||
RARCH_LOG(log);
|
||||
|
||||
if (settings->bools.content_runtime_log && g_defaults.content_runtime)
|
||||
{
|
||||
const char *path = path_get(RARCH_PATH_CONTENT);
|
||||
const char *core_path = path_get(RARCH_PATH_CORE);
|
||||
|
||||
if (!string_is_empty(path) && !string_is_empty(core_path))
|
||||
{
|
||||
playlist_push_runtime(g_defaults.content_runtime, path_get(RARCH_PATH_CONTENT), path_get(RARCH_PATH_CORE), 0, 0, 0);
|
||||
|
||||
/* if entry already existed, the runtime won't be updated, so manually update it again */
|
||||
if (playlist_get_size(g_defaults.content_runtime) > 0)
|
||||
{
|
||||
unsigned runtime_hours = 0;
|
||||
unsigned runtime_minutes = 0;
|
||||
unsigned runtime_seconds = 0;
|
||||
|
||||
playlist_get_runtime_index(g_defaults.content_runtime, 0, NULL, NULL, &runtime_hours, &runtime_minutes, &runtime_seconds);
|
||||
|
||||
runtime_seconds += seconds;
|
||||
|
||||
if (runtime_seconds >= 60)
|
||||
{
|
||||
runtime_minutes += runtime_seconds / 60;
|
||||
runtime_seconds -= runtime_minutes * 60;
|
||||
}
|
||||
|
||||
runtime_minutes += minutes;
|
||||
|
||||
if (runtime_minutes >= 60)
|
||||
{
|
||||
runtime_hours += runtime_minutes / 60;
|
||||
runtime_minutes -= runtime_hours * 60;
|
||||
}
|
||||
|
||||
runtime_hours += hours;
|
||||
|
||||
playlist_update_runtime(g_defaults.content_runtime, 0, path_get(RARCH_PATH_CONTENT), path_get(RARCH_PATH_CORE), runtime_hours, runtime_minutes, runtime_seconds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case RARCH_CTL_GET_PERFCNT:
|
||||
{
|
||||
bool **perfcnt = (bool**)data;
|
||||
@ -3685,10 +3772,16 @@ int runloop_iterate(unsigned *sleep_ms)
|
||||
)
|
||||
run_ahead(run_ahead_num_frames, settings->bools.run_ahead_secondary_instance);
|
||||
else
|
||||
{
|
||||
core_run();
|
||||
rarch_core_runtime_tick();
|
||||
}
|
||||
}
|
||||
#else
|
||||
core_run();
|
||||
{
|
||||
core_run();
|
||||
rarch_core_runtime_tick();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CHEEVOS
|
||||
|
@ -897,3 +897,6 @@
|
||||
|
||||
# File format to use when writing playlists to disk
|
||||
# playlist_use_old_format = false
|
||||
|
||||
# Keep track of how long each core+content has been running for over time
|
||||
# content_runtime_log = false
|
||||
|
@ -183,7 +183,10 @@ enum rarch_ctl_state
|
||||
|
||||
/* HTTP server */
|
||||
RARCH_CTL_HTTPSERVER_INIT,
|
||||
RARCH_CTL_HTTPSERVER_DESTROY
|
||||
RARCH_CTL_HTTPSERVER_DESTROY,
|
||||
|
||||
RARCH_CTL_CONTENT_RUNTIME_LOG_INIT,
|
||||
RARCH_CTL_CONTENT_RUNTIME_LOG_DEINIT
|
||||
};
|
||||
|
||||
enum rarch_capabilities
|
||||
@ -417,6 +420,8 @@ void runloop_msg_queue_unlock(void);
|
||||
|
||||
void rarch_force_video_driver_fallback(const char *driver);
|
||||
|
||||
void rarch_core_runtime_tick(void);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user