(Cheevos) Style nits:
* single line code blocks - remove brackets * Try to fit lines into 80 chars * Etc
This commit is contained in:
parent
b9df71b9d5
commit
05ca465aab
|
@ -119,24 +119,28 @@ void rcheevos_log(const char *fmt, ...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void rcheevos_achievement_disabled(rcheevos_racheevo_t* cheevo, unsigned address)
|
static void rcheevos_achievement_disabled(
|
||||||
|
rcheevos_racheevo_t* cheevo, unsigned address)
|
||||||
{
|
{
|
||||||
if (!cheevo)
|
if (!cheevo)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CHEEVOS_ERR(RCHEEVOS_TAG "Achievement %u disabled (invalid address %06X): %s\n",
|
CHEEVOS_ERR(RCHEEVOS_TAG
|
||||||
|
"Achievement %u disabled (invalid address %06X): %s\n",
|
||||||
cheevo->id, address, cheevo->title);
|
cheevo->id, address, cheevo->title);
|
||||||
CHEEVOS_FREE(cheevo->memaddr);
|
CHEEVOS_FREE(cheevo->memaddr);
|
||||||
cheevo->memaddr = NULL;
|
cheevo->memaddr = NULL;
|
||||||
cheevo->active |= RCHEEVOS_ACTIVE_UNSUPPORTED;
|
cheevo->active |= RCHEEVOS_ACTIVE_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rcheevos_lboard_disabled(rcheevos_ralboard_t* lboard, unsigned address)
|
static void rcheevos_lboard_disabled(
|
||||||
|
rcheevos_ralboard_t* lboard, unsigned address)
|
||||||
{
|
{
|
||||||
if (!lboard)
|
if (!lboard)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CHEEVOS_ERR(RCHEEVOS_TAG "Leaderboard %u disabled (invalid address %06X): %s\n",
|
CHEEVOS_ERR(RCHEEVOS_TAG
|
||||||
|
"Leaderboard %u disabled (invalid address %06X): %s\n",
|
||||||
lboard->id, address, lboard->title);
|
lboard->id, address, lboard->title);
|
||||||
CHEEVOS_FREE(lboard->mem);
|
CHEEVOS_FREE(lboard->mem);
|
||||||
lboard->mem = NULL;
|
lboard->mem = NULL;
|
||||||
|
@ -147,7 +151,8 @@ static void rcheevos_handle_log_message(const char* message)
|
||||||
CHEEVOS_LOG(RCHEEVOS_TAG "%s\n", message);
|
CHEEVOS_LOG(RCHEEVOS_TAG "%s\n", message);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rcheevos_get_core_memory_info(unsigned id, rc_libretro_core_memory_info_t* info)
|
static void rcheevos_get_core_memory_info(unsigned id,
|
||||||
|
rc_libretro_core_memory_info_t* info)
|
||||||
{
|
{
|
||||||
retro_ctx_memory_info_t ctx_info;
|
retro_ctx_memory_info_t ctx_info;
|
||||||
if (!info)
|
if (!info)
|
||||||
|
@ -180,9 +185,11 @@ static int rcheevos_init_memory(rcheevos_locals_t* locals)
|
||||||
mmap.descriptors = &descriptors[0];
|
mmap.descriptors = &descriptors[0];
|
||||||
mmap.num_descriptors = mmaps->num_descriptors;
|
mmap.num_descriptors = mmaps->num_descriptors;
|
||||||
|
|
||||||
/* RetroArch wraps the retro_memory_descriptor's in rarch_memory_descriptor_t's, pull them back out */
|
/* RetroArch wraps the retro_memory_descriptor's
|
||||||
|
* in rarch_memory_descriptor_t's, pull them back out */
|
||||||
for (i = 0; i < mmap.num_descriptors; ++i)
|
for (i = 0; i < mmap.num_descriptors; ++i)
|
||||||
memcpy(&descriptors[i], &mmaps->descriptors[i].core, sizeof(descriptors[0]));
|
memcpy(&descriptors[i], &mmaps->descriptors[i].core,
|
||||||
|
sizeof(descriptors[0]));
|
||||||
|
|
||||||
rc_libretro_init_verbose_message_callback(rcheevos_handle_log_message);
|
rc_libretro_init_verbose_message_callback(rcheevos_handle_log_message);
|
||||||
result = rc_libretro_memory_init(&locals->memory, &mmap,
|
result = rc_libretro_memory_init(&locals->memory, &mmap,
|
||||||
|
@ -194,18 +201,19 @@ static int rcheevos_init_memory(rcheevos_locals_t* locals)
|
||||||
|
|
||||||
uint8_t* rcheevos_patch_address(unsigned address)
|
uint8_t* rcheevos_patch_address(unsigned address)
|
||||||
{
|
{
|
||||||
|
/* Memory map was not previously initialized
|
||||||
|
* (no achievements for this game?), try now */
|
||||||
if (rcheevos_locals.memory.count == 0)
|
if (rcheevos_locals.memory.count == 0)
|
||||||
{
|
|
||||||
/* memory map was not previously initialized (no achievements for this game?) try now */
|
|
||||||
rcheevos_init_memory(&rcheevos_locals);
|
rcheevos_init_memory(&rcheevos_locals);
|
||||||
}
|
|
||||||
|
|
||||||
return rc_libretro_memory_find(&rcheevos_locals.memory, address);
|
return rc_libretro_memory_find(&rcheevos_locals.memory, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned rcheevos_peek(unsigned address, unsigned num_bytes, void* ud)
|
static unsigned rcheevos_peek(unsigned address,
|
||||||
|
unsigned num_bytes, void* ud)
|
||||||
{
|
{
|
||||||
uint8_t* data = rc_libretro_memory_find(&rcheevos_locals.memory, address);
|
uint8_t* data = rc_libretro_memory_find(
|
||||||
|
&rcheevos_locals.memory, address);
|
||||||
|
|
||||||
if (data)
|
if (data)
|
||||||
{
|
{
|
||||||
switch (num_bytes)
|
switch (num_bytes)
|
||||||
|
@ -227,12 +235,13 @@ static unsigned rcheevos_peek(unsigned address, unsigned num_bytes, void* ud)
|
||||||
|
|
||||||
static void rcheevos_activate_achievements(void)
|
static void rcheevos_activate_achievements(void)
|
||||||
{
|
{
|
||||||
|
unsigned i;
|
||||||
|
int result;
|
||||||
rcheevos_racheevo_t* achievement = rcheevos_locals.game.achievements;
|
rcheevos_racheevo_t* achievement = rcheevos_locals.game.achievements;
|
||||||
settings_t* settings = config_get_ptr();
|
settings_t* settings = config_get_ptr();
|
||||||
int result;
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
for (i = 0; i < rcheevos_locals.game.achievement_count; i++, achievement++)
|
for (i = 0; i < rcheevos_locals.game.achievement_count;
|
||||||
|
i++, achievement++)
|
||||||
{
|
{
|
||||||
if ((achievement->active & (RCHEEVOS_ACTIVE_HARDCORE | RCHEEVOS_ACTIVE_SOFTCORE)) != 0)
|
if ((achievement->active & (RCHEEVOS_ACTIVE_HARDCORE | RCHEEVOS_ACTIVE_SOFTCORE)) != 0)
|
||||||
{
|
{
|
||||||
|
@ -265,7 +274,8 @@ static void rcheevos_activate_achievements(void)
|
||||||
static rcheevos_racheevo_t* rcheevos_find_cheevo(unsigned id)
|
static rcheevos_racheevo_t* rcheevos_find_cheevo(unsigned id)
|
||||||
{
|
{
|
||||||
rcheevos_racheevo_t* cheevo = rcheevos_locals.game.achievements;
|
rcheevos_racheevo_t* cheevo = rcheevos_locals.game.achievements;
|
||||||
rcheevos_racheevo_t* stop = cheevo + rcheevos_locals.game.achievement_count;
|
rcheevos_racheevo_t* stop = cheevo
|
||||||
|
+ rcheevos_locals.game.achievement_count;
|
||||||
|
|
||||||
for(; cheevo < stop; ++cheevo)
|
for(; cheevo < stop; ++cheevo)
|
||||||
{
|
{
|
||||||
|
@ -299,9 +309,7 @@ void rcheevos_award_achievement(rcheevos_locals_t* locals,
|
||||||
/* Show the on screen message. */
|
/* Show the on screen message. */
|
||||||
#if defined(HAVE_GFX_WIDGETS)
|
#if defined(HAVE_GFX_WIDGETS)
|
||||||
if (widgets_ready)
|
if (widgets_ready)
|
||||||
{
|
|
||||||
gfx_widgets_push_achievement(cheevo->title, cheevo->badge);
|
gfx_widgets_push_achievement(cheevo->title, cheevo->badge);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
@ -314,19 +322,20 @@ void rcheevos_award_achievement(rcheevos_locals_t* locals,
|
||||||
MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
|
MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Start the award task (unofficial achievement unlocks are not submitted). */
|
/* Start the award task (unofficial achievement
|
||||||
|
* unlocks are not submitted). */
|
||||||
if (!(cheevo->active & RCHEEVOS_ACTIVE_UNOFFICIAL))
|
if (!(cheevo->active & RCHEEVOS_ACTIVE_UNOFFICIAL))
|
||||||
rcheevos_client_award_achievement(cheevo->id);
|
rcheevos_client_award_achievement(cheevo->id);
|
||||||
|
|
||||||
/* play the unlock sound */
|
|
||||||
#ifdef HAVE_AUDIOMIXER
|
#ifdef HAVE_AUDIOMIXER
|
||||||
|
/* Play the unlock sound */
|
||||||
if (settings->bools.cheevos_unlock_sound_enable)
|
if (settings->bools.cheevos_unlock_sound_enable)
|
||||||
audio_driver_mixer_play_menu_sound(
|
audio_driver_mixer_play_menu_sound(
|
||||||
AUDIO_MIXER_SYSTEM_SLOT_ACHIEVEMENT_UNLOCK);
|
AUDIO_MIXER_SYSTEM_SLOT_ACHIEVEMENT_UNLOCK);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Take a screenshot of the achievement. */
|
|
||||||
#ifdef HAVE_SCREENSHOTS
|
#ifdef HAVE_SCREENSHOTS
|
||||||
|
/* Take a screenshot of the achievement. */
|
||||||
if (settings->bools.cheevos_auto_screenshot)
|
if (settings->bools.cheevos_auto_screenshot)
|
||||||
{
|
{
|
||||||
size_t shotname_len = sizeof(char) * 8192;
|
size_t shotname_len = sizeof(char) * 8192;
|
||||||
|
@ -344,10 +353,12 @@ void rcheevos_award_achievement(rcheevos_locals_t* locals,
|
||||||
shotname, true,
|
shotname, true,
|
||||||
video_driver_cached_frame_has_valid_framebuffer(),
|
video_driver_cached_frame_has_valid_framebuffer(),
|
||||||
false, true))
|
false, true))
|
||||||
CHEEVOS_LOG(RCHEEVOS_TAG "Captured screenshot for achievement %u\n",
|
CHEEVOS_LOG(RCHEEVOS_TAG
|
||||||
|
"Captured screenshot for achievement %u\n",
|
||||||
cheevo->id);
|
cheevo->id);
|
||||||
else
|
else
|
||||||
CHEEVOS_LOG(RCHEEVOS_TAG "Failed to capture screenshot for achievement %u\n",
|
CHEEVOS_LOG(RCHEEVOS_TAG
|
||||||
|
"Failed to capture screenshot for achievement %u\n",
|
||||||
cheevo->id);
|
cheevo->id);
|
||||||
|
|
||||||
free(shotname);
|
free(shotname);
|
||||||
|
@ -359,7 +370,8 @@ void rcheevos_award_achievement(rcheevos_locals_t* locals,
|
||||||
static rcheevos_ralboard_t* rcheevos_find_lboard(unsigned id)
|
static rcheevos_ralboard_t* rcheevos_find_lboard(unsigned id)
|
||||||
{
|
{
|
||||||
rcheevos_ralboard_t* lboard = rcheevos_locals.game.leaderboards;
|
rcheevos_ralboard_t* lboard = rcheevos_locals.game.leaderboards;
|
||||||
rcheevos_ralboard_t* stop = lboard + rcheevos_locals.game.leaderboard_count;
|
rcheevos_ralboard_t* stop = lboard
|
||||||
|
+ rcheevos_locals.game.leaderboard_count;
|
||||||
|
|
||||||
for (; lboard < stop; ++lboard)
|
for (; lboard < stop; ++lboard)
|
||||||
{
|
{
|
||||||
|
@ -376,7 +388,8 @@ static void rcheevos_lboard_submit(rcheevos_locals_t* locals,
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
char formatted_value[16];
|
char formatted_value[16];
|
||||||
|
|
||||||
rc_runtime_format_lboard_value(formatted_value, sizeof(formatted_value),
|
rc_runtime_format_lboard_value(formatted_value,
|
||||||
|
sizeof(formatted_value),
|
||||||
value, lboard->format);
|
value, lboard->format);
|
||||||
CHEEVOS_LOG(RCHEEVOS_TAG "Submitting %s for leaderboard %u\n",
|
CHEEVOS_LOG(RCHEEVOS_TAG "Submitting %s for leaderboard %u\n",
|
||||||
formatted_value, lboard->id);
|
formatted_value, lboard->id);
|
||||||
|
@ -421,7 +434,8 @@ static void rcheevos_lboard_canceled(rcheevos_ralboard_t * lboard,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rcheevos_lboard_started(rcheevos_ralboard_t * lboard, int value,
|
static void rcheevos_lboard_started(
|
||||||
|
rcheevos_ralboard_t * lboard, int value,
|
||||||
bool widgets_ready)
|
bool widgets_ready)
|
||||||
{
|
{
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
|
@ -434,7 +448,8 @@ static void rcheevos_lboard_started(rcheevos_ralboard_t * lboard, int value,
|
||||||
#if defined(HAVE_GFX_WIDGETS)
|
#if defined(HAVE_GFX_WIDGETS)
|
||||||
if (widgets_ready && rcheevos_locals.leaderboard_trackers)
|
if (widgets_ready && rcheevos_locals.leaderboard_trackers)
|
||||||
{
|
{
|
||||||
rc_runtime_format_lboard_value(buffer, sizeof(buffer), value, lboard->format);
|
rc_runtime_format_lboard_value(buffer,
|
||||||
|
sizeof(buffer), value, lboard->format);
|
||||||
gfx_widgets_set_leaderboard_display(lboard->id, buffer);
|
gfx_widgets_set_leaderboard_display(lboard->id, buffer);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -456,8 +471,8 @@ static void rcheevos_lboard_started(rcheevos_ralboard_t * lboard, int value,
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_GFX_WIDGETS)
|
#if defined(HAVE_GFX_WIDGETS)
|
||||||
|
static void rcheevos_lboard_updated(
|
||||||
static void rcheevos_lboard_updated(rcheevos_ralboard_t* lboard, int value,
|
rcheevos_ralboard_t* lboard, int value,
|
||||||
bool widgets_ready)
|
bool widgets_ready)
|
||||||
{
|
{
|
||||||
if (!lboard)
|
if (!lboard)
|
||||||
|
@ -466,20 +481,25 @@ static void rcheevos_lboard_updated(rcheevos_ralboard_t* lboard, int value,
|
||||||
if (widgets_ready && rcheevos_locals.leaderboard_trackers)
|
if (widgets_ready && rcheevos_locals.leaderboard_trackers)
|
||||||
{
|
{
|
||||||
char buffer[32];
|
char buffer[32];
|
||||||
rc_runtime_format_lboard_value(buffer, sizeof(buffer), value, lboard->format);
|
rc_runtime_format_lboard_value(buffer,
|
||||||
|
sizeof(buffer), value, lboard->format);
|
||||||
gfx_widgets_set_leaderboard_display(lboard->id, buffer);
|
gfx_widgets_set_leaderboard_display(lboard->id, buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rcheevos_challenge_started(rcheevos_racheevo_t* cheevo, int value,
|
static void rcheevos_challenge_started(
|
||||||
|
rcheevos_racheevo_t* cheevo, int value,
|
||||||
bool widgets_ready)
|
bool widgets_ready)
|
||||||
{
|
{
|
||||||
settings_t* settings = config_get_ptr();
|
settings_t* settings = config_get_ptr();
|
||||||
if (cheevo && widgets_ready && settings->bools.cheevos_challenge_indicators)
|
if ( cheevo
|
||||||
|
&& widgets_ready
|
||||||
|
&& settings->bools.cheevos_challenge_indicators)
|
||||||
gfx_widgets_set_challenge_display(cheevo->id, cheevo->badge);
|
gfx_widgets_set_challenge_display(cheevo->id, cheevo->badge);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rcheevos_challenge_ended(rcheevos_racheevo_t* cheevo, int value,
|
static void rcheevos_challenge_ended(
|
||||||
|
rcheevos_racheevo_t* cheevo, int value,
|
||||||
bool widgets_ready)
|
bool widgets_ready)
|
||||||
{
|
{
|
||||||
if (cheevo && widgets_ready)
|
if (cheevo && widgets_ready)
|
||||||
|
@ -490,11 +510,12 @@ static void rcheevos_challenge_ended(rcheevos_racheevo_t* cheevo, int value,
|
||||||
|
|
||||||
int rcheevos_get_richpresence(char buffer[], int buffer_size)
|
int rcheevos_get_richpresence(char buffer[], int buffer_size)
|
||||||
{
|
{
|
||||||
int ret = rc_runtime_get_richpresence(&rcheevos_locals.runtime, buffer, buffer_size, &rcheevos_peek, NULL, NULL);
|
int ret = rc_runtime_get_richpresence(
|
||||||
|
&rcheevos_locals.runtime, buffer, buffer_size,
|
||||||
|
&rcheevos_peek, NULL, NULL);
|
||||||
|
|
||||||
if (ret <= 0 && rcheevos_locals.game.title)
|
if (ret <= 0 && rcheevos_locals.game.title)
|
||||||
ret = snprintf(buffer, buffer_size, "Playing %s", rcheevos_locals.game.title);
|
return snprintf(buffer, buffer_size, "Playing %s", rcheevos_locals.game.title);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,16 +525,15 @@ void rcheevos_reset_game(bool widgets_ready)
|
||||||
/* Hide any visible trackers */
|
/* Hide any visible trackers */
|
||||||
if (widgets_ready)
|
if (widgets_ready)
|
||||||
{
|
{
|
||||||
rcheevos_ralboard_t* lboard;
|
|
||||||
rcheevos_racheevo_t* cheevo;
|
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
rcheevos_racheevo_t* cheevo;
|
||||||
lboard = rcheevos_locals.game.leaderboards;
|
rcheevos_ralboard_t* lboard = rcheevos_locals.game.leaderboards;
|
||||||
for (i = 0; i < rcheevos_locals.game.leaderboard_count; ++i, ++lboard)
|
for (i = 0; i < rcheevos_locals.game.leaderboard_count;
|
||||||
|
++i, ++lboard)
|
||||||
gfx_widgets_set_leaderboard_display(lboard->id, NULL);
|
gfx_widgets_set_leaderboard_display(lboard->id, NULL);
|
||||||
|
|
||||||
cheevo = rcheevos_locals.game.achievements;
|
cheevo = rcheevos_locals.game.achievements;
|
||||||
for (i = 0; i < rcheevos_locals.game.achievement_count; ++i, ++cheevo)
|
for (i = 0; i < rcheevos_locals.game.achievement_count;
|
||||||
|
++i, ++cheevo)
|
||||||
gfx_widgets_set_challenge_display(cheevo->id, NULL);
|
gfx_widgets_set_challenge_display(cheevo->id, NULL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -542,7 +562,6 @@ static bool rcheevos_timer_check(void* userdata)
|
||||||
{
|
{
|
||||||
retro_time_t stop_time = *(retro_time_t*)userdata;
|
retro_time_t stop_time = *(retro_time_t*)userdata;
|
||||||
retro_time_t now = cpu_features_get_time_usec();
|
retro_time_t now = cpu_features_get_time_usec();
|
||||||
|
|
||||||
return (now < stop_time);
|
return (now < stop_time);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -561,8 +580,10 @@ bool rcheevos_unload(void)
|
||||||
rcheevos_locals.load_info.state = RCHEEVOS_LOAD_STATE_ABORTED;
|
rcheevos_locals.load_info.state = RCHEEVOS_LOAD_STATE_ABORTED;
|
||||||
CHEEVOS_LOG(RCHEEVOS_TAG "Asked the load tasks to terminate\n");
|
CHEEVOS_LOG(RCHEEVOS_TAG "Asked the load tasks to terminate\n");
|
||||||
|
|
||||||
task_queue_wait(rcheevos_timer_check, &stop_time); /* wait for pending tasks to run */
|
/* Wait for pending tasks to run */
|
||||||
task_queue_check(); /* clean up after completed tasks */
|
task_queue_wait(rcheevos_timer_check, &stop_time);
|
||||||
|
/* Clean up after completed tasks */
|
||||||
|
task_queue_check();
|
||||||
}
|
}
|
||||||
|
|
||||||
rcheevos_locals.queued_command = CMD_EVENT_NONE;
|
rcheevos_locals.queued_command = CMD_EVENT_NONE;
|
||||||
|
@ -580,7 +601,8 @@ bool rcheevos_unload(void)
|
||||||
{
|
{
|
||||||
CHEEVOS_FREE(rcheevos_locals.menuitems);
|
CHEEVOS_FREE(rcheevos_locals.menuitems);
|
||||||
rcheevos_locals.menuitems = NULL;
|
rcheevos_locals.menuitems = NULL;
|
||||||
rcheevos_locals.menuitem_capacity = rcheevos_locals.menuitem_count = 0;
|
rcheevos_locals.menuitem_capacity =
|
||||||
|
rcheevos_locals.menuitem_count = 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -609,7 +631,8 @@ bool rcheevos_unload(void)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rcheevos_toggle_hardcore_achievements(rcheevos_locals_t *locals)
|
static void rcheevos_toggle_hardcore_achievements(
|
||||||
|
rcheevos_locals_t *locals)
|
||||||
{
|
{
|
||||||
const unsigned active_mask =
|
const unsigned active_mask =
|
||||||
RCHEEVOS_ACTIVE_SOFTCORE | RCHEEVOS_ACTIVE_HARDCORE | RCHEEVOS_ACTIVE_UNSUPPORTED;
|
RCHEEVOS_ACTIVE_SOFTCORE | RCHEEVOS_ACTIVE_HARDCORE | RCHEEVOS_ACTIVE_UNSUPPORTED;
|
||||||
|
@ -640,17 +663,20 @@ static void rcheevos_toggle_hardcore_achievements(rcheevos_locals_t *locals)
|
||||||
|
|
||||||
static void rcheevos_activate_leaderboards(void)
|
static void rcheevos_activate_leaderboards(void)
|
||||||
{
|
{
|
||||||
rcheevos_ralboard_t* leaderboard = rcheevos_locals.game.leaderboards;
|
|
||||||
const settings_t* settings = config_get_ptr();
|
|
||||||
unsigned i;
|
unsigned i;
|
||||||
int result;
|
int result;
|
||||||
|
rcheevos_ralboard_t* leaderboard = rcheevos_locals.game.leaderboards;
|
||||||
|
const settings_t *settings = config_get_ptr();
|
||||||
|
|
||||||
for (i = 0; i < rcheevos_locals.game.leaderboard_count; ++i, ++leaderboard)
|
for (i = 0; i < rcheevos_locals.game.leaderboard_count;
|
||||||
|
++i, ++leaderboard)
|
||||||
{
|
{
|
||||||
if (!leaderboard->mem)
|
if (!leaderboard->mem)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
result = rc_runtime_activate_lboard(&rcheevos_locals.runtime, leaderboard->id, leaderboard->mem, NULL, 0);
|
result = rc_runtime_activate_lboard(
|
||||||
|
&rcheevos_locals.runtime, leaderboard->id,
|
||||||
|
leaderboard->mem, NULL, 0);
|
||||||
if (result != RC_OK)
|
if (result != RC_OK)
|
||||||
{
|
{
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
|
@ -673,13 +699,15 @@ static void rcheevos_activate_leaderboards(void)
|
||||||
static void rcheevos_deactivate_leaderboards()
|
static void rcheevos_deactivate_leaderboards()
|
||||||
{
|
{
|
||||||
rcheevos_ralboard_t* lboard = rcheevos_locals.game.leaderboards;
|
rcheevos_ralboard_t* lboard = rcheevos_locals.game.leaderboards;
|
||||||
rcheevos_ralboard_t* stop = lboard + rcheevos_locals.game.leaderboard_count;
|
rcheevos_ralboard_t* stop = lboard +
|
||||||
|
rcheevos_locals.game.leaderboard_count;
|
||||||
|
|
||||||
for (; lboard < stop; ++lboard)
|
for (; lboard < stop; ++lboard)
|
||||||
{
|
{
|
||||||
if (lboard->mem)
|
if (lboard->mem)
|
||||||
{
|
{
|
||||||
rc_runtime_deactivate_lboard(&rcheevos_locals.runtime, lboard->id);
|
rc_runtime_deactivate_lboard(&rcheevos_locals.runtime,
|
||||||
|
lboard->id);
|
||||||
|
|
||||||
#if defined(HAVE_GFX_WIDGETS)
|
#if defined(HAVE_GFX_WIDGETS)
|
||||||
/* Hide any visible trackers */
|
/* Hide any visible trackers */
|
||||||
|
@ -774,7 +802,8 @@ static void rcheevos_toggle_hardcore_active(rcheevos_locals_t* locals)
|
||||||
|
|
||||||
if (locals->loaded)
|
if (locals->loaded)
|
||||||
{
|
{
|
||||||
const char* msg = msg_hash_to_str(MSG_CHEEVOS_HARDCORE_MODE_ENABLE);
|
const char* msg = msg_hash_to_str(
|
||||||
|
MSG_CHEEVOS_HARDCORE_MODE_ENABLE);
|
||||||
CHEEVOS_LOG("%s\n", msg);
|
CHEEVOS_LOG("%s\n", msg);
|
||||||
runloop_msg_queue_push(msg, 0, 3 * 60, true, NULL,
|
runloop_msg_queue_push(msg, 0, 3 * 60, true, NULL,
|
||||||
MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
|
MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
|
||||||
|
@ -867,7 +896,8 @@ void rcheevos_validate_config_settings(void)
|
||||||
if (!system->library_name || !rcheevos_locals.hardcore_active)
|
if (!system->library_name || !rcheevos_locals.hardcore_active)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!(disallowed_settings = rc_libretro_get_disallowed_settings(system->library_name)))
|
if (!(disallowed_settings
|
||||||
|
= rc_libretro_get_disallowed_settings(system->library_name)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!retroarch_ctl(RARCH_CTL_CORE_OPTIONS_LIST_GET, &coreopts))
|
if (!retroarch_ctl(RARCH_CTL_CORE_OPTIONS_LIST_GET, &coreopts))
|
||||||
|
@ -880,7 +910,8 @@ void rcheevos_validate_config_settings(void)
|
||||||
if (!rc_libretro_is_setting_allowed(disallowed_settings, key, val))
|
if (!rc_libretro_is_setting_allowed(disallowed_settings, key, val))
|
||||||
{
|
{
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
snprintf(buffer, sizeof(buffer), "Hardcore paused. Setting not allowed: %s=%s", key, val);
|
snprintf(buffer, sizeof(buffer),
|
||||||
|
"Hardcore paused. Setting not allowed: %s=%s", key, val);
|
||||||
CHEEVOS_LOG(RCHEEVOS_TAG "%s\n", buffer);
|
CHEEVOS_LOG(RCHEEVOS_TAG "%s\n", buffer);
|
||||||
rcheevos_pause_hardcore();
|
rcheevos_pause_hardcore();
|
||||||
|
|
||||||
|
@ -892,7 +923,8 @@ void rcheevos_validate_config_settings(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rcheevos_runtime_event_handler(const rc_runtime_event_t* runtime_event)
|
static void rcheevos_runtime_event_handler(
|
||||||
|
const rc_runtime_event_t* runtime_event)
|
||||||
{
|
{
|
||||||
#if defined(HAVE_GFX_WIDGETS)
|
#if defined(HAVE_GFX_WIDGETS)
|
||||||
bool widgets_ready = gfx_widgets_ready();
|
bool widgets_ready = gfx_widgets_ready();
|
||||||
|
@ -904,41 +936,59 @@ static void rcheevos_runtime_event_handler(const rc_runtime_event_t* runtime_eve
|
||||||
{
|
{
|
||||||
#if defined(HAVE_GFX_WIDGETS)
|
#if defined(HAVE_GFX_WIDGETS)
|
||||||
case RC_RUNTIME_EVENT_LBOARD_UPDATED:
|
case RC_RUNTIME_EVENT_LBOARD_UPDATED:
|
||||||
rcheevos_lboard_updated(rcheevos_find_lboard(runtime_event->id), runtime_event->value, widgets_ready);
|
rcheevos_lboard_updated(
|
||||||
|
rcheevos_find_lboard(runtime_event->id),
|
||||||
|
runtime_event->value, widgets_ready);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RC_RUNTIME_EVENT_ACHIEVEMENT_PRIMED:
|
case RC_RUNTIME_EVENT_ACHIEVEMENT_PRIMED:
|
||||||
rcheevos_challenge_started(rcheevos_find_cheevo(runtime_event->id), runtime_event->value, widgets_ready);
|
rcheevos_challenge_started(
|
||||||
|
rcheevos_find_cheevo(runtime_event->id),
|
||||||
|
runtime_event->value, widgets_ready);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RC_RUNTIME_EVENT_ACHIEVEMENT_UNPRIMED:
|
case RC_RUNTIME_EVENT_ACHIEVEMENT_UNPRIMED:
|
||||||
rcheevos_challenge_ended(rcheevos_find_cheevo(runtime_event->id), runtime_event->value, widgets_ready);
|
rcheevos_challenge_ended(
|
||||||
|
rcheevos_find_cheevo(runtime_event->id),
|
||||||
|
runtime_event->value, widgets_ready);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED:
|
case RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED:
|
||||||
rcheevos_award_achievement(&rcheevos_locals, rcheevos_find_cheevo(runtime_event->id), widgets_ready);
|
rcheevos_award_achievement(
|
||||||
|
&rcheevos_locals,
|
||||||
|
rcheevos_find_cheevo(runtime_event->id), widgets_ready);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RC_RUNTIME_EVENT_LBOARD_STARTED:
|
case RC_RUNTIME_EVENT_LBOARD_STARTED:
|
||||||
rcheevos_lboard_started(rcheevos_find_lboard(runtime_event->id), runtime_event->value, widgets_ready);
|
rcheevos_lboard_started(
|
||||||
|
rcheevos_find_lboard(runtime_event->id),
|
||||||
|
runtime_event->value, widgets_ready);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RC_RUNTIME_EVENT_LBOARD_CANCELED:
|
case RC_RUNTIME_EVENT_LBOARD_CANCELED:
|
||||||
rcheevos_lboard_canceled(rcheevos_find_lboard(runtime_event->id),
|
rcheevos_lboard_canceled(
|
||||||
|
rcheevos_find_lboard(runtime_event->id),
|
||||||
widgets_ready);
|
widgets_ready);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RC_RUNTIME_EVENT_LBOARD_TRIGGERED:
|
case RC_RUNTIME_EVENT_LBOARD_TRIGGERED:
|
||||||
rcheevos_lboard_submit(&rcheevos_locals, rcheevos_find_lboard(runtime_event->id), runtime_event->value, widgets_ready);
|
rcheevos_lboard_submit(
|
||||||
|
&rcheevos_locals,
|
||||||
|
rcheevos_find_lboard(runtime_event->id),
|
||||||
|
runtime_event->value, widgets_ready);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RC_RUNTIME_EVENT_ACHIEVEMENT_DISABLED:
|
case RC_RUNTIME_EVENT_ACHIEVEMENT_DISABLED:
|
||||||
rcheevos_achievement_disabled(rcheevos_find_cheevo(runtime_event->id), runtime_event->value);
|
rcheevos_achievement_disabled(
|
||||||
|
rcheevos_find_cheevo(runtime_event->id),
|
||||||
|
runtime_event->value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RC_RUNTIME_EVENT_LBOARD_DISABLED:
|
case RC_RUNTIME_EVENT_LBOARD_DISABLED:
|
||||||
rcheevos_lboard_disabled(rcheevos_find_lboard(runtime_event->id), runtime_event->value);
|
rcheevos_lboard_disabled(
|
||||||
|
rcheevos_find_lboard(runtime_event->id),
|
||||||
|
runtime_event->value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -948,7 +998,8 @@ static void rcheevos_runtime_event_handler(const rc_runtime_event_t* runtime_eve
|
||||||
|
|
||||||
static int rcheevos_runtime_address_validator(unsigned address)
|
static int rcheevos_runtime_address_validator(unsigned address)
|
||||||
{
|
{
|
||||||
return (rc_libretro_memory_find(&rcheevos_locals.memory, address) != NULL);
|
return rc_libretro_memory_find(
|
||||||
|
&rcheevos_locals.memory, address) != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rcheevos_validate_memrefs(rcheevos_locals_t* locals)
|
static void rcheevos_validate_memrefs(rcheevos_locals_t* locals)
|
||||||
|
@ -959,11 +1010,13 @@ static void rcheevos_validate_memrefs(rcheevos_locals_t* locals)
|
||||||
* first call to retro_run. in that case, there will be a total_size
|
* first call to retro_run. in that case, there will be a total_size
|
||||||
* of memory reported by the core, but init will return false, as
|
* of memory reported by the core, but init will return false, as
|
||||||
* all of the pointers were null. if we're still loading the game,
|
* all of the pointers were null. if we're still loading the game,
|
||||||
* just reset the memory count and we'll re-evaluate in rcheevos_test()
|
* just reset the memory count and we'll re-evaluate in
|
||||||
|
* rcheevos_test()
|
||||||
*/
|
*/
|
||||||
if (!locals->loaded)
|
if (!locals->loaded)
|
||||||
{
|
{
|
||||||
/* if no memory was exposed, report the error now instead of waiting */
|
/* If no memory was exposed, report the error now
|
||||||
|
* instead of waiting */
|
||||||
if (locals->memory.total_size != 0)
|
if (locals->memory.total_size != 0)
|
||||||
{
|
{
|
||||||
locals->memory.count = 0;
|
locals->memory.count = 0;
|
||||||
|
@ -977,10 +1030,9 @@ static void rcheevos_validate_memrefs(rcheevos_locals_t* locals)
|
||||||
CHEEVOS_ERR(RCHEEVOS_TAG "No memory exposed by core\n");
|
CHEEVOS_ERR(RCHEEVOS_TAG "No memory exposed by core\n");
|
||||||
|
|
||||||
if (settings && settings->bools.cheevos_verbose_enable)
|
if (settings && settings->bools.cheevos_verbose_enable)
|
||||||
{
|
|
||||||
runloop_msg_queue_push(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CANNOT_ACTIVATE_ACHIEVEMENTS_WITH_THIS_CORE),
|
runloop_msg_queue_push(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CANNOT_ACTIVATE_ACHIEVEMENTS_WITH_THIS_CORE),
|
||||||
0, 4 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_WARNING);
|
0, 4 * 60, false, NULL,
|
||||||
}
|
MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_WARNING);
|
||||||
|
|
||||||
rcheevos_unload();
|
rcheevos_unload();
|
||||||
rcheevos_pause_hardcore();
|
rcheevos_pause_hardcore();
|
||||||
|
@ -988,7 +1040,8 @@ static void rcheevos_validate_memrefs(rcheevos_locals_t* locals)
|
||||||
}
|
}
|
||||||
|
|
||||||
rc_runtime_validate_addresses(&locals->runtime,
|
rc_runtime_validate_addresses(&locals->runtime,
|
||||||
rcheevos_runtime_event_handler, rcheevos_runtime_address_validator);
|
rcheevos_runtime_event_handler,
|
||||||
|
rcheevos_runtime_address_validator);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
@ -1007,13 +1060,12 @@ void rcheevos_test(void)
|
||||||
if (!rcheevos_locals.loaded)
|
if (!rcheevos_locals.loaded)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* We were unable to initialize memory earlier, try now */
|
||||||
if (rcheevos_locals.memory.count == 0)
|
if (rcheevos_locals.memory.count == 0)
|
||||||
{
|
|
||||||
/* we were unable to initialize memory earlier, try now */
|
|
||||||
rcheevos_validate_memrefs(&rcheevos_locals);
|
rcheevos_validate_memrefs(&rcheevos_locals);
|
||||||
}
|
|
||||||
|
|
||||||
rc_runtime_do_frame(&rcheevos_locals.runtime, &rcheevos_runtime_event_handler, rcheevos_peek, NULL, 0);
|
rc_runtime_do_frame(&rcheevos_locals.runtime,
|
||||||
|
&rcheevos_runtime_event_handler, rcheevos_peek, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t rcheevos_get_serialize_size(void)
|
size_t rcheevos_get_serialize_size(void)
|
||||||
|
@ -1027,14 +1079,17 @@ bool rcheevos_get_serialized_data(void* buffer)
|
||||||
{
|
{
|
||||||
if (!rcheevos_locals.loaded)
|
if (!rcheevos_locals.loaded)
|
||||||
return false;
|
return false;
|
||||||
return (rc_runtime_serialize_progress(buffer, &rcheevos_locals.runtime, NULL) == RC_OK);
|
return (rc_runtime_serialize_progress(
|
||||||
|
buffer, &rcheevos_locals.runtime, NULL) == RC_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rcheevos_set_serialized_data(void* buffer)
|
bool rcheevos_set_serialized_data(void* buffer)
|
||||||
{
|
{
|
||||||
if (rcheevos_locals.loaded)
|
if (rcheevos_locals.loaded)
|
||||||
{
|
{
|
||||||
if (buffer && rc_runtime_deserialize_progress(&rcheevos_locals.runtime, (const unsigned char*)buffer, NULL) == RC_OK)
|
if (buffer && rc_runtime_deserialize_progress(
|
||||||
|
&rcheevos_locals.runtime,
|
||||||
|
(const unsigned char*)buffer, NULL) == RC_OK)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
rc_runtime_reset(&rcheevos_locals.runtime);
|
rc_runtime_reset(&rcheevos_locals.runtime);
|
||||||
|
@ -1062,10 +1117,12 @@ const char* rcheevos_get_hash(void)
|
||||||
|
|
||||||
static void* rc_hash_handle_file_open(const char* path)
|
static void* rc_hash_handle_file_open(const char* path)
|
||||||
{
|
{
|
||||||
return intfstream_open_file(path, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE);
|
return intfstream_open_file(path,
|
||||||
|
RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rc_hash_handle_file_seek(void* file_handle, int64_t offset, int origin)
|
static void rc_hash_handle_file_seek(
|
||||||
|
void* file_handle, int64_t offset, int origin)
|
||||||
{
|
{
|
||||||
intfstream_seek((intfstream_t*)file_handle, offset, origin);
|
intfstream_seek((intfstream_t*)file_handle, offset, origin);
|
||||||
}
|
}
|
||||||
|
@ -1075,9 +1132,11 @@ static int64_t rc_hash_handle_file_tell(void* file_handle)
|
||||||
return intfstream_tell((intfstream_t*)file_handle);
|
return intfstream_tell((intfstream_t*)file_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t rc_hash_handle_file_read(void* file_handle, void* buffer, size_t requested_bytes)
|
static size_t rc_hash_handle_file_read(
|
||||||
|
void* file_handle, void* buffer, size_t requested_bytes)
|
||||||
{
|
{
|
||||||
return intfstream_read((intfstream_t*)file_handle, buffer, requested_bytes);
|
return intfstream_read((intfstream_t*)file_handle,
|
||||||
|
buffer, requested_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rc_hash_handle_file_close(void* file_handle)
|
static void rc_hash_handle_file_close(void* file_handle)
|
||||||
|
@ -1086,7 +1145,8 @@ static void rc_hash_handle_file_close(void* file_handle)
|
||||||
CHEEVOS_FREE(file_handle);
|
CHEEVOS_FREE(file_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* rc_hash_handle_cd_open_track(const char* path, uint32_t track)
|
static void* rc_hash_handle_cd_open_track(
|
||||||
|
const char* path, uint32_t track)
|
||||||
{
|
{
|
||||||
cdfs_track_t* cdfs_track;
|
cdfs_track_t* cdfs_track;
|
||||||
|
|
||||||
|
@ -1138,7 +1198,9 @@ static void* rc_hash_handle_cd_open_track(const char* path, uint32_t track)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t rc_hash_handle_cd_read_sector(void* track_handle, uint32_t sector, void* buffer, size_t requested_bytes)
|
static size_t rc_hash_handle_cd_read_sector(
|
||||||
|
void* track_handle, uint32_t sector,
|
||||||
|
void* buffer, size_t requested_bytes)
|
||||||
{
|
{
|
||||||
cdfs_file_t* file = (cdfs_file_t*)track_handle;
|
cdfs_file_t* file = (cdfs_file_t*)track_handle;
|
||||||
|
|
||||||
|
@ -1161,14 +1223,15 @@ static void rc_hash_handle_cd_close_track(void* track_handle)
|
||||||
|
|
||||||
static void rcheevos_show_game_placard()
|
static void rcheevos_show_game_placard()
|
||||||
{
|
{
|
||||||
|
char msg[256];
|
||||||
const settings_t* settings = config_get_ptr();
|
const settings_t* settings = config_get_ptr();
|
||||||
const rcheevos_racheevo_t* cheevo = rcheevos_locals.game.achievements;
|
const rcheevos_racheevo_t* cheevo = rcheevos_locals.game.achievements;
|
||||||
const rcheevos_racheevo_t* end = cheevo + rcheevos_locals.game.achievement_count;
|
const rcheevos_racheevo_t* end = cheevo
|
||||||
|
+ rcheevos_locals.game.achievement_count;
|
||||||
int number_of_active = 0;
|
int number_of_active = 0;
|
||||||
int number_of_unsupported = 0;
|
int number_of_unsupported = 0;
|
||||||
int number_of_core = 0;
|
int number_of_core = 0;
|
||||||
int mode = RCHEEVOS_ACTIVE_SOFTCORE;
|
int mode = RCHEEVOS_ACTIVE_SOFTCORE;
|
||||||
char msg[256];
|
|
||||||
|
|
||||||
if (rcheevos_locals.hardcore_active)
|
if (rcheevos_locals.hardcore_active)
|
||||||
mode = RCHEEVOS_ACTIVE_HARDCORE;
|
mode = RCHEEVOS_ACTIVE_HARDCORE;
|
||||||
|
@ -1186,40 +1249,30 @@ static void rcheevos_show_game_placard()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (number_of_core == 0)
|
if (number_of_core == 0)
|
||||||
{
|
|
||||||
snprintf(msg, sizeof(msg), "This game has no achievements.");
|
snprintf(msg, sizeof(msg), "This game has no achievements.");
|
||||||
}
|
|
||||||
else if (!number_of_unsupported)
|
else if (!number_of_unsupported)
|
||||||
{
|
{
|
||||||
if (settings->bools.cheevos_start_active)
|
if (settings->bools.cheevos_start_active)
|
||||||
{
|
|
||||||
snprintf(msg, sizeof(msg),
|
snprintf(msg, sizeof(msg),
|
||||||
"All %d achievements activated for this session.",
|
"All %d achievements activated for this session.",
|
||||||
number_of_core);
|
number_of_core);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
snprintf(msg, sizeof(msg),
|
snprintf(msg, sizeof(msg),
|
||||||
"You have %d of %d achievements unlocked.",
|
"You have %d of %d achievements unlocked.",
|
||||||
number_of_core - number_of_active, number_of_core);
|
number_of_core - number_of_active, number_of_core);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (settings->bools.cheevos_start_active)
|
if (settings->bools.cheevos_start_active)
|
||||||
{
|
|
||||||
snprintf(msg, sizeof(msg),
|
snprintf(msg, sizeof(msg),
|
||||||
"All %d achievements activated for this session (%d unsupported).",
|
"All %d achievements activated for this session (%d unsupported).",
|
||||||
number_of_core, number_of_unsupported);
|
number_of_core, number_of_unsupported);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
snprintf(msg, sizeof(msg),
|
snprintf(msg, sizeof(msg),
|
||||||
"You have %d of %d achievements unlocked (%d unsupported).",
|
"You have %d of %d achievements unlocked (%d unsupported).",
|
||||||
number_of_core - number_of_active - number_of_unsupported,
|
number_of_core - number_of_active - number_of_unsupported,
|
||||||
number_of_core, number_of_unsupported);
|
number_of_core, number_of_unsupported);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
msg[sizeof(msg) - 1] = 0;
|
msg[sizeof(msg) - 1] = 0;
|
||||||
CHEEVOS_LOG(RCHEEVOS_TAG "%s\n", msg);
|
CHEEVOS_LOG(RCHEEVOS_TAG "%s\n", msg);
|
||||||
|
@ -1241,7 +1294,8 @@ static void rcheevos_fetch_badges_callback(void* userdata)
|
||||||
|
|
||||||
static void rcheevos_fetch_badges(void)
|
static void rcheevos_fetch_badges(void)
|
||||||
{
|
{
|
||||||
/* this function manages the RCHEEVOS_LOAD_STATE_FETCHING_BADGES state */
|
/* this function manages the
|
||||||
|
* RCHEEVOS_LOAD_STATE_FETCHING_BADGES state */
|
||||||
rcheevos_client_fetch_badges(rcheevos_fetch_badges_callback, NULL);
|
rcheevos_client_fetch_badges(rcheevos_fetch_badges_callback, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1253,12 +1307,13 @@ static void rcheevos_start_session(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rcheevos_locals.game.achievement_count == 0 &&
|
if ( rcheevos_locals.game.achievement_count == 0
|
||||||
rcheevos_locals.game.leaderboard_count == 0)
|
&& rcheevos_locals.game.leaderboard_count == 0)
|
||||||
{
|
{
|
||||||
if (!rcheevos_locals.runtime.richpresence)
|
if (!rcheevos_locals.runtime.richpresence)
|
||||||
{
|
{
|
||||||
/* nothing for the runtime to process, disable hardcore and bail */
|
/* nothing for the runtime to process,
|
||||||
|
* disable hardcore and bail */
|
||||||
rcheevos_show_game_placard();
|
rcheevos_show_game_placard();
|
||||||
rcheevos_pause_hardcore();
|
rcheevos_pause_hardcore();
|
||||||
return;
|
return;
|
||||||
|
@ -1267,22 +1322,26 @@ static void rcheevos_start_session(void)
|
||||||
|
|
||||||
rcheevos_begin_load_state(RCHEEVOS_LOAD_STATE_STARTING_SESSION);
|
rcheevos_begin_load_state(RCHEEVOS_LOAD_STATE_STARTING_SESSION);
|
||||||
|
|
||||||
/* activate the achievements and leaderboards (rich presence has already been activated) */
|
/* activate the achievements and leaderboards
|
||||||
|
* (rich presence has already been activated) */
|
||||||
rcheevos_activate_achievements();
|
rcheevos_activate_achievements();
|
||||||
|
|
||||||
if (rcheevos_locals.leaderboards_enabled && rcheevos_locals.hardcore_active)
|
if ( rcheevos_locals.leaderboards_enabled
|
||||||
|
&& rcheevos_locals.hardcore_active)
|
||||||
rcheevos_activate_leaderboards();
|
rcheevos_activate_leaderboards();
|
||||||
|
|
||||||
#if HAVE_REWIND
|
#if HAVE_REWIND
|
||||||
if (!rcheevos_locals.hardcore_active)
|
if (!rcheevos_locals.hardcore_active)
|
||||||
{
|
{
|
||||||
/* re-enable rewind. if rcheevos_locals.loaded is true, additional space will be allocated
|
/* Re-enable rewind. If rcheevos_locals.loaded is true,
|
||||||
* for the achievement state data */
|
* additional space will be allocated for the achievement
|
||||||
|
* state data */
|
||||||
const settings_t* settings = config_get_ptr();
|
const settings_t* settings = config_get_ptr();
|
||||||
if (settings->bools.rewind_enable)
|
if (settings->bools.rewind_enable)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_THREADS
|
#ifdef HAVE_THREADS
|
||||||
/* have to "schedule" this. CMD_EVENT_REWIND_INIT should only be called on the main thread */
|
/* Have to "schedule" this. CMD_EVENT_REWIND_INIT should
|
||||||
|
* only be called on the main thread */
|
||||||
rcheevos_locals.queued_command = CMD_EVENT_REWIND_INIT;
|
rcheevos_locals.queued_command = CMD_EVENT_REWIND_INIT;
|
||||||
#else
|
#else
|
||||||
command_event(CMD_EVENT_REWIND_INIT, NULL);
|
command_event(CMD_EVENT_REWIND_INIT, NULL);
|
||||||
|
@ -1291,12 +1350,13 @@ static void rcheevos_start_session(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* we don't have to wait for this to complete to proceed to the next loading state */
|
/* We don't have to wait for this to complete
|
||||||
|
* to proceed to the next loading state */
|
||||||
rcheevos_client_start_session(rcheevos_locals.game.id);
|
rcheevos_client_start_session(rcheevos_locals.game.id);
|
||||||
|
|
||||||
rcheevos_validate_memrefs(&rcheevos_locals);
|
rcheevos_validate_memrefs(&rcheevos_locals);
|
||||||
|
|
||||||
/* let the runtime start processing the achievements */
|
/* Let the runtime start processing the achievements */
|
||||||
rcheevos_locals.loaded = true;
|
rcheevos_locals.loaded = true;
|
||||||
|
|
||||||
rcheevos_show_game_placard();
|
rcheevos_show_game_placard();
|
||||||
|
@ -1312,7 +1372,8 @@ static void rcheevos_initialize_runtime_callback(void* userdata)
|
||||||
|
|
||||||
static void rcheevos_fetch_game_data(void)
|
static void rcheevos_fetch_game_data(void)
|
||||||
{
|
{
|
||||||
if (rcheevos_locals.load_info.state == RCHEEVOS_LOAD_STATE_NETWORK_ERROR)
|
if ( rcheevos_locals.load_info.state
|
||||||
|
== RCHEEVOS_LOAD_STATE_NETWORK_ERROR)
|
||||||
{
|
{
|
||||||
strlcpy(rcheevos_locals.game.hash,
|
strlcpy(rcheevos_locals.game.hash,
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE),
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE),
|
||||||
|
@ -1325,19 +1386,15 @@ static void rcheevos_fetch_game_data(void)
|
||||||
{
|
{
|
||||||
const settings_t* settings = config_get_ptr();
|
const settings_t* settings = config_get_ptr();
|
||||||
if (settings->bools.cheevos_verbose_enable)
|
if (settings->bools.cheevos_verbose_enable)
|
||||||
{
|
|
||||||
runloop_msg_queue_push(
|
runloop_msg_queue_push(
|
||||||
"This game has no achievements.",
|
"This game has no achievements.",
|
||||||
0, 3 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
|
0, 3 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
|
||||||
}
|
|
||||||
|
|
||||||
CHEEVOS_LOG(RCHEEVOS_TAG "Game could not be identified\n");
|
CHEEVOS_LOG(RCHEEVOS_TAG "Game could not be identified\n");
|
||||||
if (rcheevos_locals.load_info.hashes_tried > 1)
|
if (rcheevos_locals.load_info.hashes_tried > 1)
|
||||||
{
|
|
||||||
strlcpy(rcheevos_locals.game.hash,
|
strlcpy(rcheevos_locals.game.hash,
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE),
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE),
|
||||||
sizeof(rcheevos_locals.game.hash));
|
sizeof(rcheevos_locals.game.hash));
|
||||||
}
|
|
||||||
|
|
||||||
rcheevos_locals.load_info.state = RCHEEVOS_LOAD_STATE_UNKNOWN_GAME;
|
rcheevos_locals.load_info.state = RCHEEVOS_LOAD_STATE_UNKNOWN_GAME;
|
||||||
rcheevos_pause_hardcore();
|
rcheevos_pause_hardcore();
|
||||||
|
@ -1367,9 +1424,7 @@ static void rcheevos_fetch_game_data(void)
|
||||||
|
|
||||||
/* wait for rewind to be disabled */
|
/* wait for rewind to be disabled */
|
||||||
while (rcheevos_locals.queued_command != CMD_EVENT_NONE)
|
while (rcheevos_locals.queued_command != CMD_EVENT_NONE)
|
||||||
{
|
|
||||||
retro_sleep(1);
|
retro_sleep(1);
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
command_event(CMD_EVENT_REWIND_DEINIT, NULL);
|
command_event(CMD_EVENT_REWIND_DEINIT, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1391,14 +1446,18 @@ struct rcheevos_identify_game_data
|
||||||
|
|
||||||
static void rcheevos_identify_game_callback(void* userdata)
|
static void rcheevos_identify_game_callback(void* userdata)
|
||||||
{
|
{
|
||||||
struct rcheevos_identify_game_data* data = (struct rcheevos_identify_game_data*)userdata;
|
struct rcheevos_identify_game_data* data =
|
||||||
|
(struct rcheevos_identify_game_data*)userdata;
|
||||||
|
|
||||||
if (data)
|
if (data)
|
||||||
{
|
{
|
||||||
/* previous hash didn't match, try the next one */
|
/* previous hash didn't match, try the next one */
|
||||||
char hash[33];
|
char hash[33];
|
||||||
if (rcheevos_locals.game.id == 0 && rc_hash_iterate(hash, &data->iterator))
|
if ( rcheevos_locals.game.id == 0
|
||||||
|
&& rc_hash_iterate(hash, &data->iterator))
|
||||||
{
|
{
|
||||||
rcheevos_client_identify_game(hash, rcheevos_identify_game_callback, data);
|
rcheevos_client_identify_game(hash,
|
||||||
|
rcheevos_identify_game_callback, data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1420,25 +1479,29 @@ static bool rcheevos_identify_game(const struct retro_game_info* info)
|
||||||
size_t len;
|
size_t len;
|
||||||
char hash[33];
|
char hash[33];
|
||||||
|
|
||||||
rc_hash_initialize_iterator(&iterator, info->path, (uint8_t*)info->data, info->size);
|
rc_hash_initialize_iterator(&iterator,
|
||||||
|
info->path, (uint8_t*)info->data, info->size);
|
||||||
if (!rc_hash_iterate(hash, &iterator))
|
if (!rc_hash_iterate(hash, &iterator))
|
||||||
{
|
{
|
||||||
CHEEVOS_LOG(RCHEEVOS_TAG "no hashes generated\n");
|
CHEEVOS_LOG(RCHEEVOS_TAG "no hashes generated\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
strlcpy(rcheevos_locals.game.hash, hash, sizeof(rcheevos_locals.game.hash));
|
strlcpy(rcheevos_locals.game.hash, hash,
|
||||||
|
sizeof(rcheevos_locals.game.hash));
|
||||||
rcheevos_locals.load_info.hashes_tried++;
|
rcheevos_locals.load_info.hashes_tried++;
|
||||||
|
|
||||||
if (iterator.consoles[iterator.index] == 0)
|
if (iterator.consoles[iterator.index] == 0)
|
||||||
{
|
{
|
||||||
/* no more potential matches, just try the one hash */
|
/* no more potential matches, just try the one hash */
|
||||||
rcheevos_client_identify_game(hash, rcheevos_identify_game_callback, NULL);
|
rcheevos_client_identify_game(hash,
|
||||||
|
rcheevos_identify_game_callback, NULL);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* multiple potential matches, clone the data for the next attempt */
|
/* multiple potential matches, clone the data for the next attempt */
|
||||||
data = (struct rcheevos_identify_game_data*)calloc(1, sizeof(struct rcheevos_identify_game_data));
|
data = (struct rcheevos_identify_game_data*)
|
||||||
|
calloc(1, sizeof(struct rcheevos_identify_game_data));
|
||||||
if (!data)
|
if (!data)
|
||||||
{
|
{
|
||||||
CHEEVOS_LOG(RCHEEVOS_TAG "allocation failed\n");
|
CHEEVOS_LOG(RCHEEVOS_TAG "allocation failed\n");
|
||||||
|
@ -1463,7 +1526,8 @@ static bool rcheevos_identify_game(const struct retro_game_info* info)
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&data->iterator, &iterator, sizeof(iterator));
|
memcpy(&data->iterator, &iterator, sizeof(iterator));
|
||||||
rcheevos_client_identify_game(hash, rcheevos_identify_game_callback, data);
|
rcheevos_client_identify_game(hash,
|
||||||
|
rcheevos_identify_game_callback, data);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1478,7 +1542,8 @@ static void rcheevos_login_callback(void* userdata)
|
||||||
snprintf(msg, sizeof(msg),
|
snprintf(msg, sizeof(msg),
|
||||||
"RetroAchievements: Logged in as \"%s\".",
|
"RetroAchievements: Logged in as \"%s\".",
|
||||||
rcheevos_locals.username);
|
rcheevos_locals.username);
|
||||||
runloop_msg_queue_push(msg, 0, 2 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
|
runloop_msg_queue_push(msg, 0, 2 * 60, false, NULL,
|
||||||
|
MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1486,7 +1551,7 @@ static void rcheevos_login_callback(void* userdata)
|
||||||
rcheevos_fetch_game_data();
|
rcheevos_fetch_game_data();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* increment the outstanding requests counter and set the load state */
|
/* Increment the outstanding requests counter and set the load state */
|
||||||
void rcheevos_begin_load_state(enum rcheevos_load_state state)
|
void rcheevos_begin_load_state(enum rcheevos_load_state state)
|
||||||
{
|
{
|
||||||
CHEEVOS_LOCK(rcheevos_locals.load_info.request_lock);
|
CHEEVOS_LOCK(rcheevos_locals.load_info.request_lock);
|
||||||
|
@ -1495,7 +1560,8 @@ void rcheevos_begin_load_state(enum rcheevos_load_state state)
|
||||||
CHEEVOS_UNLOCK(rcheevos_locals.load_info.request_lock);
|
CHEEVOS_UNLOCK(rcheevos_locals.load_info.request_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* decrement and return the outstanding requests counter. if non-zero, requests are still outstanding */
|
/* Decrement and return the outstanding requests counter.
|
||||||
|
* If non-zero, requests are still outstanding */
|
||||||
int rcheevos_end_load_state(void)
|
int rcheevos_end_load_state(void)
|
||||||
{
|
{
|
||||||
int requests = 0;
|
int requests = 0;
|
||||||
|
@ -1513,25 +1579,32 @@ bool rcheevos_load_aborted(void)
|
||||||
{
|
{
|
||||||
switch (rcheevos_locals.load_info.state)
|
switch (rcheevos_locals.load_info.state)
|
||||||
{
|
{
|
||||||
case RCHEEVOS_LOAD_STATE_ABORTED: /* unload has been called */
|
/* Unload has been called */
|
||||||
case RCHEEVOS_LOAD_STATE_NONE: /* unload quit waiting and ran to completion */
|
case RCHEEVOS_LOAD_STATE_ABORTED:
|
||||||
case RCHEEVOS_LOAD_STATE_NETWORK_ERROR: /* login/resolve hash failed after several attempts */
|
/* Unload quit waiting and ran to completion */
|
||||||
|
case RCHEEVOS_LOAD_STATE_NONE:
|
||||||
|
/* Login/resolve hash failed after several attempts */
|
||||||
|
case RCHEEVOS_LOAD_STATE_NETWORK_ERROR:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
break;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rcheevos_load(const void *data)
|
bool rcheevos_load(const void *data)
|
||||||
{
|
{
|
||||||
const struct retro_game_info *info = (const struct retro_game_info*)data;
|
|
||||||
settings_t *settings = config_get_ptr();
|
|
||||||
bool cheevos_enable = settings && settings->bools.cheevos_enable;
|
|
||||||
struct rc_hash_filereader filereader;
|
|
||||||
struct rc_hash_cdreader cdreader;
|
struct rc_hash_cdreader cdreader;
|
||||||
|
struct rc_hash_filereader filereader;
|
||||||
|
const struct retro_game_info *info = (const struct retro_game_info*)
|
||||||
|
data;
|
||||||
|
settings_t *settings = config_get_ptr();
|
||||||
|
bool cheevos_enable = settings
|
||||||
|
&& settings->bools.cheevos_enable;
|
||||||
|
|
||||||
|
memset(&rcheevos_locals.load_info, 0,
|
||||||
|
sizeof(rcheevos_locals.load_info));
|
||||||
|
|
||||||
memset(&rcheevos_locals.load_info, 0, sizeof(rcheevos_locals.load_info));
|
|
||||||
rcheevos_locals.loaded = false;
|
rcheevos_locals.loaded = false;
|
||||||
rcheevos_locals.game.id = -1;
|
rcheevos_locals.game.id = -1;
|
||||||
#ifdef HAVE_THREADS
|
#ifdef HAVE_THREADS
|
||||||
|
@ -1539,8 +1612,8 @@ bool rcheevos_load(const void *data)
|
||||||
#endif
|
#endif
|
||||||
rc_runtime_init(&rcheevos_locals.runtime);
|
rc_runtime_init(&rcheevos_locals.runtime);
|
||||||
|
|
||||||
/* if achievements are not enabled, or the core doesn't support achievements,
|
/* If achievements are not enabled, or the core doesn't
|
||||||
* disable hardcore and bail */
|
* support achievements, disable hardcore and bail */
|
||||||
if (!cheevos_enable || !rcheevos_locals.core_supports || !data)
|
if (!cheevos_enable || !rcheevos_locals.core_supports || !data)
|
||||||
{
|
{
|
||||||
rcheevos_pause_hardcore();
|
rcheevos_pause_hardcore();
|
||||||
|
@ -1575,14 +1648,15 @@ bool rcheevos_load(const void *data)
|
||||||
|
|
||||||
rc_hash_init_error_message_callback(rcheevos_handle_log_message);
|
rc_hash_init_error_message_callback(rcheevos_handle_log_message);
|
||||||
|
|
||||||
#ifndef DEBUG /* in DEBUG mode, always initialize the verbose message handler */
|
#ifndef DEBUG
|
||||||
|
/* in DEBUG mode, always initialize the verbose message handler */
|
||||||
if (settings->bools.cheevos_verbose_enable)
|
if (settings->bools.cheevos_verbose_enable)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
rc_hash_init_verbose_message_callback(rcheevos_handle_log_message);
|
rc_hash_init_verbose_message_callback(rcheevos_handle_log_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* refresh the user agent in case it's not set or has changed */
|
/* Refresh the user agent in case it's not set or has changed */
|
||||||
rcheevos_client_initialize();
|
rcheevos_client_initialize();
|
||||||
rcheevos_get_user_agent(&rcheevos_locals,
|
rcheevos_get_user_agent(&rcheevos_locals,
|
||||||
rcheevos_locals.user_agent_core,
|
rcheevos_locals.user_agent_core,
|
||||||
|
@ -1614,10 +1688,12 @@ bool rcheevos_load(const void *data)
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* identify the game and log the user in. these will run asynchronously. */
|
/* Identify the game and log the user in.
|
||||||
|
* These will run asynchronously. */
|
||||||
if (!rcheevos_identify_game(info))
|
if (!rcheevos_identify_game(info))
|
||||||
{
|
{
|
||||||
/* no hashes could be generated for the game, disable hardcore and bail */
|
/* No hashes could be generated for the game,
|
||||||
|
* disable hardcore and bail */
|
||||||
rcheevos_end_load_state();
|
rcheevos_end_load_state();
|
||||||
rcheevos_pause_hardcore();
|
rcheevos_pause_hardcore();
|
||||||
return false;
|
return false;
|
||||||
|
@ -1630,15 +1706,19 @@ bool rcheevos_load(const void *data)
|
||||||
{
|
{
|
||||||
CHEEVOS_LOG(RCHEEVOS_TAG "Attempting to login %s (with password)\n",
|
CHEEVOS_LOG(RCHEEVOS_TAG "Attempting to login %s (with password)\n",
|
||||||
settings->arrays.cheevos_username);
|
settings->arrays.cheevos_username);
|
||||||
rcheevos_client_login_with_password(settings->arrays.cheevos_username,
|
rcheevos_client_login_with_password(
|
||||||
settings->arrays.cheevos_password, rcheevos_login_callback, NULL);
|
settings->arrays.cheevos_username,
|
||||||
|
settings->arrays.cheevos_password,
|
||||||
|
rcheevos_login_callback, NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CHEEVOS_LOG(RCHEEVOS_TAG "Attempting to login %s (with token)\n",
|
CHEEVOS_LOG(RCHEEVOS_TAG "Attempting to login %s (with token)\n",
|
||||||
settings->arrays.cheevos_username);
|
settings->arrays.cheevos_username);
|
||||||
rcheevos_client_login_with_token(settings->arrays.cheevos_username,
|
rcheevos_client_login_with_token(
|
||||||
settings->arrays.cheevos_token, rcheevos_login_callback, NULL);
|
settings->arrays.cheevos_username,
|
||||||
|
settings->arrays.cheevos_token,
|
||||||
|
rcheevos_login_callback, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,10 +126,8 @@ static int append_no_spaces(char* buffer, char* stop, const char* text)
|
||||||
++text;
|
++text;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
*ptr++ = *text++;
|
*ptr++ = *text++;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
*ptr = '\0';
|
*ptr = '\0';
|
||||||
return (int)(ptr - buffer);
|
return (int)(ptr - buffer);
|
||||||
|
@ -156,11 +154,9 @@ void rcheevos_get_user_agent(rcheevos_locals_t *locals,
|
||||||
"RetroArch/%s (%s %d.%d)", PACKAGE_VERSION, tmp, major, minor);
|
"RetroArch/%s (%s %d.%d)", PACKAGE_VERSION, tmp, major, minor);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
snprintf(locals->user_agent_prefix, sizeof(locals->user_agent_prefix),
|
snprintf(locals->user_agent_prefix, sizeof(locals->user_agent_prefix),
|
||||||
"RetroArch/%s", PACKAGE_VERSION);
|
"RetroArch/%s", PACKAGE_VERSION);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* append the non-changing portion */
|
/* append the non-changing portion */
|
||||||
ptr = buffer + strlcpy(buffer, locals->user_agent_prefix, len);
|
ptr = buffer + strlcpy(buffer, locals->user_agent_prefix, len);
|
||||||
|
@ -179,9 +175,7 @@ void rcheevos_get_user_agent(rcheevos_locals_t *locals,
|
||||||
ptr += strlen(ptr);
|
ptr += strlen(ptr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
ptr += append_no_spaces(ptr, stop, system->library_name);
|
ptr += append_no_spaces(ptr, stop, system->library_name);
|
||||||
}
|
|
||||||
|
|
||||||
if (system->library_version)
|
if (system->library_version)
|
||||||
{
|
{
|
||||||
|
@ -287,18 +281,14 @@ static void rcheevos_log_post_url(const char* url, const char* post)
|
||||||
|
|
||||||
static void rcheevos_async_begin_http_request(rcheevos_async_io_request* request)
|
static void rcheevos_async_begin_http_request(rcheevos_async_io_request* request)
|
||||||
{
|
{
|
||||||
if (request->request.post_data == NULL)
|
if (request->request.post_data)
|
||||||
{
|
|
||||||
task_push_http_transfer_with_user_agent(request->request.url,
|
|
||||||
true, "GET", request->user_agent,
|
|
||||||
rcheevos_async_http_task_callback, request);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
task_push_http_post_transfer_with_user_agent(request->request.url,
|
task_push_http_post_transfer_with_user_agent(request->request.url,
|
||||||
request->request.post_data, true, "POST", request->user_agent,
|
request->request.post_data, true, "POST", request->user_agent,
|
||||||
rcheevos_async_http_task_callback, request);
|
rcheevos_async_http_task_callback, request);
|
||||||
}
|
else
|
||||||
|
task_push_http_transfer_with_user_agent(request->request.url,
|
||||||
|
true, "GET", request->user_agent,
|
||||||
|
rcheevos_async_http_task_callback, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rcheevos_async_retry_request(retro_task_t* task)
|
static void rcheevos_async_retry_request(retro_task_t* task)
|
||||||
|
@ -316,7 +306,6 @@ static void rcheevos_async_retry_request(retro_task_t* task)
|
||||||
static void rcheevos_async_retry_request_after_delay(rcheevos_async_io_request* request, const char* error)
|
static void rcheevos_async_retry_request_after_delay(rcheevos_async_io_request* request, const char* error)
|
||||||
{
|
{
|
||||||
retro_task_t* task = task_init();
|
retro_task_t* task = task_init();
|
||||||
|
|
||||||
/* Double the wait between each attempt until we hit
|
/* Double the wait between each attempt until we hit
|
||||||
* a maximum delay of two minutes.
|
* a maximum delay of two minutes.
|
||||||
* 250ms -> 500ms -> 1s -> 2s -> 4s -> 8s -> 16s -> 32s -> 64s -> 120s -> 120s... */
|
* 250ms -> 500ms -> 1s -> 2s -> 4s -> 8s -> 16s -> 32s -> 64s -> 120s -> 120s... */
|
||||||
|
@ -344,13 +333,16 @@ static bool rcheevos_async_request_failed(rcheevos_async_io_request* request, co
|
||||||
/* retry failed, don't retry these requests */
|
/* retry failed, don't retry these requests */
|
||||||
switch (request->type)
|
switch (request->type)
|
||||||
{
|
{
|
||||||
case CHEEVOS_ASYNC_RICHPRESENCE: /* timer will ping again */
|
/* timer will ping again */
|
||||||
case CHEEVOS_ASYNC_FETCH_BADGE: /* fallback to the placeholder image */
|
case CHEEVOS_ASYNC_RICHPRESENCE:
|
||||||
|
/* fallback to the placeholder image */
|
||||||
|
case CHEEVOS_ASYNC_FETCH_BADGE:
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
case CHEEVOS_ASYNC_RESOLVE_HASH:
|
case CHEEVOS_ASYNC_RESOLVE_HASH:
|
||||||
case CHEEVOS_ASYNC_LOGIN:
|
case CHEEVOS_ASYNC_LOGIN:
|
||||||
/* make a maximum of four attempts (0ms -> 250ms -> 500ms -> 1s) */
|
/* make a maximum of four attempts
|
||||||
|
(0ms -> 250ms -> 500ms -> 1s) */
|
||||||
if (request->attempt_count == 3)
|
if (request->attempt_count == 3)
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
@ -366,7 +358,8 @@ static bool rcheevos_async_request_failed(rcheevos_async_io_request* request, co
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rcheevos_async_http_task_callback(
|
static void rcheevos_async_http_task_callback(
|
||||||
retro_task_t* task, void* task_data, void* user_data, const char* error)
|
retro_task_t* task, void* task_data, void* user_data,
|
||||||
|
const char* error)
|
||||||
{
|
{
|
||||||
rcheevos_async_io_request *request = (rcheevos_async_io_request*)user_data;
|
rcheevos_async_io_request *request = (rcheevos_async_io_request*)user_data;
|
||||||
http_transfer_data_t *data = (http_transfer_data_t*)task_data;
|
http_transfer_data_t *data = (http_transfer_data_t*)task_data;
|
||||||
|
@ -383,19 +376,14 @@ static void rcheevos_async_http_task_callback(
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
/* there was a communication error */
|
/* there was a communication error */
|
||||||
if (rcheevos_async_request_failed(request, error))
|
|
||||||
{
|
|
||||||
/* automatically requeued, don't process any further */
|
/* automatically requeued, don't process any further */
|
||||||
|
if (rcheevos_async_request_failed(request, error))
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
strlcpy(buffer, error, sizeof(buffer));
|
strlcpy(buffer, error, sizeof(buffer));
|
||||||
}
|
}
|
||||||
else if (!data)
|
else if (!data) /* Server did not return HTTP headers */
|
||||||
{
|
|
||||||
/* Server did not return HTTP headers */
|
|
||||||
strlcpy(buffer, "Server communication error", sizeof(buffer));
|
strlcpy(buffer, "Server communication error", sizeof(buffer));
|
||||||
}
|
|
||||||
else if (!data->data || !data->len)
|
else if (!data->data || !data->len)
|
||||||
{
|
{
|
||||||
if (data->status <= 0)
|
if (data->status <= 0)
|
||||||
|
@ -407,30 +395,23 @@ static void rcheevos_async_http_task_callback(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->status != 200)
|
if (data->status != 200) /* Server returned error via status code. */
|
||||||
{
|
|
||||||
/* Server returned an error via status code. */
|
|
||||||
snprintf(buffer, sizeof(buffer), "HTTP error code %d", data->status);
|
snprintf(buffer, sizeof(buffer), "HTTP error code %d", data->status);
|
||||||
}
|
else /* Server sent empty response without error status code */
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Server sent an empty response without an error status code */
|
|
||||||
strlcpy(buffer, "No response from server", sizeof(buffer));
|
strlcpy(buffer, "No response from server", sizeof(buffer));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buffer[0] = '\0'; /* indicate success unless handler provides error */
|
/* indicate success unless handler provides error */
|
||||||
|
buffer[0] = '\0';
|
||||||
|
|
||||||
/* Call appropriate handler to process the response */
|
/* Call appropriate handler to process the response */
|
||||||
if (request->handler)
|
|
||||||
{
|
|
||||||
/* NOTE: data->data is not null-terminated. Most handlers assume the
|
/* NOTE: data->data is not null-terminated. Most handlers assume the
|
||||||
* response is properly formatted or will encounter a parse failure
|
* response is properly formatted or will encounter a parse failure
|
||||||
* before reading past the end of the data */
|
* before reading past the end of the data */
|
||||||
|
if (request->handler)
|
||||||
request->handler(request, data, buffer, sizeof(buffer));
|
request->handler(request, data, buffer, sizeof(buffer));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!buffer[0])
|
if (!buffer[0])
|
||||||
{
|
{
|
||||||
|
@ -469,19 +450,22 @@ static void rcheevos_async_http_task_callback(
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
char* ptr;
|
char* ptr;
|
||||||
|
|
||||||
if (rcheevos_locals->load_info.state == RCHEEVOS_LOAD_STATE_NETWORK_ERROR)
|
if ( rcheevos_locals->load_info.state
|
||||||
|
== RCHEEVOS_LOAD_STATE_NETWORK_ERROR)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
rcheevos_locals->load_info.state = RCHEEVOS_LOAD_STATE_NETWORK_ERROR;
|
rcheevos_locals->load_info.state =
|
||||||
|
RCHEEVOS_LOAD_STATE_NETWORK_ERROR;
|
||||||
|
|
||||||
while (request->request.url[len] != '/' || /* find the first single slash */
|
while (
|
||||||
request->request.url[len + 1] == '/' ||
|
/* find the first single slash */
|
||||||
request->request.url[len - 1] == '/')
|
request->request.url[len] != '/'
|
||||||
{
|
|| request->request.url[len + 1] == '/'
|
||||||
|
|| request->request.url[len - 1] == '/')
|
||||||
++len;
|
++len;
|
||||||
}
|
|
||||||
|
|
||||||
ptr = errbuf + snprintf(errbuf, sizeof(errbuf), "Could not communicate with ");
|
ptr = errbuf + snprintf(errbuf, sizeof(errbuf),
|
||||||
|
"Could not communicate with ");
|
||||||
memcpy(ptr, request->request.url, len);
|
memcpy(ptr, request->request.url, len);
|
||||||
ptr[len] = '\0';
|
ptr[len] = '\0';
|
||||||
}
|
}
|
||||||
|
@ -509,7 +493,8 @@ static void rcheevos_async_http_task_callback(
|
||||||
free(request);
|
free(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rcheevos_async_begin_request(rcheevos_async_io_request* request,
|
static void rcheevos_async_begin_request(
|
||||||
|
rcheevos_async_io_request* request,
|
||||||
rcheevos_async_handler handler, char type, int id,
|
rcheevos_async_handler handler, char type, int id,
|
||||||
const char* success_message, const char* failure_message)
|
const char* success_message, const char* failure_message)
|
||||||
{
|
{
|
||||||
|
@ -528,7 +513,8 @@ static void rcheevos_async_begin_request(rcheevos_async_io_request* request,
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool rcheevos_async_succeeded(int result,
|
static bool rcheevos_async_succeeded(int result,
|
||||||
const rc_api_response_t* response, char buffer[], size_t buffer_size)
|
const rc_api_response_t* response, char buffer[],
|
||||||
|
size_t buffer_size)
|
||||||
{
|
{
|
||||||
if (result != RC_OK)
|
if (result != RC_OK)
|
||||||
{
|
{
|
||||||
|
@ -555,28 +541,32 @@ void rcheevos_client_initialize(void)
|
||||||
* login *
|
* login *
|
||||||
****************************/
|
****************************/
|
||||||
|
|
||||||
static void rcheevos_async_login_callback(struct rcheevos_async_io_request* request,
|
static void rcheevos_async_login_callback(
|
||||||
|
struct rcheevos_async_io_request* request,
|
||||||
http_transfer_data_t* data, char buffer[], size_t buffer_size)
|
http_transfer_data_t* data, char buffer[], size_t buffer_size)
|
||||||
{
|
{
|
||||||
rcheevos_locals_t* rcheevos_locals = get_rcheevos_locals();
|
rcheevos_locals_t* rcheevos_locals = get_rcheevos_locals();
|
||||||
rc_api_login_response_t api_response;
|
rc_api_login_response_t api_response;
|
||||||
|
|
||||||
int result = rc_api_process_login_response(&api_response, data->data);
|
int result = rc_api_process_login_response(&api_response, data->data);
|
||||||
if (rcheevos_async_succeeded(result, &api_response.response, buffer, buffer_size))
|
if (rcheevos_async_succeeded(result, &api_response.response,
|
||||||
|
buffer, buffer_size))
|
||||||
{
|
{
|
||||||
CHEEVOS_LOG(RCHEEVOS_TAG "%s logged in successfully\n", api_response.username);
|
CHEEVOS_LOG(RCHEEVOS_TAG "%s logged in successfully\n",
|
||||||
strlcpy(rcheevos_locals->username, api_response.username, sizeof(rcheevos_locals->username));
|
api_response.username);
|
||||||
strlcpy(rcheevos_locals->token, api_response.api_token, sizeof(rcheevos_locals->token));
|
strlcpy(rcheevos_locals->username, api_response.username,
|
||||||
|
sizeof(rcheevos_locals->username));
|
||||||
|
strlcpy(rcheevos_locals->token, api_response.api_token,
|
||||||
|
sizeof(rcheevos_locals->token));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
rcheevos_locals->token[0] = '\0';
|
rcheevos_locals->token[0] = '\0';
|
||||||
}
|
|
||||||
|
|
||||||
rc_api_destroy_login_response(&api_response);
|
rc_api_destroy_login_response(&api_response);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rcheevos_client_login(const char* username, const char* password, const char* token,
|
static void rcheevos_client_login(const char* username,
|
||||||
|
const char* password, const char* token,
|
||||||
rcheevos_client_callback callback, void* userdata)
|
rcheevos_client_callback callback, void* userdata)
|
||||||
{
|
{
|
||||||
rcheevos_async_io_request* request = (rcheevos_async_io_request*)
|
rcheevos_async_io_request* request = (rcheevos_async_io_request*)
|
||||||
|
@ -607,13 +597,15 @@ static void rcheevos_client_login(const char* username, const char* password, co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rcheevos_client_login_with_password(const char* username, const char* password,
|
void rcheevos_client_login_with_password(const char* username,
|
||||||
|
const char* password,
|
||||||
rcheevos_client_callback callback, void* userdata)
|
rcheevos_client_callback callback, void* userdata)
|
||||||
{
|
{
|
||||||
rcheevos_client_login(username, password, NULL, callback, userdata);
|
rcheevos_client_login(username, password, NULL, callback, userdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rcheevos_client_login_with_token(const char* username, const char* token,
|
void rcheevos_client_login_with_token(const char* username,
|
||||||
|
const char* token,
|
||||||
rcheevos_client_callback callback, void* userdata)
|
rcheevos_client_callback callback, void* userdata)
|
||||||
{
|
{
|
||||||
rcheevos_client_login(username, NULL, token, callback, userdata);
|
rcheevos_client_login(username, NULL, token, callback, userdata);
|
||||||
|
@ -623,13 +615,16 @@ void rcheevos_client_login_with_token(const char* username, const char* token,
|
||||||
* identify game *
|
* identify game *
|
||||||
****************************/
|
****************************/
|
||||||
|
|
||||||
static void rcheevos_async_resolve_hash_callback(struct rcheevos_async_io_request* request,
|
static void rcheevos_async_resolve_hash_callback(
|
||||||
|
struct rcheevos_async_io_request* request,
|
||||||
http_transfer_data_t* data, char buffer[], size_t buffer_size)
|
http_transfer_data_t* data, char buffer[], size_t buffer_size)
|
||||||
{
|
{
|
||||||
rc_api_resolve_hash_response_t api_response;
|
rc_api_resolve_hash_response_t api_response;
|
||||||
|
int result = rc_api_process_resolve_hash_response(&api_response,
|
||||||
|
data->data);
|
||||||
|
|
||||||
int result = rc_api_process_resolve_hash_response(&api_response, data->data);
|
if (rcheevos_async_succeeded(result, &api_response.response,
|
||||||
if (rcheevos_async_succeeded(result, &api_response.response, buffer, buffer_size))
|
buffer, buffer_size))
|
||||||
{
|
{
|
||||||
rcheevos_locals_t* rcheevos_locals = get_rcheevos_locals();
|
rcheevos_locals_t* rcheevos_locals = get_rcheevos_locals();
|
||||||
rcheevos_locals->game.id = api_response.game_id;
|
rcheevos_locals->game.id = api_response.game_id;
|
||||||
|
@ -638,7 +633,8 @@ static void rcheevos_async_resolve_hash_callback(struct rcheevos_async_io_reques
|
||||||
rc_api_destroy_resolve_hash_response(&api_response);
|
rc_api_destroy_resolve_hash_response(&api_response);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rcheevos_client_identify_game(const char* hash, rcheevos_client_callback callback, void* userdata)
|
void rcheevos_client_identify_game(const char* hash,
|
||||||
|
rcheevos_client_callback callback, void* userdata)
|
||||||
{
|
{
|
||||||
rcheevos_async_io_request* request = (rcheevos_async_io_request*)
|
rcheevos_async_io_request* request = (rcheevos_async_io_request*)
|
||||||
calloc(1, sizeof(rcheevos_async_io_request));
|
calloc(1, sizeof(rcheevos_async_io_request));
|
||||||
|
@ -683,16 +679,18 @@ typedef struct rcheevos_async_initialize_runtime_data_t
|
||||||
void* callback_data;
|
void* callback_data;
|
||||||
} rcheevos_async_initialize_runtime_data_t;
|
} rcheevos_async_initialize_runtime_data_t;
|
||||||
|
|
||||||
static void rcheevos_client_copy_achievements(rcheevos_async_initialize_runtime_data_t* runtime_data)
|
static void rcheevos_client_copy_achievements(
|
||||||
|
rcheevos_async_initialize_runtime_data_t* runtime_data)
|
||||||
{
|
{
|
||||||
|
unsigned i, j;
|
||||||
const rc_api_achievement_definition_t* definition;
|
const rc_api_achievement_definition_t* definition;
|
||||||
rcheevos_racheevo_t *achievement;
|
rcheevos_racheevo_t *achievement;
|
||||||
rcheevos_locals_t *rcheevos_locals = get_rcheevos_locals();
|
rcheevos_locals_t *rcheevos_locals = get_rcheevos_locals();
|
||||||
const settings_t *settings = config_get_ptr();
|
const settings_t *settings = config_get_ptr();
|
||||||
unsigned i, j;
|
|
||||||
|
|
||||||
rcheevos_locals->game.achievements = (rcheevos_racheevo_t*)
|
rcheevos_locals->game.achievements = (rcheevos_racheevo_t*)
|
||||||
calloc(runtime_data->game_data.num_achievements, sizeof(rcheevos_racheevo_t));
|
calloc(runtime_data->game_data.num_achievements,
|
||||||
|
sizeof(rcheevos_racheevo_t));
|
||||||
|
|
||||||
achievement = rcheevos_locals->game.achievements;
|
achievement = rcheevos_locals->game.achievements;
|
||||||
if (!achievement)
|
if (!achievement)
|
||||||
|
@ -702,40 +700,50 @@ static void rcheevos_client_copy_achievements(rcheevos_async_initialize_runtime_
|
||||||
}
|
}
|
||||||
|
|
||||||
definition = runtime_data->game_data.achievements;
|
definition = runtime_data->game_data.achievements;
|
||||||
for (i = 0; i < runtime_data->game_data.num_achievements; ++i, ++definition)
|
for (i = 0; i < runtime_data->game_data.num_achievements;
|
||||||
{
|
++i, ++definition)
|
||||||
if (definition->category == 0 ||
|
|
||||||
!definition->definition || !definition->definition[0] ||
|
|
||||||
!definition->title || !definition->title[0] ||
|
|
||||||
!definition->description || !definition->description[0])
|
|
||||||
{
|
{
|
||||||
/* invalid definition, ignore */
|
/* invalid definition, ignore */
|
||||||
|
if (
|
||||||
|
definition->category == 0
|
||||||
|
|| !definition->definition
|
||||||
|
|| !definition->definition[0]
|
||||||
|
|| !definition->title
|
||||||
|
|| !definition->title[0]
|
||||||
|
|| !definition->description
|
||||||
|
|| !definition->description[0])
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
if (definition->category != 3)
|
if (definition->category != 3)
|
||||||
{
|
{
|
||||||
achievement->active = RCHEEVOS_ACTIVE_UNOFFICIAL;
|
achievement->active = RCHEEVOS_ACTIVE_UNOFFICIAL;
|
||||||
|
|
||||||
if (settings->bools.cheevos_test_unofficial)
|
if (settings->bools.cheevos_test_unofficial)
|
||||||
achievement->active |= RCHEEVOS_ACTIVE_SOFTCORE | RCHEEVOS_ACTIVE_HARDCORE;
|
achievement->active |= RCHEEVOS_ACTIVE_SOFTCORE
|
||||||
|
| RCHEEVOS_ACTIVE_HARDCORE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
achievement->active = RCHEEVOS_ACTIVE_SOFTCORE | RCHEEVOS_ACTIVE_HARDCORE;
|
achievement->active = RCHEEVOS_ACTIVE_SOFTCORE
|
||||||
|
| RCHEEVOS_ACTIVE_HARDCORE;
|
||||||
|
|
||||||
for (j = 0; j < runtime_data->hardcore_unlocks.num_achievement_ids; ++j)
|
for (j = 0; j <
|
||||||
|
runtime_data->hardcore_unlocks.num_achievement_ids; ++j)
|
||||||
{
|
{
|
||||||
if (runtime_data->hardcore_unlocks.achievement_ids[j] == definition->id)
|
if (runtime_data->hardcore_unlocks.achievement_ids[j]
|
||||||
|
== definition->id)
|
||||||
{
|
{
|
||||||
achievement->active &= ~(RCHEEVOS_ACTIVE_HARDCORE | RCHEEVOS_ACTIVE_SOFTCORE);
|
achievement->active &= ~(RCHEEVOS_ACTIVE_HARDCORE
|
||||||
|
| RCHEEVOS_ACTIVE_SOFTCORE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((achievement->active & RCHEEVOS_ACTIVE_SOFTCORE) != 0)
|
if ((achievement->active & RCHEEVOS_ACTIVE_SOFTCORE) != 0)
|
||||||
{
|
{
|
||||||
for (j = 0; j < runtime_data->non_hardcore_unlocks.num_achievement_ids; ++j)
|
for (j = 0; j <
|
||||||
|
runtime_data->non_hardcore_unlocks.num_achievement_ids;
|
||||||
|
++j)
|
||||||
{
|
{
|
||||||
if (runtime_data->non_hardcore_unlocks.achievement_ids[j] == definition->id)
|
if (runtime_data->non_hardcore_unlocks.achievement_ids[j] == definition->id)
|
||||||
{
|
{
|
||||||
|
@ -752,27 +760,34 @@ static void rcheevos_client_copy_achievements(rcheevos_async_initialize_runtime_
|
||||||
achievement->badge = strdup(definition->badge_name);
|
achievement->badge = strdup(definition->badge_name);
|
||||||
achievement->points = definition->points;
|
achievement->points = definition->points;
|
||||||
|
|
||||||
/* if an achievement has been fully unlocked, we don't need to keep the definition around
|
/* If an achievement has been fully unlocked,
|
||||||
* as it won't be reactivated. otherwise, we do have to keep a copy of it. */
|
* we don't need to keep the definition around
|
||||||
if ((achievement->active & (RCHEEVOS_ACTIVE_HARDCORE | RCHEEVOS_ACTIVE_SOFTCORE)) != 0)
|
* as it won't be reactivated. Otherwise,
|
||||||
|
* we do have to keep a copy of it. */
|
||||||
|
if ((achievement->active & (RCHEEVOS_ACTIVE_HARDCORE
|
||||||
|
| RCHEEVOS_ACTIVE_SOFTCORE)) != 0)
|
||||||
achievement->memaddr = strdup(definition->definition);
|
achievement->memaddr = strdup(definition->definition);
|
||||||
|
|
||||||
++achievement;
|
++achievement;
|
||||||
}
|
}
|
||||||
|
|
||||||
rcheevos_locals->game.achievement_count = achievement - rcheevos_locals->game.achievements;
|
rcheevos_locals->game.achievement_count = achievement
|
||||||
|
- rcheevos_locals->game.achievements;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rcheevos_client_copy_leaderboards(rcheevos_async_initialize_runtime_data_t* runtime_data)
|
static void rcheevos_client_copy_leaderboards(
|
||||||
|
rcheevos_async_initialize_runtime_data_t* runtime_data)
|
||||||
{
|
{
|
||||||
const rc_api_leaderboard_definition_t* definition;
|
|
||||||
rcheevos_ralboard_t* leaderboard;
|
|
||||||
rcheevos_locals_t* rcheevos_locals = get_rcheevos_locals();
|
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
rcheevos_ralboard_t *leaderboard;
|
||||||
|
const rc_api_leaderboard_definition_t *definition;
|
||||||
|
rcheevos_locals_t* rcheevos_locals = get_rcheevos_locals();
|
||||||
|
|
||||||
rcheevos_locals->game.leaderboards = (rcheevos_ralboard_t*)
|
rcheevos_locals->game.leaderboards = (rcheevos_ralboard_t*)
|
||||||
calloc(runtime_data->game_data.num_leaderboards, sizeof(rcheevos_ralboard_t));
|
calloc(runtime_data->game_data.num_leaderboards,
|
||||||
rcheevos_locals->game.leaderboard_count = runtime_data->game_data.num_leaderboards;
|
sizeof(rcheevos_ralboard_t));
|
||||||
|
rcheevos_locals->game.leaderboard_count =
|
||||||
|
runtime_data->game_data.num_leaderboards;
|
||||||
|
|
||||||
leaderboard = rcheevos_locals->game.leaderboards;
|
leaderboard = rcheevos_locals->game.leaderboards;
|
||||||
if (!leaderboard)
|
if (!leaderboard)
|
||||||
|
@ -792,16 +807,20 @@ static void rcheevos_client_copy_leaderboards(rcheevos_async_initialize_runtime_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rcheevos_client_initialize_runtime_rich_presence(rcheevos_async_initialize_runtime_data_t* runtime_data)
|
static void rcheevos_client_initialize_runtime_rich_presence(
|
||||||
|
rcheevos_async_initialize_runtime_data_t* runtime_data)
|
||||||
{
|
{
|
||||||
if (runtime_data->game_data.rich_presence_script && *runtime_data->game_data.rich_presence_script)
|
if (runtime_data->game_data.rich_presence_script && *runtime_data->game_data.rich_presence_script)
|
||||||
{
|
{
|
||||||
rcheevos_locals_t* rcheevos_locals = get_rcheevos_locals();
|
rcheevos_locals_t* rcheevos_locals = get_rcheevos_locals();
|
||||||
|
|
||||||
/* just activate the rich presence script now. it can't be toggled on or off,
|
/* Just activate the rich presence script now.
|
||||||
* so there's no reason to keep the unparsed version around any longer than
|
* It can't be toggled on or off,
|
||||||
* necessary, and we can avoid making a copy in the process. */
|
* so there's no reason to keep the unparsed version
|
||||||
int result = rc_runtime_activate_richpresence(&rcheevos_locals->runtime,
|
* around any longer than necessary, and we can avoid
|
||||||
|
* making a copy in the process. */
|
||||||
|
int result = rc_runtime_activate_richpresence(
|
||||||
|
&rcheevos_locals->runtime,
|
||||||
runtime_data->game_data.rich_presence_script, NULL, 0);
|
runtime_data->game_data.rich_presence_script, NULL, 0);
|
||||||
|
|
||||||
if (result != RC_OK)
|
if (result != RC_OK)
|
||||||
|
@ -809,7 +828,8 @@ static void rcheevos_client_initialize_runtime_rich_presence(rcheevos_async_init
|
||||||
const settings_t* settings = config_get_ptr();
|
const settings_t* settings = config_get_ptr();
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
snprintf(buffer, sizeof(buffer),
|
snprintf(buffer, sizeof(buffer),
|
||||||
"Could not activate rich presence: %s", rc_error_str(result));
|
"Could not activate rich presence: %s",
|
||||||
|
rc_error_str(result));
|
||||||
|
|
||||||
if (settings->bools.cheevos_verbose_enable)
|
if (settings->bools.cheevos_verbose_enable)
|
||||||
runloop_msg_queue_push(buffer, 0, 4 * 60, false, NULL,
|
runloop_msg_queue_push(buffer, 0, 4 * 60, false, NULL,
|
||||||
|
@ -844,50 +864,65 @@ static void rcheevos_client_initialize_runtime_callback(void* userdata)
|
||||||
free(runtime_data);
|
free(runtime_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rcheevos_async_fetch_user_unlocks_callback(struct rcheevos_async_io_request* request,
|
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)
|
http_transfer_data_t* data, char buffer[], size_t buffer_size)
|
||||||
{
|
{
|
||||||
rcheevos_async_initialize_runtime_data_t* runtime_data = (rcheevos_async_initialize_runtime_data_t*)request->callback_data;
|
rcheevos_async_initialize_runtime_data_t* runtime_data =
|
||||||
|
(rcheevos_async_initialize_runtime_data_t*)request->callback_data;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (request->type == CHEEVOS_ASYNC_FETCH_HARDCORE_USER_UNLOCKS)
|
if (request->type == CHEEVOS_ASYNC_FETCH_HARDCORE_USER_UNLOCKS)
|
||||||
{
|
{
|
||||||
result = rc_api_process_fetch_user_unlocks_response(&runtime_data->hardcore_unlocks, data->data);
|
result = rc_api_process_fetch_user_unlocks_response(
|
||||||
rcheevos_async_succeeded(result, &runtime_data->hardcore_unlocks.response, buffer, buffer_size);
|
&runtime_data->hardcore_unlocks, data->data);
|
||||||
|
rcheevos_async_succeeded(result,
|
||||||
|
&runtime_data->hardcore_unlocks.response,
|
||||||
|
buffer, buffer_size);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = rc_api_process_fetch_user_unlocks_response(&runtime_data->non_hardcore_unlocks, data->data);
|
result = rc_api_process_fetch_user_unlocks_response(
|
||||||
rcheevos_async_succeeded(result, &runtime_data->non_hardcore_unlocks.response, buffer, buffer_size);
|
&runtime_data->non_hardcore_unlocks, data->data);
|
||||||
|
rcheevos_async_succeeded(result,
|
||||||
|
&runtime_data->non_hardcore_unlocks.response,
|
||||||
|
buffer, buffer_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rcheevos_async_fetch_game_data_callback(struct rcheevos_async_io_request* request,
|
static void rcheevos_async_fetch_game_data_callback(
|
||||||
|
struct rcheevos_async_io_request* request,
|
||||||
http_transfer_data_t* data, char buffer[], size_t buffer_size)
|
http_transfer_data_t* data, char buffer[], size_t buffer_size)
|
||||||
{
|
{
|
||||||
rcheevos_async_initialize_runtime_data_t* runtime_data = (rcheevos_async_initialize_runtime_data_t*)request->callback_data;
|
rcheevos_async_initialize_runtime_data_t* runtime_data =
|
||||||
|
(rcheevos_async_initialize_runtime_data_t*)request->callback_data;
|
||||||
|
|
||||||
#ifdef CHEEVOS_SAVE_JSON
|
#ifdef CHEEVOS_SAVE_JSON
|
||||||
filestream_write_file(CHEEVOS_SAVE_JSON, data->data, data->len);
|
filestream_write_file(CHEEVOS_SAVE_JSON, data->data, data->len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int result = rc_api_process_fetch_game_data_response(&runtime_data->game_data, data->data);
|
int result = rc_api_process_fetch_game_data_response(
|
||||||
|
&runtime_data->game_data, data->data);
|
||||||
if (rcheevos_async_succeeded(result, &runtime_data->game_data.response, buffer, buffer_size))
|
if (rcheevos_async_succeeded(result, &runtime_data->game_data.response, buffer, buffer_size))
|
||||||
{
|
{
|
||||||
rcheevos_locals_t* rcheevos_locals = get_rcheevos_locals();
|
rcheevos_locals_t* rcheevos_locals = get_rcheevos_locals();
|
||||||
rcheevos_locals->game.title = strdup(runtime_data->game_data.title);
|
rcheevos_locals->game.title = strdup(
|
||||||
rcheevos_locals->game.console_id = runtime_data->game_data.console_id;
|
runtime_data->game_data.title);
|
||||||
|
rcheevos_locals->game.console_id =
|
||||||
|
runtime_data->game_data.console_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rcheevos_client_initialize_runtime(unsigned game_id, rcheevos_client_callback callback, void* userdata)
|
void rcheevos_client_initialize_runtime(unsigned game_id,
|
||||||
|
rcheevos_client_callback callback, void* userdata)
|
||||||
{
|
{
|
||||||
rcheevos_async_io_request* request;
|
rcheevos_async_io_request* request;
|
||||||
const settings_t *settings = config_get_ptr();
|
const settings_t *settings = config_get_ptr();
|
||||||
const rcheevos_locals_t *rcheevos_locals = get_rcheevos_locals();
|
const rcheevos_locals_t *rcheevos_locals = get_rcheevos_locals();
|
||||||
|
rcheevos_async_initialize_runtime_data_t *data =
|
||||||
rcheevos_async_initialize_runtime_data_t* data = (rcheevos_async_initialize_runtime_data_t*)
|
(rcheevos_async_initialize_runtime_data_t*)
|
||||||
malloc(sizeof(rcheevos_async_initialize_runtime_data_t));
|
malloc(sizeof(rcheevos_async_initialize_runtime_data_t));
|
||||||
|
|
||||||
if (!data)
|
if (!data)
|
||||||
{
|
{
|
||||||
CHEEVOS_LOG(RCHEEVOS_TAG "Failed to allocate runtime initalization data\n");
|
CHEEVOS_LOG(RCHEEVOS_TAG "Failed to allocate runtime initalization data\n");
|
||||||
|
@ -896,8 +931,9 @@ void rcheevos_client_initialize_runtime(unsigned game_id, rcheevos_client_callba
|
||||||
|
|
||||||
data->callback = callback;
|
data->callback = callback;
|
||||||
data->callback_data = userdata;
|
data->callback_data = userdata;
|
||||||
|
request = (rcheevos_async_io_request*)
|
||||||
|
calloc(1, sizeof(rcheevos_async_io_request));
|
||||||
|
|
||||||
request = (rcheevos_async_io_request*)calloc(1, sizeof(rcheevos_async_io_request));
|
|
||||||
if (!request)
|
if (!request)
|
||||||
{
|
{
|
||||||
CHEEVOS_LOG(RCHEEVOS_TAG "Failed to allocate game data fetch request\n");
|
CHEEVOS_LOG(RCHEEVOS_TAG "Failed to allocate game data fetch request\n");
|
||||||
|
@ -1012,13 +1048,14 @@ void rcheevos_client_initialize_runtime(unsigned game_id, rcheevos_client_callba
|
||||||
* ping *
|
* ping *
|
||||||
****************************/
|
****************************/
|
||||||
|
|
||||||
static retro_time_t rcheevos_client_prepare_ping(rcheevos_async_io_request* request)
|
static retro_time_t rcheevos_client_prepare_ping(
|
||||||
|
rcheevos_async_io_request* request)
|
||||||
{
|
{
|
||||||
|
rc_api_ping_request_t api_params;
|
||||||
const rcheevos_locals_t* rcheevos_locals = get_rcheevos_locals();
|
const rcheevos_locals_t* rcheevos_locals = get_rcheevos_locals();
|
||||||
const settings_t *settings = config_get_ptr();
|
const settings_t *settings = config_get_ptr();
|
||||||
const bool cheevos_richpresence_enable =
|
const bool cheevos_richpresence_enable =
|
||||||
settings->bools.cheevos_richpresence_enable;
|
settings->bools.cheevos_richpresence_enable;
|
||||||
rc_api_ping_request_t api_params;
|
|
||||||
char buffer[256] = "";
|
char buffer[256] = "";
|
||||||
|
|
||||||
memset(&api_params, 0, sizeof(api_params));
|
memset(&api_params, 0, sizeof(api_params));
|
||||||
|
@ -1034,7 +1071,8 @@ static retro_time_t rcheevos_client_prepare_ping(rcheevos_async_io_request* requ
|
||||||
|
|
||||||
rc_api_init_ping_request(&request->request, &api_params);
|
rc_api_init_ping_request(&request->request, &api_params);
|
||||||
|
|
||||||
rcheevos_log_post_url(request->request.url, request->request.post_data);
|
rcheevos_log_post_url(request->request.url,
|
||||||
|
request->request.post_data);
|
||||||
|
|
||||||
#ifdef HAVE_DISCORD
|
#ifdef HAVE_DISCORD
|
||||||
if (settings->bools.discord_enable && discord_is_ready())
|
if (settings->bools.discord_enable && discord_is_ready())
|
||||||
|
@ -1060,7 +1098,8 @@ static void rcheevos_async_ping_handler(retro_task_t* task)
|
||||||
/* game changed; stop the recurring task - a new one will
|
/* game changed; stop the recurring task - a new one will
|
||||||
* be scheduled if a new game is loaded */
|
* be scheduled if a new game is loaded */
|
||||||
task_set_finished(task, 1);
|
task_set_finished(task, 1);
|
||||||
/* request->request was destroyed in rcheevos_async_http_task_callback */
|
/* request->request was destroyed
|
||||||
|
* in rcheevos_async_http_task_callback */
|
||||||
free(request);
|
free(request);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1075,18 +1114,20 @@ static void rcheevos_async_ping_handler(retro_task_t* task)
|
||||||
rcheevos_async_http_task_callback, request);
|
rcheevos_async_http_task_callback, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************
|
/****************************
|
||||||
* start session *
|
* start session *
|
||||||
****************************/
|
****************************/
|
||||||
|
|
||||||
static void rcheevos_async_start_session_callback(struct rcheevos_async_io_request* request,
|
static void rcheevos_async_start_session_callback(
|
||||||
|
struct rcheevos_async_io_request* request,
|
||||||
http_transfer_data_t* data, char buffer[], size_t buffer_size)
|
http_transfer_data_t* data, char buffer[], size_t buffer_size)
|
||||||
{
|
{
|
||||||
rc_api_start_session_response_t api_response;
|
rc_api_start_session_response_t api_response;
|
||||||
|
|
||||||
int result = rc_api_process_start_session_response(&api_response, data->data);
|
int result = rc_api_process_start_session_response(
|
||||||
rcheevos_async_succeeded(result, &api_response.response, buffer, buffer_size);
|
&api_response, data->data);
|
||||||
|
rcheevos_async_succeeded(result,
|
||||||
|
&api_response.response, buffer, buffer_size);
|
||||||
rc_api_destroy_start_session_response(&api_response);
|
rc_api_destroy_start_session_response(&api_response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1106,7 +1147,8 @@ void rcheevos_client_start_session(unsigned game_id)
|
||||||
calloc(1, sizeof(rcheevos_async_io_request));
|
calloc(1, sizeof(rcheevos_async_io_request));
|
||||||
if (!request)
|
if (!request)
|
||||||
{
|
{
|
||||||
CHEEVOS_LOG(RCHEEVOS_TAG "Failed to allocate rich presence request\n");
|
CHEEVOS_LOG(RCHEEVOS_TAG
|
||||||
|
"Failed to allocate rich presence request\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1133,7 +1175,8 @@ void rcheevos_client_start_session(unsigned game_id)
|
||||||
calloc(1, sizeof(rcheevos_async_io_request));
|
calloc(1, sizeof(rcheevos_async_io_request));
|
||||||
if (!request)
|
if (!request)
|
||||||
{
|
{
|
||||||
CHEEVOS_LOG(RCHEEVOS_TAG "Failed to allocate new session request\n");
|
CHEEVOS_LOG(RCHEEVOS_TAG
|
||||||
|
"Failed to allocate new session request\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1144,7 +1187,8 @@ void rcheevos_client_start_session(unsigned game_id)
|
||||||
api_params.api_token = rcheevos_locals->token;
|
api_params.api_token = rcheevos_locals->token;
|
||||||
api_params.game_id = game_id;
|
api_params.game_id = game_id;
|
||||||
|
|
||||||
rc_api_init_start_session_request(&request->request, &api_params);
|
rc_api_init_start_session_request(
|
||||||
|
&request->request, &api_params);
|
||||||
|
|
||||||
rcheevos_async_begin_request(request,
|
rcheevos_async_begin_request(request,
|
||||||
rcheevos_async_start_session_callback,
|
rcheevos_async_start_session_callback,
|
||||||
|
@ -1173,7 +1217,8 @@ typedef struct rcheevos_fetch_badge_state
|
||||||
const char* badge_directory;
|
const char* badge_directory;
|
||||||
rcheevos_client_callback callback;
|
rcheevos_client_callback callback;
|
||||||
void* callback_data;
|
void* callback_data;
|
||||||
char requested_badges[RCHEEVOS_CONCURRENT_BADGE_DOWNLOADS][32];
|
char requested_badges[
|
||||||
|
RCHEEVOS_CONCURRENT_BADGE_DOWNLOADS][32];
|
||||||
} rcheevos_fetch_badge_state;
|
} rcheevos_fetch_badge_state;
|
||||||
|
|
||||||
typedef struct rcheevos_fetch_badge_data
|
typedef struct rcheevos_fetch_badge_data
|
||||||
|
@ -1196,7 +1241,8 @@ static void rcheevos_end_fetch_badges(rcheevos_fetch_badge_state* state)
|
||||||
|
|
||||||
static void rcheevos_async_download_next_badge(void* userdata)
|
static void rcheevos_async_download_next_badge(void* userdata)
|
||||||
{
|
{
|
||||||
rcheevos_fetch_badge_data* badge_data = (rcheevos_fetch_badge_data*)userdata;
|
rcheevos_fetch_badge_data* badge_data =
|
||||||
|
(rcheevos_fetch_badge_data*)userdata;
|
||||||
rcheevos_fetch_next_badge(badge_data->state);
|
rcheevos_fetch_next_badge(badge_data->state);
|
||||||
|
|
||||||
if (rcheevos_end_load_state() == 0)
|
if (rcheevos_end_load_state() == 0)
|
||||||
|
@ -1205,25 +1251,31 @@ static void rcheevos_async_download_next_badge(void* userdata)
|
||||||
free(badge_data);
|
free(badge_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rcheevos_async_fetch_badge_callback(struct 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)
|
http_transfer_data_t* data, char buffer[], size_t buffer_size)
|
||||||
{
|
{
|
||||||
rcheevos_fetch_badge_data* badge_data = (rcheevos_fetch_badge_data*)request->callback_data;
|
|
||||||
const rcheevos_locals_t* rcheevos_locals = get_rcheevos_locals();
|
|
||||||
char badge_fullpath[PATH_MAX_LENGTH];
|
char badge_fullpath[PATH_MAX_LENGTH];
|
||||||
|
rcheevos_fetch_badge_data* badge_data =
|
||||||
|
(rcheevos_fetch_badge_data*)request->callback_data;
|
||||||
|
const rcheevos_locals_t* rcheevos_locals = get_rcheevos_locals();
|
||||||
|
|
||||||
fill_pathname_join(badge_fullpath, badge_data->state->badge_directory,
|
fill_pathname_join(badge_fullpath, badge_data->state->badge_directory,
|
||||||
badge_data->state->requested_badges[badge_data->request_index], sizeof(badge_fullpath));
|
badge_data->state->requested_badges[badge_data->request_index],
|
||||||
|
sizeof(badge_fullpath));
|
||||||
|
|
||||||
if (!filestream_write_file(badge_fullpath, data->data, data->len))
|
if (!filestream_write_file(badge_fullpath, data->data, data->len))
|
||||||
CHEEVOS_ERR(RCHEEVOS_TAG "Error writing badge %s\n", badge_fullpath);
|
CHEEVOS_ERR(RCHEEVOS_TAG "Error writing badge %s\n",
|
||||||
|
badge_fullpath);
|
||||||
|
|
||||||
CHEEVOS_LOCK(rcheevos_locals->load_info.request_lock);
|
CHEEVOS_LOCK(rcheevos_locals->load_info.request_lock);
|
||||||
badge_data->state->requested_badges[badge_data->request_index][0] = '\0';
|
badge_data->state->requested_badges[badge_data->request_index][0] = '\0';
|
||||||
CHEEVOS_UNLOCK(rcheevos_locals->load_info.request_lock);
|
CHEEVOS_UNLOCK(rcheevos_locals->load_info.request_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool rcheevos_client_fetch_badge(const char* badge_name, int locked, rcheevos_fetch_badge_state* state)
|
static bool rcheevos_client_fetch_badge(
|
||||||
|
const char* badge_name, int locked,
|
||||||
|
rcheevos_fetch_badge_state* state)
|
||||||
{
|
{
|
||||||
char badge_fullpath[PATH_MAX_LENGTH];
|
char badge_fullpath[PATH_MAX_LENGTH];
|
||||||
char* badge_fullname = NULL;
|
char* badge_fullname = NULL;
|
||||||
|
@ -1233,12 +1285,15 @@ static bool rcheevos_client_fetch_badge(const char* badge_name, int locked, rche
|
||||||
if (!badge_name || !badge_name[0])
|
if (!badge_name || !badge_name[0])
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
strlcpy(badge_fullpath, state->badge_directory, sizeof(badge_fullpath));
|
strlcpy(badge_fullpath,
|
||||||
|
state->badge_directory, sizeof(badge_fullpath));
|
||||||
fill_pathname_slash(badge_fullpath, sizeof(badge_fullpath));
|
fill_pathname_slash(badge_fullpath, sizeof(badge_fullpath));
|
||||||
badge_fullname = badge_fullpath + strlen(state->badge_directory);
|
badge_fullname = badge_fullpath + strlen(state->badge_directory);
|
||||||
badge_fullname_size = sizeof(badge_fullpath) - (badge_fullname - badge_fullpath);
|
badge_fullname_size = sizeof(badge_fullpath) -
|
||||||
|
(badge_fullname - badge_fullpath);
|
||||||
|
|
||||||
snprintf(badge_fullname, badge_fullname_size, "%s%s" FILE_PATH_PNG_EXTENSION,
|
snprintf(badge_fullname,
|
||||||
|
badge_fullname_size, "%s%s" FILE_PATH_PNG_EXTENSION,
|
||||||
badge_name, locked ? "_lock" : "");
|
badge_name, locked ? "_lock" : "");
|
||||||
|
|
||||||
/* check if it's already available */
|
/* check if it's already available */
|
||||||
|
@ -1255,10 +1310,9 @@ static bool rcheevos_client_fetch_badge(const char* badge_name, int locked, rche
|
||||||
for (i = RCHEEVOS_CONCURRENT_BADGE_DOWNLOADS - 1; i >= 0; --i)
|
for (i = RCHEEVOS_CONCURRENT_BADGE_DOWNLOADS - 1; i >= 0; --i)
|
||||||
{
|
{
|
||||||
if (!state->requested_badges[i][0])
|
if (!state->requested_badges[i][0])
|
||||||
{
|
|
||||||
request_index = i;
|
request_index = i;
|
||||||
}
|
else if (string_is_equal(badge_fullname,
|
||||||
else if (string_is_equal(badge_fullname, state->requested_badges[i]))
|
state->requested_badges[i]))
|
||||||
{
|
{
|
||||||
found_index = i;
|
found_index = i;
|
||||||
break;
|
break;
|
||||||
|
@ -1267,15 +1321,15 @@ static bool rcheevos_client_fetch_badge(const char* badge_name, int locked, rche
|
||||||
|
|
||||||
if (found_index == -1)
|
if (found_index == -1)
|
||||||
{
|
{
|
||||||
|
/* unexpected - but if it happens,
|
||||||
|
* the queue is full. Pretend we found
|
||||||
|
* a match to prevent an exception */
|
||||||
if (request_index == -1)
|
if (request_index == -1)
|
||||||
{
|
|
||||||
/* unexpected - but if it happens, the queue is full. pretend we found a match to prevent an exception */
|
|
||||||
found_index = 0;
|
found_index = 0;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
strlcpy(state->requested_badges[request_index],
|
||||||
strlcpy(state->requested_badges[request_index], badge_fullname, sizeof(state->requested_badges[request_index]));
|
badge_fullname,
|
||||||
}
|
sizeof(state->requested_badges[request_index]));
|
||||||
}
|
}
|
||||||
CHEEVOS_UNLOCK(rcheevos_locals->load_info.request_lock);
|
CHEEVOS_UNLOCK(rcheevos_locals->load_info.request_lock);
|
||||||
|
|
||||||
|
@ -1296,7 +1350,8 @@ static bool rcheevos_client_fetch_badge(const char* badge_name, int locked, rche
|
||||||
|
|
||||||
if (!request || !data)
|
if (!request || !data)
|
||||||
{
|
{
|
||||||
CHEEVOS_LOG(RCHEEVOS_TAG "Failed to allocate fetch badge request\n");
|
CHEEVOS_LOG(RCHEEVOS_TAG
|
||||||
|
"Failed to allocate fetch badge request\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1304,7 +1359,9 @@ static bool rcheevos_client_fetch_badge(const char* badge_name, int locked, rche
|
||||||
|
|
||||||
memset(&api_params, 0, sizeof(api_params));
|
memset(&api_params, 0, sizeof(api_params));
|
||||||
api_params.image_name = badge_name;
|
api_params.image_name = badge_name;
|
||||||
api_params.image_type = locked ? RC_IMAGE_TYPE_ACHIEVEMENT_LOCKED : RC_IMAGE_TYPE_ACHIEVEMENT;
|
api_params.image_type = locked
|
||||||
|
? RC_IMAGE_TYPE_ACHIEVEMENT_LOCKED
|
||||||
|
: RC_IMAGE_TYPE_ACHIEVEMENT;
|
||||||
|
|
||||||
rc_api_init_fetch_image_request(&request->request, &api_params);
|
rc_api_init_fetch_image_request(&request->request, &api_params);
|
||||||
|
|
||||||
|
@ -1341,7 +1398,8 @@ static bool rcheevos_fetch_next_badge(rcheevos_fetch_badge_state* state)
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
CHEEVOS_LOCK(rcheevos_locals->load_info.request_lock);
|
CHEEVOS_LOCK(rcheevos_locals->load_info.request_lock);
|
||||||
if (state->locked_badge_fetch_index < rcheevos_locals->game.achievement_count)
|
if ( state->locked_badge_fetch_index
|
||||||
|
< rcheevos_locals->game.achievement_count)
|
||||||
cheevo = &rcheevos_locals->game.achievements[state->locked_badge_fetch_index++];
|
cheevo = &rcheevos_locals->game.achievements[state->locked_badge_fetch_index++];
|
||||||
else
|
else
|
||||||
cheevo = NULL;
|
cheevo = NULL;
|
||||||
|
@ -1350,7 +1408,8 @@ static bool rcheevos_fetch_next_badge(rcheevos_fetch_badge_state* state)
|
||||||
if (!cheevo)
|
if (!cheevo)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
active = (cheevo->active & (RCHEEVOS_ACTIVE_HARDCORE | RCHEEVOS_ACTIVE_SOFTCORE));
|
active = (cheevo->active
|
||||||
|
& (RCHEEVOS_ACTIVE_HARDCORE | RCHEEVOS_ACTIVE_SOFTCORE));
|
||||||
if (rcheevos_client_fetch_badge(cheevo->badge, active, state))
|
if (rcheevos_client_fetch_badge(cheevo->badge, active, state))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -1364,6 +1423,7 @@ static bool rcheevos_fetch_next_badge(rcheevos_fetch_badge_state* state)
|
||||||
cheevo = &rcheevos_locals->game.achievements[state->badge_fetch_index++];
|
cheevo = &rcheevos_locals->game.achievements[state->badge_fetch_index++];
|
||||||
else
|
else
|
||||||
cheevo = NULL;
|
cheevo = NULL;
|
||||||
|
|
||||||
CHEEVOS_UNLOCK(rcheevos_locals->load_info.request_lock);
|
CHEEVOS_UNLOCK(rcheevos_locals->load_info.request_lock);
|
||||||
|
|
||||||
if (!cheevo)
|
if (!cheevo)
|
||||||
|
@ -1381,10 +1441,12 @@ static bool rcheevos_fetch_next_badge(rcheevos_fetch_badge_state* state)
|
||||||
void rcheevos_client_fetch_badges(rcheevos_client_callback callback, void* userdata)
|
void rcheevos_client_fetch_badges(rcheevos_client_callback callback, void* userdata)
|
||||||
{
|
{
|
||||||
#if defined(HAVE_MENU) || defined(HAVE_GFX_WIDGETS) /* don't need badges unless menu or widgets are enabled */
|
#if defined(HAVE_MENU) || defined(HAVE_GFX_WIDGETS) /* don't need badges unless menu or widgets are enabled */
|
||||||
|
rcheevos_fetch_badge_state* state = NULL;
|
||||||
char badge_fullpath[PATH_MAX_LENGTH] = "";
|
char badge_fullpath[PATH_MAX_LENGTH] = "";
|
||||||
#if !defined(HAVE_GFX_WIDGETS) /* we always want badges if widgets are enabled */
|
#if !defined(HAVE_GFX_WIDGETS) /* we always want badges if widgets are enabled */
|
||||||
settings_t* settings = config_get_ptr();
|
settings_t* settings = config_get_ptr();
|
||||||
if (!settings->bools.cheevos_badges_enable) /* user has explicitly disabled badges */
|
/* User has explicitly disabled badges */
|
||||||
|
if (!settings->bools.cheevos_badges_enable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* badges are only needed for xmb and ozone menus */
|
/* badges are only needed for xmb and ozone menus */
|
||||||
|
@ -1394,7 +1456,8 @@ void rcheevos_client_fetch_badges(rcheevos_client_callback callback, void* userd
|
||||||
#endif /* !defined(HAVE_GFX_WIDGETS) */
|
#endif /* !defined(HAVE_GFX_WIDGETS) */
|
||||||
|
|
||||||
/* make sure the directory exists */
|
/* make sure the directory exists */
|
||||||
fill_pathname_application_special(badge_fullpath, sizeof(badge_fullpath),
|
fill_pathname_application_special(badge_fullpath,
|
||||||
|
sizeof(badge_fullpath),
|
||||||
APPLICATION_SPECIAL_DIRECTORY_THUMBNAILS_CHEEVOS_BADGES);
|
APPLICATION_SPECIAL_DIRECTORY_THUMBNAILS_CHEEVOS_BADGES);
|
||||||
|
|
||||||
if (!path_is_directory(badge_fullpath))
|
if (!path_is_directory(badge_fullpath))
|
||||||
|
@ -1404,8 +1467,9 @@ void rcheevos_client_fetch_badges(rcheevos_client_callback callback, void* userd
|
||||||
}
|
}
|
||||||
|
|
||||||
/* start the download task */
|
/* start the download task */
|
||||||
rcheevos_fetch_badge_state* state = (rcheevos_fetch_badge_state*)
|
state = (rcheevos_fetch_badge_state*)
|
||||||
calloc(1, sizeof(rcheevos_fetch_badge_state));
|
calloc(1, sizeof(rcheevos_fetch_badge_state));
|
||||||
|
|
||||||
if (!state)
|
if (!state)
|
||||||
{
|
{
|
||||||
CHEEVOS_LOG(RCHEEVOS_TAG "Failed to allocate fetch badge state\n");
|
CHEEVOS_LOG(RCHEEVOS_TAG "Failed to allocate fetch badge state\n");
|
||||||
|
@ -1446,19 +1510,20 @@ void rcheevos_client_fetch_badges(rcheevos_client_callback callback, void* userd
|
||||||
* award achievement *
|
* award achievement *
|
||||||
****************************/
|
****************************/
|
||||||
|
|
||||||
static void rcheevos_async_award_achievement_callback(struct rcheevos_async_io_request* request,
|
static void rcheevos_async_award_achievement_callback(
|
||||||
|
struct rcheevos_async_io_request* request,
|
||||||
http_transfer_data_t *data, char buffer[], size_t buffer_size)
|
http_transfer_data_t *data, char buffer[], size_t buffer_size)
|
||||||
{
|
{
|
||||||
rc_api_award_achievement_response_t api_response;
|
rc_api_award_achievement_response_t api_response;
|
||||||
|
|
||||||
int result = rc_api_process_award_achievement_response(&api_response, data->data);
|
int result = rc_api_process_award_achievement_response(
|
||||||
if (rcheevos_async_succeeded(result, &api_response.response, buffer, buffer_size))
|
&api_response, data->data);
|
||||||
|
if (rcheevos_async_succeeded(result, &api_response.response,
|
||||||
|
buffer, buffer_size))
|
||||||
{
|
{
|
||||||
if (api_response.awarded_achievement_id != request->id)
|
if (api_response.awarded_achievement_id != request->id)
|
||||||
{
|
|
||||||
snprintf(buffer, buffer_size, "Achievement %u awarded instead",
|
snprintf(buffer, buffer_size, "Achievement %u awarded instead",
|
||||||
api_response.awarded_achievement_id);
|
api_response.awarded_achievement_id);
|
||||||
}
|
|
||||||
else if (api_response.response.error_message)
|
else if (api_response.response.error_message)
|
||||||
{
|
{
|
||||||
/* previously unlocked achievements are returned as a "successful" error */
|
/* previously unlocked achievements are returned as a "successful" error */
|
||||||
|
@ -1481,8 +1546,8 @@ void rcheevos_client_award_achievement(unsigned achievement_id)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const rcheevos_locals_t* rcheevos_locals = get_rcheevos_locals();
|
|
||||||
rc_api_award_achievement_request_t api_params;
|
rc_api_award_achievement_request_t api_params;
|
||||||
|
const rcheevos_locals_t* rcheevos_locals = get_rcheevos_locals();
|
||||||
|
|
||||||
memset(&api_params, 0, sizeof(api_params));
|
memset(&api_params, 0, sizeof(api_params));
|
||||||
api_params.username = rcheevos_locals->username;
|
api_params.username = rcheevos_locals->username;
|
||||||
|
@ -1491,7 +1556,8 @@ void rcheevos_client_award_achievement(unsigned achievement_id)
|
||||||
api_params.hardcore = rcheevos_locals->hardcore_active ? 1 : 0;
|
api_params.hardcore = rcheevos_locals->hardcore_active ? 1 : 0;
|
||||||
api_params.game_hash = rcheevos_locals->game.hash;
|
api_params.game_hash = rcheevos_locals->game.hash;
|
||||||
|
|
||||||
rc_api_init_award_achievement_request(&request->request, &api_params);
|
rc_api_init_award_achievement_request(&request->request,
|
||||||
|
&api_params);
|
||||||
|
|
||||||
rcheevos_async_begin_request(request,
|
rcheevos_async_begin_request(request,
|
||||||
rcheevos_async_award_achievement_callback,
|
rcheevos_async_award_achievement_callback,
|
||||||
|
@ -1506,28 +1572,30 @@ void rcheevos_client_award_achievement(unsigned achievement_id)
|
||||||
* submit leaderboard *
|
* submit leaderboard *
|
||||||
****************************/
|
****************************/
|
||||||
|
|
||||||
static void rcheevos_async_submit_lboard_entry_callback(struct rcheevos_async_io_request* request,
|
static void rcheevos_async_submit_lboard_entry_callback(
|
||||||
|
struct rcheevos_async_io_request* request,
|
||||||
http_transfer_data_t* data, char buffer[], size_t buffer_size)
|
http_transfer_data_t* data, char buffer[], size_t buffer_size)
|
||||||
{
|
{
|
||||||
rc_api_submit_lboard_entry_response_t api_response;
|
rc_api_submit_lboard_entry_response_t api_response;
|
||||||
|
int result = rc_api_process_submit_lboard_entry_response(
|
||||||
|
&api_response, data->data);
|
||||||
|
|
||||||
int result = rc_api_process_submit_lboard_entry_response(&api_response, data->data);
|
|
||||||
|
|
||||||
if (rcheevos_async_succeeded(result, &api_response.response, buffer, buffer_size))
|
|
||||||
{
|
|
||||||
/* not currently doing anything with the response */
|
/* not currently doing anything with the response */
|
||||||
}
|
if (rcheevos_async_succeeded(result, &api_response.response, buffer,
|
||||||
|
buffer_size)) { }
|
||||||
|
|
||||||
rc_api_destroy_submit_lboard_entry_response(&api_response);
|
rc_api_destroy_submit_lboard_entry_response(&api_response);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rcheevos_client_submit_lboard_entry(unsigned leaderboard_id, int value)
|
void rcheevos_client_submit_lboard_entry(unsigned leaderboard_id,
|
||||||
|
int value)
|
||||||
{
|
{
|
||||||
rcheevos_async_io_request *request = (rcheevos_async_io_request*)
|
rcheevos_async_io_request *request = (rcheevos_async_io_request*)
|
||||||
calloc(1, sizeof(rcheevos_async_io_request));
|
calloc(1, sizeof(rcheevos_async_io_request));
|
||||||
if (!request)
|
if (!request)
|
||||||
{
|
{
|
||||||
CHEEVOS_LOG(RCHEEVOS_TAG "Failed to allocate request for lboard %u submit\n",
|
CHEEVOS_LOG(RCHEEVOS_TAG
|
||||||
|
"Failed to allocate request for lboard %u submit\n",
|
||||||
leaderboard_id);
|
leaderboard_id);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1542,7 +1610,8 @@ void rcheevos_client_submit_lboard_entry(unsigned leaderboard_id, int value)
|
||||||
api_params.score = value;
|
api_params.score = value;
|
||||||
api_params.game_hash = rcheevos_locals->game.hash;
|
api_params.game_hash = rcheevos_locals->game.hash;
|
||||||
|
|
||||||
rc_api_init_submit_lboard_entry_request(&request->request, &api_params);
|
rc_api_init_submit_lboard_entry_request(&request->request,
|
||||||
|
&api_params);
|
||||||
|
|
||||||
rcheevos_async_begin_request(request,
|
rcheevos_async_begin_request(request,
|
||||||
rcheevos_async_submit_lboard_entry_callback,
|
rcheevos_async_submit_lboard_entry_callback,
|
||||||
|
@ -1551,4 +1620,3 @@ void rcheevos_client_submit_lboard_entry(unsigned leaderboard_id, int value)
|
||||||
"Error submitting leaderboard");
|
"Error submitting leaderboard");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -115,15 +115,11 @@ bool rcheevos_menu_get_state(unsigned menu_offset, char *buffer, size_t len)
|
||||||
if (cheevo)
|
if (cheevo)
|
||||||
{
|
{
|
||||||
if (cheevo->menu_progress)
|
if (cheevo->menu_progress)
|
||||||
{
|
|
||||||
snprintf(buffer, len, "%s - %d%%",
|
snprintf(buffer, len, "%s - %d%%",
|
||||||
msg_hash_to_str(menuitem->state_label_idx),
|
msg_hash_to_str(menuitem->state_label_idx),
|
||||||
cheevo->menu_progress);
|
cheevo->menu_progress);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
strlcpy(buffer, msg_hash_to_str(menuitem->state_label_idx), len);
|
strlcpy(buffer, msg_hash_to_str(menuitem->state_label_idx), len);
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -183,9 +179,7 @@ static rcheevos_menuitem_t* rcheevos_menu_allocate(
|
||||||
rcheevos_locals->menuitem_capacity * sizeof(rcheevos_menuitem_t));
|
rcheevos_locals->menuitem_capacity * sizeof(rcheevos_menuitem_t));
|
||||||
|
|
||||||
if (new_menuitems)
|
if (new_menuitems)
|
||||||
{
|
|
||||||
rcheevos_locals->menuitems = new_menuitems;
|
rcheevos_locals->menuitems = new_menuitems;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* realloc failed */
|
/* realloc failed */
|
||||||
|
@ -353,10 +347,8 @@ static void rcheevos_menu_append_items(rcheevos_locals_t* rcheevos_locals,
|
||||||
|
|
||||||
if (cheevo->badge && cheevo->badge[0] && settings &&
|
if (cheevo->badge && cheevo->badge[0] && settings &&
|
||||||
settings->bools.cheevos_badges_enable)
|
settings->bools.cheevos_badges_enable)
|
||||||
{
|
|
||||||
rcheevos_menu_update_badge(cheevo);
|
rcheevos_menu_update_badge(cheevo);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
++cheevo;
|
++cheevo;
|
||||||
}
|
}
|
||||||
|
@ -480,9 +472,7 @@ void rcheevos_menu_populate(void* data)
|
||||||
++num_recently_unlocked;
|
++num_recently_unlocked;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
++num_unlocked;
|
++num_unlocked;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RCHEEVOS_MENUITEM_BUCKET_LOCKED:
|
case RCHEEVOS_MENUITEM_BUCKET_LOCKED:
|
||||||
|
@ -555,10 +545,8 @@ void rcheevos_menu_populate(void* data)
|
||||||
if (num_locked)
|
if (num_locked)
|
||||||
{
|
{
|
||||||
if (rcheevos_locals->menuitem_count > 0)
|
if (rcheevos_locals->menuitem_count > 0)
|
||||||
{
|
|
||||||
rcheevos_menu_append_header(rcheevos_locals,
|
rcheevos_menu_append_header(rcheevos_locals,
|
||||||
MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ENTRY);
|
MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ENTRY);
|
||||||
}
|
|
||||||
|
|
||||||
rcheevos_menu_append_items(rcheevos_locals,
|
rcheevos_menu_append_items(rcheevos_locals,
|
||||||
RCHEEVOS_MENUITEM_BUCKET_LOCKED);
|
RCHEEVOS_MENUITEM_BUCKET_LOCKED);
|
||||||
|
@ -570,10 +558,8 @@ void rcheevos_menu_populate(void* data)
|
||||||
if (num_unsupported)
|
if (num_unsupported)
|
||||||
{
|
{
|
||||||
if (rcheevos_locals->menuitem_count > 0)
|
if (rcheevos_locals->menuitem_count > 0)
|
||||||
{
|
|
||||||
rcheevos_menu_append_header(rcheevos_locals,
|
rcheevos_menu_append_header(rcheevos_locals,
|
||||||
MENU_ENUM_LABEL_VALUE_CHEEVOS_UNSUPPORTED_ENTRY);
|
MENU_ENUM_LABEL_VALUE_CHEEVOS_UNSUPPORTED_ENTRY);
|
||||||
}
|
|
||||||
|
|
||||||
rcheevos_menu_append_items(rcheevos_locals,
|
rcheevos_menu_append_items(rcheevos_locals,
|
||||||
RCHEEVOS_MENUITEM_BUCKET_UNSUPPORTED);
|
RCHEEVOS_MENUITEM_BUCKET_UNSUPPORTED);
|
||||||
|
@ -583,10 +569,8 @@ void rcheevos_menu_populate(void* data)
|
||||||
if (num_unlocked)
|
if (num_unlocked)
|
||||||
{
|
{
|
||||||
if (rcheevos_locals->menuitem_count > 0)
|
if (rcheevos_locals->menuitem_count > 0)
|
||||||
{
|
|
||||||
rcheevos_menu_append_header(rcheevos_locals,
|
rcheevos_menu_append_header(rcheevos_locals,
|
||||||
MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ENTRY);
|
MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ENTRY);
|
||||||
}
|
|
||||||
|
|
||||||
rcheevos_menu_append_items(rcheevos_locals,
|
rcheevos_menu_append_items(rcheevos_locals,
|
||||||
RCHEEVOS_MENUITEM_BUCKET_UNLOCKED);
|
RCHEEVOS_MENUITEM_BUCKET_UNLOCKED);
|
||||||
|
@ -594,21 +578,20 @@ void rcheevos_menu_populate(void* data)
|
||||||
|
|
||||||
if (rcheevos_locals->menuitem_count > 0)
|
if (rcheevos_locals->menuitem_count > 0)
|
||||||
{
|
{
|
||||||
/* convert to menu entries */
|
|
||||||
rcheevos_menuitem_t* menuitem = rcheevos_locals->menuitems;
|
|
||||||
rcheevos_menuitem_t* stop = menuitem + rcheevos_locals->menuitem_count;
|
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
unsigned idx = 0;
|
unsigned idx = 0;
|
||||||
|
/* convert to menu entries */
|
||||||
|
rcheevos_menuitem_t* menuitem = rcheevos_locals->menuitems;
|
||||||
|
rcheevos_menuitem_t* stop = menuitem +
|
||||||
|
rcheevos_locals->menuitem_count;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (menuitem->cheevo)
|
if (menuitem->cheevo)
|
||||||
{
|
|
||||||
menu_entries_append_enum(info->list, menuitem->cheevo->title,
|
menu_entries_append_enum(info->list, menuitem->cheevo->title,
|
||||||
menuitem->cheevo->description,
|
menuitem->cheevo->description,
|
||||||
MENU_ENUM_LABEL_CHEEVOS_LOCKED_ENTRY,
|
MENU_ENUM_LABEL_CHEEVOS_LOCKED_ENTRY,
|
||||||
MENU_SETTINGS_CHEEVOS_START + idx, 0, 0);
|
MENU_SETTINGS_CHEEVOS_START + idx, 0, 0);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
snprintf(buffer, sizeof(buffer), "----- %s -----",
|
snprintf(buffer, sizeof(buffer), "----- %s -----",
|
||||||
|
@ -627,39 +610,30 @@ void rcheevos_menu_populate(void* data)
|
||||||
{
|
{
|
||||||
/* no achievements found */
|
/* no achievements found */
|
||||||
if (!rcheevos_locals->core_supports)
|
if (!rcheevos_locals->core_supports)
|
||||||
{
|
|
||||||
menu_entries_append_enum(info->list,
|
menu_entries_append_enum(info->list,
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CANNOT_ACTIVATE_ACHIEVEMENTS_WITH_THIS_CORE),
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CANNOT_ACTIVATE_ACHIEVEMENTS_WITH_THIS_CORE),
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_CANNOT_ACTIVATE_ACHIEVEMENTS_WITH_THIS_CORE),
|
msg_hash_to_str(MENU_ENUM_LABEL_CANNOT_ACTIVATE_ACHIEVEMENTS_WITH_THIS_CORE),
|
||||||
MENU_ENUM_LABEL_CANNOT_ACTIVATE_ACHIEVEMENTS_WITH_THIS_CORE,
|
MENU_ENUM_LABEL_CANNOT_ACTIVATE_ACHIEVEMENTS_WITH_THIS_CORE,
|
||||||
FILE_TYPE_NONE, 0, 0);
|
FILE_TYPE_NONE, 0, 0);
|
||||||
}
|
|
||||||
else if (rcheevos_locals->load_info.state == RCHEEVOS_LOAD_STATE_NETWORK_ERROR)
|
else if (rcheevos_locals->load_info.state == RCHEEVOS_LOAD_STATE_NETWORK_ERROR)
|
||||||
{
|
|
||||||
menu_entries_append_enum(info->list,
|
menu_entries_append_enum(info->list,
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETWORK_ERROR),
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETWORK_ERROR),
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_NETWORK_ERROR),
|
msg_hash_to_str(MENU_ENUM_LABEL_NETWORK_ERROR),
|
||||||
MENU_ENUM_LABEL_NETWORK_ERROR,
|
MENU_ENUM_LABEL_NETWORK_ERROR,
|
||||||
FILE_TYPE_NONE, 0, 0);
|
FILE_TYPE_NONE, 0, 0);
|
||||||
}
|
|
||||||
else if (!rcheevos_locals->game.id)
|
else if (!rcheevos_locals->game.id)
|
||||||
{
|
|
||||||
menu_entries_append_enum(info->list,
|
menu_entries_append_enum(info->list,
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_UNKNOWN_GAME),
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_UNKNOWN_GAME),
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_UNKNOWN_GAME),
|
msg_hash_to_str(MENU_ENUM_LABEL_UNKNOWN_GAME),
|
||||||
MENU_ENUM_LABEL_UNKNOWN_GAME,
|
MENU_ENUM_LABEL_UNKNOWN_GAME,
|
||||||
FILE_TYPE_NONE, 0, 0);
|
FILE_TYPE_NONE, 0, 0);
|
||||||
}
|
|
||||||
else if (!rcheevos_locals->token[0])
|
else if (!rcheevos_locals->token[0])
|
||||||
{
|
|
||||||
menu_entries_append_enum(info->list,
|
menu_entries_append_enum(info->list,
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_LOGGED_IN),
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_LOGGED_IN),
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_NOT_LOGGED_IN),
|
msg_hash_to_str(MENU_ENUM_LABEL_NOT_LOGGED_IN),
|
||||||
MENU_ENUM_LABEL_NOT_LOGGED_IN,
|
MENU_ENUM_LABEL_NOT_LOGGED_IN,
|
||||||
FILE_TYPE_NONE, 0, 0);
|
FILE_TYPE_NONE, 0, 0);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
menu_entries_append_enum(info->list,
|
menu_entries_append_enum(info->list,
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_ACHIEVEMENTS_TO_DISPLAY),
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_ACHIEVEMENTS_TO_DISPLAY),
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_NO_ACHIEVEMENTS_TO_DISPLAY),
|
msg_hash_to_str(MENU_ENUM_LABEL_NO_ACHIEVEMENTS_TO_DISPLAY),
|
||||||
|
@ -667,7 +641,6 @@ void rcheevos_menu_populate(void* data)
|
||||||
FILE_TYPE_NONE, 0, 0);
|
FILE_TYPE_NONE, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* HAVE_MENU */
|
#endif /* HAVE_MENU */
|
||||||
|
|
||||||
|
@ -688,10 +661,7 @@ uintptr_t rcheevos_get_badge_texture(const char *badge, bool locked)
|
||||||
|
|
||||||
if (!gfx_display_reset_textures_list(badge_file, fullpath,
|
if (!gfx_display_reset_textures_list(badge_file, fullpath,
|
||||||
&tex, TEXTURE_FILTER_MIPMAP_LINEAR, NULL, NULL))
|
&tex, TEXTURE_FILTER_MIPMAP_LINEAR, NULL, NULL))
|
||||||
{
|
return 0;
|
||||||
tex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue