rc_client.h (27476B)
1 #ifndef RC_CLIENT_H 2 #define RC_CLIENT_H 3 4 #include "rc_api_request.h" 5 #include "rc_error.h" 6 7 #include <stddef.h> 8 #include <stdint.h> 9 #include <time.h> 10 11 RC_BEGIN_C_DECLS 12 13 /* implementation abstracted in rc_client_internal.h */ 14 typedef struct rc_client_t rc_client_t; 15 typedef struct rc_client_async_handle_t rc_client_async_handle_t; 16 17 /*****************************************************************************\ 18 | Callbacks | 19 \*****************************************************************************/ 20 21 /** 22 * Callback used to read num_bytes bytes from memory starting at address into buffer. 23 * Returns the number of bytes read. A return value of 0 indicates the address was invalid. 24 */ 25 typedef uint32_t (RC_CCONV *rc_client_read_memory_func_t)(uint32_t address, uint8_t* buffer, uint32_t num_bytes, rc_client_t* client); 26 27 /** 28 * Internal method passed to rc_client_server_call_t to process the server response. 29 */ 30 typedef void (RC_CCONV *rc_client_server_callback_t)(const rc_api_server_response_t* server_response, void* callback_data); 31 32 /** 33 * Callback used to issue a request to the server. 34 */ 35 typedef void (RC_CCONV *rc_client_server_call_t)(const rc_api_request_t* request, rc_client_server_callback_t callback, void* callback_data, rc_client_t* client); 36 37 /** 38 * Generic callback for asynchronous eventing. 39 */ 40 typedef void (RC_CCONV *rc_client_callback_t)(int result, const char* error_message, rc_client_t* client, void* userdata); 41 42 /** 43 * Callback for logging or displaying a message. 44 */ 45 typedef void (RC_CCONV *rc_client_message_callback_t)(const char* message, const rc_client_t* client); 46 47 /*****************************************************************************\ 48 | Runtime | 49 \*****************************************************************************/ 50 51 /** 52 * Creates a new rc_client_t object. 53 */ 54 RC_EXPORT rc_client_t* RC_CCONV rc_client_create(rc_client_read_memory_func_t read_memory_function, rc_client_server_call_t server_call_function); 55 56 /** 57 * Releases resources associated to a rc_client_t object. 58 * Pointer will no longer be valid after making this call. 59 */ 60 RC_EXPORT void RC_CCONV rc_client_destroy(rc_client_t* client); 61 62 /** 63 * Sets whether hardcore is enabled (on by default). 64 * Can be called with a game loaded. 65 * Enabling hardcore with a game loaded will raise an RC_CLIENT_EVENT_RESET 66 * event. Processing will be disabled until rc_client_reset is called. 67 */ 68 RC_EXPORT void RC_CCONV rc_client_set_hardcore_enabled(rc_client_t* client, int enabled); 69 70 /** 71 * Gets whether hardcore is enabled (on by default). 72 */ 73 RC_EXPORT int RC_CCONV rc_client_get_hardcore_enabled(const rc_client_t* client); 74 75 /** 76 * Sets whether encore mode is enabled (off by default). 77 * Evaluated when loading a game. Has no effect while a game is loaded. 78 */ 79 RC_EXPORT void RC_CCONV rc_client_set_encore_mode_enabled(rc_client_t* client, int enabled); 80 81 /** 82 * Gets whether encore mode is enabled (off by default). 83 */ 84 RC_EXPORT int RC_CCONV rc_client_get_encore_mode_enabled(const rc_client_t* client); 85 86 /** 87 * Sets whether unofficial achievements should be loaded. 88 * Evaluated when loading a game. Has no effect while a game is loaded. 89 */ 90 RC_EXPORT void RC_CCONV rc_client_set_unofficial_enabled(rc_client_t* client, int enabled); 91 92 /** 93 * Gets whether unofficial achievements should be loaded. 94 */ 95 RC_EXPORT int RC_CCONV rc_client_get_unofficial_enabled(const rc_client_t* client); 96 97 /** 98 * Sets whether spectator mode is enabled (off by default). 99 * If enabled, events for achievement unlocks and leaderboard submissions will be 100 * raised, but server calls to actually perform the unlock/submit will not occur. 101 * Can be modified while a game is loaded. Evaluated at unlock/submit time. 102 * Cannot be modified if disabled before a game is loaded. 103 */ 104 RC_EXPORT void RC_CCONV rc_client_set_spectator_mode_enabled(rc_client_t* client, int enabled); 105 106 /** 107 * Gets whether spectator mode is enabled (off by default). 108 */ 109 RC_EXPORT int RC_CCONV rc_client_get_spectator_mode_enabled(const rc_client_t* client); 110 111 /** 112 * Attaches client-specific data to the runtime. 113 */ 114 RC_EXPORT void RC_CCONV rc_client_set_userdata(rc_client_t* client, void* userdata); 115 116 /** 117 * Gets the client-specific data attached to the runtime. 118 */ 119 RC_EXPORT void* RC_CCONV rc_client_get_userdata(const rc_client_t* client); 120 121 /** 122 * Sets the name of the server to use. 123 */ 124 RC_EXPORT void RC_CCONV rc_client_set_host(const rc_client_t* client, const char* hostname); 125 126 typedef uint64_t rc_clock_t; 127 typedef rc_clock_t (RC_CCONV *rc_get_time_millisecs_func_t)(const rc_client_t* client); 128 129 /** 130 * Specifies a function that returns a value that increases once per millisecond. 131 */ 132 RC_EXPORT void RC_CCONV rc_client_set_get_time_millisecs_function(rc_client_t* client, rc_get_time_millisecs_func_t handler); 133 134 /** 135 * Marks an async process as aborted. The associated callback will not be called. 136 */ 137 RC_EXPORT void RC_CCONV rc_client_abort_async(rc_client_t* client, rc_client_async_handle_t* async_handle); 138 139 /** 140 * Gets a clause that can be added to the User-Agent to identify the version of rcheevos being used. 141 */ 142 RC_EXPORT size_t RC_CCONV rc_client_get_user_agent_clause(rc_client_t* client, char buffer[], size_t buffer_size); 143 144 /*****************************************************************************\ 145 | Logging | 146 \*****************************************************************************/ 147 148 /** 149 * Sets the logging level and provides a callback to be called to do the logging. 150 */ 151 RC_EXPORT void RC_CCONV rc_client_enable_logging(rc_client_t* client, int level, rc_client_message_callback_t callback); 152 enum { 153 RC_CLIENT_LOG_LEVEL_NONE = 0, 154 RC_CLIENT_LOG_LEVEL_ERROR = 1, 155 RC_CLIENT_LOG_LEVEL_WARN = 2, 156 RC_CLIENT_LOG_LEVEL_INFO = 3, 157 RC_CLIENT_LOG_LEVEL_VERBOSE = 4, 158 NUM_RC_CLIENT_LOG_LEVELS = 5 159 }; 160 161 /*****************************************************************************\ 162 | User | 163 \*****************************************************************************/ 164 165 /** 166 * Attempt to login a user. 167 */ 168 RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_login_with_password(rc_client_t* client, 169 const char* username, const char* password, 170 rc_client_callback_t callback, void* callback_userdata); 171 172 /** 173 * Attempt to login a user. 174 */ 175 RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_login_with_token(rc_client_t* client, 176 const char* username, const char* token, 177 rc_client_callback_t callback, void* callback_userdata); 178 179 /** 180 * Logout the user. 181 */ 182 RC_EXPORT void RC_CCONV rc_client_logout(rc_client_t* client); 183 184 typedef struct rc_client_user_t { 185 const char* display_name; 186 const char* username; 187 const char* token; 188 uint32_t score; 189 uint32_t score_softcore; 190 uint32_t num_unread_messages; 191 } rc_client_user_t; 192 193 /** 194 * Gets information about the logged in user. Will return NULL if the user is not logged in. 195 */ 196 RC_EXPORT const rc_client_user_t* RC_CCONV rc_client_get_user_info(const rc_client_t* client); 197 198 /** 199 * Gets the URL for the user's profile picture. 200 * Returns RC_OK on success. 201 */ 202 RC_EXPORT int RC_CCONV rc_client_user_get_image_url(const rc_client_user_t* user, char buffer[], size_t buffer_size); 203 204 typedef struct rc_client_user_game_summary_t { 205 uint32_t num_core_achievements; 206 uint32_t num_unofficial_achievements; 207 uint32_t num_unlocked_achievements; 208 uint32_t num_unsupported_achievements; 209 210 uint32_t points_core; 211 uint32_t points_unlocked; 212 } rc_client_user_game_summary_t; 213 214 /** 215 * Gets a breakdown of the number of achievements in the game, and how many the user has unlocked. 216 * Used for the "You have unlocked X of Y achievements" message shown when the game starts. 217 */ 218 RC_EXPORT void RC_CCONV rc_client_get_user_game_summary(const rc_client_t* client, rc_client_user_game_summary_t* summary); 219 220 /*****************************************************************************\ 221 | Game | 222 \*****************************************************************************/ 223 224 #ifdef RC_CLIENT_SUPPORTS_HASH 225 /** 226 * Start loading an unidentified game. 227 */ 228 RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_identify_and_load_game(rc_client_t* client, 229 uint32_t console_id, const char* file_path, 230 const uint8_t* data, size_t data_size, 231 rc_client_callback_t callback, void* callback_userdata); 232 #endif 233 234 /** 235 * Start loading a game. 236 */ 237 RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_load_game(rc_client_t* client, const char* hash, 238 rc_client_callback_t callback, void* callback_userdata); 239 240 /** 241 * Gets the current progress of the asynchronous load game process. 242 */ 243 RC_EXPORT int RC_CCONV rc_client_get_load_game_state(const rc_client_t* client); 244 enum { 245 RC_CLIENT_LOAD_GAME_STATE_NONE, 246 RC_CLIENT_LOAD_GAME_STATE_IDENTIFYING_GAME, 247 RC_CLIENT_LOAD_GAME_STATE_AWAIT_LOGIN, 248 RC_CLIENT_LOAD_GAME_STATE_FETCHING_GAME_DATA, 249 RC_CLIENT_LOAD_GAME_STATE_STARTING_SESSION, 250 RC_CLIENT_LOAD_GAME_STATE_DONE, 251 RC_CLIENT_LOAD_GAME_STATE_ABORTED 252 }; 253 254 /** 255 * Determines if a game was successfully identified and loaded. 256 */ 257 RC_EXPORT int RC_CCONV rc_client_is_game_loaded(const rc_client_t* client); 258 259 /** 260 * Unloads the current game. 261 */ 262 RC_EXPORT void RC_CCONV rc_client_unload_game(rc_client_t* client); 263 264 typedef struct rc_client_game_t { 265 uint32_t id; 266 uint32_t console_id; 267 const char* title; 268 const char* hash; 269 const char* badge_name; 270 } rc_client_game_t; 271 272 /** 273 * Get information about the current game. Returns NULL if no game is loaded. 274 * NOTE: returns a dummy game record if an unidentified game is loaded. 275 */ 276 RC_EXPORT const rc_client_game_t* RC_CCONV rc_client_get_game_info(const rc_client_t* client); 277 278 /** 279 * Gets the URL for the game image. 280 * Returns RC_OK on success. 281 */ 282 RC_EXPORT int RC_CCONV rc_client_game_get_image_url(const rc_client_game_t* game, char buffer[], size_t buffer_size); 283 284 #ifdef RC_CLIENT_SUPPORTS_HASH 285 /** 286 * Changes the active disc in a multi-disc game. 287 */ 288 RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_change_media(rc_client_t* client, const char* file_path, 289 const uint8_t* data, size_t data_size, rc_client_callback_t callback, void* callback_userdata); 290 #endif 291 292 /** 293 * Changes the active disc in a multi-disc game. 294 */ 295 RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_change_media_from_hash(rc_client_t* client, const char* hash, 296 rc_client_callback_t callback, void* callback_userdata); 297 298 /*****************************************************************************\ 299 | Subsets | 300 \*****************************************************************************/ 301 302 typedef struct rc_client_subset_t { 303 uint32_t id; 304 const char* title; 305 char badge_name[16]; 306 307 uint32_t num_achievements; 308 uint32_t num_leaderboards; 309 } rc_client_subset_t; 310 311 RC_EXPORT const rc_client_subset_t* RC_CCONV rc_client_get_subset_info(rc_client_t* client, uint32_t subset_id); 312 313 /*****************************************************************************\ 314 | Achievements | 315 \*****************************************************************************/ 316 317 enum { 318 RC_CLIENT_ACHIEVEMENT_STATE_INACTIVE = 0, /* unprocessed */ 319 RC_CLIENT_ACHIEVEMENT_STATE_ACTIVE = 1, /* eligible to trigger */ 320 RC_CLIENT_ACHIEVEMENT_STATE_UNLOCKED = 2, /* earned by user */ 321 RC_CLIENT_ACHIEVEMENT_STATE_DISABLED = 3, /* not supported by this version of the runtime */ 322 NUM_RC_CLIENT_ACHIEVEMENT_STATES = 4 323 }; 324 325 enum { 326 RC_CLIENT_ACHIEVEMENT_CATEGORY_NONE = 0, 327 RC_CLIENT_ACHIEVEMENT_CATEGORY_CORE = (1 << 0), 328 RC_CLIENT_ACHIEVEMENT_CATEGORY_UNOFFICIAL = (1 << 1), 329 RC_CLIENT_ACHIEVEMENT_CATEGORY_CORE_AND_UNOFFICIAL = RC_CLIENT_ACHIEVEMENT_CATEGORY_CORE | RC_CLIENT_ACHIEVEMENT_CATEGORY_UNOFFICIAL 330 }; 331 332 enum { 333 RC_CLIENT_ACHIEVEMENT_TYPE_STANDARD = 0, 334 RC_CLIENT_ACHIEVEMENT_TYPE_MISSABLE = 1, 335 RC_CLIENT_ACHIEVEMENT_TYPE_PROGRESSION = 2, 336 RC_CLIENT_ACHIEVEMENT_TYPE_WIN = 3 337 }; 338 339 enum { 340 RC_CLIENT_ACHIEVEMENT_BUCKET_UNKNOWN = 0, 341 RC_CLIENT_ACHIEVEMENT_BUCKET_LOCKED = 1, 342 RC_CLIENT_ACHIEVEMENT_BUCKET_UNLOCKED = 2, 343 RC_CLIENT_ACHIEVEMENT_BUCKET_UNSUPPORTED = 3, 344 RC_CLIENT_ACHIEVEMENT_BUCKET_UNOFFICIAL = 4, 345 RC_CLIENT_ACHIEVEMENT_BUCKET_RECENTLY_UNLOCKED = 5, 346 RC_CLIENT_ACHIEVEMENT_BUCKET_ACTIVE_CHALLENGE = 6, 347 RC_CLIENT_ACHIEVEMENT_BUCKET_ALMOST_THERE = 7, 348 RC_CLIENT_ACHIEVEMENT_BUCKET_UNSYNCED = 8, 349 NUM_RC_CLIENT_ACHIEVEMENT_BUCKETS = 9 350 }; 351 352 enum { 353 RC_CLIENT_ACHIEVEMENT_UNLOCKED_NONE = 0, 354 RC_CLIENT_ACHIEVEMENT_UNLOCKED_SOFTCORE = (1 << 0), 355 RC_CLIENT_ACHIEVEMENT_UNLOCKED_HARDCORE = (1 << 1), 356 RC_CLIENT_ACHIEVEMENT_UNLOCKED_BOTH = RC_CLIENT_ACHIEVEMENT_UNLOCKED_SOFTCORE | RC_CLIENT_ACHIEVEMENT_UNLOCKED_HARDCORE 357 }; 358 359 typedef struct rc_client_achievement_t { 360 const char* title; 361 const char* description; 362 char badge_name[8]; 363 char measured_progress[24]; 364 float measured_percent; 365 uint32_t id; 366 uint32_t points; 367 time_t unlock_time; 368 uint8_t state; 369 uint8_t category; 370 uint8_t bucket; 371 uint8_t unlocked; 372 /* minimum version: 11.1 */ 373 float rarity; 374 float rarity_hardcore; 375 uint8_t type; 376 } rc_client_achievement_t; 377 378 /** 379 * Get information about an achievement. Returns NULL if not found. 380 */ 381 RC_EXPORT const rc_client_achievement_t* RC_CCONV rc_client_get_achievement_info(rc_client_t* client, uint32_t id); 382 383 /** 384 * Gets the URL for the achievement image. 385 * Returns RC_OK on success. 386 */ 387 RC_EXPORT int RC_CCONV rc_client_achievement_get_image_url(const rc_client_achievement_t* achievement, int state, char buffer[], size_t buffer_size); 388 389 typedef struct rc_client_achievement_bucket_t { 390 rc_client_achievement_t** achievements; 391 uint32_t num_achievements; 392 393 const char* label; 394 uint32_t subset_id; 395 uint8_t bucket_type; 396 } rc_client_achievement_bucket_t; 397 398 typedef struct rc_client_achievement_list_t { 399 rc_client_achievement_bucket_t* buckets; 400 uint32_t num_buckets; 401 } rc_client_achievement_list_t; 402 403 enum { 404 RC_CLIENT_ACHIEVEMENT_LIST_GROUPING_LOCK_STATE = 0, 405 RC_CLIENT_ACHIEVEMENT_LIST_GROUPING_PROGRESS = 1 406 }; 407 408 /** 409 * Creates a list of achievements matching the specified category and grouping. 410 * Returns an allocated list that must be free'd by calling rc_client_destroy_achievement_list. 411 */ 412 RC_EXPORT rc_client_achievement_list_t* RC_CCONV rc_client_create_achievement_list(rc_client_t* client, int category, int grouping); 413 414 /** 415 * Destroys a list allocated by rc_client_get_achievement_list. 416 */ 417 RC_EXPORT void RC_CCONV rc_client_destroy_achievement_list(rc_client_achievement_list_t* list); 418 419 /** 420 * Returns non-zero if there are any achievements that can be queried through rc_client_create_achievement_list(). 421 */ 422 RC_EXPORT int RC_CCONV rc_client_has_achievements(rc_client_t* client); 423 424 /*****************************************************************************\ 425 | Leaderboards | 426 \*****************************************************************************/ 427 428 enum { 429 RC_CLIENT_LEADERBOARD_STATE_INACTIVE = 0, 430 RC_CLIENT_LEADERBOARD_STATE_ACTIVE = 1, 431 RC_CLIENT_LEADERBOARD_STATE_TRACKING = 2, 432 RC_CLIENT_LEADERBOARD_STATE_DISABLED = 3, 433 NUM_RC_CLIENT_LEADERBOARD_STATES = 4 434 }; 435 436 enum { 437 RC_CLIENT_LEADERBOARD_FORMAT_TIME = 0, 438 RC_CLIENT_LEADERBOARD_FORMAT_SCORE = 1, 439 RC_CLIENT_LEADERBOARD_FORMAT_VALUE = 2, 440 NUM_RC_CLIENT_LEADERBOARD_FORMATS = 3 441 }; 442 443 #define RC_CLIENT_LEADERBOARD_DISPLAY_SIZE 24 444 445 typedef struct rc_client_leaderboard_t { 446 const char* title; 447 const char* description; 448 const char* tracker_value; 449 uint32_t id; 450 uint8_t state; 451 uint8_t format; 452 uint8_t lower_is_better; 453 } rc_client_leaderboard_t; 454 455 /** 456 * Get information about a leaderboard. Returns NULL if not found. 457 */ 458 RC_EXPORT const rc_client_leaderboard_t* RC_CCONV rc_client_get_leaderboard_info(const rc_client_t* client, uint32_t id); 459 460 typedef struct rc_client_leaderboard_tracker_t { 461 char display[RC_CLIENT_LEADERBOARD_DISPLAY_SIZE]; 462 uint32_t id; 463 } rc_client_leaderboard_tracker_t; 464 465 typedef struct rc_client_leaderboard_bucket_t { 466 rc_client_leaderboard_t** leaderboards; 467 uint32_t num_leaderboards; 468 469 const char* label; 470 uint32_t subset_id; 471 uint8_t bucket_type; 472 } rc_client_leaderboard_bucket_t; 473 474 typedef struct rc_client_leaderboard_list_t { 475 rc_client_leaderboard_bucket_t* buckets; 476 uint32_t num_buckets; 477 } rc_client_leaderboard_list_t; 478 479 enum { 480 RC_CLIENT_LEADERBOARD_BUCKET_UNKNOWN = 0, 481 RC_CLIENT_LEADERBOARD_BUCKET_INACTIVE = 1, 482 RC_CLIENT_LEADERBOARD_BUCKET_ACTIVE = 2, 483 RC_CLIENT_LEADERBOARD_BUCKET_UNSUPPORTED = 3, 484 RC_CLIENT_LEADERBOARD_BUCKET_ALL = 4, 485 NUM_RC_CLIENT_LEADERBOARD_BUCKETS = 5 486 }; 487 488 enum { 489 RC_CLIENT_LEADERBOARD_LIST_GROUPING_NONE = 0, 490 RC_CLIENT_LEADERBOARD_LIST_GROUPING_TRACKING = 1 491 }; 492 493 /** 494 * Creates a list of leaderboards matching the specified grouping. 495 * Returns an allocated list that must be free'd by calling rc_client_destroy_leaderboard_list. 496 */ 497 RC_EXPORT rc_client_leaderboard_list_t* RC_CCONV rc_client_create_leaderboard_list(rc_client_t* client, int grouping); 498 499 /** 500 * Destroys a list allocated by rc_client_get_leaderboard_list. 501 */ 502 RC_EXPORT void RC_CCONV rc_client_destroy_leaderboard_list(rc_client_leaderboard_list_t* list); 503 504 /** 505 * Returns non-zero if the current game has any leaderboards. 506 */ 507 RC_EXPORT int RC_CCONV rc_client_has_leaderboards(rc_client_t* client); 508 509 typedef struct rc_client_leaderboard_entry_t { 510 const char* user; 511 char display[RC_CLIENT_LEADERBOARD_DISPLAY_SIZE]; 512 time_t submitted; 513 uint32_t rank; 514 uint32_t index; 515 } rc_client_leaderboard_entry_t; 516 517 typedef struct rc_client_leaderboard_entry_list_t { 518 rc_client_leaderboard_entry_t* entries; 519 uint32_t num_entries; 520 uint32_t total_entries; 521 int32_t user_index; 522 } rc_client_leaderboard_entry_list_t; 523 524 typedef void (RC_CCONV *rc_client_fetch_leaderboard_entries_callback_t)(int result, const char* error_message, 525 rc_client_leaderboard_entry_list_t* list, rc_client_t* client, void* callback_userdata); 526 527 /** 528 * Fetches a list of leaderboard entries from the server. 529 * Callback receives an allocated list that must be free'd by calling rc_client_destroy_leaderboard_entry_list. 530 */ 531 RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_fetch_leaderboard_entries(rc_client_t* client, uint32_t leaderboard_id, 532 uint32_t first_entry, uint32_t count, rc_client_fetch_leaderboard_entries_callback_t callback, void* callback_userdata); 533 534 /** 535 * Fetches a list of leaderboard entries from the server containing the logged-in user. 536 * Callback receives an allocated list that must be free'd by calling rc_client_destroy_leaderboard_entry_list. 537 */ 538 RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_fetch_leaderboard_entries_around_user(rc_client_t* client, uint32_t leaderboard_id, 539 uint32_t count, rc_client_fetch_leaderboard_entries_callback_t callback, void* callback_userdata); 540 541 /** 542 * Gets the URL for the profile picture of the user associated to a leaderboard entry. 543 * Returns RC_OK on success. 544 */ 545 RC_EXPORT int RC_CCONV rc_client_leaderboard_entry_get_user_image_url(const rc_client_leaderboard_entry_t* entry, char buffer[], size_t buffer_size); 546 547 /** 548 * Destroys a list allocated by rc_client_begin_fetch_leaderboard_entries or rc_client_begin_fetch_leaderboard_entries_around_user. 549 */ 550 RC_EXPORT void RC_CCONV rc_client_destroy_leaderboard_entry_list(rc_client_leaderboard_entry_list_t* list); 551 552 /** 553 * Used for scoreboard events. Contains the response from the server when a leaderboard entry is submitted. 554 * NOTE: This structure is only valid within the event callback. If you want to make use of the data outside 555 * of the callback, you should create copies of both the top entries and usernames within. 556 */ 557 typedef struct rc_client_leaderboard_scoreboard_entry_t { 558 /* The user associated to the entry */ 559 const char* username; 560 /* The rank of the entry */ 561 uint32_t rank; 562 /* The value of the entry */ 563 char score[RC_CLIENT_LEADERBOARD_DISPLAY_SIZE]; 564 } rc_client_leaderboard_scoreboard_entry_t; 565 566 typedef struct rc_client_leaderboard_scoreboard_t { 567 /* The ID of the leaderboard which was submitted */ 568 uint32_t leaderboard_id; 569 /* The value that was submitted */ 570 char submitted_score[RC_CLIENT_LEADERBOARD_DISPLAY_SIZE]; 571 /* The player's best submitted value */ 572 char best_score[RC_CLIENT_LEADERBOARD_DISPLAY_SIZE]; 573 /* The player's new rank within the leaderboard */ 574 uint32_t new_rank; 575 /* The total number of entries in the leaderboard */ 576 uint32_t num_entries; 577 578 /* An array of the top entries for the leaderboard */ 579 rc_client_leaderboard_scoreboard_entry_t* top_entries; 580 /* The number of items in the top_entries array */ 581 uint32_t num_top_entries; 582 } rc_client_leaderboard_scoreboard_t; 583 584 /*****************************************************************************\ 585 | Rich Presence | 586 \*****************************************************************************/ 587 588 /** 589 * Returns non-zero if the current game supports rich presence. 590 */ 591 RC_EXPORT int RC_CCONV rc_client_has_rich_presence(rc_client_t* client); 592 593 /** 594 * Gets the current rich presence message. 595 * Returns the number of characters written to buffer. 596 */ 597 RC_EXPORT size_t RC_CCONV rc_client_get_rich_presence_message(rc_client_t* client, char buffer[], size_t buffer_size); 598 599 /** 600 * Returns a list of all possible rich presence strings. 601 * The list is terminated by NULL. 602 */ 603 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); 604 605 /*****************************************************************************\ 606 | Processing | 607 \*****************************************************************************/ 608 609 enum { 610 RC_CLIENT_EVENT_TYPE_NONE = 0, 611 RC_CLIENT_EVENT_ACHIEVEMENT_TRIGGERED = 1, /* [achievement] was earned by the player */ 612 RC_CLIENT_EVENT_LEADERBOARD_STARTED = 2, /* [leaderboard] attempt has started */ 613 RC_CLIENT_EVENT_LEADERBOARD_FAILED = 3, /* [leaderboard] attempt failed */ 614 RC_CLIENT_EVENT_LEADERBOARD_SUBMITTED = 4, /* [leaderboard] attempt submitted */ 615 RC_CLIENT_EVENT_ACHIEVEMENT_CHALLENGE_INDICATOR_SHOW = 5, /* [achievement] challenge indicator should be shown */ 616 RC_CLIENT_EVENT_ACHIEVEMENT_CHALLENGE_INDICATOR_HIDE = 6, /* [achievement] challenge indicator should be hidden */ 617 RC_CLIENT_EVENT_ACHIEVEMENT_PROGRESS_INDICATOR_SHOW = 7, /* progress indicator should be shown for [achievement] */ 618 RC_CLIENT_EVENT_ACHIEVEMENT_PROGRESS_INDICATOR_HIDE = 8, /* progress indicator should be hidden */ 619 RC_CLIENT_EVENT_ACHIEVEMENT_PROGRESS_INDICATOR_UPDATE = 9, /* progress indicator should be updated to reflect new badge/progress for [achievement] */ 620 RC_CLIENT_EVENT_LEADERBOARD_TRACKER_SHOW = 10, /* [leaderboard_tracker] should be shown */ 621 RC_CLIENT_EVENT_LEADERBOARD_TRACKER_HIDE = 11, /* [leaderboard_tracker] should be hidden */ 622 RC_CLIENT_EVENT_LEADERBOARD_TRACKER_UPDATE = 12, /* [leaderboard_tracker] updated */ 623 RC_CLIENT_EVENT_LEADERBOARD_SCOREBOARD = 13, /* [leaderboard_scoreboard] possibly-new ranking received for [leaderboard] */ 624 RC_CLIENT_EVENT_RESET = 14, /* emulated system should be reset (as the result of enabling hardcore) */ 625 RC_CLIENT_EVENT_GAME_COMPLETED = 15, /* all achievements for the game have been earned */ 626 RC_CLIENT_EVENT_SERVER_ERROR = 16, /* an API response returned a [server_error] and will not be retried */ 627 RC_CLIENT_EVENT_DISCONNECTED = 17, /* an unlock request could not be completed and is pending */ 628 RC_CLIENT_EVENT_RECONNECTED = 18 /* all pending unlocks have been completed */ 629 }; 630 631 typedef struct rc_client_server_error_t { 632 const char* error_message; 633 const char* api; 634 int result; 635 uint32_t related_id; 636 } rc_client_server_error_t; 637 638 typedef struct rc_client_event_t { 639 uint32_t type; 640 641 rc_client_achievement_t* achievement; 642 rc_client_leaderboard_t* leaderboard; 643 rc_client_leaderboard_tracker_t* leaderboard_tracker; 644 rc_client_leaderboard_scoreboard_t* leaderboard_scoreboard; 645 rc_client_server_error_t* server_error; 646 647 } rc_client_event_t; 648 649 /** 650 * Callback used to notify the client when certain events occur. 651 */ 652 typedef void (RC_CCONV *rc_client_event_handler_t)(const rc_client_event_t* event, rc_client_t* client); 653 654 /** 655 * Provides a callback for event handling. 656 */ 657 RC_EXPORT void RC_CCONV rc_client_set_event_handler(rc_client_t* client, rc_client_event_handler_t handler); 658 659 /** 660 * Provides a callback for reading memory. 661 */ 662 RC_EXPORT void RC_CCONV rc_client_set_read_memory_function(rc_client_t* client, rc_client_read_memory_func_t handler); 663 664 /** 665 * Determines if there are any active achievements/leaderboards/rich presence that need processing. 666 */ 667 RC_EXPORT int RC_CCONV rc_client_is_processing_required(rc_client_t* client); 668 669 /** 670 * Processes achievements for the current frame. 671 */ 672 RC_EXPORT void RC_CCONV rc_client_do_frame(rc_client_t* client); 673 674 /** 675 * Processes the periodic queue. 676 * Called internally by rc_client_do_frame. 677 * Should be explicitly called if rc_client_do_frame is not being called because emulation is paused. 678 */ 679 RC_EXPORT void RC_CCONV rc_client_idle(rc_client_t* client); 680 681 /** 682 * Determines if a sufficient amount of frames have been processed since the last call to rc_client_can_pause. 683 * Should not be called unless the client is trying to pause. 684 * If false is returned, and frames_remaining is not NULL, frames_remaining will be set to the number of frames 685 * still required before pause is allowed, which can be converted to a time in seconds for displaying to the user. 686 */ 687 RC_EXPORT int RC_CCONV rc_client_can_pause(rc_client_t* client, uint32_t* frames_remaining); 688 689 /** 690 * Informs the runtime that the emulator has been reset. Will reset all achievements and leaderboards 691 * to their initial state (includes hiding indicators/trackers). 692 */ 693 RC_EXPORT void RC_CCONV rc_client_reset(rc_client_t* client); 694 695 /** 696 * Gets the number of bytes needed to serialized the runtime state. 697 */ 698 RC_EXPORT size_t RC_CCONV rc_client_progress_size(rc_client_t* client); 699 700 /** 701 * Serializes the runtime state into a buffer. 702 * Returns RC_OK on success, or an error indicator. 703 * [deprecated] use rc_client_serialize_progress_sized instead 704 */ 705 RC_EXPORT int RC_CCONV rc_client_serialize_progress(rc_client_t* client, uint8_t* buffer); 706 707 /** 708 * Serializes the runtime state into a buffer. 709 * Returns RC_OK on success, or an error indicator. 710 */ 711 RC_EXPORT int RC_CCONV rc_client_serialize_progress_sized(rc_client_t* client, uint8_t* buffer, size_t buffer_size); 712 713 /** 714 * Deserializes the runtime state from a buffer. 715 * Returns RC_OK on success, or an error indicator. 716 * [deprecated] use rc_client_deserialize_progress_sized instead 717 */ 718 RC_EXPORT int RC_CCONV rc_client_deserialize_progress(rc_client_t* client, const uint8_t* serialized); 719 720 /** 721 * Serializes the runtime state into a buffer. 722 * Returns RC_OK on success, or an error indicator. 723 */ 724 RC_EXPORT int RC_CCONV rc_client_deserialize_progress_sized(rc_client_t* client, const uint8_t* serialized, size_t serialized_size); 725 726 RC_END_C_DECLS 727 728 #endif /* RC_RUNTIME_H */