gemba 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/THIRD_PARTY_NOTICES +37 -2
- data/assets/placeholder_boxart.png +0 -0
- data/bin/gemba +2 -2
- data/ext/gemba/extconf.rb +23 -1
- data/ext/gemba/gemba_ext.c +436 -2
- data/ext/gemba/gemba_ext.h +2 -0
- data/gemba.gemspec +5 -3
- data/lib/gemba/achievements/achievement.rb +23 -0
- data/lib/gemba/achievements/backend.rb +186 -0
- data/lib/gemba/achievements/cache.rb +70 -0
- data/lib/gemba/achievements/credentials_presenter.rb +142 -0
- data/lib/gemba/achievements/fake_backend.rb +205 -0
- data/lib/gemba/achievements/null_backend.rb +11 -0
- data/lib/gemba/achievements/offline_backend.rb +168 -0
- data/lib/gemba/achievements/retro_achievements/backend.rb +453 -0
- data/lib/gemba/achievements/retro_achievements/cli_sync_requester.rb +64 -0
- data/lib/gemba/achievements/retro_achievements/ping_worker.rb +27 -0
- data/lib/gemba/achievements.rb +19 -0
- data/lib/gemba/achievements_window.rb +556 -0
- data/lib/gemba/app_controller.rb +1015 -0
- data/lib/gemba/bios.rb +54 -0
- data/lib/gemba/boxart_fetcher/libretro_backend.rb +39 -0
- data/lib/gemba/boxart_fetcher/null_backend.rb +12 -0
- data/lib/gemba/boxart_fetcher.rb +79 -0
- data/lib/gemba/bus_emitter.rb +13 -0
- data/lib/gemba/child_window.rb +24 -1
- data/lib/gemba/cli/commands/config_cmd.rb +83 -0
- data/lib/gemba/cli/commands/decode.rb +154 -0
- data/lib/gemba/cli/commands/patch.rb +78 -0
- data/lib/gemba/cli/commands/play.rb +78 -0
- data/lib/gemba/cli/commands/record.rb +114 -0
- data/lib/gemba/cli/commands/replay.rb +161 -0
- data/lib/gemba/cli/commands/retro_achievements.rb +213 -0
- data/lib/gemba/cli/commands/version.rb +22 -0
- data/lib/gemba/cli.rb +52 -364
- data/lib/gemba/config.rb +134 -1
- data/lib/gemba/data/gb_games.json +1 -0
- data/lib/gemba/data/gb_md5.json +1 -0
- data/lib/gemba/data/gba_games.json +1 -0
- data/lib/gemba/data/gba_md5.json +1 -0
- data/lib/gemba/data/gbc_games.json +1 -0
- data/lib/gemba/data/gbc_md5.json +1 -0
- data/lib/gemba/emulator_frame.rb +1060 -0
- data/lib/gemba/event_bus.rb +48 -0
- data/lib/gemba/frame_stack.rb +60 -0
- data/lib/gemba/game_index.rb +84 -0
- data/lib/gemba/game_picker_frame.rb +268 -0
- data/lib/gemba/gamepad_map.rb +103 -0
- data/lib/gemba/headless.rb +6 -5
- data/lib/gemba/headless_player.rb +33 -3
- data/lib/gemba/help_window.rb +61 -0
- data/lib/gemba/hotkey_map.rb +3 -1
- data/lib/gemba/input_recorder.rb +107 -0
- data/lib/gemba/input_replayer.rb +119 -0
- data/lib/gemba/keyboard_map.rb +90 -0
- data/lib/gemba/locales/en.yml +97 -5
- data/lib/gemba/locales/ja.yml +97 -5
- data/lib/gemba/main_window.rb +56 -0
- data/lib/gemba/modal_stack.rb +81 -0
- data/lib/gemba/patcher_window.rb +223 -0
- data/lib/gemba/platform/gb.rb +21 -0
- data/lib/gemba/platform/gba.rb +21 -0
- data/lib/gemba/platform/gbc.rb +23 -0
- data/lib/gemba/platform.rb +20 -0
- data/lib/gemba/platform_open.rb +19 -0
- data/lib/gemba/recorder.rb +4 -3
- data/lib/gemba/replay_player.rb +691 -0
- data/lib/gemba/rom_info.rb +57 -0
- data/lib/gemba/rom_info_window.rb +16 -3
- data/lib/gemba/rom_library.rb +106 -0
- data/lib/gemba/rom_overrides.rb +47 -0
- data/lib/gemba/rom_patcher/bps.rb +161 -0
- data/lib/gemba/rom_patcher/ips.rb +101 -0
- data/lib/gemba/rom_patcher/ups.rb +118 -0
- data/lib/gemba/rom_patcher.rb +109 -0
- data/lib/gemba/{rom_loader.rb → rom_resolver.rb} +7 -6
- data/lib/gemba/runtime.rb +59 -26
- data/lib/gemba/save_state_manager.rb +4 -7
- data/lib/gemba/save_state_picker.rb +17 -4
- data/lib/gemba/session_logger.rb +64 -0
- data/lib/gemba/settings/audio_tab.rb +77 -0
- data/lib/gemba/settings/gamepad_tab.rb +351 -0
- data/lib/gemba/settings/hotkeys_tab.rb +259 -0
- data/lib/gemba/settings/paths.rb +11 -0
- data/lib/gemba/settings/recording_tab.rb +83 -0
- data/lib/gemba/settings/save_states_tab.rb +91 -0
- data/lib/gemba/settings/system_tab.rb +362 -0
- data/lib/gemba/settings/video_tab.rb +318 -0
- data/lib/gemba/settings_window.rb +162 -1036
- data/lib/gemba/version.rb +1 -1
- data/lib/gemba/virtual_keyboard.rb +19 -0
- data/lib/gemba.rb +2 -12
- data/test/achievements_window/test_bulk_sync.rb +218 -0
- data/test/achievements_window/test_bus_events.rb +125 -0
- data/test/achievements_window/test_close_confirmation.rb +201 -0
- data/test/achievements_window/test_initial_state.rb +164 -0
- data/test/achievements_window/test_sorting.rb +227 -0
- data/test/achievements_window/test_tree_rendering.rb +133 -0
- data/test/fixtures/fake_bios.bin +0 -0
- data/test/fixtures/pong.gba +0 -0
- data/test/fixtures/test.gb +0 -0
- data/test/fixtures/test.gbc +0 -0
- data/test/fixtures/test_quicksave.ss +0 -0
- data/test/screenshots/no_focus.png +0 -0
- data/test/shared/teek_test_worker.rb +17 -1
- data/test/shared/tk_test_helper.rb +91 -4
- data/test/support/achievements_window_helpers.rb +18 -0
- data/test/support/fake_core.rb +25 -0
- data/test/support/fake_ra_runtime.rb +74 -0
- data/test/support/fake_requester.rb +68 -0
- data/test/support/player_helpers.rb +20 -5
- data/test/test_achievement.rb +32 -0
- data/test/{test_player.rb → test_app_controller.rb} +353 -85
- data/test/test_bios.rb +123 -0
- data/test/test_boxart_fetcher.rb +150 -0
- data/test/test_cli.rb +17 -265
- data/test/test_cli_config.rb +64 -0
- data/test/test_cli_decode.rb +97 -0
- data/test/test_cli_patch.rb +58 -0
- data/test/test_cli_play.rb +213 -0
- data/test/test_cli_ra.rb +175 -0
- data/test/test_cli_record.rb +69 -0
- data/test/test_cli_replay.rb +72 -0
- data/test/test_cli_sync_requester.rb +152 -0
- data/test/test_cli_version.rb +27 -0
- data/test/test_config.rb +2 -3
- data/test/test_config_ra.rb +69 -0
- data/test/test_core.rb +62 -1
- data/test/test_credentials_presenter.rb +192 -0
- data/test/test_event_bus.rb +100 -0
- data/test/test_fake_backend_achievements.rb +130 -0
- data/test/test_fake_backend_auth.rb +68 -0
- data/test/test_game_index.rb +77 -0
- data/test/test_game_picker_frame.rb +310 -0
- data/test/test_gamepad_map.rb +1 -3
- data/test/test_headless_player.rb +17 -3
- data/test/test_help_window.rb +82 -0
- data/test/test_hotkey_map.rb +22 -1
- data/test/test_input_recorder.rb +179 -0
- data/test/test_input_replay_determinism.rb +113 -0
- data/test/test_input_replayer.rb +162 -0
- data/test/test_keyboard_map.rb +1 -3
- data/test/test_libretro_backend.rb +41 -0
- data/test/test_locale.rb +1 -1
- data/test/test_logging.rb +123 -0
- data/test/test_null_backend.rb +42 -0
- data/test/test_offline_backend.rb +116 -0
- data/test/test_overlay_renderer.rb +1 -1
- data/test/test_platform.rb +149 -0
- data/test/test_ra_backend.rb +313 -0
- data/test/test_ra_backend_unlock_gate.rb +56 -0
- data/test/test_recorder.rb +0 -3
- data/test/test_replay_player.rb +316 -0
- data/test/test_rom_info.rb +149 -0
- data/test/test_rom_overrides.rb +86 -0
- data/test/test_rom_patcher.rb +382 -0
- data/test/{test_rom_loader.rb → test_rom_resolver.rb} +25 -26
- data/test/test_save_state_manager.rb +2 -4
- data/test/test_settings_audio.rb +107 -0
- data/test/test_settings_hotkeys.rb +83 -66
- data/test/test_settings_recording.rb +49 -0
- data/test/test_settings_save_states.rb +97 -0
- data/test/test_settings_system.rb +133 -0
- data/test/test_settings_video.rb +450 -0
- data/test/test_settings_window.rb +76 -507
- data/test/test_tip_service.rb +6 -6
- data/test/test_toast_overlay.rb +1 -1
- data/test/test_virtual_events.rb +156 -0
- data/test/test_virtual_keyboard.rb +1 -1
- data/vendor/rcheevos/CHANGELOG.md +495 -0
- data/vendor/rcheevos/LICENSE +21 -0
- data/vendor/rcheevos/Package.swift +33 -0
- data/vendor/rcheevos/README.md +67 -0
- data/vendor/rcheevos/include/module.modulemap +70 -0
- data/vendor/rcheevos/include/rc_api_editor.h +296 -0
- data/vendor/rcheevos/include/rc_api_info.h +280 -0
- data/vendor/rcheevos/include/rc_api_request.h +77 -0
- data/vendor/rcheevos/include/rc_api_runtime.h +417 -0
- data/vendor/rcheevos/include/rc_api_user.h +262 -0
- data/vendor/rcheevos/include/rc_client.h +877 -0
- data/vendor/rcheevos/include/rc_client_raintegration.h +101 -0
- data/vendor/rcheevos/include/rc_consoles.h +138 -0
- data/vendor/rcheevos/include/rc_error.h +59 -0
- data/vendor/rcheevos/include/rc_export.h +100 -0
- data/vendor/rcheevos/include/rc_hash.h +200 -0
- data/vendor/rcheevos/include/rc_runtime.h +148 -0
- data/vendor/rcheevos/include/rc_runtime_types.h +452 -0
- data/vendor/rcheevos/include/rc_util.h +51 -0
- data/vendor/rcheevos/include/rcheevos.h +8 -0
- data/vendor/rcheevos/src/rapi/rc_api_common.c +1379 -0
- data/vendor/rcheevos/src/rapi/rc_api_common.h +88 -0
- data/vendor/rcheevos/src/rapi/rc_api_editor.c +625 -0
- data/vendor/rcheevos/src/rapi/rc_api_info.c +587 -0
- data/vendor/rcheevos/src/rapi/rc_api_runtime.c +901 -0
- data/vendor/rcheevos/src/rapi/rc_api_user.c +483 -0
- data/vendor/rcheevos/src/rc_client.c +6941 -0
- data/vendor/rcheevos/src/rc_client_external.c +281 -0
- data/vendor/rcheevos/src/rc_client_external.h +177 -0
- data/vendor/rcheevos/src/rc_client_external_versions.h +171 -0
- data/vendor/rcheevos/src/rc_client_internal.h +409 -0
- data/vendor/rcheevos/src/rc_client_raintegration.c +566 -0
- data/vendor/rcheevos/src/rc_client_raintegration_internal.h +61 -0
- data/vendor/rcheevos/src/rc_client_types.natvis +396 -0
- data/vendor/rcheevos/src/rc_compat.c +251 -0
- data/vendor/rcheevos/src/rc_compat.h +121 -0
- data/vendor/rcheevos/src/rc_libretro.c +915 -0
- data/vendor/rcheevos/src/rc_libretro.h +98 -0
- data/vendor/rcheevos/src/rc_util.c +199 -0
- data/vendor/rcheevos/src/rc_version.c +11 -0
- data/vendor/rcheevos/src/rc_version.h +32 -0
- data/vendor/rcheevos/src/rcheevos/alloc.c +312 -0
- data/vendor/rcheevos/src/rcheevos/condition.c +754 -0
- data/vendor/rcheevos/src/rcheevos/condset.c +777 -0
- data/vendor/rcheevos/src/rcheevos/consoleinfo.c +1215 -0
- data/vendor/rcheevos/src/rcheevos/format.c +330 -0
- data/vendor/rcheevos/src/rcheevos/lboard.c +287 -0
- data/vendor/rcheevos/src/rcheevos/memref.c +805 -0
- data/vendor/rcheevos/src/rcheevos/operand.c +607 -0
- data/vendor/rcheevos/src/rcheevos/rc_internal.h +390 -0
- data/vendor/rcheevos/src/rcheevos/rc_runtime_types.natvis +541 -0
- data/vendor/rcheevos/src/rcheevos/rc_validate.c +1406 -0
- data/vendor/rcheevos/src/rcheevos/rc_validate.h +18 -0
- data/vendor/rcheevos/src/rcheevos/richpresence.c +922 -0
- data/vendor/rcheevos/src/rcheevos/runtime.c +852 -0
- data/vendor/rcheevos/src/rcheevos/runtime_progress.c +1073 -0
- data/vendor/rcheevos/src/rcheevos/trigger.c +344 -0
- data/vendor/rcheevos/src/rcheevos/value.c +935 -0
- data/vendor/rcheevos/src/rhash/aes.c +480 -0
- data/vendor/rcheevos/src/rhash/aes.h +49 -0
- data/vendor/rcheevos/src/rhash/cdreader.c +838 -0
- data/vendor/rcheevos/src/rhash/hash.c +1402 -0
- data/vendor/rcheevos/src/rhash/hash_disc.c +1340 -0
- data/vendor/rcheevos/src/rhash/hash_encrypted.c +566 -0
- data/vendor/rcheevos/src/rhash/hash_rom.c +426 -0
- data/vendor/rcheevos/src/rhash/hash_zip.c +460 -0
- data/vendor/rcheevos/src/rhash/md5.c +382 -0
- data/vendor/rcheevos/src/rhash/md5.h +91 -0
- data/vendor/rcheevos/src/rhash/rc_hash_internal.h +116 -0
- data/vendor/rcheevos/test/libretro.h +205 -0
- data/vendor/rcheevos/test/rapi/test_rc_api_common.c +941 -0
- data/vendor/rcheevos/test/rapi/test_rc_api_editor.c +931 -0
- data/vendor/rcheevos/test/rapi/test_rc_api_info.c +545 -0
- data/vendor/rcheevos/test/rapi/test_rc_api_runtime.c +2213 -0
- data/vendor/rcheevos/test/rapi/test_rc_api_user.c +998 -0
- data/vendor/rcheevos/test/rcheevos/mock_memory.h +32 -0
- data/vendor/rcheevos/test/rcheevos/test_condition.c +570 -0
- data/vendor/rcheevos/test/rcheevos/test_condset.c +5170 -0
- data/vendor/rcheevos/test/rcheevos/test_consoleinfo.c +203 -0
- data/vendor/rcheevos/test/rcheevos/test_format.c +112 -0
- data/vendor/rcheevos/test/rcheevos/test_lboard.c +746 -0
- data/vendor/rcheevos/test/rcheevos/test_memref.c +520 -0
- data/vendor/rcheevos/test/rcheevos/test_operand.c +692 -0
- data/vendor/rcheevos/test/rcheevos/test_rc_validate.c +502 -0
- data/vendor/rcheevos/test/rcheevos/test_richpresence.c +1564 -0
- data/vendor/rcheevos/test/rcheevos/test_runtime.c +1667 -0
- data/vendor/rcheevos/test/rcheevos/test_runtime_progress.c +1821 -0
- data/vendor/rcheevos/test/rcheevos/test_timing.c +166 -0
- data/vendor/rcheevos/test/rcheevos/test_trigger.c +2521 -0
- data/vendor/rcheevos/test/rcheevos/test_value.c +870 -0
- data/vendor/rcheevos/test/rcheevos-test.sln +46 -0
- data/vendor/rcheevos/test/rcheevos-test.vcxproj +239 -0
- data/vendor/rcheevos/test/rcheevos-test.vcxproj.filters +335 -0
- data/vendor/rcheevos/test/rhash/data.c +657 -0
- data/vendor/rcheevos/test/rhash/data.h +32 -0
- data/vendor/rcheevos/test/rhash/mock_filereader.c +236 -0
- data/vendor/rcheevos/test/rhash/mock_filereader.h +31 -0
- data/vendor/rcheevos/test/rhash/test_cdreader.c +920 -0
- data/vendor/rcheevos/test/rhash/test_hash.c +310 -0
- data/vendor/rcheevos/test/rhash/test_hash_disc.c +1450 -0
- data/vendor/rcheevos/test/rhash/test_hash_rom.c +899 -0
- data/vendor/rcheevos/test/rhash/test_hash_zip.c +551 -0
- data/vendor/rcheevos/test/test.c +113 -0
- data/vendor/rcheevos/test/test_framework.h +205 -0
- data/vendor/rcheevos/test/test_rc_client.c +10509 -0
- data/vendor/rcheevos/test/test_rc_client_external.c +2197 -0
- data/vendor/rcheevos/test/test_rc_client_raintegration.c +441 -0
- data/vendor/rcheevos/test/test_rc_libretro.c +952 -0
- data/vendor/rcheevos/test/test_types.natvis +9 -0
- data/vendor/rcheevos/validator/validator.c +658 -0
- data/vendor/rcheevos/validator/validator.vcxproj +152 -0
- data/vendor/rcheevos/validator/validator.vcxproj.filters +82 -0
- metadata +274 -11
- data/lib/gemba/input_mappings.rb +0 -214
- data/lib/gemba/player.rb +0 -1525
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
#include "rc_client_external.h"
|
|
2
|
+
|
|
3
|
+
#include "rc_client_external_versions.h"
|
|
4
|
+
#include "rc_client_internal.h"
|
|
5
|
+
|
|
6
|
+
#include "rc_api_runtime.h"
|
|
7
|
+
|
|
8
|
+
#ifdef RC_CLIENT_SUPPORTS_EXTERNAL
|
|
9
|
+
|
|
10
|
+
#define RC_CONVERSION_FILL(obj, obj_type, src_type) memset((uint8_t*)obj + sizeof(src_type), 0, sizeof(obj_type) - sizeof(src_type))
|
|
11
|
+
|
|
12
|
+
/* https://media.retroachievements.org/Badge/123456_lock.png is 58 with null terminator */
|
|
13
|
+
#define RC_CLIENT_IMAGE_URL_BUFFER_SIZE 64
|
|
14
|
+
/* https://media.retroachievements.org/UserPic/TwentyCharUserNameXX.png is 69 with null terminator */
|
|
15
|
+
#define RC_CLIENT_USER_IMAGE_URL_BUFFER_SIZE 80
|
|
16
|
+
|
|
17
|
+
typedef struct rc_client_external_conversions_t {
|
|
18
|
+
rc_client_user_t user;
|
|
19
|
+
rc_client_game_t game;
|
|
20
|
+
rc_client_subset_t subsets[4];
|
|
21
|
+
rc_client_achievement_t achievements[16];
|
|
22
|
+
char user_avatar_url[RC_CLIENT_USER_IMAGE_URL_BUFFER_SIZE];
|
|
23
|
+
char game_badge_url[RC_CLIENT_IMAGE_URL_BUFFER_SIZE];
|
|
24
|
+
char subset_badge_url[4][RC_CLIENT_IMAGE_URL_BUFFER_SIZE];
|
|
25
|
+
char achievement_badge_url[16][RC_CLIENT_IMAGE_URL_BUFFER_SIZE];
|
|
26
|
+
char achievement_badge_locked_url[16][RC_CLIENT_IMAGE_URL_BUFFER_SIZE];
|
|
27
|
+
uint32_t next_subset_index;
|
|
28
|
+
uint32_t next_achievement_index;
|
|
29
|
+
} rc_client_external_conversions_t;
|
|
30
|
+
|
|
31
|
+
static const char* rc_client_external_build_avatar_url(char buffer[], size_t buffer_size, uint32_t image_type, const char* image_name)
|
|
32
|
+
{
|
|
33
|
+
rc_api_fetch_image_request_t image_request;
|
|
34
|
+
rc_api_request_t request;
|
|
35
|
+
int result;
|
|
36
|
+
|
|
37
|
+
memset(&image_request, 0, sizeof(image_request));
|
|
38
|
+
image_request.image_type = image_type;
|
|
39
|
+
image_request.image_name = image_name;
|
|
40
|
+
|
|
41
|
+
result = rc_api_init_fetch_image_request(&request, &image_request);
|
|
42
|
+
if (result != RC_OK)
|
|
43
|
+
return NULL;
|
|
44
|
+
|
|
45
|
+
snprintf(buffer, buffer_size, "%s", request.url);
|
|
46
|
+
return buffer;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
static void rc_client_external_conversions_init(const rc_client_t* client)
|
|
50
|
+
{
|
|
51
|
+
if (!client->state.external_client_conversions) {
|
|
52
|
+
rc_client_t* mutable_client = (rc_client_t*)client;
|
|
53
|
+
rc_client_external_conversions_t* conversions = (rc_client_external_conversions_t*)
|
|
54
|
+
rc_buffer_alloc(&mutable_client->state.buffer, sizeof(rc_client_external_conversions_t));
|
|
55
|
+
|
|
56
|
+
memset(conversions, 0, sizeof(*conversions));
|
|
57
|
+
|
|
58
|
+
mutable_client->state.external_client_conversions = conversions;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const rc_client_user_t* rc_client_external_convert_v1_user(const rc_client_t* client, const rc_client_user_t* v1_user)
|
|
63
|
+
{
|
|
64
|
+
rc_client_user_t* converted;
|
|
65
|
+
|
|
66
|
+
if (!v1_user)
|
|
67
|
+
return NULL;
|
|
68
|
+
|
|
69
|
+
rc_client_external_conversions_init(client);
|
|
70
|
+
|
|
71
|
+
converted = &client->state.external_client_conversions->user;
|
|
72
|
+
memcpy(converted, v1_user, sizeof(v1_rc_client_user_t));
|
|
73
|
+
RC_CONVERSION_FILL(converted, rc_client_user_t, v1_rc_client_user_t);
|
|
74
|
+
|
|
75
|
+
converted->avatar_url = rc_client_external_build_avatar_url(
|
|
76
|
+
client->state.external_client_conversions->user_avatar_url,
|
|
77
|
+
sizeof(client->state.external_client_conversions->user_avatar_url),
|
|
78
|
+
RC_IMAGE_TYPE_USER, v1_user->username);
|
|
79
|
+
|
|
80
|
+
return converted;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const rc_client_game_t* rc_client_external_convert_v1_game(const rc_client_t* client, const rc_client_game_t* v1_game)
|
|
84
|
+
{
|
|
85
|
+
rc_client_game_t* converted;
|
|
86
|
+
|
|
87
|
+
if (!v1_game)
|
|
88
|
+
return NULL;
|
|
89
|
+
|
|
90
|
+
rc_client_external_conversions_init(client);
|
|
91
|
+
|
|
92
|
+
converted = &client->state.external_client_conversions->game;
|
|
93
|
+
memcpy(converted, v1_game, sizeof(v1_rc_client_game_t));
|
|
94
|
+
RC_CONVERSION_FILL(converted, rc_client_game_t, v1_rc_client_game_t);
|
|
95
|
+
|
|
96
|
+
converted->badge_url = rc_client_external_build_avatar_url(
|
|
97
|
+
client->state.external_client_conversions->game_badge_url,
|
|
98
|
+
sizeof(client->state.external_client_conversions->game_badge_url),
|
|
99
|
+
RC_IMAGE_TYPE_GAME, v1_game->badge_name);
|
|
100
|
+
|
|
101
|
+
return converted;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const rc_client_subset_t* rc_client_external_convert_v1_subset(const rc_client_t* client, const rc_client_subset_t* v1_subset)
|
|
105
|
+
{
|
|
106
|
+
rc_client_subset_t* converted = NULL;
|
|
107
|
+
char* badge_url = NULL;
|
|
108
|
+
const uint32_t num_subsets = sizeof(client->state.external_client_conversions->subsets) / sizeof(client->state.external_client_conversions->subsets[0]);
|
|
109
|
+
uint32_t index;
|
|
110
|
+
|
|
111
|
+
if (!v1_subset)
|
|
112
|
+
return NULL;
|
|
113
|
+
|
|
114
|
+
rc_client_external_conversions_init(client);
|
|
115
|
+
|
|
116
|
+
for (index = 0; index < num_subsets; ++index) {
|
|
117
|
+
if (client->state.external_client_conversions->subsets[index].id == v1_subset->id) {
|
|
118
|
+
converted = &client->state.external_client_conversions->subsets[index];
|
|
119
|
+
badge_url = client->state.external_client_conversions->subset_badge_url[index];
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (!converted) {
|
|
125
|
+
index = client->state.external_client_conversions->next_subset_index;
|
|
126
|
+
converted = &client->state.external_client_conversions->subsets[index];
|
|
127
|
+
badge_url = client->state.external_client_conversions->subset_badge_url[client->state.external_client_conversions->next_subset_index];
|
|
128
|
+
client->state.external_client_conversions->next_subset_index = (index + 1) % num_subsets;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
memcpy(converted, v1_subset, sizeof(v1_rc_client_subset_t));
|
|
132
|
+
RC_CONVERSION_FILL(converted, rc_client_subset_t, v1_rc_client_subset_t);
|
|
133
|
+
|
|
134
|
+
converted->badge_url = rc_client_external_build_avatar_url(badge_url,
|
|
135
|
+
sizeof(client->state.external_client_conversions->subset_badge_url[0]),
|
|
136
|
+
RC_IMAGE_TYPE_GAME, v1_subset->badge_name);
|
|
137
|
+
|
|
138
|
+
return converted;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const rc_client_achievement_t* rc_client_external_convert_v1_achievement(const rc_client_t* client, const rc_client_achievement_t* v1_achievement)
|
|
142
|
+
{
|
|
143
|
+
rc_client_achievement_t* converted = NULL;
|
|
144
|
+
char* badge_url = NULL;
|
|
145
|
+
char* badge_locked_url = NULL;
|
|
146
|
+
const uint32_t num_achievements = sizeof(client->state.external_client_conversions->achievements) / sizeof(client->state.external_client_conversions->achievements[0]);
|
|
147
|
+
uint32_t index;
|
|
148
|
+
|
|
149
|
+
if (!v1_achievement)
|
|
150
|
+
return NULL;
|
|
151
|
+
|
|
152
|
+
rc_client_external_conversions_init(client);
|
|
153
|
+
|
|
154
|
+
for (index = 0; index < num_achievements; ++index) {
|
|
155
|
+
if (client->state.external_client_conversions->achievements[index].id == v1_achievement->id) {
|
|
156
|
+
converted = &client->state.external_client_conversions->achievements[index];
|
|
157
|
+
badge_url = client->state.external_client_conversions->achievement_badge_url[index];
|
|
158
|
+
badge_locked_url = client->state.external_client_conversions->achievement_badge_locked_url[index];
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (!converted) {
|
|
164
|
+
index = client->state.external_client_conversions->next_achievement_index;
|
|
165
|
+
converted = &client->state.external_client_conversions->achievements[index];
|
|
166
|
+
badge_url = client->state.external_client_conversions->achievement_badge_url[index];
|
|
167
|
+
badge_locked_url = client->state.external_client_conversions->achievement_badge_locked_url[index];
|
|
168
|
+
client->state.external_client_conversions->next_achievement_index = (index + 1) % num_achievements;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
memcpy(converted, v1_achievement, sizeof(v1_rc_client_achievement_t));
|
|
172
|
+
RC_CONVERSION_FILL(converted, rc_client_achievement_t, v1_rc_client_achievement_t);
|
|
173
|
+
|
|
174
|
+
converted->badge_url = rc_client_external_build_avatar_url(badge_url,
|
|
175
|
+
sizeof(client->state.external_client_conversions->achievement_badge_url[0]),
|
|
176
|
+
RC_IMAGE_TYPE_ACHIEVEMENT, v1_achievement->badge_name);
|
|
177
|
+
converted->badge_locked_url = rc_client_external_build_avatar_url(badge_locked_url,
|
|
178
|
+
sizeof(client->state.external_client_conversions->achievement_badge_locked_url[0]),
|
|
179
|
+
RC_IMAGE_TYPE_ACHIEVEMENT_LOCKED, v1_achievement->badge_name);
|
|
180
|
+
|
|
181
|
+
return converted;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
typedef struct rc_client_achievement_list_wrapper_t {
|
|
185
|
+
rc_client_achievement_list_info_t info;
|
|
186
|
+
rc_client_achievement_list_t* source_list;
|
|
187
|
+
rc_client_achievement_t* achievements;
|
|
188
|
+
rc_client_achievement_t** achievements_pointers;
|
|
189
|
+
char* badge_url_buffer;
|
|
190
|
+
} rc_client_achievement_list_wrapper_t;
|
|
191
|
+
|
|
192
|
+
static void rc_client_destroy_achievement_list_wrapper(rc_client_achievement_list_info_t* info)
|
|
193
|
+
{
|
|
194
|
+
rc_client_achievement_list_wrapper_t* wrapper = (rc_client_achievement_list_wrapper_t*)info;
|
|
195
|
+
|
|
196
|
+
if (wrapper->achievements)
|
|
197
|
+
free(wrapper->achievements);
|
|
198
|
+
if (wrapper->achievements_pointers)
|
|
199
|
+
free(wrapper->achievements_pointers);
|
|
200
|
+
if (wrapper->info.public_.buckets)
|
|
201
|
+
free((void*)wrapper->info.public_.buckets);
|
|
202
|
+
if (wrapper->badge_url_buffer)
|
|
203
|
+
free(wrapper->badge_url_buffer);
|
|
204
|
+
|
|
205
|
+
rc_client_destroy_achievement_list(wrapper->source_list);
|
|
206
|
+
|
|
207
|
+
free(wrapper);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
rc_client_achievement_list_t* rc_client_external_convert_v1_achievement_list(const rc_client_t* client, rc_client_achievement_list_t* v1_achievement_list)
|
|
211
|
+
{
|
|
212
|
+
rc_client_achievement_list_wrapper_t* new_list;
|
|
213
|
+
(void)client;
|
|
214
|
+
|
|
215
|
+
if (!v1_achievement_list)
|
|
216
|
+
return NULL;
|
|
217
|
+
|
|
218
|
+
new_list = (rc_client_achievement_list_wrapper_t*)calloc(1, sizeof(*new_list));
|
|
219
|
+
if (!new_list)
|
|
220
|
+
return NULL;
|
|
221
|
+
|
|
222
|
+
new_list->source_list = v1_achievement_list;
|
|
223
|
+
new_list->info.destroy_func = rc_client_destroy_achievement_list_wrapper;
|
|
224
|
+
|
|
225
|
+
if (v1_achievement_list->num_buckets) {
|
|
226
|
+
const v1_rc_client_achievement_bucket_t* src_bucket = (const v1_rc_client_achievement_bucket_t*)&v1_achievement_list->buckets[0];
|
|
227
|
+
const v1_rc_client_achievement_bucket_t* stop_bucket = src_bucket + v1_achievement_list->num_buckets;
|
|
228
|
+
rc_client_achievement_bucket_t* bucket;
|
|
229
|
+
uint32_t num_achievements = 0;
|
|
230
|
+
char* badge_url = NULL;
|
|
231
|
+
|
|
232
|
+
new_list->info.public_.buckets = bucket = (rc_client_achievement_bucket_t*)calloc(v1_achievement_list->num_buckets, sizeof(*new_list->info.public_.buckets));
|
|
233
|
+
if (!new_list->info.public_.buckets)
|
|
234
|
+
return (rc_client_achievement_list_t*)new_list;
|
|
235
|
+
|
|
236
|
+
for (; src_bucket < stop_bucket; src_bucket++)
|
|
237
|
+
num_achievements += src_bucket->num_achievements;
|
|
238
|
+
|
|
239
|
+
if (num_achievements) {
|
|
240
|
+
new_list->achievements = (rc_client_achievement_t*)calloc(num_achievements, sizeof(*new_list->achievements));
|
|
241
|
+
new_list->achievements_pointers = (rc_client_achievement_t**)malloc(num_achievements * sizeof(rc_client_achievement_t*));
|
|
242
|
+
new_list->badge_url_buffer = badge_url = (char*)malloc(num_achievements * 2 * RC_CLIENT_IMAGE_URL_BUFFER_SIZE);
|
|
243
|
+
if (!new_list->achievements || !new_list->achievements_pointers || !new_list->badge_url_buffer)
|
|
244
|
+
return (rc_client_achievement_list_t*)new_list;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
num_achievements = 0;
|
|
248
|
+
src_bucket = (const v1_rc_client_achievement_bucket_t*)&v1_achievement_list->buckets[0];
|
|
249
|
+
for (; src_bucket < stop_bucket; src_bucket++, bucket++) {
|
|
250
|
+
memcpy(bucket, src_bucket, sizeof(*src_bucket));
|
|
251
|
+
|
|
252
|
+
if (src_bucket->num_achievements) {
|
|
253
|
+
const v1_rc_client_achievement_t** src_achievement = (const v1_rc_client_achievement_t**)src_bucket->achievements;
|
|
254
|
+
const v1_rc_client_achievement_t** stop_achievement = src_achievement + src_bucket->num_achievements;
|
|
255
|
+
rc_client_achievement_t** achievement = &new_list->achievements_pointers[num_achievements];
|
|
256
|
+
|
|
257
|
+
bucket->achievements = (const rc_client_achievement_t**)achievement;
|
|
258
|
+
|
|
259
|
+
for (; src_achievement < stop_achievement; ++src_achievement, ++achievement) {
|
|
260
|
+
*achievement = &new_list->achievements[num_achievements++];
|
|
261
|
+
memcpy(*achievement, *src_achievement, sizeof(**src_achievement));
|
|
262
|
+
|
|
263
|
+
(*achievement)->badge_url = rc_client_external_build_avatar_url(badge_url,
|
|
264
|
+
sizeof(client->state.external_client_conversions->achievement_badge_url[0]),
|
|
265
|
+
RC_IMAGE_TYPE_ACHIEVEMENT, (*achievement)->badge_name);
|
|
266
|
+
badge_url += RC_CLIENT_IMAGE_URL_BUFFER_SIZE;
|
|
267
|
+
(*achievement)->badge_locked_url = rc_client_external_build_avatar_url(badge_url,
|
|
268
|
+
sizeof(client->state.external_client_conversions->achievement_badge_locked_url[0]),
|
|
269
|
+
RC_IMAGE_TYPE_ACHIEVEMENT_LOCKED, (*achievement)->badge_name);
|
|
270
|
+
badge_url += RC_CLIENT_IMAGE_URL_BUFFER_SIZE;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
new_list->info.public_.num_buckets = v1_achievement_list->num_buckets;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return (rc_client_achievement_list_t*)new_list;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
#endif /* RC_CLIENT_SUPPORTS_EXTERNAL */
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
#ifndef RC_CLIENT_EXTERNAL_H
|
|
2
|
+
#define RC_CLIENT_EXTERNAL_H
|
|
3
|
+
|
|
4
|
+
#include "rc_client.h"
|
|
5
|
+
|
|
6
|
+
RC_BEGIN_C_DECLS
|
|
7
|
+
|
|
8
|
+
/* NOTE: any function that is passed a callback also needs to be passed a client instance to pass
|
|
9
|
+
* to the callback, and the external interface has to capture both. */
|
|
10
|
+
|
|
11
|
+
typedef void (RC_CCONV *rc_client_external_enable_logging_func_t)(rc_client_t* client, int level, rc_client_message_callback_t callback);
|
|
12
|
+
typedef void (RC_CCONV *rc_client_external_set_event_handler_func_t)(rc_client_t* client, rc_client_event_handler_t handler);
|
|
13
|
+
typedef void (RC_CCONV *rc_client_external_set_read_memory_func_t)(rc_client_t* client, rc_client_read_memory_func_t handler);
|
|
14
|
+
typedef void (RC_CCONV *rc_client_external_set_get_time_millisecs_func_t)(rc_client_t* client, rc_get_time_millisecs_func_t handler);
|
|
15
|
+
typedef int (RC_CCONV *rc_client_external_can_pause_func_t)(uint32_t* frames_remaining);
|
|
16
|
+
|
|
17
|
+
typedef void (RC_CCONV *rc_client_external_set_int_func_t)(int value);
|
|
18
|
+
typedef int (RC_CCONV *rc_client_external_get_int_func_t)(void);
|
|
19
|
+
typedef void (RC_CCONV *rc_client_external_set_string_func_t)(const char* value);
|
|
20
|
+
typedef size_t (RC_CCONV *rc_client_external_copy_string_func_t)(char buffer[], size_t buffer_size);
|
|
21
|
+
typedef void (RC_CCONV *rc_client_external_action_func_t)(void);
|
|
22
|
+
|
|
23
|
+
typedef void (RC_CCONV *rc_client_external_async_handle_func_t)(rc_client_async_handle_t* handle);
|
|
24
|
+
|
|
25
|
+
typedef rc_client_async_handle_t* (RC_CCONV *rc_client_external_begin_login_func_t)(rc_client_t* client,
|
|
26
|
+
const char* username, const char* pass_token, rc_client_callback_t callback, void* callback_userdata);
|
|
27
|
+
typedef const rc_client_user_t* (RC_CCONV *rc_client_external_get_user_info_func_t)(void);
|
|
28
|
+
|
|
29
|
+
typedef rc_client_async_handle_t* (RC_CCONV *rc_client_external_begin_identify_and_load_game_func_t)(
|
|
30
|
+
rc_client_t* client, uint32_t console_id, const char* file_path,
|
|
31
|
+
const uint8_t* data, size_t data_size, rc_client_callback_t callback, void* callback_userdata);
|
|
32
|
+
typedef rc_client_async_handle_t* (RC_CCONV *rc_client_external_begin_load_game_func_t)(rc_client_t* client,
|
|
33
|
+
const char* hash, rc_client_callback_t callback, void* callback_userdata);
|
|
34
|
+
typedef rc_client_async_handle_t* (RC_CCONV *rc_client_external_begin_load_subset_t)(rc_client_t* client,
|
|
35
|
+
uint32_t subset_id, rc_client_callback_t callback, void* callback_userdata);
|
|
36
|
+
typedef const rc_client_game_t* (RC_CCONV *rc_client_external_get_game_info_func_t)(void);
|
|
37
|
+
typedef const rc_client_subset_t* (RC_CCONV *rc_client_external_get_subset_info_func_t)(uint32_t subset_id);
|
|
38
|
+
typedef void (RC_CCONV* rc_client_external_get_user_subset_summary_func_t)(uint32_t subset_id, rc_client_user_game_summary_t* summary);
|
|
39
|
+
typedef void (RC_CCONV *rc_client_external_get_user_game_summary_func_t)(rc_client_user_game_summary_t* summary);
|
|
40
|
+
typedef rc_client_async_handle_t* (RC_CCONV *rc_client_external_begin_change_media_func_t)(rc_client_t* client, const char* file_path,
|
|
41
|
+
const uint8_t* data, size_t data_size, rc_client_callback_t callback, void* callback_userdata);
|
|
42
|
+
typedef void (RC_CCONV* rc_client_external_add_game_hash_func_t)(const char* hash, uint32_t game_id);
|
|
43
|
+
|
|
44
|
+
/* NOTE: rc_client_external_create_achievement_list_func_t returns an internal wrapper structure which contains the public list
|
|
45
|
+
* and a destructor function. */
|
|
46
|
+
struct rc_client_achievement_list_info_t;
|
|
47
|
+
typedef struct rc_client_achievement_list_info_t* (RC_CCONV *rc_client_external_create_achievement_list_func_t)(int category, int grouping);
|
|
48
|
+
typedef const rc_client_achievement_t* (RC_CCONV *rc_client_external_get_achievement_info_func_t)(uint32_t id);
|
|
49
|
+
typedef const rc_client_achievement_t* (RC_CCONV* rc_client_external_get_next_achievement_info_func_t)(uint32_t id, int grouping);
|
|
50
|
+
|
|
51
|
+
/* NOTE: rc_client_external_create_leaderboard_list_func_t returns an internal wrapper structure which contains the public list
|
|
52
|
+
* and a destructor function. */
|
|
53
|
+
struct rc_client_leaderboard_list_info_t;
|
|
54
|
+
typedef struct rc_client_leaderboard_list_info_t* (RC_CCONV *rc_client_external_create_leaderboard_list_func_t)(int grouping);
|
|
55
|
+
typedef const rc_client_leaderboard_t* (RC_CCONV *rc_client_external_get_leaderboard_info_func_t)(uint32_t id);
|
|
56
|
+
|
|
57
|
+
/* NOTE: rc_client_external_begin_fetch_leaderboard_entries_func_t and rc_client_external_begin_fetch_leaderboard_entries_around_user_func_t
|
|
58
|
+
* pass an internal wrapper structure around the list, which contains the public list and a destructor function. */
|
|
59
|
+
typedef rc_client_async_handle_t* (RC_CCONV *rc_client_external_begin_fetch_leaderboard_entries_func_t)(rc_client_t* client,
|
|
60
|
+
uint32_t leaderboard_id, uint32_t first_entry, uint32_t count,
|
|
61
|
+
rc_client_fetch_leaderboard_entries_callback_t callback, void* callback_userdata);
|
|
62
|
+
typedef rc_client_async_handle_t* (RC_CCONV *rc_client_external_begin_fetch_leaderboard_entries_around_user_func_t)(rc_client_t* client,
|
|
63
|
+
uint32_t leaderboard_id, uint32_t count, rc_client_fetch_leaderboard_entries_callback_t callback, void* callback_userdata);
|
|
64
|
+
|
|
65
|
+
/* NOTE: rc_client_external_create_subset_list_func_t returns an internal wrapper structure which contains the public list
|
|
66
|
+
* and a destructor function. */
|
|
67
|
+
struct rc_client_subset_list_info_t;
|
|
68
|
+
typedef struct rc_client_subset_list_info_t* (RC_CCONV* rc_client_external_create_subset_list_func_t)();
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
typedef size_t (RC_CCONV *rc_client_external_progress_size_func_t)(void);
|
|
72
|
+
typedef int (RC_CCONV *rc_client_external_serialize_progress_func_t)(uint8_t* buffer, size_t buffer_size);
|
|
73
|
+
typedef int (RC_CCONV *rc_client_external_deserialize_progress_func_t)(const uint8_t* buffer, size_t buffer_size);
|
|
74
|
+
|
|
75
|
+
typedef struct rc_client_external_t
|
|
76
|
+
{
|
|
77
|
+
rc_client_external_action_func_t destroy;
|
|
78
|
+
|
|
79
|
+
rc_client_external_enable_logging_func_t enable_logging;
|
|
80
|
+
rc_client_external_set_event_handler_func_t set_event_handler;
|
|
81
|
+
rc_client_external_set_read_memory_func_t set_read_memory;
|
|
82
|
+
rc_client_external_set_get_time_millisecs_func_t set_get_time_millisecs;
|
|
83
|
+
rc_client_external_set_string_func_t set_host;
|
|
84
|
+
rc_client_external_copy_string_func_t get_user_agent_clause;
|
|
85
|
+
|
|
86
|
+
rc_client_external_set_int_func_t set_hardcore_enabled;
|
|
87
|
+
rc_client_external_get_int_func_t get_hardcore_enabled;
|
|
88
|
+
rc_client_external_set_int_func_t set_unofficial_enabled;
|
|
89
|
+
rc_client_external_get_int_func_t get_unofficial_enabled;
|
|
90
|
+
rc_client_external_set_int_func_t set_encore_mode_enabled;
|
|
91
|
+
rc_client_external_get_int_func_t get_encore_mode_enabled;
|
|
92
|
+
rc_client_external_set_int_func_t set_spectator_mode_enabled;
|
|
93
|
+
rc_client_external_get_int_func_t get_spectator_mode_enabled;
|
|
94
|
+
|
|
95
|
+
rc_client_external_async_handle_func_t abort_async;
|
|
96
|
+
|
|
97
|
+
rc_client_external_begin_login_func_t begin_login_with_password;
|
|
98
|
+
rc_client_external_begin_login_func_t begin_login_with_token;
|
|
99
|
+
rc_client_external_action_func_t logout;
|
|
100
|
+
rc_client_external_get_user_info_func_t get_user_info;
|
|
101
|
+
|
|
102
|
+
rc_client_external_begin_identify_and_load_game_func_t begin_identify_and_load_game;
|
|
103
|
+
rc_client_external_begin_load_game_func_t begin_load_game;
|
|
104
|
+
rc_client_external_get_game_info_func_t get_game_info;
|
|
105
|
+
rc_client_external_begin_load_subset_t begin_load_subset; /* DEPRECATED */
|
|
106
|
+
rc_client_external_get_subset_info_func_t get_subset_info;
|
|
107
|
+
rc_client_external_action_func_t unload_game;
|
|
108
|
+
rc_client_external_get_user_game_summary_func_t get_user_game_summary;
|
|
109
|
+
rc_client_external_begin_change_media_func_t begin_identify_and_change_media;
|
|
110
|
+
rc_client_external_begin_load_game_func_t begin_change_media;
|
|
111
|
+
|
|
112
|
+
rc_client_external_create_achievement_list_func_t create_achievement_list;
|
|
113
|
+
rc_client_external_get_int_func_t has_achievements;
|
|
114
|
+
rc_client_external_get_achievement_info_func_t get_achievement_info;
|
|
115
|
+
|
|
116
|
+
rc_client_external_create_leaderboard_list_func_t create_leaderboard_list;
|
|
117
|
+
rc_client_external_get_int_func_t has_leaderboards;
|
|
118
|
+
rc_client_external_get_leaderboard_info_func_t get_leaderboard_info;
|
|
119
|
+
rc_client_external_begin_fetch_leaderboard_entries_func_t begin_fetch_leaderboard_entries;
|
|
120
|
+
rc_client_external_begin_fetch_leaderboard_entries_around_user_func_t begin_fetch_leaderboard_entries_around_user;
|
|
121
|
+
|
|
122
|
+
rc_client_external_copy_string_func_t get_rich_presence_message;
|
|
123
|
+
rc_client_external_get_int_func_t has_rich_presence;
|
|
124
|
+
|
|
125
|
+
rc_client_external_action_func_t do_frame;
|
|
126
|
+
rc_client_external_action_func_t idle;
|
|
127
|
+
rc_client_external_get_int_func_t is_processing_required;
|
|
128
|
+
rc_client_external_can_pause_func_t can_pause;
|
|
129
|
+
rc_client_external_action_func_t reset;
|
|
130
|
+
|
|
131
|
+
rc_client_external_progress_size_func_t progress_size;
|
|
132
|
+
rc_client_external_serialize_progress_func_t serialize_progress;
|
|
133
|
+
rc_client_external_deserialize_progress_func_t deserialize_progress;
|
|
134
|
+
|
|
135
|
+
/* VERSION 2 */
|
|
136
|
+
rc_client_external_add_game_hash_func_t add_game_hash;
|
|
137
|
+
rc_client_external_set_string_func_t load_unknown_game;
|
|
138
|
+
|
|
139
|
+
/* VERSION 3 */
|
|
140
|
+
rc_client_external_get_user_info_func_t get_user_info_v3;
|
|
141
|
+
rc_client_external_get_game_info_func_t get_game_info_v3;
|
|
142
|
+
rc_client_external_get_subset_info_func_t get_subset_info_v3;
|
|
143
|
+
rc_client_external_get_achievement_info_func_t get_achievement_info_v3;
|
|
144
|
+
rc_client_external_create_achievement_list_func_t create_achievement_list_v3;
|
|
145
|
+
|
|
146
|
+
/* VERSION 4 */
|
|
147
|
+
rc_client_external_set_int_func_t set_allow_background_memory_reads;
|
|
148
|
+
|
|
149
|
+
/* VERSION 5 */
|
|
150
|
+
rc_client_external_get_user_game_summary_func_t get_user_game_summary_v5;
|
|
151
|
+
rc_client_external_get_user_subset_summary_func_t get_user_subset_summary;
|
|
152
|
+
|
|
153
|
+
/* VERSION 6 */
|
|
154
|
+
rc_client_external_create_subset_list_func_t create_subset_list;
|
|
155
|
+
|
|
156
|
+
/* VERSION 7 */
|
|
157
|
+
rc_client_external_get_next_achievement_info_func_t get_next_achievement_info;
|
|
158
|
+
|
|
159
|
+
} rc_client_external_t;
|
|
160
|
+
|
|
161
|
+
#define RC_CLIENT_EXTERNAL_VERSION 7
|
|
162
|
+
|
|
163
|
+
void rc_client_add_game_hash(rc_client_t* client, const char* hash, uint32_t game_id);
|
|
164
|
+
void rc_client_load_unknown_game(rc_client_t* client, const char* hash);
|
|
165
|
+
|
|
166
|
+
/* conversion support */
|
|
167
|
+
|
|
168
|
+
struct rc_client_external_conversions_t;
|
|
169
|
+
const rc_client_user_t* rc_client_external_convert_v1_user(const rc_client_t* client, const rc_client_user_t* v1_user);
|
|
170
|
+
const rc_client_game_t* rc_client_external_convert_v1_game(const rc_client_t* client, const rc_client_game_t* v1_game);
|
|
171
|
+
const rc_client_subset_t* rc_client_external_convert_v1_subset(const rc_client_t* client, const rc_client_subset_t* v1_subset);
|
|
172
|
+
const rc_client_achievement_t* rc_client_external_convert_v1_achievement(const rc_client_t* client, const rc_client_achievement_t* v1_achievement);
|
|
173
|
+
rc_client_achievement_list_t* rc_client_external_convert_v1_achievement_list(const rc_client_t* client, rc_client_achievement_list_t* v1_achievement_list);
|
|
174
|
+
|
|
175
|
+
RC_END_C_DECLS
|
|
176
|
+
|
|
177
|
+
#endif /* RC_CLIENT_EXTERNAL_H */
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
#ifndef RC_CLIENT_EXTERNAL_CONVERSIONS_H
|
|
2
|
+
#define RC_CLIENT_EXTERNAL_CONVERSIONS_H
|
|
3
|
+
|
|
4
|
+
#include "rc_client_internal.h"
|
|
5
|
+
|
|
6
|
+
RC_BEGIN_C_DECLS
|
|
7
|
+
|
|
8
|
+
/* user */
|
|
9
|
+
|
|
10
|
+
typedef struct v1_rc_client_user_t {
|
|
11
|
+
const char* display_name;
|
|
12
|
+
const char* username;
|
|
13
|
+
const char* token;
|
|
14
|
+
uint32_t score;
|
|
15
|
+
uint32_t score_softcore;
|
|
16
|
+
uint32_t num_unread_messages;
|
|
17
|
+
} v1_rc_client_user_t;
|
|
18
|
+
|
|
19
|
+
typedef struct v3_rc_client_user_t {
|
|
20
|
+
const char* display_name;
|
|
21
|
+
const char* username;
|
|
22
|
+
const char* token;
|
|
23
|
+
uint32_t score;
|
|
24
|
+
uint32_t score_softcore;
|
|
25
|
+
uint32_t num_unread_messages;
|
|
26
|
+
const char* avatar_url;
|
|
27
|
+
} v3_rc_client_user_t;
|
|
28
|
+
|
|
29
|
+
/* game */
|
|
30
|
+
|
|
31
|
+
typedef struct v1_rc_client_game_t {
|
|
32
|
+
uint32_t id;
|
|
33
|
+
uint32_t console_id;
|
|
34
|
+
const char* title;
|
|
35
|
+
const char* hash;
|
|
36
|
+
const char* badge_name;
|
|
37
|
+
} v1_rc_client_game_t;
|
|
38
|
+
|
|
39
|
+
typedef struct v3_rc_client_game_t {
|
|
40
|
+
uint32_t id;
|
|
41
|
+
uint32_t console_id;
|
|
42
|
+
const char* title;
|
|
43
|
+
const char* hash;
|
|
44
|
+
const char* badge_name;
|
|
45
|
+
const char* badge_url;
|
|
46
|
+
} v3_rc_client_game_t;
|
|
47
|
+
|
|
48
|
+
/* subset */
|
|
49
|
+
|
|
50
|
+
typedef struct v1_rc_client_subset_t {
|
|
51
|
+
uint32_t id;
|
|
52
|
+
const char* title;
|
|
53
|
+
char badge_name[16];
|
|
54
|
+
uint32_t num_achievements;
|
|
55
|
+
uint32_t num_leaderboards;
|
|
56
|
+
} v1_rc_client_subset_t;
|
|
57
|
+
|
|
58
|
+
typedef struct v3_rc_client_subset_t {
|
|
59
|
+
uint32_t id;
|
|
60
|
+
const char* title;
|
|
61
|
+
char badge_name[16];
|
|
62
|
+
uint32_t num_achievements;
|
|
63
|
+
uint32_t num_leaderboards;
|
|
64
|
+
const char* badge_url;
|
|
65
|
+
} v3_rc_client_subset_t;
|
|
66
|
+
|
|
67
|
+
/* achievement */
|
|
68
|
+
|
|
69
|
+
typedef struct v1_rc_client_achievement_t {
|
|
70
|
+
const char* title;
|
|
71
|
+
const char* description;
|
|
72
|
+
char badge_name[8];
|
|
73
|
+
char measured_progress[24];
|
|
74
|
+
float measured_percent;
|
|
75
|
+
uint32_t id;
|
|
76
|
+
uint32_t points;
|
|
77
|
+
time_t unlock_time;
|
|
78
|
+
uint8_t state;
|
|
79
|
+
uint8_t category;
|
|
80
|
+
uint8_t bucket;
|
|
81
|
+
uint8_t unlocked;
|
|
82
|
+
float rarity;
|
|
83
|
+
float rarity_hardcore;
|
|
84
|
+
uint8_t type;
|
|
85
|
+
} v1_rc_client_achievement_t;
|
|
86
|
+
|
|
87
|
+
typedef struct v3_rc_client_achievement_t {
|
|
88
|
+
const char* title;
|
|
89
|
+
const char* description;
|
|
90
|
+
char badge_name[8];
|
|
91
|
+
char measured_progress[24];
|
|
92
|
+
float measured_percent;
|
|
93
|
+
uint32_t id;
|
|
94
|
+
uint32_t points;
|
|
95
|
+
time_t unlock_time;
|
|
96
|
+
uint8_t state;
|
|
97
|
+
uint8_t category;
|
|
98
|
+
uint8_t bucket;
|
|
99
|
+
uint8_t unlocked;
|
|
100
|
+
float rarity;
|
|
101
|
+
float rarity_hardcore;
|
|
102
|
+
uint8_t type;
|
|
103
|
+
const char* badge_url;
|
|
104
|
+
const char* badge_locked_url;
|
|
105
|
+
} v3_rc_client_achievement_t;
|
|
106
|
+
|
|
107
|
+
/* achievement list */
|
|
108
|
+
|
|
109
|
+
typedef struct v1_rc_client_achievement_bucket_t {
|
|
110
|
+
v1_rc_client_achievement_t** achievements;
|
|
111
|
+
uint32_t num_achievements;
|
|
112
|
+
|
|
113
|
+
const char* label;
|
|
114
|
+
uint32_t subset_id;
|
|
115
|
+
uint8_t bucket_type;
|
|
116
|
+
} v1_rc_client_achievement_bucket_t;
|
|
117
|
+
|
|
118
|
+
typedef struct v1_rc_client_achievement_list_t {
|
|
119
|
+
v1_rc_client_achievement_bucket_t* buckets;
|
|
120
|
+
uint32_t num_buckets;
|
|
121
|
+
} v1_rc_client_achievement_list_t;
|
|
122
|
+
|
|
123
|
+
typedef struct v1_rc_client_achievement_list_info_t {
|
|
124
|
+
v1_rc_client_achievement_list_t public_;
|
|
125
|
+
rc_client_destroy_achievement_list_func_t destroy_func;
|
|
126
|
+
} v1_rc_client_achievement_list_info_t;
|
|
127
|
+
|
|
128
|
+
typedef struct v3_rc_client_achievement_bucket_t {
|
|
129
|
+
const v3_rc_client_achievement_t** achievements;
|
|
130
|
+
uint32_t num_achievements;
|
|
131
|
+
|
|
132
|
+
const char* label;
|
|
133
|
+
uint32_t subset_id;
|
|
134
|
+
uint8_t bucket_type;
|
|
135
|
+
} v3_rc_client_achievement_bucket_t;
|
|
136
|
+
|
|
137
|
+
typedef struct v3_rc_client_achievement_list_t {
|
|
138
|
+
const v3_rc_client_achievement_bucket_t* buckets;
|
|
139
|
+
uint32_t num_buckets;
|
|
140
|
+
} v3_rc_client_achievement_list_t;
|
|
141
|
+
|
|
142
|
+
typedef struct v3_rc_client_achievement_list_info_t {
|
|
143
|
+
v3_rc_client_achievement_list_t public_;
|
|
144
|
+
rc_client_destroy_achievement_list_func_t destroy_func;
|
|
145
|
+
} v3_rc_client_achievement_list_info_t;
|
|
146
|
+
|
|
147
|
+
/* user_game_summary */
|
|
148
|
+
|
|
149
|
+
typedef struct v1_rc_client_user_game_summary_t {
|
|
150
|
+
uint32_t num_core_achievements;
|
|
151
|
+
uint32_t num_unofficial_achievements;
|
|
152
|
+
uint32_t num_unlocked_achievements;
|
|
153
|
+
uint32_t num_unsupported_achievements;
|
|
154
|
+
uint32_t points_core;
|
|
155
|
+
uint32_t points_unlocked;
|
|
156
|
+
} v1_rc_client_user_game_summary_t;
|
|
157
|
+
|
|
158
|
+
typedef struct v5_rc_client_user_game_summary_t {
|
|
159
|
+
uint32_t num_core_achievements;
|
|
160
|
+
uint32_t num_unofficial_achievements;
|
|
161
|
+
uint32_t num_unlocked_achievements;
|
|
162
|
+
uint32_t num_unsupported_achievements;
|
|
163
|
+
uint32_t points_core;
|
|
164
|
+
uint32_t points_unlocked;
|
|
165
|
+
time_t beaten_time;
|
|
166
|
+
time_t completed_time;
|
|
167
|
+
} v5_rc_client_user_game_summary_t;
|
|
168
|
+
|
|
169
|
+
RC_END_C_DECLS
|
|
170
|
+
|
|
171
|
+
#endif /* RC_CLIENT_EXTERNAL_CONVERSIONS_H */
|