show widget for loaded game

This commit is contained in:
Jamiras 2021-11-07 15:53:03 -07:00
parent a410cf1377
commit a3b508f136
5 changed files with 153 additions and 38 deletions

View File

@ -307,7 +307,7 @@ void rcheevos_award_achievement(rcheevos_locals_t* locals,
/* Show the on screen message. */
#if defined(HAVE_GFX_WIDGETS)
if (widgets_ready)
gfx_widgets_push_achievement(cheevo->title, cheevo->badge);
gfx_widgets_push_achievement(msg_hash_to_str(MSG_ACHIEVEMENT_UNLOCKED), cheevo->title, cheevo->badge);
else
#endif
{
@ -1285,7 +1285,14 @@ static void rcheevos_show_game_placard()
CHEEVOS_LOG(RCHEEVOS_TAG "%s\n", msg);
if (settings->bools.cheevos_verbose_enable)
runloop_msg_queue_push(msg, 0, 3 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
{
#if defined (HAVE_GFX_WIDGETS)
if (gfx_widgets_ready())
gfx_widgets_push_achievement(rcheevos_locals.game.title, msg, rcheevos_locals.game.badge_name);
else
#endif
runloop_msg_queue_push(msg, 0, 3 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
}
}
static void rcheevos_end_load(void)

View File

@ -99,6 +99,29 @@ typedef struct rcheevos_async_io_request
char type;
} rcheevos_async_io_request;
#ifdef HAVE_THREADS
#define RCHEEVOS_CONCURRENT_BADGE_DOWNLOADS 2
#else
#define RCHEEVOS_CONCURRENT_BADGE_DOWNLOADS 1
#endif
typedef struct rcheevos_fetch_badge_state
{
unsigned badge_fetch_index;
unsigned locked_badge_fetch_index;
const char* badge_directory;
rcheevos_client_callback callback;
void* callback_data;
char requested_badges[
RCHEEVOS_CONCURRENT_BADGE_DOWNLOADS][32];
} rcheevos_fetch_badge_state;
typedef struct rcheevos_fetch_badge_data
{
rcheevos_fetch_badge_state* state;
int request_index;
} rcheevos_fetch_badge_data;
/****************************
* forward declarations *
@ -111,6 +134,10 @@ static void rcheevos_async_http_task_callback(
static void rcheevos_async_end_request(rcheevos_async_io_request* request);
static void rcheevos_async_fetch_badge_callback(
struct rcheevos_async_io_request* request,
http_transfer_data_t* data, char buffer[], size_t buffer_size);
/****************************
* user agent construction *
****************************/
@ -893,6 +920,98 @@ static void rcheevos_client_initialize_runtime_callback(void* userdata)
free(runtime_data);
}
static void rcheevos_client_fetch_game_badge_callback(void* userdata)
{
rcheevos_fetch_badge_data* data = (rcheevos_fetch_badge_data*)userdata;
rcheevos_async_initialize_runtime_data_t* runtime_data =
(rcheevos_async_initialize_runtime_data_t*)data->state->callback_data;
free((void*)data->state->badge_directory);
free(data->state);
free(data);
rcheevos_client_initialize_runtime_callback(runtime_data);
}
static void rcheevos_client_fetch_game_badge(const char* badge_name, rcheevos_async_initialize_runtime_data_t* runtime_data)
{
#if defined(HAVE_GFX_WIDGETS) /* don't need game badge unless widgets are enabled */
char badge_fullpath[PATH_MAX_LENGTH] = "";
char* badge_fullname = NULL;
size_t badge_fullname_size = 0;
/* make sure the directory exists */
fill_pathname_application_special(badge_fullpath,
sizeof(badge_fullpath),
APPLICATION_SPECIAL_DIRECTORY_THUMBNAILS_CHEEVOS_BADGES);
if (!path_is_directory(badge_fullpath))
{
CHEEVOS_LOG(RCHEEVOS_TAG "Creating %s\n", badge_fullpath);
path_mkdir(badge_fullpath);
}
fill_pathname_slash(badge_fullpath, sizeof(badge_fullpath));
badge_fullname = badge_fullpath + strlen(badge_fullpath);
badge_fullname_size = sizeof(badge_fullpath) -
(badge_fullname - badge_fullpath);
snprintf(badge_fullname,
badge_fullname_size, "i%s" FILE_PATH_PNG_EXTENSION, badge_name);
/* check if it's already available */
if (path_is_valid(badge_fullpath))
return;
#ifdef CHEEVOS_LOG_BADGES
CHEEVOS_LOG(RCHEEVOS_TAG "Downloading game badge %s\n", badge_name);
#endif
{
rcheevos_async_io_request* request = (rcheevos_async_io_request*)
calloc(1, sizeof(rcheevos_async_io_request));
rcheevos_fetch_badge_data* data = (rcheevos_fetch_badge_data*)
calloc(1, sizeof(rcheevos_fetch_badge_data));
rcheevos_fetch_badge_state* state = (rcheevos_fetch_badge_state*)
calloc(1, sizeof(rcheevos_fetch_badge_state));
if (!request || !data || !state)
{
CHEEVOS_LOG(RCHEEVOS_TAG
"Failed to allocate fetch badge request\n");
}
else
{
rc_api_fetch_image_request_t api_params;
int result;
memset(&api_params, 0, sizeof(api_params));
api_params.image_name = badge_name;
api_params.image_type = RC_IMAGE_TYPE_GAME;
result = rc_api_init_fetch_image_request(&request->request, &api_params);
strlcpy(state->requested_badges[0], badge_fullname, sizeof(state->requested_badges[0]));
*badge_fullname = '\0';
state->badge_directory = strdup(badge_fullpath);
state->callback_data = runtime_data;
data->state = state;
data->request_index = 0;
request->callback = rcheevos_client_fetch_game_badge_callback;
request->callback_data = data;
rcheevos_begin_load_state(RCHEEVOS_LOAD_STATE_FETCHING_GAME_DATA);
rcheevos_async_begin_request(request, result,
rcheevos_async_fetch_badge_callback,
CHEEVOS_ASYNC_FETCH_BADGE, atoi(badge_name), NULL,
"Error fetching game badge");
}
}
#endif
}
static void rcheevos_async_fetch_user_unlocks_callback(
struct rcheevos_async_io_request* request,
http_transfer_data_t* data, char buffer[], size_t buffer_size)
@ -939,6 +1058,10 @@ static void rcheevos_async_fetch_game_data_callback(
runtime_data->game_data.title);
rcheevos_locals->game.console_id =
runtime_data->game_data.console_id;
snprintf(rcheevos_locals->game.badge_name, sizeof(rcheevos_locals->game.badge_name),
"i%s", runtime_data->game_data.image_name);
rcheevos_client_fetch_game_badge(runtime_data->game_data.image_name, runtime_data);
}
}
@ -1238,30 +1361,6 @@ void rcheevos_client_start_session(unsigned game_id)
* fetch badge *
****************************/
#ifdef HAVE_THREADS
#define RCHEEVOS_CONCURRENT_BADGE_DOWNLOADS 2
#else
#define RCHEEVOS_CONCURRENT_BADGE_DOWNLOADS 1
#endif
typedef struct rcheevos_fetch_badge_state
{
unsigned badge_fetch_index;
unsigned locked_badge_fetch_index;
const char* badge_directory;
rcheevos_client_callback callback;
void* callback_data;
char requested_badges[
RCHEEVOS_CONCURRENT_BADGE_DOWNLOADS][32];
} rcheevos_fetch_badge_state;
typedef struct rcheevos_fetch_badge_data
{
rcheevos_fetch_badge_state* state;
int request_index;
} rcheevos_fetch_badge_data;
static bool rcheevos_fetch_next_badge(rcheevos_fetch_badge_state* state);
static void rcheevos_end_fetch_badges(rcheevos_fetch_badge_state* state)

View File

@ -125,6 +125,7 @@ typedef struct rcheevos_game_info_t
int id;
int console_id;
char* title;
char badge_name[16];
char hash[33];
rcheevos_racheevo_t* achievements;

View File

@ -110,12 +110,6 @@ typedef struct
gfx_widget_font_data_t msg_queue;
} gfx_widget_fonts_t;
typedef struct cheevo_popup
{
char* title;
uintptr_t badge;
} cheevo_popup;
typedef struct disp_widget_msg
{
char *msg;
@ -353,7 +347,7 @@ void gfx_widgets_ai_service_overlay_unload(void);
#endif
#ifdef HAVE_CHEEVOS
void gfx_widgets_push_achievement(const char *title, const char *badge);
void gfx_widgets_push_achievement(const char *title, const char* subtitle, const char *badge);
void gfx_widgets_set_leaderboard_display(unsigned id, const char* value);
void gfx_widgets_set_challenge_display(unsigned id, const char* badge);
#endif

View File

@ -32,6 +32,13 @@
#define CHEEVO_QUEUE_SIZE 8
typedef struct cheevo_popup
{
char* title;
char* subtitle;
uintptr_t badge;
} cheevo_popup;
struct gfx_widget_achievement_popup_state
{
#ifdef HAVE_THREADS
@ -222,7 +229,7 @@ static void gfx_widget_achievement_popup_frame(void* data, void* userdata)
/* Title */
gfx_widgets_draw_text(&p_dispwidget->gfx_widget_fonts.regular,
msg_hash_to_str(MSG_ACHIEVEMENT_UNLOCKED),
state->queue[state->queue_read_index].title,
state->height + p_dispwidget->simple_widget_padding - unfold_offet,
state->y + p_dispwidget->gfx_widget_fonts.regular.line_height
+ p_dispwidget->gfx_widget_fonts.regular.line_ascender,
@ -235,7 +242,7 @@ static void gfx_widget_achievement_popup_frame(void* data, void* userdata)
/* TODO: is a ticker necessary ? */
gfx_widgets_draw_text(&p_dispwidget->gfx_widget_fonts.regular,
state->queue[state->queue_read_index].title,
state->queue[state->queue_read_index].subtitle,
state->height + p_dispwidget->simple_widget_padding - unfold_offet,
state->y + state->height
- p_dispwidget->gfx_widget_fonts.regular.line_height
@ -267,6 +274,12 @@ static void gfx_widget_achievement_popup_free_current(
state->queue[state->queue_read_index].title = NULL;
}
if (state->queue[state->queue_read_index].subtitle)
{
free(state->queue[state->queue_read_index].subtitle);
state->queue[state->queue_read_index].subtitle = NULL;
}
if (state->queue[state->queue_read_index].badge)
{
video_driver_texture_unload(&state->queue[state->queue_read_index].badge);
@ -370,10 +383,10 @@ static void gfx_widget_achievement_popup_start(
state->width = MAX(
font_driver_get_message_width(
p_dispwidget->gfx_widget_fonts.regular.font,
msg_hash_to_str(MSG_ACHIEVEMENT_UNLOCKED), 0, 1),
state->queue[state->queue_read_index].title, 0, 1),
font_driver_get_message_width(
p_dispwidget->gfx_widget_fonts.regular.font,
state->queue[state->queue_read_index].title, 0, 1)
state->queue[state->queue_read_index].subtitle, 0, 1)
);
state->width += p_dispwidget->simple_widget_padding * 2;
state->y = (float)(-(int)state->height);
@ -391,7 +404,7 @@ static void gfx_widget_achievement_popup_start(
gfx_animation_push(&entry);
}
void gfx_widgets_push_achievement(const char *title, const char *badge)
void gfx_widgets_push_achievement(const char *title, const char* subtitle, const char *badge)
{
gfx_widget_achievement_popup_state_t *state = &p_w_achievement_popup_st;
int start_notification = 1;
@ -429,6 +442,7 @@ void gfx_widgets_push_achievement(const char *title, const char *badge)
state->queue[state->queue_write_index].badge = badge_id;
state->queue[state->queue_write_index].title = strdup(title);
state->queue[state->queue_write_index].subtitle = strdup(subtitle);
state->queue_write_index = (state->queue_write_index + 1) % ARRAY_SIZE(state->queue);