Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/dep/rcheevos/include/rc_client.h
7531 views
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(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
* Returns true if any achievement submissions have failed and are currently pending.
146
*/
147
RC_EXPORT int RC_CCONV rc_client_is_disconnected(rc_client_t* client);
148
149
/*****************************************************************************\
150
| Logging |
151
\*****************************************************************************/
152
153
/**
154
* Sets the logging level and provides a callback to be called to do the logging.
155
*/
156
RC_EXPORT void RC_CCONV rc_client_enable_logging(rc_client_t* client, int level, rc_client_message_callback_t callback);
157
enum {
158
RC_CLIENT_LOG_LEVEL_NONE = 0,
159
RC_CLIENT_LOG_LEVEL_ERROR = 1,
160
RC_CLIENT_LOG_LEVEL_WARN = 2,
161
RC_CLIENT_LOG_LEVEL_INFO = 3,
162
RC_CLIENT_LOG_LEVEL_VERBOSE = 4,
163
NUM_RC_CLIENT_LOG_LEVELS = 5
164
};
165
166
/*****************************************************************************\
167
| User |
168
\*****************************************************************************/
169
170
/**
171
* Attempt to login a user.
172
*/
173
RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_login_with_password(rc_client_t* client,
174
const char* username, const char* password,
175
rc_client_callback_t callback, void* callback_userdata);
176
177
/**
178
* Attempt to login a user.
179
*/
180
RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_login_with_token(rc_client_t* client,
181
const char* username, const char* token,
182
rc_client_callback_t callback, void* callback_userdata);
183
184
/**
185
* Logout the user.
186
*/
187
RC_EXPORT void RC_CCONV rc_client_logout(rc_client_t* client);
188
189
typedef struct rc_client_user_t {
190
const char* display_name;
191
const char* username;
192
const char* token;
193
uint32_t score;
194
uint32_t score_softcore;
195
uint32_t num_unread_messages;
196
/* minimum version: 12.0 */
197
const char* avatar_url;
198
} rc_client_user_t;
199
200
/**
201
* Gets information about the logged in user. Will return NULL if the user is not logged in.
202
*/
203
RC_EXPORT const rc_client_user_t* RC_CCONV rc_client_get_user_info(const rc_client_t* client);
204
205
/**
206
* Gets the URL for the user's profile picture.
207
* Returns RC_OK on success.
208
*/
209
RC_EXPORT int RC_CCONV rc_client_user_get_image_url(const rc_client_user_t* user, char buffer[], size_t buffer_size);
210
211
typedef struct rc_client_user_game_summary_t {
212
uint32_t num_core_achievements;
213
uint32_t num_unofficial_achievements;
214
uint32_t num_unlocked_achievements;
215
uint32_t num_unsupported_achievements;
216
217
uint32_t points_core;
218
uint32_t points_unlocked;
219
220
/* minimum version: 12.1 */
221
time_t beaten_time;
222
time_t completed_time;
223
} rc_client_user_game_summary_t;
224
225
/**
226
* Gets a breakdown of the number of achievements in the game, and how many the user has unlocked.
227
* Used for the "You have unlocked X of Y achievements" message shown when the game starts.
228
*/
229
RC_EXPORT void RC_CCONV rc_client_get_user_game_summary(const rc_client_t* client, rc_client_user_game_summary_t* summary);
230
231
typedef struct rc_client_all_user_progress_entry_t {
232
uint32_t game_id;
233
uint32_t num_achievements;
234
uint32_t num_unlocked_achievements;
235
uint32_t num_unlocked_achievements_hardcore;
236
} rc_client_all_user_progress_entry_t;
237
238
typedef struct rc_client_all_user_progress_t {
239
rc_client_all_user_progress_entry_t* entries;
240
uint32_t num_entries;
241
} rc_client_all_user_progress_t;
242
243
/**
244
* Callback that is fired when an all progress query completes. list may be null if the query failed.
245
*/
246
typedef void(RC_CCONV* rc_client_fetch_all_user_progress_callback_t)(int result, const char* error_message,
247
rc_client_all_user_progress_t* list,
248
rc_client_t* client, void* callback_userdata);
249
250
/**
251
* Starts an asynchronous request for all progress for the given console.
252
* This query returns the total number of achievements for all games tracked by this console, as well as
253
* the user's achievement unlock count for both softcore and hardcore modes.
254
*/
255
RC_EXPORT rc_client_async_handle_t* RC_CCONV
256
rc_client_begin_fetch_all_user_progress(rc_client_t* client, uint32_t console_id,
257
rc_client_fetch_all_user_progress_callback_t callback, void* callback_userdata);
258
259
/**
260
* Destroys a previously-allocated result from the rc_client_begin_fetch_all_progress_list() callback.
261
*/
262
RC_EXPORT void RC_CCONV rc_client_destroy_all_user_progress(rc_client_all_user_progress_t* list);
263
264
/*****************************************************************************\
265
| Game |
266
\*****************************************************************************/
267
268
#ifdef RC_CLIENT_SUPPORTS_HASH
269
/**
270
* Start loading an unidentified game.
271
*/
272
RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_identify_and_load_game(rc_client_t* client,
273
uint32_t console_id, const char* file_path,
274
const uint8_t* data, size_t data_size,
275
rc_client_callback_t callback, void* callback_userdata);
276
277
struct rc_hash_callbacks;
278
/**
279
* Provide callback functions for interacting with the file system and processing disc-based files when generating hashes.
280
*/
281
RC_EXPORT void rc_client_set_hash_callbacks(rc_client_t* client, const struct rc_hash_callbacks* callbacks);
282
#endif
283
284
/**
285
* Start loading a game.
286
*/
287
RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_load_game(rc_client_t* client, const char* hash,
288
rc_client_callback_t callback, void* callback_userdata);
289
290
/**
291
* Gets the current progress of the asynchronous load game process.
292
*/
293
RC_EXPORT int RC_CCONV rc_client_get_load_game_state(const rc_client_t* client);
294
enum {
295
RC_CLIENT_LOAD_GAME_STATE_NONE,
296
RC_CLIENT_LOAD_GAME_STATE_AWAIT_LOGIN,
297
RC_CLIENT_LOAD_GAME_STATE_IDENTIFYING_GAME,
298
RC_CLIENT_LOAD_GAME_STATE_FETCHING_GAME_DATA, /* [deprecated] - game data is now returned by identify call */
299
RC_CLIENT_LOAD_GAME_STATE_STARTING_SESSION,
300
RC_CLIENT_LOAD_GAME_STATE_DONE,
301
RC_CLIENT_LOAD_GAME_STATE_ABORTED
302
};
303
304
/**
305
* Determines if a game was successfully identified and loaded.
306
*/
307
RC_EXPORT int RC_CCONV rc_client_is_game_loaded(const rc_client_t* client);
308
309
/**
310
* Unloads the current game.
311
*/
312
RC_EXPORT void RC_CCONV rc_client_unload_game(rc_client_t* client);
313
314
typedef struct rc_client_game_t {
315
uint32_t id;
316
uint32_t console_id;
317
const char* title;
318
const char* hash;
319
const char* badge_name;
320
/* minimum version: 12.0 */
321
const char* badge_url;
322
} rc_client_game_t;
323
324
/**
325
* Get information about the current game. Returns NULL if no game is loaded.
326
* NOTE: returns a dummy game record if an unidentified game is loaded.
327
*/
328
RC_EXPORT const rc_client_game_t* RC_CCONV rc_client_get_game_info(const rc_client_t* client);
329
330
/**
331
* Gets the URL for the game image.
332
* Returns RC_OK on success.
333
*/
334
RC_EXPORT int RC_CCONV rc_client_game_get_image_url(const rc_client_game_t* game, char buffer[], size_t buffer_size);
335
336
#ifdef RC_CLIENT_SUPPORTS_HASH
337
/**
338
* Changes the active disc in a multi-disc game.
339
*/
340
RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_identify_and_change_media(rc_client_t* client, const char* file_path,
341
const uint8_t* data, size_t data_size, rc_client_callback_t callback, void* callback_userdata);
342
#endif
343
344
/**
345
* Changes the active disc in a multi-disc game.
346
*/
347
RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_change_media(rc_client_t* client, const char* hash,
348
rc_client_callback_t callback, void* callback_userdata);
349
/* this function was renamed in rcheevos 12.0 */
350
#define rc_client_begin_change_media_from_hash rc_client_begin_change_media
351
352
/*****************************************************************************\
353
| Subsets |
354
\*****************************************************************************/
355
356
typedef struct rc_client_subset_t {
357
uint32_t id;
358
const char* title;
359
char badge_name[16];
360
361
uint32_t num_achievements;
362
uint32_t num_leaderboards;
363
364
/* minimum version: 12.0 */
365
const char* badge_url;
366
} rc_client_subset_t;
367
368
RC_EXPORT const rc_client_subset_t* RC_CCONV rc_client_get_subset_info(rc_client_t* client, uint32_t subset_id);
369
370
RC_EXPORT void RC_CCONV rc_client_get_user_subset_summary(const rc_client_t* client, uint32_t subset_id, rc_client_user_game_summary_t* summary);
371
372
typedef struct rc_client_subset_list_t {
373
const rc_client_subset_t** subsets;
374
uint32_t num_subsets;
375
} rc_client_subset_list_t;
376
377
/**
378
* Creates a list of subsets for the currently loaded game.
379
* Returns an allocated list that must be free'd by calling rc_client_destroy_subset_list.
380
*/
381
RC_EXPORT rc_client_subset_list_t* RC_CCONV rc_client_create_subset_list(rc_client_t* client);
382
383
/**
384
* Destroys a list allocated by rc_client_create_subset_list_list.
385
*/
386
RC_EXPORT void RC_CCONV rc_client_destroy_subset_list(rc_client_subset_list_t* list);
387
388
/*****************************************************************************\
389
| Fetch Game Hashes |
390
\*****************************************************************************/
391
392
typedef struct rc_client_hash_library_entry_t {
393
char hash[33];
394
uint32_t game_id;
395
} rc_client_hash_library_entry_t;
396
397
typedef struct rc_client_hash_library_t {
398
rc_client_hash_library_entry_t* entries;
399
uint32_t num_entries;
400
} rc_client_hash_library_t;
401
402
/**
403
* Callback that is fired when a hash library request completes. list may be null if the query failed.
404
*/
405
typedef void(RC_CCONV* rc_client_fetch_hash_library_callback_t)(int result, const char* error_message,
406
rc_client_hash_library_t* list, rc_client_t* client,
407
void* callback_userdata);
408
409
/**
410
* Starts an asynchronous request for all hashes for the given console.
411
* This request returns a mapping from hashes to the game's unique identifier. A single game may have multiple
412
* hashes in the case of multi-disc games, or variants that are still compatible with the same achievement set.
413
*/
414
RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_fetch_hash_library(
415
rc_client_t* client, uint32_t console_id, rc_client_fetch_hash_library_callback_t callback, void* callback_userdata);
416
417
/**
418
* Destroys a previously-allocated result from the rc_client_destroy_hash_library() callback.
419
*/
420
RC_EXPORT void RC_CCONV rc_client_destroy_hash_library(rc_client_hash_library_t* list);
421
422
/*****************************************************************************\
423
| Fetch Game Titles |
424
\*****************************************************************************/
425
426
typedef struct rc_client_game_title_entry_t {
427
uint32_t game_id;
428
const char* title;
429
char badge_name[16];
430
const char* badge_url;
431
} rc_client_game_title_entry_t;
432
433
typedef struct rc_client_game_title_list_t {
434
rc_client_game_title_entry_t* entries;
435
uint32_t num_entries;
436
} rc_client_game_title_list_t;
437
438
/**
439
* Callback that is fired when a game titles request completes. list may be null if the query failed.
440
*/
441
typedef void(RC_CCONV* rc_client_fetch_game_titles_callback_t)(int result, const char* error_message,
442
rc_client_game_title_list_t* list, rc_client_t* client,
443
void* callback_userdata);
444
445
/**
446
* Starts an asynchronous request for titles and badge names for the specified games.
447
* The caller must provide an array of game IDs and the number of IDs in the array.
448
*/
449
RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_fetch_game_titles(
450
rc_client_t* client, const uint32_t* game_ids, uint32_t num_game_ids,
451
rc_client_fetch_game_titles_callback_t callback, void* callback_userdata);
452
453
/**
454
* Destroys a previously-allocated result from the rc_client_begin_fetch_game_titles() callback.
455
*/
456
RC_EXPORT void RC_CCONV rc_client_destroy_game_title_list(rc_client_game_title_list_t* list);
457
458
/*****************************************************************************\
459
| Achievements |
460
\*****************************************************************************/
461
462
enum {
463
RC_CLIENT_ACHIEVEMENT_STATE_INACTIVE = 0, /* unprocessed */
464
RC_CLIENT_ACHIEVEMENT_STATE_ACTIVE = 1, /* eligible to trigger */
465
RC_CLIENT_ACHIEVEMENT_STATE_UNLOCKED = 2, /* earned by user */
466
RC_CLIENT_ACHIEVEMENT_STATE_DISABLED = 3, /* not supported by this version of the runtime */
467
NUM_RC_CLIENT_ACHIEVEMENT_STATES = 4
468
};
469
470
enum {
471
RC_CLIENT_ACHIEVEMENT_CATEGORY_NONE = 0,
472
RC_CLIENT_ACHIEVEMENT_CATEGORY_CORE = (1 << 0),
473
RC_CLIENT_ACHIEVEMENT_CATEGORY_UNOFFICIAL = (1 << 1),
474
RC_CLIENT_ACHIEVEMENT_CATEGORY_CORE_AND_UNOFFICIAL = RC_CLIENT_ACHIEVEMENT_CATEGORY_CORE | RC_CLIENT_ACHIEVEMENT_CATEGORY_UNOFFICIAL
475
};
476
477
enum {
478
RC_CLIENT_ACHIEVEMENT_TYPE_STANDARD = 0,
479
RC_CLIENT_ACHIEVEMENT_TYPE_MISSABLE = 1,
480
RC_CLIENT_ACHIEVEMENT_TYPE_PROGRESSION = 2,
481
RC_CLIENT_ACHIEVEMENT_TYPE_WIN = 3
482
};
483
484
enum {
485
RC_CLIENT_ACHIEVEMENT_BUCKET_UNKNOWN = 0,
486
RC_CLIENT_ACHIEVEMENT_BUCKET_LOCKED = 1,
487
RC_CLIENT_ACHIEVEMENT_BUCKET_UNLOCKED = 2,
488
RC_CLIENT_ACHIEVEMENT_BUCKET_UNSUPPORTED = 3,
489
RC_CLIENT_ACHIEVEMENT_BUCKET_UNOFFICIAL = 4,
490
RC_CLIENT_ACHIEVEMENT_BUCKET_RECENTLY_UNLOCKED = 5,
491
RC_CLIENT_ACHIEVEMENT_BUCKET_ACTIVE_CHALLENGE = 6,
492
RC_CLIENT_ACHIEVEMENT_BUCKET_ALMOST_THERE = 7,
493
RC_CLIENT_ACHIEVEMENT_BUCKET_UNSYNCED = 8,
494
NUM_RC_CLIENT_ACHIEVEMENT_BUCKETS = 9
495
};
496
497
enum {
498
RC_CLIENT_ACHIEVEMENT_UNLOCKED_NONE = 0,
499
RC_CLIENT_ACHIEVEMENT_UNLOCKED_SOFTCORE = (1 << 0),
500
RC_CLIENT_ACHIEVEMENT_UNLOCKED_HARDCORE = (1 << 1),
501
RC_CLIENT_ACHIEVEMENT_UNLOCKED_BOTH = RC_CLIENT_ACHIEVEMENT_UNLOCKED_SOFTCORE | RC_CLIENT_ACHIEVEMENT_UNLOCKED_HARDCORE
502
};
503
504
typedef struct rc_client_achievement_t {
505
const char* title;
506
const char* description;
507
char badge_name[8];
508
char measured_progress[24];
509
float measured_percent;
510
uint32_t id;
511
uint32_t points;
512
time_t unlock_time;
513
uint8_t state;
514
uint8_t category;
515
uint8_t bucket;
516
uint8_t unlocked;
517
/* minimum version: 11.1 */
518
float rarity;
519
float rarity_hardcore;
520
uint8_t type;
521
/* minimum version: 12.0 */
522
const char* badge_url;
523
const char* badge_locked_url;
524
} rc_client_achievement_t;
525
526
/**
527
* Get information about an achievement. Returns NULL if not found.
528
*/
529
RC_EXPORT const rc_client_achievement_t* RC_CCONV rc_client_get_achievement_info(rc_client_t* client, uint32_t id);
530
531
/**
532
* Gets the next achievement after a provided achievement that fits in the specified bucket. Returns NULL if none found.
533
*/
534
RC_EXPORT const rc_client_achievement_t * RC_CCONV rc_client_get_next_achievement_info(rc_client_t * client, const rc_client_achievement_t * achievement, int bucket);
535
536
/**
537
* Gets the URL for the achievement image.
538
* Returns RC_OK on success.
539
*/
540
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);
541
542
typedef struct rc_client_achievement_bucket_t {
543
const rc_client_achievement_t** achievements;
544
uint32_t num_achievements;
545
546
const char* label;
547
uint32_t subset_id;
548
uint8_t bucket_type;
549
} rc_client_achievement_bucket_t;
550
551
typedef struct rc_client_achievement_list_t {
552
const rc_client_achievement_bucket_t* buckets;
553
uint32_t num_buckets;
554
} rc_client_achievement_list_t;
555
556
enum {
557
RC_CLIENT_ACHIEVEMENT_LIST_GROUPING_LOCK_STATE = 0,
558
RC_CLIENT_ACHIEVEMENT_LIST_GROUPING_PROGRESS = 1,
559
RC_CLIENT_ACHIEVEMENT_LIST_GROUPING_SUBSET_BUCKETS = 2, /* Same as progress, but does not share any subset buckets */
560
};
561
562
/**
563
* Creates a list of achievements matching the specified category and grouping.
564
* Returns an allocated list that must be free'd by calling rc_client_destroy_achievement_list.
565
*/
566
RC_EXPORT rc_client_achievement_list_t* RC_CCONV rc_client_create_achievement_list(rc_client_t* client, int category, int grouping);
567
568
/**
569
* Destroys a list allocated by rc_client_create_achievement_list.
570
*/
571
RC_EXPORT void RC_CCONV rc_client_destroy_achievement_list(rc_client_achievement_list_t* list);
572
573
/**
574
* Returns non-zero if there are any achievements that can be queried through rc_client_create_achievement_list().
575
*/
576
RC_EXPORT int RC_CCONV rc_client_has_achievements(rc_client_t* client);
577
578
/**
579
* Returns the number of outstanding achievement unlocks.
580
*/
581
RC_EXPORT int RC_CCONV rc_client_get_award_achievement_pending_count(rc_client_t* client);
582
583
/*****************************************************************************\
584
| Leaderboards |
585
\*****************************************************************************/
586
587
enum {
588
RC_CLIENT_LEADERBOARD_STATE_INACTIVE = 0,
589
RC_CLIENT_LEADERBOARD_STATE_ACTIVE = 1,
590
RC_CLIENT_LEADERBOARD_STATE_TRACKING = 2,
591
RC_CLIENT_LEADERBOARD_STATE_DISABLED = 3,
592
NUM_RC_CLIENT_LEADERBOARD_STATES = 4
593
};
594
595
enum {
596
RC_CLIENT_LEADERBOARD_FORMAT_TIME = 0,
597
RC_CLIENT_LEADERBOARD_FORMAT_SCORE = 1,
598
RC_CLIENT_LEADERBOARD_FORMAT_VALUE = 2,
599
NUM_RC_CLIENT_LEADERBOARD_FORMATS = 3
600
};
601
602
#define RC_CLIENT_LEADERBOARD_DISPLAY_SIZE 24
603
604
typedef struct rc_client_leaderboard_t {
605
const char* title;
606
const char* description;
607
const char* tracker_value;
608
uint32_t id;
609
uint8_t state;
610
uint8_t format;
611
uint8_t lower_is_better;
612
} rc_client_leaderboard_t;
613
614
/**
615
* Get information about a leaderboard. Returns NULL if not found.
616
*/
617
RC_EXPORT const rc_client_leaderboard_t* RC_CCONV rc_client_get_leaderboard_info(const rc_client_t* client, uint32_t id);
618
619
typedef struct rc_client_leaderboard_tracker_t {
620
char display[RC_CLIENT_LEADERBOARD_DISPLAY_SIZE];
621
uint32_t id;
622
} rc_client_leaderboard_tracker_t;
623
624
typedef struct rc_client_leaderboard_bucket_t {
625
const rc_client_leaderboard_t** leaderboards;
626
uint32_t num_leaderboards;
627
628
const char* label;
629
uint32_t subset_id;
630
uint8_t bucket_type;
631
} rc_client_leaderboard_bucket_t;
632
633
typedef struct rc_client_leaderboard_list_t {
634
const rc_client_leaderboard_bucket_t* buckets;
635
uint32_t num_buckets;
636
} rc_client_leaderboard_list_t;
637
638
enum {
639
RC_CLIENT_LEADERBOARD_BUCKET_UNKNOWN = 0,
640
RC_CLIENT_LEADERBOARD_BUCKET_INACTIVE = 1,
641
RC_CLIENT_LEADERBOARD_BUCKET_ACTIVE = 2,
642
RC_CLIENT_LEADERBOARD_BUCKET_UNSUPPORTED = 3,
643
RC_CLIENT_LEADERBOARD_BUCKET_ALL = 4,
644
NUM_RC_CLIENT_LEADERBOARD_BUCKETS = 5
645
};
646
647
enum {
648
RC_CLIENT_LEADERBOARD_LIST_GROUPING_NONE = 0,
649
RC_CLIENT_LEADERBOARD_LIST_GROUPING_TRACKING = 1
650
};
651
652
/**
653
* Creates a list of leaderboards matching the specified grouping.
654
* Returns an allocated list that must be free'd by calling rc_client_destroy_leaderboard_list.
655
*/
656
RC_EXPORT rc_client_leaderboard_list_t* RC_CCONV rc_client_create_leaderboard_list(rc_client_t* client, int grouping);
657
658
/**
659
* Destroys a list allocated by rc_client_create_leaderboard_list.
660
*/
661
RC_EXPORT void RC_CCONV rc_client_destroy_leaderboard_list(rc_client_leaderboard_list_t* list);
662
663
/**
664
* Returns non-zero if the current game has any leaderboards.
665
*/
666
RC_EXPORT int RC_CCONV rc_client_has_leaderboards(rc_client_t* client);
667
668
typedef struct rc_client_leaderboard_entry_t {
669
const char* user;
670
char display[RC_CLIENT_LEADERBOARD_DISPLAY_SIZE];
671
time_t submitted;
672
uint32_t rank;
673
uint32_t index;
674
} rc_client_leaderboard_entry_t;
675
676
typedef struct rc_client_leaderboard_entry_list_t {
677
rc_client_leaderboard_entry_t* entries;
678
uint32_t num_entries;
679
uint32_t total_entries;
680
int32_t user_index;
681
} rc_client_leaderboard_entry_list_t;
682
683
typedef void (RC_CCONV *rc_client_fetch_leaderboard_entries_callback_t)(int result, const char* error_message,
684
rc_client_leaderboard_entry_list_t* list, rc_client_t* client, void* callback_userdata);
685
686
/**
687
* Fetches a list of leaderboard entries from the server.
688
* Callback receives an allocated list that must be free'd by calling rc_client_destroy_leaderboard_entry_list.
689
*/
690
RC_EXPORT rc_client_async_handle_t* RC_CCONV rc_client_begin_fetch_leaderboard_entries(rc_client_t* client, uint32_t leaderboard_id,
691
uint32_t first_entry, uint32_t count, rc_client_fetch_leaderboard_entries_callback_t callback, void* callback_userdata);
692
693
/**
694
* Fetches a list of leaderboard entries from the server containing the logged-in user.
695
* Callback receives an allocated list that must be free'd by calling rc_client_destroy_leaderboard_entry_list.
696
*/
697
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,
698
uint32_t count, rc_client_fetch_leaderboard_entries_callback_t callback, void* callback_userdata);
699
700
/**
701
* Gets the URL for the profile picture of the user associated to a leaderboard entry.
702
* Returns RC_OK on success.
703
*/
704
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);
705
706
/**
707
* Destroys a list allocated by rc_client_begin_fetch_leaderboard_entries or rc_client_begin_fetch_leaderboard_entries_around_user.
708
*/
709
RC_EXPORT void RC_CCONV rc_client_destroy_leaderboard_entry_list(rc_client_leaderboard_entry_list_t* list);
710
711
/**
712
* Used for scoreboard events. Contains the response from the server when a leaderboard entry is submitted.
713
* NOTE: This structure is only valid within the event callback. If you want to make use of the data outside
714
* of the callback, you should create copies of both the top entries and usernames within.
715
*/
716
typedef struct rc_client_leaderboard_scoreboard_entry_t {
717
/* The user associated to the entry */
718
const char* username;
719
/* The rank of the entry */
720
uint32_t rank;
721
/* The value of the entry */
722
char score[RC_CLIENT_LEADERBOARD_DISPLAY_SIZE];
723
} rc_client_leaderboard_scoreboard_entry_t;
724
725
typedef struct rc_client_leaderboard_scoreboard_t {
726
/* The ID of the leaderboard which was submitted */
727
uint32_t leaderboard_id;
728
/* The value that was submitted */
729
char submitted_score[RC_CLIENT_LEADERBOARD_DISPLAY_SIZE];
730
/* The player's best submitted value */
731
char best_score[RC_CLIENT_LEADERBOARD_DISPLAY_SIZE];
732
/* The player's new rank within the leaderboard */
733
uint32_t new_rank;
734
/* The total number of entries in the leaderboard */
735
uint32_t num_entries;
736
737
/* An array of the top entries for the leaderboard */
738
rc_client_leaderboard_scoreboard_entry_t* top_entries;
739
/* The number of items in the top_entries array */
740
uint32_t num_top_entries;
741
} rc_client_leaderboard_scoreboard_t;
742
743
/*****************************************************************************\
744
| Rich Presence |
745
\*****************************************************************************/
746
747
/**
748
* Returns non-zero if the current game supports rich presence.
749
*/
750
RC_EXPORT int RC_CCONV rc_client_has_rich_presence(rc_client_t* client);
751
752
/**
753
* Gets the current rich presence message.
754
* Returns the number of characters written to buffer.
755
*/
756
RC_EXPORT size_t RC_CCONV rc_client_get_rich_presence_message(rc_client_t* client, char buffer[], size_t buffer_size);
757
758
/*****************************************************************************\
759
| Processing |
760
\*****************************************************************************/
761
762
enum {
763
RC_CLIENT_EVENT_TYPE_NONE = 0,
764
RC_CLIENT_EVENT_ACHIEVEMENT_TRIGGERED = 1, /* [achievement] was earned by the player */
765
RC_CLIENT_EVENT_LEADERBOARD_STARTED = 2, /* [leaderboard] attempt has started */
766
RC_CLIENT_EVENT_LEADERBOARD_FAILED = 3, /* [leaderboard] attempt failed */
767
RC_CLIENT_EVENT_LEADERBOARD_SUBMITTED = 4, /* [leaderboard] attempt submitted */
768
RC_CLIENT_EVENT_ACHIEVEMENT_CHALLENGE_INDICATOR_SHOW = 5, /* [achievement] challenge indicator should be shown */
769
RC_CLIENT_EVENT_ACHIEVEMENT_CHALLENGE_INDICATOR_HIDE = 6, /* [achievement] challenge indicator should be hidden */
770
RC_CLIENT_EVENT_ACHIEVEMENT_PROGRESS_INDICATOR_SHOW = 7, /* progress indicator should be shown for [achievement] */
771
RC_CLIENT_EVENT_ACHIEVEMENT_PROGRESS_INDICATOR_HIDE = 8, /* progress indicator should be hidden */
772
RC_CLIENT_EVENT_ACHIEVEMENT_PROGRESS_INDICATOR_UPDATE = 9, /* progress indicator should be updated to reflect new badge/progress for [achievement] */
773
RC_CLIENT_EVENT_LEADERBOARD_TRACKER_SHOW = 10, /* [leaderboard_tracker] should be shown */
774
RC_CLIENT_EVENT_LEADERBOARD_TRACKER_HIDE = 11, /* [leaderboard_tracker] should be hidden */
775
RC_CLIENT_EVENT_LEADERBOARD_TRACKER_UPDATE = 12, /* [leaderboard_tracker] updated */
776
RC_CLIENT_EVENT_LEADERBOARD_SCOREBOARD = 13, /* [leaderboard_scoreboard] possibly-new ranking received for [leaderboard] */
777
RC_CLIENT_EVENT_RESET = 14, /* emulated system should be reset (as the result of enabling hardcore) */
778
RC_CLIENT_EVENT_GAME_COMPLETED = 15, /* all achievements for the game have been earned */
779
RC_CLIENT_EVENT_SERVER_ERROR = 16, /* an API response returned a [server_error] and will not be retried */
780
RC_CLIENT_EVENT_DISCONNECTED = 17, /* an unlock request could not be completed and is pending */
781
RC_CLIENT_EVENT_RECONNECTED = 18, /* all pending unlocks have been completed */
782
RC_CLIENT_EVENT_SUBSET_COMPLETED = 19 /* all achievements for the subset have been earned */
783
};
784
785
typedef struct rc_client_server_error_t {
786
const char* error_message;
787
const char* api;
788
int result;
789
uint32_t related_id;
790
} rc_client_server_error_t;
791
792
typedef struct rc_client_event_t {
793
uint32_t type;
794
795
rc_client_achievement_t* achievement;
796
rc_client_leaderboard_t* leaderboard;
797
rc_client_leaderboard_tracker_t* leaderboard_tracker;
798
rc_client_leaderboard_scoreboard_t* leaderboard_scoreboard;
799
rc_client_server_error_t* server_error;
800
rc_client_subset_t* subset;
801
802
} rc_client_event_t;
803
804
/**
805
* Callback used to notify the client when certain events occur.
806
*/
807
typedef void (RC_CCONV *rc_client_event_handler_t)(const rc_client_event_t* event, rc_client_t* client);
808
809
/**
810
* Provides a callback for event handling.
811
*/
812
RC_EXPORT void RC_CCONV rc_client_set_event_handler(rc_client_t* client, rc_client_event_handler_t handler);
813
814
/**
815
* Provides a callback for reading memory.
816
*/
817
RC_EXPORT void RC_CCONV rc_client_set_read_memory_function(rc_client_t* client, rc_client_read_memory_func_t handler);
818
819
/**
820
* Specifies whether rc_client is allowed to read memory outside of rc_client_do_frame/rc_client_idle.
821
*/
822
RC_EXPORT void RC_CCONV rc_client_set_allow_background_memory_reads(rc_client_t* client, int allowed);
823
824
/**
825
* Determines if there are any active achievements/leaderboards/rich presence that need processing.
826
*/
827
RC_EXPORT int RC_CCONV rc_client_is_processing_required(rc_client_t* client);
828
829
/**
830
* Processes achievements for the current frame.
831
*/
832
RC_EXPORT void RC_CCONV rc_client_do_frame(rc_client_t* client);
833
834
/**
835
* Processes the periodic queue.
836
* Called internally by rc_client_do_frame.
837
* Should be explicitly called if rc_client_do_frame is not being called because emulation is paused.
838
*/
839
RC_EXPORT void RC_CCONV rc_client_idle(rc_client_t* client);
840
841
/**
842
* Determines if a sufficient amount of frames have been processed since the last call to rc_client_can_pause.
843
* Should not be called unless the client is trying to pause.
844
* If false is returned, and frames_remaining is not NULL, frames_remaining will be set to the number of frames
845
* still required before pause is allowed, which can be converted to a time in seconds for displaying to the user.
846
*/
847
RC_EXPORT int RC_CCONV rc_client_can_pause(rc_client_t* client, uint32_t* frames_remaining);
848
849
/**
850
* Informs the runtime that the emulator has been reset. Will reset all achievements and leaderboards
851
* to their initial state (includes hiding indicators/trackers).
852
*/
853
RC_EXPORT void RC_CCONV rc_client_reset(rc_client_t* client);
854
855
/**
856
* Gets the number of bytes needed to serialized the runtime state.
857
*/
858
RC_EXPORT size_t RC_CCONV rc_client_progress_size(rc_client_t* client);
859
860
/**
861
* Serializes the runtime state into a buffer.
862
* Returns RC_OK on success, or an error indicator.
863
* [deprecated] use rc_client_serialize_progress_sized instead
864
*/
865
RC_EXPORT int RC_CCONV rc_client_serialize_progress(rc_client_t* client, uint8_t* buffer);
866
867
/**
868
* Serializes the runtime state into a buffer.
869
* Returns RC_OK on success, or an error indicator.
870
*/
871
RC_EXPORT int RC_CCONV rc_client_serialize_progress_sized(rc_client_t* client, uint8_t* buffer, size_t buffer_size);
872
873
/**
874
* Deserializes the runtime state from a buffer.
875
* Returns RC_OK on success, or an error indicator.
876
* [deprecated] use rc_client_deserialize_progress_sized instead
877
*/
878
RC_EXPORT int RC_CCONV rc_client_deserialize_progress(rc_client_t* client, const uint8_t* serialized);
879
880
/**
881
* Serializes the runtime state into a buffer.
882
* Returns RC_OK on success, or an error indicator.
883
*/
884
RC_EXPORT int RC_CCONV rc_client_deserialize_progress_sized(rc_client_t* client, const uint8_t* serialized, size_t serialized_size);
885
886
RC_END_C_DECLS
887
888
#endif /* RC_RUNTIME_H */
889
890