diff --git a/dep/rcheevos/include/rc_client.h b/dep/rcheevos/include/rc_client.h index 26db52932..dcbd35430 100644 --- a/dep/rcheevos/include/rc_client.h +++ b/dep/rcheevos/include/rc_client.h @@ -596,6 +596,12 @@ RC_EXPORT int RC_CCONV rc_client_has_rich_presence(rc_client_t* client); */ RC_EXPORT size_t RC_CCONV rc_client_get_rich_presence_message(rc_client_t* client, char buffer[], size_t buffer_size); +/** + * Returns a list of all possible rich presence strings. + * The list is terminated by NULL. + */ +RC_EXPORT int RC_CCONV rc_client_get_rich_presence_strings(rc_client_t* client, const char** buffer, size_t buffer_size, size_t* count); + /*****************************************************************************\ | Processing | \*****************************************************************************/ diff --git a/dep/rcheevos/include/rc_runtime.h b/dep/rcheevos/include/rc_runtime.h index d778fde5c..8186c010b 100644 --- a/dep/rcheevos/include/rc_runtime.h +++ b/dep/rcheevos/include/rc_runtime.h @@ -110,6 +110,7 @@ RC_EXPORT int RC_CCONV rc_runtime_format_lboard_value(char* buffer, int size, in RC_EXPORT int RC_CCONV rc_runtime_activate_richpresence(rc_runtime_t* runtime, const char* script, lua_State* L, int funcs_idx); RC_EXPORT int RC_CCONV rc_runtime_get_richpresence(const rc_runtime_t* runtime, char* buffer, size_t buffersize, rc_runtime_peek_t peek, void* peek_ud, lua_State* L); +RC_EXPORT int RC_CCONV rc_runtime_get_richpresence_strings(const rc_runtime_t* runtime, const char** buffer, size_t buffersize, size_t* count); enum { RC_RUNTIME_EVENT_ACHIEVEMENT_ACTIVATED, /* from WAITING, PAUSED, or PRIMED to ACTIVE */ diff --git a/dep/rcheevos/include/rc_runtime_types.h b/dep/rcheevos/include/rc_runtime_types.h index 4bf1b13bf..77d2390f4 100644 --- a/dep/rcheevos/include/rc_runtime_types.h +++ b/dep/rcheevos/include/rc_runtime_types.h @@ -432,6 +432,7 @@ RC_EXPORT int RC_CCONV rc_evaluate_richpresence(rc_richpresence_t* richpresence, RC_EXPORT void RC_CCONV rc_update_richpresence(rc_richpresence_t* richpresence, rc_peek_t peek, void* peek_ud, lua_State* L); RC_EXPORT int RC_CCONV rc_get_richpresence_display_string(rc_richpresence_t* richpresence, char* buffer, size_t buffersize, rc_peek_t peek, void* peek_ud, lua_State* L); RC_EXPORT void RC_CCONV rc_reset_richpresence(rc_richpresence_t* self); +RC_EXPORT int RC_CCONV rc_get_richpresence_strings(rc_richpresence_t* richpresence, const char** buffer, size_t buffersize, size_t* count); RC_END_C_DECLS diff --git a/dep/rcheevos/src/rc_client.c b/dep/rcheevos/src/rc_client.c index db8ab8bcc..d57f86f9f 100644 --- a/dep/rcheevos/src/rc_client.c +++ b/dep/rcheevos/src/rc_client.c @@ -4694,6 +4694,18 @@ size_t rc_client_get_rich_presence_message(rc_client_t* client, char buffer[], s return result; } +int rc_client_get_rich_presence_strings(rc_client_t* client, const char** buffer, size_t buffer_size, size_t* count) { + int result; + + if (!client || !buffer) + return RC_INVALID_STATE; + + rc_mutex_lock(&client->state.mutex); + result = rc_runtime_get_richpresence_strings(&client->game->runtime, buffer, buffer_size, count); + rc_mutex_unlock(&client->state.mutex); + return result; +} + /* ===== Processing ===== */ void rc_client_set_event_handler(rc_client_t* client, rc_client_event_handler_t handler) diff --git a/dep/rcheevos/src/rcheevos/richpresence.c b/dep/rcheevos/src/rcheevos/richpresence.c index 0dd660e68..43f5ed1f5 100644 --- a/dep/rcheevos/src/rcheevos/richpresence.c +++ b/dep/rcheevos/src/rcheevos/richpresence.c @@ -827,3 +827,78 @@ void rc_reset_richpresence(rc_richpresence_t* self) { for (variable = self->variables; variable; variable = variable->next) rc_reset_value(variable); } + +static int rc_get_richpresence_strings_has_string(const char** buffer, size_t written, const char* search) { + for (size_t i = 0; i < written; i++) { + if (buffer[i] == search) + return 1; + } + + return 0; +} + +static int rc_get_richpresence_strings_recurse(const rc_richpresence_lookup_item_t* item, const char** buffer, size_t buffersize, size_t* written) { + size_t len; + int err; + + if (!rc_get_richpresence_strings_has_string(buffer, *written, item->label)) { + if (*written == buffersize) + return RC_INSUFFICIENT_BUFFER; + + buffer[(*written)++] = item->label; + } + + if (item->left && (err = rc_get_richpresence_strings_recurse(item->left, buffer, buffersize, written)) != RC_OK) + return err; + if (item->right && (err = rc_get_richpresence_strings_recurse(item->right, buffer, buffersize, written)) != RC_OK) + return err; + + return RC_OK; +} + +int rc_get_richpresence_strings(rc_richpresence_t* richpresence, const char** buffer, size_t buffersize, size_t* count) { + const rc_richpresence_display_t* display; + const rc_richpresence_display_part_t* part; + size_t written; + size_t len; + int err; + + written = 0; + for (display = richpresence->first_display; display; display = display->next) { + for (part = display->display; part; part = part->next) { + switch (part->display_type) { + case RC_FORMAT_STRING: + if (!rc_get_richpresence_strings_has_string(buffer, written, part->text)) { + if (written == buffersize) + return RC_INSUFFICIENT_BUFFER; + + buffer[written++] = part->text; + } + break; + + case RC_FORMAT_LOOKUP: + if (part->lookup->default_label && !rc_get_richpresence_strings_has_string(buffer, written, part->lookup->default_label)) { + if (written == buffersize) + return RC_INSUFFICIENT_BUFFER; + + buffer[written++] = part->lookup->default_label; + } + + if ((err = rc_get_richpresence_strings_recurse(part->lookup->root, buffer, buffersize, &written)) != RC_OK) + return err; + + break; + + default: + break; + } + } + } + + if (written == buffersize) + return RC_INSUFFICIENT_BUFFER; + + *count = written; + buffer[written++] = NULL; /* terminate list */ + return RC_OK; +} diff --git a/dep/rcheevos/src/rcheevos/runtime.c b/dep/rcheevos/src/rcheevos/runtime.c index 25e9885dc..5d9f60d9a 100644 --- a/dep/rcheevos/src/rcheevos/runtime.c +++ b/dep/rcheevos/src/rcheevos/runtime.c @@ -537,6 +537,17 @@ int rc_runtime_get_richpresence(const rc_runtime_t* self, char* buffer, size_t b return 0; } +int rc_runtime_get_richpresence_strings(const rc_runtime_t* self, const char** buffer, size_t buffersize, size_t* count) { + int err = RC_INVALID_STATE; + if (self->richpresence && self->richpresence->richpresence) + err = rc_get_richpresence_strings(self->richpresence->richpresence, buffer, buffersize, count); + + if (err != RC_OK) + *buffer = '\0'; + + return err; +} + void rc_runtime_do_frame(rc_runtime_t* self, rc_runtime_event_handler_t event_handler, rc_runtime_peek_t peek, void* ud, lua_State* L) { rc_runtime_event_t runtime_event; int i;