gemba 0.1.0 → 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 +24 -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 +135 -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 -1515
|
@@ -0,0 +1,1667 @@
|
|
|
1
|
+
#include "rc_runtime.h"
|
|
2
|
+
#include "rc_internal.h"
|
|
3
|
+
|
|
4
|
+
#include "mock_memory.h"
|
|
5
|
+
|
|
6
|
+
#include "../test_framework.h"
|
|
7
|
+
|
|
8
|
+
static rc_runtime_event_t events[16];
|
|
9
|
+
static int event_count = 0;
|
|
10
|
+
|
|
11
|
+
static void event_handler(const rc_runtime_event_t* e)
|
|
12
|
+
{
|
|
13
|
+
memcpy(&events[event_count++], e, sizeof(rc_runtime_event_t));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
static void _assert_event(uint8_t type, uint32_t id, int32_t value)
|
|
17
|
+
{
|
|
18
|
+
int i;
|
|
19
|
+
|
|
20
|
+
for (i = 0; i < event_count; ++i) {
|
|
21
|
+
if (events[i].id == id && events[i].type == type && events[i].value == value)
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
ASSERT_FAIL("expected event not found");
|
|
26
|
+
}
|
|
27
|
+
#define assert_event(type, id, value) ASSERT_HELPER(_assert_event(type, id, value), "assert_event")
|
|
28
|
+
|
|
29
|
+
static void _assert_activate_achievement(rc_runtime_t* runtime, uint32_t id, const char* memaddr)
|
|
30
|
+
{
|
|
31
|
+
int result = rc_runtime_activate_achievement(runtime, id, memaddr, NULL, 0);
|
|
32
|
+
ASSERT_NUM_EQUALS(result, RC_OK);
|
|
33
|
+
}
|
|
34
|
+
#define assert_activate_achievement(runtime, id, memaddr) ASSERT_HELPER(_assert_activate_achievement(runtime, id, memaddr), "assert_activate_achievement")
|
|
35
|
+
|
|
36
|
+
static void _assert_activate_lboard(rc_runtime_t* runtime, uint32_t id, const char* memaddr)
|
|
37
|
+
{
|
|
38
|
+
int result = rc_runtime_activate_lboard(runtime, id, memaddr, NULL, 0);
|
|
39
|
+
ASSERT_NUM_EQUALS(result, RC_OK);
|
|
40
|
+
}
|
|
41
|
+
#define assert_activate_lboard(runtime, id, memaddr) ASSERT_HELPER(_assert_activate_lboard(runtime, id, memaddr), "assert_activate_lboard")
|
|
42
|
+
|
|
43
|
+
static void _assert_activate_richpresence(rc_runtime_t* runtime, const char* script)
|
|
44
|
+
{
|
|
45
|
+
int result = rc_runtime_activate_richpresence(runtime, script, NULL, 0);
|
|
46
|
+
ASSERT_NUM_EQUALS(result, RC_OK);
|
|
47
|
+
}
|
|
48
|
+
#define assert_activate_richpresence(runtime, script) ASSERT_HELPER(_assert_activate_richpresence(runtime, script), "assert_activate_richpresence")
|
|
49
|
+
|
|
50
|
+
static void assert_do_frame(rc_runtime_t* runtime, memory_t* memory)
|
|
51
|
+
{
|
|
52
|
+
event_count = 0;
|
|
53
|
+
rc_runtime_do_frame(runtime, event_handler, peek, memory, NULL);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
static void _assert_richpresence_display_string(rc_runtime_t* runtime, memory_t* memory, const char* expected)
|
|
57
|
+
{
|
|
58
|
+
char buffer[512];
|
|
59
|
+
const int expected_len = (int)strlen(expected);
|
|
60
|
+
const int result = rc_runtime_get_richpresence(runtime, buffer, sizeof(buffer), peek, memory, NULL);
|
|
61
|
+
ASSERT_STR_EQUALS(buffer, expected);
|
|
62
|
+
ASSERT_NUM_EQUALS(result, expected_len);
|
|
63
|
+
}
|
|
64
|
+
#define assert_richpresence_display_string(runtime, memory, expected) ASSERT_HELPER(_assert_richpresence_display_string(runtime, memory, expected), "assert_richpresence_display_string")
|
|
65
|
+
|
|
66
|
+
static void test_two_achievements_activate_and_trigger(void)
|
|
67
|
+
{
|
|
68
|
+
uint8_t ram[] = { 0, 10, 10 };
|
|
69
|
+
memory_t memory;
|
|
70
|
+
rc_runtime_t runtime;
|
|
71
|
+
|
|
72
|
+
memory.ram = ram;
|
|
73
|
+
memory.size = sizeof(ram);
|
|
74
|
+
|
|
75
|
+
rc_runtime_init(&runtime);
|
|
76
|
+
|
|
77
|
+
assert_activate_achievement(&runtime, 1, "0xH0001=10");
|
|
78
|
+
assert_activate_achievement(&runtime, 2, "0xH0002=10");
|
|
79
|
+
|
|
80
|
+
/* both achievements are true, should remain in waiting state */
|
|
81
|
+
assert_do_frame(&runtime, &memory);
|
|
82
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
83
|
+
ASSERT_NUM_EQUALS(runtime.triggers[1].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
84
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
85
|
+
|
|
86
|
+
/* both achievements are false, should activate */
|
|
87
|
+
ram[1] = ram[2] = 9;
|
|
88
|
+
assert_do_frame(&runtime, &memory);
|
|
89
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_ACTIVE);
|
|
90
|
+
ASSERT_NUM_EQUALS(runtime.triggers[1].trigger->state, RC_TRIGGER_STATE_ACTIVE);
|
|
91
|
+
ASSERT_NUM_EQUALS(event_count, 2);
|
|
92
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_ACTIVATED, 1, 0);
|
|
93
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_ACTIVATED, 2, 0);
|
|
94
|
+
|
|
95
|
+
/* second achievement is true, should trigger */
|
|
96
|
+
ram[2] = 10;
|
|
97
|
+
assert_do_frame(&runtime, &memory);
|
|
98
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_ACTIVE);
|
|
99
|
+
ASSERT_NUM_EQUALS(runtime.triggers[1].trigger->state, RC_TRIGGER_STATE_TRIGGERED);
|
|
100
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
101
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED, 2, 0);
|
|
102
|
+
|
|
103
|
+
/* first achievement is true, should trigger. second is already triggered */
|
|
104
|
+
ram[1] = 10;
|
|
105
|
+
assert_do_frame(&runtime, &memory);
|
|
106
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_TRIGGERED);
|
|
107
|
+
ASSERT_NUM_EQUALS(runtime.triggers[1].trigger->state, RC_TRIGGER_STATE_TRIGGERED);
|
|
108
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
109
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED, 1, 0);
|
|
110
|
+
|
|
111
|
+
/* reset second achievement, should go back to WAITING and stay there */
|
|
112
|
+
rc_reset_trigger(runtime.triggers[1].trigger);
|
|
113
|
+
assert_do_frame(&runtime, &memory);
|
|
114
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_TRIGGERED);
|
|
115
|
+
ASSERT_NUM_EQUALS(runtime.triggers[1].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
116
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
117
|
+
|
|
118
|
+
/* both achievements are false again. second should active, first should be ignored */
|
|
119
|
+
ram[1] = ram[2] = 9;
|
|
120
|
+
assert_do_frame(&runtime, &memory);
|
|
121
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_TRIGGERED);
|
|
122
|
+
ASSERT_NUM_EQUALS(runtime.triggers[1].trigger->state, RC_TRIGGER_STATE_ACTIVE);
|
|
123
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
124
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_ACTIVATED, 2, 0);
|
|
125
|
+
|
|
126
|
+
rc_runtime_destroy(&runtime);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
static void test_deactivate_achievements(void)
|
|
130
|
+
{
|
|
131
|
+
uint8_t ram[] = { 0, 10, 10 };
|
|
132
|
+
memory_t memory;
|
|
133
|
+
rc_runtime_t runtime;
|
|
134
|
+
|
|
135
|
+
memory.ram = ram;
|
|
136
|
+
memory.size = sizeof(ram);
|
|
137
|
+
|
|
138
|
+
rc_runtime_init(&runtime);
|
|
139
|
+
|
|
140
|
+
assert_activate_achievement(&runtime, 1, "0xH0001=10");
|
|
141
|
+
assert_activate_achievement(&runtime, 2, "0xH0002=10");
|
|
142
|
+
|
|
143
|
+
/* both achievements are true, should remain in waiting state */
|
|
144
|
+
assert_do_frame(&runtime, &memory);
|
|
145
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
146
|
+
ASSERT_NUM_EQUALS(runtime.triggers[1].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
147
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
148
|
+
|
|
149
|
+
/* deactivate the first. */
|
|
150
|
+
rc_runtime_deactivate_achievement(&runtime, 1);
|
|
151
|
+
ASSERT_NUM_EQUALS(runtime.trigger_count, 1);
|
|
152
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
153
|
+
|
|
154
|
+
/* both achievements are false, deactivated one should not activate */
|
|
155
|
+
ram[1] = ram[2] = 9;
|
|
156
|
+
assert_do_frame(&runtime, &memory);
|
|
157
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
158
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_ACTIVATED, 2, 0);
|
|
159
|
+
|
|
160
|
+
/* both achievements are true, deactivated one should not trigger */
|
|
161
|
+
ram[1] = ram[2] = 10;
|
|
162
|
+
assert_do_frame(&runtime, &memory);
|
|
163
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
164
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED, 2, 0);
|
|
165
|
+
|
|
166
|
+
/* reactivate achievement. */
|
|
167
|
+
assert_activate_achievement(&runtime, 1, "0xH0001=10");
|
|
168
|
+
ASSERT_NUM_EQUALS(runtime.trigger_count, 2);
|
|
169
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_TRIGGERED);
|
|
170
|
+
ASSERT_NUM_EQUALS(runtime.triggers[1].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
171
|
+
|
|
172
|
+
/* reactivated achievement is waiting and should not trigger */
|
|
173
|
+
assert_do_frame(&runtime, &memory);
|
|
174
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_TRIGGERED);
|
|
175
|
+
ASSERT_NUM_EQUALS(runtime.triggers[1].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
176
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
177
|
+
|
|
178
|
+
/* both achievements are false. first should activate, second should be ignored */
|
|
179
|
+
ram[1] = ram[2] = 9;
|
|
180
|
+
assert_do_frame(&runtime, &memory);
|
|
181
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_TRIGGERED);
|
|
182
|
+
ASSERT_NUM_EQUALS(runtime.triggers[1].trigger->state, RC_TRIGGER_STATE_ACTIVE);
|
|
183
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
184
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_ACTIVATED, 1, 0);
|
|
185
|
+
|
|
186
|
+
rc_runtime_destroy(&runtime);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
static void test_achievement_measured(void)
|
|
190
|
+
{
|
|
191
|
+
/* bytes 3-7 are the float value for 16*pi */
|
|
192
|
+
uint8_t ram[] = { 0, 10, 10, 0xDB, 0x0F, 0x49, 0x41 };
|
|
193
|
+
char buffer[32];
|
|
194
|
+
memory_t memory;
|
|
195
|
+
rc_runtime_t runtime;
|
|
196
|
+
uint32_t value, target;
|
|
197
|
+
|
|
198
|
+
memory.ram = ram;
|
|
199
|
+
memory.size = sizeof(ram);
|
|
200
|
+
|
|
201
|
+
rc_runtime_init(&runtime);
|
|
202
|
+
|
|
203
|
+
/* use equality so we can test values greater than the target */
|
|
204
|
+
assert_activate_achievement(&runtime, 1, "0xH0002==10");
|
|
205
|
+
assert_activate_achievement(&runtime, 2, "M:0xH0002==10");
|
|
206
|
+
assert_activate_achievement(&runtime, 3, "G:0xH0002==10");
|
|
207
|
+
assert_activate_achievement(&runtime, 4, "M:fF0003==f12.56637");
|
|
208
|
+
|
|
209
|
+
/* achievements are true, should remain in waiting state with no measured value */
|
|
210
|
+
assert_do_frame(&runtime, &memory);
|
|
211
|
+
ASSERT_TRUE(rc_runtime_get_achievement_measured(&runtime, 1, &value, &target));
|
|
212
|
+
ASSERT_NUM_EQUALS(value, 0);
|
|
213
|
+
ASSERT_NUM_EQUALS(target, 0);
|
|
214
|
+
ASSERT_FALSE(rc_runtime_format_achievement_measured(&runtime, 1, buffer, sizeof(buffer)));
|
|
215
|
+
ASSERT_STR_EQUALS(buffer, "");
|
|
216
|
+
ASSERT_TRUE(rc_runtime_get_achievement_measured(&runtime, 2, &value, &target));
|
|
217
|
+
ASSERT_NUM_EQUALS(value, 0);
|
|
218
|
+
ASSERT_NUM_EQUALS(target, 10);
|
|
219
|
+
ASSERT_TRUE(rc_runtime_format_achievement_measured(&runtime, 2, buffer, sizeof(buffer)));
|
|
220
|
+
ASSERT_STR_EQUALS(buffer, "0/10");
|
|
221
|
+
ASSERT_TRUE(rc_runtime_get_achievement_measured(&runtime, 3, &value, &target));
|
|
222
|
+
ASSERT_NUM_EQUALS(value, 0);
|
|
223
|
+
ASSERT_NUM_EQUALS(target, 10);
|
|
224
|
+
ASSERT_TRUE(rc_runtime_format_achievement_measured(&runtime, 3, buffer, sizeof(buffer)));
|
|
225
|
+
ASSERT_STR_EQUALS(buffer, "0%");
|
|
226
|
+
ASSERT_TRUE(rc_runtime_get_achievement_measured(&runtime, 4, &value, &target));
|
|
227
|
+
ASSERT_NUM_EQUALS(value, 0);
|
|
228
|
+
ASSERT_NUM_EQUALS(target, 12);
|
|
229
|
+
ASSERT_TRUE(rc_runtime_format_achievement_measured(&runtime, 4, buffer, sizeof(buffer)));
|
|
230
|
+
ASSERT_STR_EQUALS(buffer, "0/12");
|
|
231
|
+
ASSERT_FALSE(rc_runtime_get_achievement_measured(&runtime, 5, &value, &target));
|
|
232
|
+
ASSERT_FALSE(rc_runtime_format_achievement_measured(&runtime, 5, buffer, sizeof(buffer)));
|
|
233
|
+
ASSERT_STR_EQUALS(buffer, "");
|
|
234
|
+
|
|
235
|
+
/* achievements are false, should activate */
|
|
236
|
+
ram[2] = 9;
|
|
237
|
+
ram[6] = 0x40;
|
|
238
|
+
assert_do_frame(&runtime, &memory);
|
|
239
|
+
ASSERT_TRUE(rc_runtime_get_achievement_measured(&runtime, 1, &value, &target));
|
|
240
|
+
ASSERT_NUM_EQUALS(value, 0);
|
|
241
|
+
ASSERT_NUM_EQUALS(target, 0);
|
|
242
|
+
ASSERT_FALSE(rc_runtime_format_achievement_measured(&runtime, 1, buffer, sizeof(buffer)));
|
|
243
|
+
ASSERT_STR_EQUALS(buffer, "");
|
|
244
|
+
ASSERT_TRUE(rc_runtime_get_achievement_measured(&runtime, 2, &value, &target));
|
|
245
|
+
ASSERT_NUM_EQUALS(value, 9);
|
|
246
|
+
ASSERT_NUM_EQUALS(target, 10);
|
|
247
|
+
ASSERT_TRUE(rc_runtime_format_achievement_measured(&runtime, 2, buffer, sizeof(buffer)));
|
|
248
|
+
ASSERT_STR_EQUALS(buffer, "9/10");
|
|
249
|
+
ASSERT_TRUE(rc_runtime_get_achievement_measured(&runtime, 3, &value, &target));
|
|
250
|
+
ASSERT_NUM_EQUALS(value, 9);
|
|
251
|
+
ASSERT_NUM_EQUALS(target, 10);
|
|
252
|
+
ASSERT_TRUE(rc_runtime_format_achievement_measured(&runtime, 3, buffer, sizeof(buffer)));
|
|
253
|
+
ASSERT_STR_EQUALS(buffer, "90%");
|
|
254
|
+
ASSERT_TRUE(rc_runtime_get_achievement_measured(&runtime, 4, &value, &target));
|
|
255
|
+
ASSERT_NUM_EQUALS(value, 3);
|
|
256
|
+
ASSERT_NUM_EQUALS(target, 12);
|
|
257
|
+
ASSERT_TRUE(rc_runtime_format_achievement_measured(&runtime, 4, buffer, sizeof(buffer)));
|
|
258
|
+
ASSERT_STR_EQUALS(buffer, "3/12"); /* captured measured value and target are integers, so 3.14/12.56 -> 3/12 */
|
|
259
|
+
|
|
260
|
+
/* value greater than target (i.e. "6 >= 5" should report maximum "5/5" or "100%" */
|
|
261
|
+
ram[2] = 12;
|
|
262
|
+
ram[6] = 0x42;
|
|
263
|
+
assert_do_frame(&runtime, &memory);
|
|
264
|
+
ASSERT_TRUE(rc_runtime_get_achievement_measured(&runtime, 1, &value, &target));
|
|
265
|
+
ASSERT_NUM_EQUALS(value, 0);
|
|
266
|
+
ASSERT_NUM_EQUALS(target, 0);
|
|
267
|
+
ASSERT_FALSE(rc_runtime_format_achievement_measured(&runtime, 1, buffer, sizeof(buffer)));
|
|
268
|
+
ASSERT_STR_EQUALS(buffer, "");
|
|
269
|
+
ASSERT_TRUE(rc_runtime_get_achievement_measured(&runtime, 2, &value, &target));
|
|
270
|
+
ASSERT_NUM_EQUALS(value, 12);
|
|
271
|
+
ASSERT_NUM_EQUALS(target, 10);
|
|
272
|
+
ASSERT_TRUE(rc_runtime_format_achievement_measured(&runtime, 2, buffer, sizeof(buffer)));
|
|
273
|
+
ASSERT_STR_EQUALS(buffer, "10/10");
|
|
274
|
+
ASSERT_TRUE(rc_runtime_get_achievement_measured(&runtime, 3, &value, &target));
|
|
275
|
+
ASSERT_NUM_EQUALS(value, 12);
|
|
276
|
+
ASSERT_NUM_EQUALS(target, 10);
|
|
277
|
+
ASSERT_TRUE(rc_runtime_format_achievement_measured(&runtime, 3, buffer, sizeof(buffer)));
|
|
278
|
+
ASSERT_STR_EQUALS(buffer, "100%");
|
|
279
|
+
ASSERT_TRUE(rc_runtime_get_achievement_measured(&runtime, 4, &value, &target));
|
|
280
|
+
ASSERT_NUM_EQUALS(value, 50);
|
|
281
|
+
ASSERT_NUM_EQUALS(target, 12);
|
|
282
|
+
ASSERT_TRUE(rc_runtime_format_achievement_measured(&runtime, 4, buffer, sizeof(buffer)));
|
|
283
|
+
ASSERT_STR_EQUALS(buffer, "12/12");
|
|
284
|
+
|
|
285
|
+
/* achievements are true, should trigger - triggered achievement is not measurable */
|
|
286
|
+
ram[2] = 10;
|
|
287
|
+
ram[6] = 0x41;
|
|
288
|
+
assert_do_frame(&runtime, &memory);
|
|
289
|
+
ASSERT_TRUE(rc_runtime_get_achievement_measured(&runtime, 1, &value, &target));
|
|
290
|
+
ASSERT_NUM_EQUALS(value, 0);
|
|
291
|
+
ASSERT_NUM_EQUALS(target, 0);
|
|
292
|
+
ASSERT_FALSE(rc_runtime_format_achievement_measured(&runtime, 1, buffer, sizeof(buffer)));
|
|
293
|
+
ASSERT_STR_EQUALS(buffer, "");
|
|
294
|
+
ASSERT_TRUE(rc_runtime_get_achievement_measured(&runtime, 2, &value, &target));
|
|
295
|
+
ASSERT_NUM_EQUALS(value, 0);
|
|
296
|
+
ASSERT_NUM_EQUALS(target, 0);
|
|
297
|
+
ASSERT_FALSE(rc_runtime_format_achievement_measured(&runtime, 2, buffer, sizeof(buffer)));
|
|
298
|
+
ASSERT_STR_EQUALS(buffer, "");
|
|
299
|
+
ASSERT_TRUE(rc_runtime_get_achievement_measured(&runtime, 3, &value, &target));
|
|
300
|
+
ASSERT_NUM_EQUALS(value, 0);
|
|
301
|
+
ASSERT_NUM_EQUALS(target, 0);
|
|
302
|
+
ASSERT_FALSE(rc_runtime_format_achievement_measured(&runtime, 3, buffer, sizeof(buffer)));
|
|
303
|
+
ASSERT_STR_EQUALS(buffer, "");
|
|
304
|
+
ASSERT_TRUE(rc_runtime_get_achievement_measured(&runtime, 4, &value, &target));
|
|
305
|
+
ASSERT_NUM_EQUALS(value, 0);
|
|
306
|
+
ASSERT_NUM_EQUALS(target, 0);
|
|
307
|
+
ASSERT_FALSE(rc_runtime_format_achievement_measured(&runtime, 4, buffer, sizeof(buffer)));
|
|
308
|
+
ASSERT_STR_EQUALS(buffer, "");
|
|
309
|
+
|
|
310
|
+
rc_runtime_destroy(&runtime);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
static void test_achievement_measured_maxint(void)
|
|
314
|
+
{
|
|
315
|
+
uint8_t ram[] = { 0xFF, 0xFF, 0xFF, 0xFF };
|
|
316
|
+
char buffer[32];
|
|
317
|
+
memory_t memory;
|
|
318
|
+
rc_runtime_t runtime;
|
|
319
|
+
uint32_t value, target;
|
|
320
|
+
|
|
321
|
+
memory.ram = ram;
|
|
322
|
+
memory.size = sizeof(ram);
|
|
323
|
+
|
|
324
|
+
rc_runtime_init(&runtime);
|
|
325
|
+
|
|
326
|
+
assert_activate_achievement(&runtime, 2, "M:0xX0000==hFFFFFFFF");
|
|
327
|
+
assert_activate_achievement(&runtime, 3, "G:0xX0000==hFFFFFFFF");
|
|
328
|
+
|
|
329
|
+
/* achievements are true, should remain in waiting state */
|
|
330
|
+
assert_do_frame(&runtime, &memory);
|
|
331
|
+
ASSERT_TRUE(rc_runtime_get_achievement_measured(&runtime, 2, &value, &target));
|
|
332
|
+
ASSERT_NUM_EQUALS(value, 0);
|
|
333
|
+
ASSERT_NUM_EQUALS(target, 0xFFFFFFFF);
|
|
334
|
+
ASSERT_TRUE(rc_runtime_format_achievement_measured(&runtime, 2, buffer, sizeof(buffer)));
|
|
335
|
+
ASSERT_STR_EQUALS(buffer, "0/4294967295");
|
|
336
|
+
ASSERT_TRUE(rc_runtime_get_achievement_measured(&runtime, 3, &value, &target));
|
|
337
|
+
ASSERT_NUM_EQUALS(value, 0);
|
|
338
|
+
ASSERT_NUM_EQUALS(target, 0xFFFFFFFF);
|
|
339
|
+
ASSERT_TRUE(rc_runtime_format_achievement_measured(&runtime, 3, buffer, sizeof(buffer)));
|
|
340
|
+
ASSERT_STR_EQUALS(buffer, "0%");
|
|
341
|
+
|
|
342
|
+
/* achievements are false (value fits in 31-bits), should activate */
|
|
343
|
+
ram[1] = ram[3] = 0x7F;
|
|
344
|
+
assert_do_frame(&runtime, &memory);
|
|
345
|
+
ASSERT_TRUE(rc_runtime_get_achievement_measured(&runtime, 2, &value, &target));
|
|
346
|
+
ASSERT_NUM_EQUALS(value, 0x7FFF7FFF);
|
|
347
|
+
ASSERT_NUM_EQUALS(target, 0xFFFFFFFF);
|
|
348
|
+
ASSERT_TRUE(rc_runtime_format_achievement_measured(&runtime, 2, buffer, sizeof(buffer)));
|
|
349
|
+
ASSERT_STR_EQUALS(buffer, "2147450879/4294967295");
|
|
350
|
+
ASSERT_TRUE(rc_runtime_get_achievement_measured(&runtime, 3, &value, &target));
|
|
351
|
+
ASSERT_NUM_EQUALS(value, 0x7FFF7FFF);
|
|
352
|
+
ASSERT_NUM_EQUALS(target, 0xFFFFFFFF);
|
|
353
|
+
ASSERT_TRUE(rc_runtime_format_achievement_measured(&runtime, 3, buffer, sizeof(buffer)));
|
|
354
|
+
ASSERT_STR_EQUALS(buffer, "49%");
|
|
355
|
+
|
|
356
|
+
/* achievements are false (value requires 32-bits) */
|
|
357
|
+
ram[1] = ram[3] = 0xFE;
|
|
358
|
+
assert_do_frame(&runtime, &memory);
|
|
359
|
+
ASSERT_TRUE(rc_runtime_get_achievement_measured(&runtime, 2, &value, &target));
|
|
360
|
+
ASSERT_NUM_EQUALS(value, 0xFEFFFEFF);
|
|
361
|
+
ASSERT_NUM_EQUALS(target, 0xFFFFFFFF);
|
|
362
|
+
ASSERT_TRUE(rc_runtime_format_achievement_measured(&runtime, 2, buffer, sizeof(buffer)));
|
|
363
|
+
ASSERT_STR_EQUALS(buffer, "4278189823/4294967295");
|
|
364
|
+
ASSERT_TRUE(rc_runtime_get_achievement_measured(&runtime, 3, &value, &target));
|
|
365
|
+
ASSERT_NUM_EQUALS(value, 0xFEFFFEFF);
|
|
366
|
+
ASSERT_NUM_EQUALS(target, 0xFFFFFFFF);
|
|
367
|
+
ASSERT_TRUE(rc_runtime_format_achievement_measured(&runtime, 3, buffer, sizeof(buffer)));
|
|
368
|
+
ASSERT_STR_EQUALS(buffer, "99%");
|
|
369
|
+
|
|
370
|
+
/* achievements are true, should trigger - triggered achievement is not measurable */
|
|
371
|
+
ram[1] = ram[3] = 0xFF;
|
|
372
|
+
assert_do_frame(&runtime, &memory);
|
|
373
|
+
ASSERT_TRUE(rc_runtime_get_achievement_measured(&runtime, 2, &value, &target));
|
|
374
|
+
ASSERT_NUM_EQUALS(value, 0);
|
|
375
|
+
ASSERT_NUM_EQUALS(target, 0);
|
|
376
|
+
ASSERT_FALSE(rc_runtime_format_achievement_measured(&runtime, 2, buffer, sizeof(buffer)));
|
|
377
|
+
ASSERT_STR_EQUALS(buffer, "");
|
|
378
|
+
ASSERT_TRUE(rc_runtime_get_achievement_measured(&runtime, 3, &value, &target));
|
|
379
|
+
ASSERT_NUM_EQUALS(value, 0);
|
|
380
|
+
ASSERT_NUM_EQUALS(target, 0);
|
|
381
|
+
ASSERT_FALSE(rc_runtime_format_achievement_measured(&runtime, 3, buffer, sizeof(buffer)));
|
|
382
|
+
ASSERT_STR_EQUALS(buffer, "");
|
|
383
|
+
|
|
384
|
+
rc_runtime_destroy(&runtime);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
static void test_two_achievements_differing_resets_in_alts(void)
|
|
388
|
+
{
|
|
389
|
+
uint8_t ram[] = { 0, 10, 10 };
|
|
390
|
+
memory_t memory;
|
|
391
|
+
rc_runtime_t runtime;
|
|
392
|
+
|
|
393
|
+
memory.ram = ram;
|
|
394
|
+
memory.size = sizeof(ram);
|
|
395
|
+
|
|
396
|
+
rc_runtime_init(&runtime);
|
|
397
|
+
|
|
398
|
+
assert_activate_achievement(&runtime, 1, "0xH0001=10S1=1SR:0xH0000!=0");
|
|
399
|
+
assert_activate_achievement(&runtime, 2, "0xH0001=10S1=1SR:0xH0000!=1");
|
|
400
|
+
|
|
401
|
+
/* first achievement true (stays waiting), second not true because of reset */
|
|
402
|
+
assert_do_frame(&runtime, &memory);
|
|
403
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
404
|
+
ASSERT_NUM_EQUALS(runtime.triggers[1].trigger->state, RC_TRIGGER_STATE_ACTIVE);
|
|
405
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
406
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_ACTIVATED, 2, 0);
|
|
407
|
+
|
|
408
|
+
/* both achievements are false, should activate */
|
|
409
|
+
ram[1] = 9;
|
|
410
|
+
assert_do_frame(&runtime, &memory);
|
|
411
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_ACTIVE);
|
|
412
|
+
ASSERT_NUM_EQUALS(runtime.triggers[1].trigger->state, RC_TRIGGER_STATE_ACTIVE);
|
|
413
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
414
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_ACTIVATED, 1, 0);
|
|
415
|
+
|
|
416
|
+
/* first should fire, second prevented by reset */
|
|
417
|
+
ram[1] = 10;
|
|
418
|
+
assert_do_frame(&runtime, &memory);
|
|
419
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_TRIGGERED);
|
|
420
|
+
ASSERT_NUM_EQUALS(runtime.triggers[1].trigger->state, RC_TRIGGER_STATE_ACTIVE);
|
|
421
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
422
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED, 1, 0);
|
|
423
|
+
|
|
424
|
+
/* second can fire, reset first which will be activated due to reset */
|
|
425
|
+
ram[0] = 1;
|
|
426
|
+
rc_reset_trigger(runtime.triggers[0].trigger);
|
|
427
|
+
assert_do_frame(&runtime, &memory);
|
|
428
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_ACTIVE);
|
|
429
|
+
ASSERT_NUM_EQUALS(runtime.triggers[1].trigger->state, RC_TRIGGER_STATE_TRIGGERED);
|
|
430
|
+
ASSERT_NUM_EQUALS(event_count, 2);
|
|
431
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_ACTIVATED, 1, 0);
|
|
432
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED, 2, 0);
|
|
433
|
+
|
|
434
|
+
/* both achievements are false again. second should active, first should be ignored */
|
|
435
|
+
ram[0] = 0;
|
|
436
|
+
assert_do_frame(&runtime, &memory);
|
|
437
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_TRIGGERED);
|
|
438
|
+
ASSERT_NUM_EQUALS(runtime.triggers[1].trigger->state, RC_TRIGGER_STATE_TRIGGERED);
|
|
439
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
440
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED, 1, 0);
|
|
441
|
+
|
|
442
|
+
rc_runtime_destroy(&runtime);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
static void test_shared_memref(void)
|
|
446
|
+
{
|
|
447
|
+
uint8_t ram[] = { 0, 10, 10 };
|
|
448
|
+
memory_t memory;
|
|
449
|
+
rc_runtime_t runtime;
|
|
450
|
+
rc_memref_t* memref1;
|
|
451
|
+
rc_memref_t* memref2;
|
|
452
|
+
|
|
453
|
+
memory.ram = ram;
|
|
454
|
+
memory.size = sizeof(ram);
|
|
455
|
+
|
|
456
|
+
rc_runtime_init(&runtime);
|
|
457
|
+
|
|
458
|
+
assert_activate_achievement(&runtime, 1, "0xH0001=10");
|
|
459
|
+
assert_activate_achievement(&runtime, 2, "0xH0001=12");
|
|
460
|
+
|
|
461
|
+
memref1 = runtime.triggers[0].trigger->requirement->conditions->operand1.value.memref;
|
|
462
|
+
memref2 = runtime.triggers[1].trigger->requirement->conditions->operand1.value.memref;
|
|
463
|
+
ASSERT_PTR_EQUALS(memref1, memref2);
|
|
464
|
+
|
|
465
|
+
/* first is true, should remain waiting. second should activate */
|
|
466
|
+
assert_do_frame(&runtime, &memory);
|
|
467
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
468
|
+
ASSERT_NUM_EQUALS(runtime.triggers[1].trigger->state, RC_TRIGGER_STATE_ACTIVE);
|
|
469
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
470
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_ACTIVATED, 2, 0);
|
|
471
|
+
|
|
472
|
+
/* deactivate second one. it doesn't have any unique memrefs, so can be free'd */
|
|
473
|
+
rc_runtime_deactivate_achievement(&runtime, 2);
|
|
474
|
+
ASSERT_NUM_EQUALS(runtime.trigger_count, 1);
|
|
475
|
+
ASSERT_PTR_NOT_NULL(runtime.triggers[0].trigger);
|
|
476
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
477
|
+
|
|
478
|
+
/* second is true, but no longer in runtime. first should activate, expect nothing from second */
|
|
479
|
+
ram[1] = 12;
|
|
480
|
+
assert_do_frame(&runtime, &memory);
|
|
481
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
482
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_ACTIVATED, 1, 0);
|
|
483
|
+
|
|
484
|
+
/* first is true and should trigger */
|
|
485
|
+
ram[1] = 10;
|
|
486
|
+
assert_do_frame(&runtime, &memory);
|
|
487
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
488
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED, 1, 0);
|
|
489
|
+
|
|
490
|
+
/* reactivate achievement. old definition was free'd so should be recreated */
|
|
491
|
+
assert_activate_achievement(&runtime, 2, "0xH0001=12");
|
|
492
|
+
ASSERT_NUM_EQUALS(runtime.trigger_count, 2);
|
|
493
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_TRIGGERED);
|
|
494
|
+
ASSERT_NUM_EQUALS(runtime.triggers[1].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
495
|
+
|
|
496
|
+
/* reactivated achievement is waiting and false. should activate */
|
|
497
|
+
assert_do_frame(&runtime, &memory);
|
|
498
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
499
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_ACTIVATED, 2, 0);
|
|
500
|
+
|
|
501
|
+
/* deactivate first achievement. */
|
|
502
|
+
rc_runtime_deactivate_achievement(&runtime, 1);
|
|
503
|
+
ASSERT_NUM_EQUALS(runtime.trigger_count, 1);
|
|
504
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_ACTIVE);
|
|
505
|
+
|
|
506
|
+
/* second achievement is true. should trigger using memrefs from first */
|
|
507
|
+
ram[1] = 12;
|
|
508
|
+
assert_do_frame(&runtime, &memory);
|
|
509
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
510
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED, 2, 0);
|
|
511
|
+
|
|
512
|
+
rc_runtime_destroy(&runtime);
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
static void test_replace_active_trigger(void)
|
|
516
|
+
{
|
|
517
|
+
uint8_t ram[] = { 0, 10, 10 };
|
|
518
|
+
memory_t memory;
|
|
519
|
+
rc_runtime_t runtime;
|
|
520
|
+
|
|
521
|
+
memory.ram = ram;
|
|
522
|
+
memory.size = sizeof(ram);
|
|
523
|
+
|
|
524
|
+
rc_runtime_init(&runtime);
|
|
525
|
+
|
|
526
|
+
assert_activate_achievement(&runtime, 1, "0xH0001=10");
|
|
527
|
+
assert_activate_achievement(&runtime, 1, "0xH0002=10");
|
|
528
|
+
|
|
529
|
+
/* both are true, but first should have been overwritten by second */
|
|
530
|
+
assert_do_frame(&runtime, &memory);
|
|
531
|
+
ASSERT_NUM_EQUALS(runtime.trigger_count, 1);
|
|
532
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
533
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
534
|
+
|
|
535
|
+
/* both are false. only second should be getting processed, expect single event */
|
|
536
|
+
ram[1] = ram[2] = 9;
|
|
537
|
+
assert_do_frame(&runtime, &memory);
|
|
538
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
539
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_ACTIVATED, 1, 0);
|
|
540
|
+
|
|
541
|
+
/* first is true, but should not trigger */
|
|
542
|
+
ram[1] = 10;
|
|
543
|
+
assert_do_frame(&runtime, &memory);
|
|
544
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
545
|
+
|
|
546
|
+
/* second is true and should trigger */
|
|
547
|
+
ram[2] = 10;
|
|
548
|
+
assert_do_frame(&runtime, &memory);
|
|
549
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
550
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED, 1, 0);
|
|
551
|
+
|
|
552
|
+
/* switch back to original definition. */
|
|
553
|
+
assert_activate_achievement(&runtime, 1, "0xH0001=10");
|
|
554
|
+
ASSERT_NUM_EQUALS(runtime.trigger_count, 1);
|
|
555
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
556
|
+
|
|
557
|
+
rc_runtime_destroy(&runtime);
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
static rc_runtime_t* discarding_event_handler_runtime = NULL;
|
|
561
|
+
static void discarding_event_handler(const rc_runtime_event_t* e)
|
|
562
|
+
{
|
|
563
|
+
event_handler(e);
|
|
564
|
+
rc_runtime_deactivate_achievement(discarding_event_handler_runtime, e->id);
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
static void test_trigger_deactivation(void)
|
|
568
|
+
{
|
|
569
|
+
uint8_t ram[] = { 0, 9, 10 };
|
|
570
|
+
memory_t memory;
|
|
571
|
+
rc_runtime_t runtime;
|
|
572
|
+
|
|
573
|
+
memory.ram = ram;
|
|
574
|
+
memory.size = sizeof(ram);
|
|
575
|
+
|
|
576
|
+
rc_runtime_init(&runtime);
|
|
577
|
+
|
|
578
|
+
/* three identical achievements that should trigger when $1 changes from 9 to 10 */
|
|
579
|
+
assert_activate_achievement(&runtime, 1, "0xH0001=10_d0xH0001=9");
|
|
580
|
+
assert_activate_achievement(&runtime, 2, "0xH0001=10_d0xH0001=9");
|
|
581
|
+
assert_activate_achievement(&runtime, 3, "0xH0001=10_d0xH0001=9");
|
|
582
|
+
|
|
583
|
+
/* prep the delta and make sure the achievements are active */
|
|
584
|
+
assert_do_frame(&runtime, &memory);
|
|
585
|
+
ASSERT_NUM_EQUALS(runtime.trigger_count, 3);
|
|
586
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_ACTIVE);
|
|
587
|
+
ASSERT_NUM_EQUALS(runtime.triggers[1].trigger->state, RC_TRIGGER_STATE_ACTIVE);
|
|
588
|
+
ASSERT_NUM_EQUALS(runtime.triggers[2].trigger->state, RC_TRIGGER_STATE_ACTIVE);
|
|
589
|
+
|
|
590
|
+
/* trigger all three */
|
|
591
|
+
ram[1] = 10;
|
|
592
|
+
event_count = 0;
|
|
593
|
+
discarding_event_handler_runtime = &runtime;
|
|
594
|
+
rc_runtime_do_frame(&runtime, discarding_event_handler, peek, &memory, NULL);
|
|
595
|
+
discarding_event_handler_runtime = NULL;
|
|
596
|
+
|
|
597
|
+
ASSERT_NUM_EQUALS(event_count, 3);
|
|
598
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED, 1, 0);
|
|
599
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED, 2, 0);
|
|
600
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED, 3, 0);
|
|
601
|
+
|
|
602
|
+
/* triggers are no longer active and should have been removed from the runtime */
|
|
603
|
+
ASSERT_NUM_EQUALS(runtime.trigger_count, 0);
|
|
604
|
+
|
|
605
|
+
rc_runtime_destroy(&runtime);
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
static void test_trigger_with_resetif() {
|
|
609
|
+
uint8_t ram[] = {0x00, 0x00, 0x00, 0x00, 0x00};
|
|
610
|
+
memory_t memory;
|
|
611
|
+
rc_runtime_t runtime;
|
|
612
|
+
|
|
613
|
+
memory.ram = ram;
|
|
614
|
+
memory.size = sizeof(ram);
|
|
615
|
+
|
|
616
|
+
rc_runtime_init(&runtime);
|
|
617
|
+
|
|
618
|
+
/* never(byte(3)==1) && once(byte(4)==1) && trigger_when(byte(0)==1) */
|
|
619
|
+
assert_activate_achievement(&runtime, 1, "R:0xH0003=1_0xH0004=1.1._T:0xH0000=1");
|
|
620
|
+
assert_do_frame(&runtime, &memory);
|
|
621
|
+
ASSERT_NUM_EQUALS(runtime.trigger_count, 1);
|
|
622
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_ACTIVE);
|
|
623
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
624
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_ACTIVATED, 1, 0);
|
|
625
|
+
|
|
626
|
+
/* non-trigger condition is true */
|
|
627
|
+
ram[4] = 1;
|
|
628
|
+
assert_do_frame(&runtime, &memory);
|
|
629
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_PRIMED);
|
|
630
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
631
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_PRIMED, 1, 0);
|
|
632
|
+
|
|
633
|
+
/* ResetIf is true */
|
|
634
|
+
ram[3] = 1;
|
|
635
|
+
assert_do_frame(&runtime, &memory);
|
|
636
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_ACTIVE);
|
|
637
|
+
ASSERT_NUM_EQUALS(event_count, 2);
|
|
638
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_RESET, 1, 0);
|
|
639
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_UNPRIMED, 1, 0);
|
|
640
|
+
|
|
641
|
+
/* ResetIf no longer true */
|
|
642
|
+
ram[3] = 0;
|
|
643
|
+
assert_do_frame(&runtime, &memory);
|
|
644
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_PRIMED);
|
|
645
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
646
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_PRIMED, 1, 0);
|
|
647
|
+
|
|
648
|
+
rc_runtime_destroy(&runtime);
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
static void test_trigger_with_resetnextif() {
|
|
652
|
+
uint8_t ram[] = {0x00, 0x00, 0x00, 0x00, 0x00};
|
|
653
|
+
memory_t memory;
|
|
654
|
+
rc_runtime_t runtime;
|
|
655
|
+
|
|
656
|
+
memory.ram = ram;
|
|
657
|
+
memory.size = sizeof(ram);
|
|
658
|
+
|
|
659
|
+
rc_runtime_init(&runtime);
|
|
660
|
+
|
|
661
|
+
/* once(byte(4)==1 && never(repeated(2, byte(3)==1 && never(byte(1)==1 || byte(2)==1))) && trigger_when(byte(0)==1) */
|
|
662
|
+
assert_activate_achievement(&runtime, 1, "O:0xH0001=1_Z:0xH0002=1_Z:0xH0003=1.2._0xH0004=1.1._T:0xH0000=1");
|
|
663
|
+
assert_do_frame(&runtime, &memory);
|
|
664
|
+
ASSERT_NUM_EQUALS(runtime.trigger_count, 1);
|
|
665
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_ACTIVE);
|
|
666
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
667
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_ACTIVATED, 1, 0);
|
|
668
|
+
|
|
669
|
+
/* non-trigger condition is true */
|
|
670
|
+
ram[4] = 1;
|
|
671
|
+
assert_do_frame(&runtime, &memory);
|
|
672
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_PRIMED);
|
|
673
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
674
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_PRIMED, 1, 0);
|
|
675
|
+
|
|
676
|
+
/* second ResetNextIf is true */
|
|
677
|
+
ram[3] = 1;
|
|
678
|
+
assert_do_frame(&runtime, &memory);
|
|
679
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_PRIMED);
|
|
680
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
681
|
+
|
|
682
|
+
/* OrNext resets second ResetNextIf */
|
|
683
|
+
ram[1] = 1;
|
|
684
|
+
assert_do_frame(&runtime, &memory);
|
|
685
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_PRIMED);
|
|
686
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
687
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_RESET, 1, 0);
|
|
688
|
+
|
|
689
|
+
/* OrNext no longer true */
|
|
690
|
+
ram[1] = 0;
|
|
691
|
+
assert_do_frame(&runtime, &memory);
|
|
692
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_PRIMED);
|
|
693
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
694
|
+
|
|
695
|
+
/* second ResetNextIf fires */
|
|
696
|
+
assert_do_frame(&runtime, &memory);
|
|
697
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_ACTIVE);
|
|
698
|
+
ASSERT_NUM_EQUALS(event_count, 2);
|
|
699
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_RESET, 1, 0);
|
|
700
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_UNPRIMED, 1, 0);
|
|
701
|
+
|
|
702
|
+
rc_runtime_destroy(&runtime);
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
static void test_reset_event(void)
|
|
706
|
+
{
|
|
707
|
+
uint8_t ram[] = { 0, 10, 10 };
|
|
708
|
+
memory_t memory;
|
|
709
|
+
rc_runtime_t runtime;
|
|
710
|
+
rc_condition_t* cond;
|
|
711
|
+
|
|
712
|
+
memory.ram = ram;
|
|
713
|
+
memory.size = sizeof(ram);
|
|
714
|
+
|
|
715
|
+
rc_runtime_init(&runtime);
|
|
716
|
+
|
|
717
|
+
assert_activate_achievement(&runtime, 1, "0xH0001=10.2._R:0xH0002=10");
|
|
718
|
+
cond = runtime.triggers[0].trigger->requirement->conditions;
|
|
719
|
+
|
|
720
|
+
/* reset is true, so achievement is false and should activate, but not notify reset */
|
|
721
|
+
assert_do_frame(&runtime, &memory);
|
|
722
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
723
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_ACTIVATED, 1, 0);
|
|
724
|
+
ASSERT_NUM_EQUALS(cond->current_hits, 0);
|
|
725
|
+
|
|
726
|
+
/* reset is still true, but since no hits were accumulated there shouldn't be a reset event */
|
|
727
|
+
assert_do_frame(&runtime, &memory);
|
|
728
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
729
|
+
|
|
730
|
+
/* reset is not true, hits should increment */
|
|
731
|
+
ram[2] = 9;
|
|
732
|
+
assert_do_frame(&runtime, &memory);
|
|
733
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
734
|
+
ASSERT_NUM_EQUALS(cond->current_hits, 1);
|
|
735
|
+
|
|
736
|
+
/* reset is true. hits will reset. expect event */
|
|
737
|
+
ram[2] = 10;
|
|
738
|
+
assert_do_frame(&runtime, &memory);
|
|
739
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
740
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_RESET, 1, 0);
|
|
741
|
+
ASSERT_NUM_EQUALS(cond->current_hits, 0);
|
|
742
|
+
|
|
743
|
+
/* reset is still true, but since hits were previously reset there shouldn't be a reset event */
|
|
744
|
+
assert_do_frame(&runtime, &memory);
|
|
745
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
746
|
+
|
|
747
|
+
/* reset is not true, hits should increment */
|
|
748
|
+
ram[2] = 9;
|
|
749
|
+
assert_do_frame(&runtime, &memory);
|
|
750
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
751
|
+
ASSERT_NUM_EQUALS(cond->current_hits, 1);
|
|
752
|
+
|
|
753
|
+
/* reset is not true, hits should increment, causing achievement to trigger */
|
|
754
|
+
assert_do_frame(&runtime, &memory);
|
|
755
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
756
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED, 1, 0);
|
|
757
|
+
ASSERT_NUM_EQUALS(cond->current_hits, 2);
|
|
758
|
+
|
|
759
|
+
/* reset is true, but hits shouldn't reset as achievement is no longer active */
|
|
760
|
+
ram[2] = 10;
|
|
761
|
+
assert_do_frame(&runtime, &memory);
|
|
762
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
763
|
+
ASSERT_NUM_EQUALS(cond->current_hits, 2);
|
|
764
|
+
|
|
765
|
+
rc_runtime_destroy(&runtime);
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
static void test_paused_event(void)
|
|
769
|
+
{
|
|
770
|
+
uint8_t ram[] = { 0, 10, 10 };
|
|
771
|
+
memory_t memory;
|
|
772
|
+
rc_runtime_t runtime;
|
|
773
|
+
|
|
774
|
+
memory.ram = ram;
|
|
775
|
+
memory.size = sizeof(ram);
|
|
776
|
+
|
|
777
|
+
rc_runtime_init(&runtime);
|
|
778
|
+
|
|
779
|
+
assert_activate_achievement(&runtime, 1, "0xH0001=10.2._P:0xH0002=10");
|
|
780
|
+
|
|
781
|
+
/* pause is true, so achievement is false and should activate, but only notify pause */
|
|
782
|
+
assert_do_frame(&runtime, &memory);
|
|
783
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
784
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_PAUSED, 1, 0);
|
|
785
|
+
|
|
786
|
+
/* pause is still true, but previously paused, so no event */
|
|
787
|
+
assert_do_frame(&runtime, &memory);
|
|
788
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
789
|
+
|
|
790
|
+
/* pause is not true, expect activate event */
|
|
791
|
+
ram[2] = 9;
|
|
792
|
+
assert_do_frame(&runtime, &memory);
|
|
793
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
794
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_ACTIVATED, 1, 0);
|
|
795
|
+
|
|
796
|
+
/* pause is true. expect event */
|
|
797
|
+
ram[2] = 10;
|
|
798
|
+
assert_do_frame(&runtime, &memory);
|
|
799
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
800
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_PAUSED, 1, 0);
|
|
801
|
+
|
|
802
|
+
/* pause is still true, but previously paused, so no event */
|
|
803
|
+
assert_do_frame(&runtime, &memory);
|
|
804
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
805
|
+
|
|
806
|
+
/* pause is not true, expect trigger*/
|
|
807
|
+
ram[2] = 9;
|
|
808
|
+
assert_do_frame(&runtime, &memory);
|
|
809
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
810
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED, 1, 0);
|
|
811
|
+
|
|
812
|
+
/* pause is true, but shouldn't notify as achievement is no longer active */
|
|
813
|
+
ram[2] = 10;
|
|
814
|
+
assert_do_frame(&runtime, &memory);
|
|
815
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
816
|
+
|
|
817
|
+
rc_runtime_destroy(&runtime);
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
static void test_primed_event(void)
|
|
821
|
+
{
|
|
822
|
+
uint8_t ram[] = { 0, 1, 0, 1, 0, 0 };
|
|
823
|
+
memory_t memory;
|
|
824
|
+
rc_runtime_t runtime;
|
|
825
|
+
|
|
826
|
+
memory.ram = ram;
|
|
827
|
+
memory.size = sizeof(ram);
|
|
828
|
+
|
|
829
|
+
rc_runtime_init(&runtime);
|
|
830
|
+
|
|
831
|
+
/* byte(0)==1 && trigger(byte(1)==1) && byte(2)==1 && trigger(byte(3)==1) && unless(byte(4)==1) && never(byte(5) == 1) */
|
|
832
|
+
assert_activate_achievement(&runtime, 1, "0xH0000=1_T:0xH0001=1_0xH0002=1_T:0xH0003=1_P:0xH0004=1_R:0xH0005=1");
|
|
833
|
+
|
|
834
|
+
/* trigger conditions are true, but nothing else */
|
|
835
|
+
assert_do_frame(&runtime, &memory);
|
|
836
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
837
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_ACTIVATED, 1, 0);
|
|
838
|
+
|
|
839
|
+
/* primed */
|
|
840
|
+
ram[1] = ram[3] = 0;
|
|
841
|
+
ram[0] = ram[2] = 1;
|
|
842
|
+
assert_do_frame(&runtime, &memory);
|
|
843
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
844
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_PRIMED, 1, 0);
|
|
845
|
+
|
|
846
|
+
/* no longer primed */
|
|
847
|
+
ram[0] = 0;
|
|
848
|
+
assert_do_frame(&runtime, &memory);
|
|
849
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
850
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_UNPRIMED, 1, 0);
|
|
851
|
+
|
|
852
|
+
/* primed */
|
|
853
|
+
ram[0] = 1;
|
|
854
|
+
assert_do_frame(&runtime, &memory);
|
|
855
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
856
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_PRIMED, 1, 0);
|
|
857
|
+
|
|
858
|
+
/* paused */
|
|
859
|
+
ram[4] = 1;
|
|
860
|
+
assert_do_frame(&runtime, &memory);
|
|
861
|
+
ASSERT_NUM_EQUALS(event_count, 2);
|
|
862
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_UNPRIMED, 1, 0);
|
|
863
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_PAUSED, 1, 0);
|
|
864
|
+
|
|
865
|
+
/* unpaused */
|
|
866
|
+
ram[4] = 0;
|
|
867
|
+
assert_do_frame(&runtime, &memory);
|
|
868
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
869
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_PRIMED, 1, 0);
|
|
870
|
+
|
|
871
|
+
/* reset */
|
|
872
|
+
ram[5] = 1;
|
|
873
|
+
assert_do_frame(&runtime, &memory);
|
|
874
|
+
ASSERT_NUM_EQUALS(event_count, 2);
|
|
875
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_UNPRIMED, 1, 0);
|
|
876
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_RESET, 1, 0);
|
|
877
|
+
|
|
878
|
+
/* not reset */
|
|
879
|
+
ram[5] = 0;
|
|
880
|
+
assert_do_frame(&runtime, &memory);
|
|
881
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
882
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_PRIMED, 1, 0);
|
|
883
|
+
|
|
884
|
+
/* all conditions are true */
|
|
885
|
+
ram[1] = ram[3] = 1;
|
|
886
|
+
assert_do_frame(&runtime, &memory);
|
|
887
|
+
ASSERT_NUM_EQUALS(event_count, 2);
|
|
888
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_UNPRIMED, 1, 0);
|
|
889
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED, 1, 0);
|
|
890
|
+
|
|
891
|
+
rc_runtime_destroy(&runtime);
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
static void test_progress_event(void)
|
|
895
|
+
{
|
|
896
|
+
uint8_t ram[] = { 0, 1 };
|
|
897
|
+
memory_t memory;
|
|
898
|
+
rc_runtime_t runtime;
|
|
899
|
+
|
|
900
|
+
memory.ram = ram;
|
|
901
|
+
memory.size = sizeof(ram);
|
|
902
|
+
|
|
903
|
+
rc_runtime_init(&runtime);
|
|
904
|
+
|
|
905
|
+
/* measured(byte(0x0001) >= 10) */
|
|
906
|
+
assert_activate_achievement(&runtime, 1, "M:0xH0001>=10");
|
|
907
|
+
runtime.triggers[0].trigger->state = RC_TRIGGER_STATE_ACTIVE;
|
|
908
|
+
|
|
909
|
+
/* should not receive notification when initialized first measured value */
|
|
910
|
+
assert_do_frame(&runtime, &memory);
|
|
911
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
912
|
+
|
|
913
|
+
/* unchanged */
|
|
914
|
+
assert_do_frame(&runtime, &memory);
|
|
915
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
916
|
+
|
|
917
|
+
/* increased */
|
|
918
|
+
ram[1] = 2;
|
|
919
|
+
assert_do_frame(&runtime, &memory);
|
|
920
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
921
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_PROGRESS_UPDATED, 1, 2);
|
|
922
|
+
|
|
923
|
+
/* unchanged */
|
|
924
|
+
assert_do_frame(&runtime, &memory);
|
|
925
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
926
|
+
|
|
927
|
+
/* decreased */
|
|
928
|
+
ram[1] = 0;
|
|
929
|
+
assert_do_frame(&runtime, &memory);
|
|
930
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
931
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_PROGRESS_UPDATED, 1, 0);
|
|
932
|
+
|
|
933
|
+
/* increased */
|
|
934
|
+
ram[1] = 9;
|
|
935
|
+
assert_do_frame(&runtime, &memory);
|
|
936
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
937
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_PROGRESS_UPDATED, 1, 9);
|
|
938
|
+
|
|
939
|
+
/* triggered. should not receive change event */
|
|
940
|
+
ram[1] = 10;
|
|
941
|
+
assert_do_frame(&runtime, &memory);
|
|
942
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
943
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED, 1, 0);
|
|
944
|
+
|
|
945
|
+
/* no longer active */
|
|
946
|
+
ram[1] = 11;
|
|
947
|
+
assert_do_frame(&runtime, &memory);
|
|
948
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
949
|
+
|
|
950
|
+
rc_runtime_destroy(&runtime);
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
static void test_progress_event_as_percent(void)
|
|
954
|
+
{
|
|
955
|
+
uint8_t ram[] = { 0, 1 };
|
|
956
|
+
memory_t memory;
|
|
957
|
+
rc_runtime_t runtime;
|
|
958
|
+
|
|
959
|
+
memory.ram = ram;
|
|
960
|
+
memory.size = sizeof(ram);
|
|
961
|
+
|
|
962
|
+
rc_runtime_init(&runtime);
|
|
963
|
+
|
|
964
|
+
/* measured(byte(0x0001) >= 200, format='percent') */
|
|
965
|
+
assert_activate_achievement(&runtime, 1, "G:0xH0001>=200");
|
|
966
|
+
runtime.triggers[0].trigger->state = RC_TRIGGER_STATE_ACTIVE;
|
|
967
|
+
|
|
968
|
+
/* should not receive notification when initialized first measured value */
|
|
969
|
+
assert_do_frame(&runtime, &memory);
|
|
970
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
971
|
+
|
|
972
|
+
/* unchanged */
|
|
973
|
+
assert_do_frame(&runtime, &memory);
|
|
974
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
975
|
+
|
|
976
|
+
/* increased (0% -> 1%) */
|
|
977
|
+
ram[1] = 2;
|
|
978
|
+
assert_do_frame(&runtime, &memory);
|
|
979
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
980
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_PROGRESS_UPDATED, 1, 1);
|
|
981
|
+
|
|
982
|
+
/* unchanged */
|
|
983
|
+
assert_do_frame(&runtime, &memory);
|
|
984
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
985
|
+
|
|
986
|
+
/* increased (1% -> 1%, no event) */
|
|
987
|
+
ram[1] = 3;
|
|
988
|
+
assert_do_frame(&runtime, &memory);
|
|
989
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
990
|
+
|
|
991
|
+
/* increased (1% -> 2%) */
|
|
992
|
+
ram[1] = 4;
|
|
993
|
+
assert_do_frame(&runtime, &memory);
|
|
994
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
995
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_PROGRESS_UPDATED, 1, 2);
|
|
996
|
+
|
|
997
|
+
/* decreased */
|
|
998
|
+
ram[1] = 1;
|
|
999
|
+
assert_do_frame(&runtime, &memory);
|
|
1000
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
1001
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_PROGRESS_UPDATED, 1, 0);
|
|
1002
|
+
|
|
1003
|
+
/* increased */
|
|
1004
|
+
ram[1] = 199;
|
|
1005
|
+
assert_do_frame(&runtime, &memory);
|
|
1006
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
1007
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_PROGRESS_UPDATED, 1, 99);
|
|
1008
|
+
|
|
1009
|
+
/* triggered. should not receive change event */
|
|
1010
|
+
ram[1] = 200;
|
|
1011
|
+
assert_do_frame(&runtime, &memory);
|
|
1012
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
1013
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_TRIGGERED, 1, 0);
|
|
1014
|
+
|
|
1015
|
+
/* no longer active */
|
|
1016
|
+
ram[1] = 40;
|
|
1017
|
+
assert_do_frame(&runtime, &memory);
|
|
1018
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
1019
|
+
|
|
1020
|
+
rc_runtime_destroy(&runtime);
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
static void test_lboard(void)
|
|
1024
|
+
{
|
|
1025
|
+
uint8_t ram[] = { 2, 10, 10 };
|
|
1026
|
+
memory_t memory;
|
|
1027
|
+
rc_runtime_t runtime;
|
|
1028
|
+
|
|
1029
|
+
memory.ram = ram;
|
|
1030
|
+
memory.size = sizeof(ram);
|
|
1031
|
+
|
|
1032
|
+
rc_runtime_init(&runtime);
|
|
1033
|
+
|
|
1034
|
+
assert_activate_lboard(&runtime, 1, "STA:0xH0001=10::SUB:0xH0001=11::CAN:0xH0001=12::VAL:0xH0000");
|
|
1035
|
+
assert_activate_lboard(&runtime, 2, "STA:0xH0002=10::SUB:0xH0002=11::CAN:0xH0002=12::VAL:0xH0000*2");
|
|
1036
|
+
|
|
1037
|
+
/* both start conditions are true, leaderboards will not be active */
|
|
1038
|
+
assert_do_frame(&runtime, &memory);
|
|
1039
|
+
ASSERT_NUM_EQUALS(runtime.lboards[0].lboard->state, RC_LBOARD_STATE_WAITING);
|
|
1040
|
+
ASSERT_NUM_EQUALS(runtime.lboards[1].lboard->state, RC_LBOARD_STATE_WAITING);
|
|
1041
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
1042
|
+
|
|
1043
|
+
/* both start conditions are false, leaderboards will activate */
|
|
1044
|
+
ram[1] = ram[2] = 9;
|
|
1045
|
+
assert_do_frame(&runtime, &memory);
|
|
1046
|
+
ASSERT_NUM_EQUALS(runtime.lboards[0].lboard->state, RC_LBOARD_STATE_ACTIVE);
|
|
1047
|
+
ASSERT_NUM_EQUALS(runtime.lboards[1].lboard->state, RC_LBOARD_STATE_ACTIVE);
|
|
1048
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
1049
|
+
|
|
1050
|
+
/* both start conditions are true, leaderboards will start */
|
|
1051
|
+
ram[1] = ram[2] = 10;
|
|
1052
|
+
assert_do_frame(&runtime, &memory);
|
|
1053
|
+
ASSERT_NUM_EQUALS(runtime.lboards[0].lboard->state, RC_LBOARD_STATE_STARTED);
|
|
1054
|
+
ASSERT_NUM_EQUALS(runtime.lboards[1].lboard->state, RC_LBOARD_STATE_STARTED);
|
|
1055
|
+
ASSERT_NUM_EQUALS(event_count, 2);
|
|
1056
|
+
assert_event(RC_RUNTIME_EVENT_LBOARD_STARTED, 1, 2);
|
|
1057
|
+
assert_event(RC_RUNTIME_EVENT_LBOARD_STARTED, 2, 4);
|
|
1058
|
+
|
|
1059
|
+
/* start condition no longer true, leaderboard should continue processing */
|
|
1060
|
+
ram[1] = ram[2] = 9;
|
|
1061
|
+
assert_do_frame(&runtime, &memory);
|
|
1062
|
+
ASSERT_NUM_EQUALS(runtime.lboards[0].lboard->state, RC_LBOARD_STATE_STARTED);
|
|
1063
|
+
ASSERT_NUM_EQUALS(runtime.lboards[1].lboard->state, RC_LBOARD_STATE_STARTED);
|
|
1064
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
1065
|
+
|
|
1066
|
+
/* value changed */
|
|
1067
|
+
ram[0] = 3;
|
|
1068
|
+
assert_do_frame(&runtime, &memory);
|
|
1069
|
+
ASSERT_NUM_EQUALS(runtime.lboards[0].lboard->state, RC_LBOARD_STATE_STARTED);
|
|
1070
|
+
ASSERT_NUM_EQUALS(runtime.lboards[1].lboard->state, RC_LBOARD_STATE_STARTED);
|
|
1071
|
+
ASSERT_NUM_EQUALS(event_count, 2);
|
|
1072
|
+
assert_event(RC_RUNTIME_EVENT_LBOARD_UPDATED, 1, 3);
|
|
1073
|
+
assert_event(RC_RUNTIME_EVENT_LBOARD_UPDATED, 2, 6);
|
|
1074
|
+
|
|
1075
|
+
/* value changed; first leaderboard submit, second canceled - expect events for submit and cancel, none for update */
|
|
1076
|
+
ram[0] = 4;
|
|
1077
|
+
ram[1] = 11;
|
|
1078
|
+
ram[2] = 12;
|
|
1079
|
+
assert_do_frame(&runtime, &memory);
|
|
1080
|
+
ASSERT_NUM_EQUALS(runtime.lboards[0].lboard->state, RC_LBOARD_STATE_TRIGGERED);
|
|
1081
|
+
ASSERT_NUM_EQUALS(runtime.lboards[1].lboard->state, RC_LBOARD_STATE_CANCELED);
|
|
1082
|
+
ASSERT_NUM_EQUALS(event_count, 2);
|
|
1083
|
+
assert_event(RC_RUNTIME_EVENT_LBOARD_TRIGGERED, 1, 4);
|
|
1084
|
+
assert_event(RC_RUNTIME_EVENT_LBOARD_CANCELED, 2, 0);
|
|
1085
|
+
|
|
1086
|
+
/* both start conditions are true, leaderboards will not be active */
|
|
1087
|
+
ram[1] = ram[2] = 10;
|
|
1088
|
+
assert_do_frame(&runtime, &memory);
|
|
1089
|
+
ASSERT_NUM_EQUALS(runtime.lboards[0].lboard->state, RC_LBOARD_STATE_TRIGGERED);
|
|
1090
|
+
ASSERT_NUM_EQUALS(runtime.lboards[1].lboard->state, RC_LBOARD_STATE_CANCELED);
|
|
1091
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
1092
|
+
|
|
1093
|
+
/* both start conditions are false, leaderboards will re-activate */
|
|
1094
|
+
ram[1] = ram[2] = 9;
|
|
1095
|
+
assert_do_frame(&runtime, &memory);
|
|
1096
|
+
ASSERT_NUM_EQUALS(runtime.lboards[0].lboard->state, RC_LBOARD_STATE_ACTIVE);
|
|
1097
|
+
ASSERT_NUM_EQUALS(runtime.lboards[1].lboard->state, RC_LBOARD_STATE_ACTIVE);
|
|
1098
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
1099
|
+
|
|
1100
|
+
/* both start conditions are true, leaderboards will start */
|
|
1101
|
+
ram[1] = ram[2] = 10;
|
|
1102
|
+
assert_do_frame(&runtime, &memory);
|
|
1103
|
+
ASSERT_NUM_EQUALS(runtime.lboards[0].lboard->state, RC_LBOARD_STATE_STARTED);
|
|
1104
|
+
ASSERT_NUM_EQUALS(runtime.lboards[1].lboard->state, RC_LBOARD_STATE_STARTED);
|
|
1105
|
+
ASSERT_NUM_EQUALS(event_count, 2);
|
|
1106
|
+
assert_event(RC_RUNTIME_EVENT_LBOARD_STARTED, 1, 4);
|
|
1107
|
+
assert_event(RC_RUNTIME_EVENT_LBOARD_STARTED, 2, 8);
|
|
1108
|
+
|
|
1109
|
+
rc_runtime_destroy(&runtime);
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
static void test_format_lboard_value(int format, int value, const char* expected) {
|
|
1113
|
+
char buffer[64];
|
|
1114
|
+
int result;
|
|
1115
|
+
|
|
1116
|
+
result = rc_runtime_format_lboard_value(buffer, sizeof(buffer), value, format);
|
|
1117
|
+
ASSERT_STR_EQUALS(buffer, expected);
|
|
1118
|
+
ASSERT_NUM_EQUALS(result, strlen(expected));
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
static void test_richpresence(void)
|
|
1122
|
+
{
|
|
1123
|
+
uint8_t ram[] = { 2, 10, 10 };
|
|
1124
|
+
memory_t memory;
|
|
1125
|
+
rc_runtime_t runtime;
|
|
1126
|
+
|
|
1127
|
+
memory.ram = ram;
|
|
1128
|
+
memory.size = sizeof(ram);
|
|
1129
|
+
|
|
1130
|
+
rc_runtime_init(&runtime);
|
|
1131
|
+
|
|
1132
|
+
/* initial value */
|
|
1133
|
+
assert_richpresence_display_string(&runtime, &memory, "");
|
|
1134
|
+
|
|
1135
|
+
/* loading generates a display string with uninitialized memrefs, which ensures a non-empty display string */
|
|
1136
|
+
assert_activate_richpresence(&runtime,
|
|
1137
|
+
"Format:Points\nFormatType=VALUE\n\nDisplay:\nScore is @Points(0x 0001) Points");
|
|
1138
|
+
assert_richpresence_display_string(&runtime, &memory, "Score is 0 Points");
|
|
1139
|
+
|
|
1140
|
+
/* first frame should update display string with correct memrfs */
|
|
1141
|
+
assert_do_frame(&runtime, &memory);
|
|
1142
|
+
assert_richpresence_display_string(&runtime, &memory, "Score is 2,570 Points");
|
|
1143
|
+
|
|
1144
|
+
/* calling rc_runtime_get_richpresence without calling rc_runtime_do_frame should return the same string as memrefs aren't updated */
|
|
1145
|
+
ram[1] = 20;
|
|
1146
|
+
assert_richpresence_display_string(&runtime, &memory, "Score is 2,570 Points");
|
|
1147
|
+
|
|
1148
|
+
/* call rc_runtime_do_frame to update memrefs */
|
|
1149
|
+
assert_do_frame(&runtime, &memory);
|
|
1150
|
+
assert_richpresence_display_string(&runtime, &memory, "Score is 2,580 Points");
|
|
1151
|
+
|
|
1152
|
+
rc_runtime_destroy(&runtime);
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
static void test_richpresence_starts_with_macro(void)
|
|
1156
|
+
{
|
|
1157
|
+
uint8_t ram[] = { 2, 10, 10 };
|
|
1158
|
+
memory_t memory;
|
|
1159
|
+
rc_runtime_t runtime;
|
|
1160
|
+
|
|
1161
|
+
memory.ram = ram;
|
|
1162
|
+
memory.size = sizeof(ram);
|
|
1163
|
+
|
|
1164
|
+
rc_runtime_init(&runtime);
|
|
1165
|
+
|
|
1166
|
+
assert_activate_richpresence(&runtime,
|
|
1167
|
+
"Format:Points\nFormatType=VALUE\n\nDisplay:\n@Points(0x 0001) Points");
|
|
1168
|
+
assert_do_frame(&runtime, &memory);
|
|
1169
|
+
assert_richpresence_display_string(&runtime, &memory, "2,570 Points");
|
|
1170
|
+
|
|
1171
|
+
rc_runtime_destroy(&runtime);
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
static void test_richpresence_macro_only(void)
|
|
1175
|
+
{
|
|
1176
|
+
uint8_t ram[] = { 2, 10, 10 };
|
|
1177
|
+
memory_t memory;
|
|
1178
|
+
rc_runtime_t runtime;
|
|
1179
|
+
|
|
1180
|
+
memory.ram = ram;
|
|
1181
|
+
memory.size = sizeof(ram);
|
|
1182
|
+
|
|
1183
|
+
rc_runtime_init(&runtime);
|
|
1184
|
+
|
|
1185
|
+
assert_activate_richpresence(&runtime,
|
|
1186
|
+
"Format:Points\nFormatType=VALUE\n\nDisplay:\n@Points(0x 0001)");
|
|
1187
|
+
assert_do_frame(&runtime, &memory);
|
|
1188
|
+
assert_richpresence_display_string(&runtime, &memory, "2,570");
|
|
1189
|
+
|
|
1190
|
+
rc_runtime_destroy(&runtime);
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
static void test_richpresence_conditional(void)
|
|
1194
|
+
{
|
|
1195
|
+
uint8_t ram[] = { 2, 10, 10 };
|
|
1196
|
+
memory_t memory;
|
|
1197
|
+
rc_runtime_t runtime;
|
|
1198
|
+
|
|
1199
|
+
memory.ram = ram;
|
|
1200
|
+
memory.size = sizeof(ram);
|
|
1201
|
+
|
|
1202
|
+
rc_runtime_init(&runtime);
|
|
1203
|
+
|
|
1204
|
+
/* loading generates a display string with uninitialized memrefs, which ensures a non-empty display string */
|
|
1205
|
+
assert_activate_richpresence(&runtime,
|
|
1206
|
+
"Format:Points\nFormatType=VALUE\n\nDisplay:\n?0xH0000=2?@Points(0x 0001) points\nScore is @Points(0x 0001) Points");
|
|
1207
|
+
assert_richpresence_display_string(&runtime, &memory, "Score is 0 Points");
|
|
1208
|
+
|
|
1209
|
+
/* first frame should update display string with correct memrfs */
|
|
1210
|
+
assert_do_frame(&runtime, &memory);
|
|
1211
|
+
assert_richpresence_display_string(&runtime, &memory, "2,570 points");
|
|
1212
|
+
|
|
1213
|
+
/* update display string */
|
|
1214
|
+
ram[0] = 0;
|
|
1215
|
+
ram[1] = 20;
|
|
1216
|
+
assert_do_frame(&runtime, &memory);
|
|
1217
|
+
assert_richpresence_display_string(&runtime, &memory, "Score is 2,580 Points");
|
|
1218
|
+
|
|
1219
|
+
rc_runtime_destroy(&runtime);
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
static void test_richpresence_conditional_with_hits(void)
|
|
1223
|
+
{
|
|
1224
|
+
uint8_t ram[] = { 2, 10, 10 };
|
|
1225
|
+
memory_t memory;
|
|
1226
|
+
rc_runtime_t runtime;
|
|
1227
|
+
|
|
1228
|
+
memory.ram = ram;
|
|
1229
|
+
memory.size = sizeof(ram);
|
|
1230
|
+
|
|
1231
|
+
rc_runtime_init(&runtime);
|
|
1232
|
+
|
|
1233
|
+
/* loading generates a display string with uninitialized memrefs, which ensures a non-empty display string */
|
|
1234
|
+
assert_activate_richpresence(&runtime,
|
|
1235
|
+
"Format:Points\nFormatType=VALUE\n\nDisplay:\n?0xH0000=1.2.?Score is @Points(0x 0001) Points\n@Points(0x 0001) points");
|
|
1236
|
+
assert_richpresence_display_string(&runtime, &memory, "0 points");
|
|
1237
|
+
|
|
1238
|
+
/* first frame should update display string with correct memrfs */
|
|
1239
|
+
assert_do_frame(&runtime, &memory);
|
|
1240
|
+
assert_richpresence_display_string(&runtime, &memory, "2,570 points");
|
|
1241
|
+
|
|
1242
|
+
/* one hit is not enough to switch display strings, but the memref does get updated */
|
|
1243
|
+
ram[0] = 1;
|
|
1244
|
+
ram[1] = 20;
|
|
1245
|
+
assert_do_frame(&runtime, &memory);
|
|
1246
|
+
assert_richpresence_display_string(&runtime, &memory, "2,580 points");
|
|
1247
|
+
|
|
1248
|
+
/* second hit is enough */
|
|
1249
|
+
assert_do_frame(&runtime, &memory);
|
|
1250
|
+
assert_richpresence_display_string(&runtime, &memory, "Score is 2,580 Points");
|
|
1251
|
+
|
|
1252
|
+
/* no more hits are accumulated */
|
|
1253
|
+
assert_do_frame(&runtime, &memory);
|
|
1254
|
+
assert_richpresence_display_string(&runtime, &memory, "Score is 2,580 Points");
|
|
1255
|
+
|
|
1256
|
+
/* same test without intermediary evaluation of display string */
|
|
1257
|
+
rc_runtime_reset(&runtime);
|
|
1258
|
+
ram[0] = 2;
|
|
1259
|
+
ram[1] = 30;
|
|
1260
|
+
assert_do_frame(&runtime, &memory); /* no hits */
|
|
1261
|
+
|
|
1262
|
+
ram[0] = 1;
|
|
1263
|
+
assert_do_frame(&runtime, &memory); /* one hit */
|
|
1264
|
+
assert_do_frame(&runtime, &memory); /* two hits */
|
|
1265
|
+
assert_richpresence_display_string(&runtime, &memory, "Score is 2,590 Points");
|
|
1266
|
+
|
|
1267
|
+
rc_runtime_destroy(&runtime);
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
static void test_richpresence_conditional_with_hits_after_match(void)
|
|
1271
|
+
{
|
|
1272
|
+
uint8_t ram[] = { 2, 10, 10 };
|
|
1273
|
+
memory_t memory;
|
|
1274
|
+
rc_runtime_t runtime;
|
|
1275
|
+
|
|
1276
|
+
memory.ram = ram;
|
|
1277
|
+
memory.size = sizeof(ram);
|
|
1278
|
+
|
|
1279
|
+
rc_runtime_init(&runtime);
|
|
1280
|
+
|
|
1281
|
+
/* loading generates a display string with uninitialized memrefs, which ensures a non-empty display string */
|
|
1282
|
+
assert_activate_richpresence(&runtime,
|
|
1283
|
+
"Format:Points\nFormatType=VALUE\n\nDisplay:\n?0xH0002=10?It's @Points(0x 0001)\n?0xH0000=1.2.?Score is @Points(0x 0001) Points\n@Points(0x 0001) points");
|
|
1284
|
+
assert_richpresence_display_string(&runtime, &memory, "0 points");
|
|
1285
|
+
|
|
1286
|
+
/* first frame should update display string with correct memrfs */
|
|
1287
|
+
assert_do_frame(&runtime, &memory);
|
|
1288
|
+
assert_richpresence_display_string(&runtime, &memory, "It's 2,570");
|
|
1289
|
+
|
|
1290
|
+
/* first condition is true, but one hit should still be tallied on the second conditional */
|
|
1291
|
+
ram[0] = 1;
|
|
1292
|
+
ram[1] = 20;
|
|
1293
|
+
assert_do_frame(&runtime, &memory);
|
|
1294
|
+
assert_richpresence_display_string(&runtime, &memory, "It's 2,580");
|
|
1295
|
+
|
|
1296
|
+
/* first conditio no longer true, second condtion will get it's second hit, which is enough */
|
|
1297
|
+
ram[2] = 20;
|
|
1298
|
+
assert_do_frame(&runtime, &memory);
|
|
1299
|
+
assert_richpresence_display_string(&runtime, &memory, "Score is 5,140 Points");
|
|
1300
|
+
|
|
1301
|
+
/* same test without intermediary evaluation of display string */
|
|
1302
|
+
rc_runtime_reset(&runtime);
|
|
1303
|
+
ram[0] = 2;
|
|
1304
|
+
ram[1] = 10;
|
|
1305
|
+
ram[2] = 10;
|
|
1306
|
+
assert_do_frame(&runtime, &memory); /* no hits */
|
|
1307
|
+
|
|
1308
|
+
ram[0] = 1;
|
|
1309
|
+
ram[1] = 20;
|
|
1310
|
+
assert_do_frame(&runtime, &memory); /* one hit */
|
|
1311
|
+
ram[2] = 20;
|
|
1312
|
+
assert_do_frame(&runtime, &memory); /* two hits */
|
|
1313
|
+
assert_richpresence_display_string(&runtime, &memory, "Score is 5,140 Points");
|
|
1314
|
+
|
|
1315
|
+
rc_runtime_destroy(&runtime);
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
static void test_richpresence_reload(void)
|
|
1319
|
+
{
|
|
1320
|
+
uint8_t ram[] = { 2, 10, 10 };
|
|
1321
|
+
memory_t memory;
|
|
1322
|
+
rc_runtime_t runtime;
|
|
1323
|
+
|
|
1324
|
+
memory.ram = ram;
|
|
1325
|
+
memory.size = sizeof(ram);
|
|
1326
|
+
|
|
1327
|
+
rc_runtime_init(&runtime);
|
|
1328
|
+
|
|
1329
|
+
/* loading generates a display string with uninitialized memrefs, which ensures a non-empty display string */
|
|
1330
|
+
assert_activate_richpresence(&runtime,
|
|
1331
|
+
"Format:Points\nFormatType=VALUE\n\nDisplay:\n@Points(0x 0001) Points");
|
|
1332
|
+
assert_richpresence_display_string(&runtime, &memory, "0 Points");
|
|
1333
|
+
|
|
1334
|
+
/* first frame should update display string with correct memrfs */
|
|
1335
|
+
assert_do_frame(&runtime, &memory);
|
|
1336
|
+
assert_richpresence_display_string(&runtime, &memory, "2,570 Points");
|
|
1337
|
+
|
|
1338
|
+
/* reloading should generate display string with current memrefs */
|
|
1339
|
+
ram[1] = 20;
|
|
1340
|
+
assert_activate_richpresence(&runtime,
|
|
1341
|
+
"Format:Points\nFormatType=VALUE\n\nDisplay:\n@Points(0x 0001) Bananas");
|
|
1342
|
+
assert_richpresence_display_string(&runtime, &memory, "2,570 Bananas");
|
|
1343
|
+
|
|
1344
|
+
/* first frame after reloading should update display string */
|
|
1345
|
+
assert_do_frame(&runtime, &memory);
|
|
1346
|
+
assert_richpresence_display_string(&runtime, &memory, "2,580 Bananas");
|
|
1347
|
+
|
|
1348
|
+
rc_runtime_destroy(&runtime);
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
static void test_richpresence_reload_addaddress(void)
|
|
1352
|
+
{
|
|
1353
|
+
/* ram[1] must be non-zero */
|
|
1354
|
+
uint8_t ram[] = { 1, 10, 10, 10 };
|
|
1355
|
+
memory_t memory;
|
|
1356
|
+
rc_runtime_t runtime;
|
|
1357
|
+
|
|
1358
|
+
memory.ram = ram;
|
|
1359
|
+
memory.size = sizeof(ram);
|
|
1360
|
+
|
|
1361
|
+
rc_runtime_init(&runtime);
|
|
1362
|
+
|
|
1363
|
+
/* loading generates a display string with uninitialized memrefs, which ensures a non-empty display string */
|
|
1364
|
+
assert_activate_richpresence(&runtime,
|
|
1365
|
+
"Format:Points\nFormatType=VALUE\n\nDisplay:\n@Points(I:0xH0000_M:0x 0001) Points");
|
|
1366
|
+
assert_richpresence_display_string(&runtime, &memory, "0 Points");
|
|
1367
|
+
|
|
1368
|
+
/* first frame should update display string with correct memrfs */
|
|
1369
|
+
assert_do_frame(&runtime, &memory);
|
|
1370
|
+
assert_richpresence_display_string(&runtime, &memory, "2,570 Points");
|
|
1371
|
+
|
|
1372
|
+
/* reloading should generate display string with current memrefs */
|
|
1373
|
+
/* the entire AddAddress expression will be a single variable, which will have a current value. */
|
|
1374
|
+
ram[2] = 20;
|
|
1375
|
+
assert_activate_richpresence(&runtime,
|
|
1376
|
+
"Format:Points\nFormatType=VALUE\n\nDisplay:\n@Points(I:0xH0000_M:0x 0001) Bananas");
|
|
1377
|
+
assert_richpresence_display_string(&runtime, &memory, "2,570 Bananas");
|
|
1378
|
+
|
|
1379
|
+
/* first frame after reloading should update display string */
|
|
1380
|
+
assert_do_frame(&runtime, &memory);
|
|
1381
|
+
assert_richpresence_display_string(&runtime, &memory, "2,580 Bananas");
|
|
1382
|
+
|
|
1383
|
+
rc_runtime_destroy(&runtime);
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
static void test_richpresence_static(void)
|
|
1387
|
+
{
|
|
1388
|
+
uint8_t ram[] = { 2, 10, 10 };
|
|
1389
|
+
memory_t memory;
|
|
1390
|
+
rc_runtime_t runtime;
|
|
1391
|
+
|
|
1392
|
+
memory.ram = ram;
|
|
1393
|
+
memory.size = sizeof(ram);
|
|
1394
|
+
|
|
1395
|
+
rc_runtime_init(&runtime);
|
|
1396
|
+
|
|
1397
|
+
assert_activate_richpresence(&runtime, "Display:\nHello, world!");
|
|
1398
|
+
assert_do_frame(&runtime, &memory);
|
|
1399
|
+
assert_richpresence_display_string(&runtime, &memory, "Hello, world!");
|
|
1400
|
+
|
|
1401
|
+
/* first frame won't affect the display string */
|
|
1402
|
+
assert_do_frame(&runtime, &memory);
|
|
1403
|
+
assert_richpresence_display_string(&runtime, &memory, "Hello, world!");
|
|
1404
|
+
|
|
1405
|
+
rc_runtime_destroy(&runtime);
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
static void test_richpresence_addsource_chain(void)
|
|
1409
|
+
{
|
|
1410
|
+
rc_runtime_t runtime;
|
|
1411
|
+
rc_runtime_init(&runtime);
|
|
1412
|
+
|
|
1413
|
+
/* large number of AddSources will exceed the runtime buffer of 32 memrefs and 16 modified memrefs */
|
|
1414
|
+
assert_activate_richpresence(&runtime,
|
|
1415
|
+
"Display:\n"
|
|
1416
|
+
"@Number(0xH0000_0xH0001_0xH0002_0xH0003_0xH0004_0xH0005_0xH0006_0xH0007_"
|
|
1417
|
+
"0xH0010_0xH0011_0xH0012_0xH0013_0xH0014_0xH0015_0xH0016_0xH0017_"
|
|
1418
|
+
"0xH0020_0xH0021_0xH0022_0xH0023_0xH0024_0xH0025_0xH0026_0xH0027_"
|
|
1419
|
+
"0xH0030_0xH0031_0xH0032_0xH0033_0xH0034_0xH0035_0xH0036_0xH0037_"
|
|
1420
|
+
"0xH0040_0xH0041_0xH0042_0xH0043)\n");
|
|
1421
|
+
|
|
1422
|
+
rc_runtime_destroy(&runtime);
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
typedef struct {
|
|
1426
|
+
memory_t memory;
|
|
1427
|
+
rc_runtime_t* runtime;
|
|
1428
|
+
uint32_t invalid_address;
|
|
1429
|
+
}
|
|
1430
|
+
memory_invalid_t;
|
|
1431
|
+
|
|
1432
|
+
static uint32_t peek_invalid(uint32_t address, uint32_t num_bytes, void* ud)
|
|
1433
|
+
{
|
|
1434
|
+
memory_invalid_t* memory = (memory_invalid_t*)ud;
|
|
1435
|
+
if (memory->invalid_address != address)
|
|
1436
|
+
return peek(address, num_bytes, &memory->memory);
|
|
1437
|
+
|
|
1438
|
+
rc_runtime_invalidate_address(memory->runtime, address);
|
|
1439
|
+
return 0;
|
|
1440
|
+
}
|
|
1441
|
+
|
|
1442
|
+
static void assert_do_frame_invalid(rc_runtime_t* runtime, memory_invalid_t* memory, uint32_t invalid_address)
|
|
1443
|
+
{
|
|
1444
|
+
event_count = 0;
|
|
1445
|
+
memory->runtime = runtime;
|
|
1446
|
+
memory->invalid_address = invalid_address;
|
|
1447
|
+
rc_runtime_do_frame(runtime, event_handler, peek_invalid, memory, NULL);
|
|
1448
|
+
}
|
|
1449
|
+
|
|
1450
|
+
static void test_invalidate_address(void)
|
|
1451
|
+
{
|
|
1452
|
+
uint8_t ram[] = { 0, 10, 10 };
|
|
1453
|
+
memory_invalid_t memory;
|
|
1454
|
+
rc_runtime_t runtime;
|
|
1455
|
+
|
|
1456
|
+
memory.memory.ram = ram;
|
|
1457
|
+
memory.memory.size = sizeof(ram);
|
|
1458
|
+
|
|
1459
|
+
rc_runtime_init(&runtime);
|
|
1460
|
+
event_count = 0;
|
|
1461
|
+
|
|
1462
|
+
assert_activate_achievement(&runtime, 1, "0xH0001=10");
|
|
1463
|
+
assert_activate_achievement(&runtime, 2, "0xH0002=10");
|
|
1464
|
+
|
|
1465
|
+
/* achievements should start in waiting state */
|
|
1466
|
+
assert_do_frame_invalid(&runtime, &memory, 0);
|
|
1467
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
1468
|
+
ASSERT_NUM_EQUALS(runtime.triggers[1].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
1469
|
+
|
|
1470
|
+
/* nothing depends on address 3 */
|
|
1471
|
+
assert_do_frame_invalid(&runtime, &memory, 3);
|
|
1472
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
1473
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
1474
|
+
ASSERT_NUM_EQUALS(runtime.triggers[1].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
1475
|
+
|
|
1476
|
+
/* second achievement depends on address 2 */
|
|
1477
|
+
assert_do_frame_invalid(&runtime, &memory, 2);
|
|
1478
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
1479
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
1480
|
+
ASSERT_NUM_EQUALS(runtime.triggers[1].trigger->state, RC_TRIGGER_STATE_DISABLED);
|
|
1481
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_DISABLED, 2, 2);
|
|
1482
|
+
|
|
1483
|
+
/* second achievement already disabled, don't raise event again */
|
|
1484
|
+
assert_do_frame_invalid(&runtime, &memory, 2);
|
|
1485
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
1486
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
1487
|
+
ASSERT_NUM_EQUALS(runtime.triggers[1].trigger->state, RC_TRIGGER_STATE_DISABLED);
|
|
1488
|
+
|
|
1489
|
+
rc_runtime_destroy(&runtime);
|
|
1490
|
+
}
|
|
1491
|
+
|
|
1492
|
+
static void test_invalidate_address_no_memrefs(void)
|
|
1493
|
+
{
|
|
1494
|
+
rc_runtime_t runtime;
|
|
1495
|
+
rc_runtime_init(&runtime);
|
|
1496
|
+
|
|
1497
|
+
/* simple test to ensure a null reference doesn't occur when no memrefs are present */
|
|
1498
|
+
rc_runtime_invalidate_address(&runtime, 0);
|
|
1499
|
+
|
|
1500
|
+
rc_runtime_destroy(&runtime);
|
|
1501
|
+
}
|
|
1502
|
+
|
|
1503
|
+
static void test_invalidate_address_shared_memref(void)
|
|
1504
|
+
{
|
|
1505
|
+
uint8_t ram[] = { 0, 10, 10 };
|
|
1506
|
+
memory_invalid_t memory;
|
|
1507
|
+
rc_runtime_t runtime;
|
|
1508
|
+
|
|
1509
|
+
memory.memory.ram = ram;
|
|
1510
|
+
memory.memory.size = sizeof(ram);
|
|
1511
|
+
|
|
1512
|
+
rc_runtime_init(&runtime);
|
|
1513
|
+
event_count = 0;
|
|
1514
|
+
|
|
1515
|
+
assert_activate_achievement(&runtime, 1, "0xH0001=10");
|
|
1516
|
+
assert_activate_achievement(&runtime, 2, "0xH0002=10");
|
|
1517
|
+
assert_activate_achievement(&runtime, 3, "0xH0001=10S0xH0002=10S0xH0003=10");
|
|
1518
|
+
|
|
1519
|
+
/* achievements should start in waiting state */
|
|
1520
|
+
assert_do_frame_invalid(&runtime, &memory, 0);
|
|
1521
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
1522
|
+
ASSERT_NUM_EQUALS(runtime.triggers[1].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
1523
|
+
ASSERT_NUM_EQUALS(runtime.triggers[2].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
1524
|
+
|
|
1525
|
+
/* second and third achievements depend on address 2 */
|
|
1526
|
+
assert_do_frame_invalid(&runtime, &memory, 2);
|
|
1527
|
+
ASSERT_NUM_EQUALS(event_count, 2);
|
|
1528
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
1529
|
+
ASSERT_NUM_EQUALS(runtime.triggers[1].trigger->state, RC_TRIGGER_STATE_DISABLED);
|
|
1530
|
+
ASSERT_NUM_EQUALS(runtime.triggers[2].trigger->state, RC_TRIGGER_STATE_DISABLED);
|
|
1531
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_DISABLED, 2, 2);
|
|
1532
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_DISABLED, 3, 2);
|
|
1533
|
+
|
|
1534
|
+
rc_runtime_destroy(&runtime);
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
static void test_invalidate_address_leaderboard(void)
|
|
1538
|
+
{
|
|
1539
|
+
uint8_t ram[] = { 0, 10, 10 };
|
|
1540
|
+
memory_invalid_t memory;
|
|
1541
|
+
rc_runtime_t runtime;
|
|
1542
|
+
|
|
1543
|
+
memory.memory.ram = ram;
|
|
1544
|
+
memory.memory.size = sizeof(ram);
|
|
1545
|
+
|
|
1546
|
+
rc_runtime_init(&runtime);
|
|
1547
|
+
event_count = 0;
|
|
1548
|
+
|
|
1549
|
+
assert_activate_lboard(&runtime, 1, "STA:0xH0001=10::SUB:0xH0001=11::CAN:0xH0001=12::VAL:0xH0001");
|
|
1550
|
+
assert_activate_lboard(&runtime, 2, "STA:0xH0002=10::SUB:0xH0002=11::CAN:0xH0002=12::VAL:0xH0002*2");
|
|
1551
|
+
|
|
1552
|
+
/* leaderboards should start in waiting state */
|
|
1553
|
+
assert_do_frame_invalid(&runtime, &memory, 0);
|
|
1554
|
+
ASSERT_NUM_EQUALS(runtime.lboards[0].lboard->state, RC_LBOARD_STATE_WAITING);
|
|
1555
|
+
ASSERT_NUM_EQUALS(runtime.lboards[1].lboard->state, RC_LBOARD_STATE_WAITING);
|
|
1556
|
+
ASSERT_NUM_EQUALS(event_count, 0);
|
|
1557
|
+
|
|
1558
|
+
/* second leaderboard depends on address 2 */
|
|
1559
|
+
assert_do_frame_invalid(&runtime, &memory, 2);
|
|
1560
|
+
ASSERT_NUM_EQUALS(event_count, 1);
|
|
1561
|
+
ASSERT_NUM_EQUALS(runtime.lboards[0].lboard->state, RC_LBOARD_STATE_WAITING);
|
|
1562
|
+
ASSERT_NUM_EQUALS(runtime.lboards[1].lboard->state, RC_LBOARD_STATE_DISABLED);
|
|
1563
|
+
assert_event(RC_RUNTIME_EVENT_LBOARD_DISABLED, 2, 2);
|
|
1564
|
+
|
|
1565
|
+
rc_runtime_destroy(&runtime);
|
|
1566
|
+
}
|
|
1567
|
+
|
|
1568
|
+
static int validate_address_handler(uint32_t address)
|
|
1569
|
+
{
|
|
1570
|
+
return (address & 1) == 0; /* all even addresses are valid */
|
|
1571
|
+
}
|
|
1572
|
+
|
|
1573
|
+
static void test_validate_addresses(void)
|
|
1574
|
+
{
|
|
1575
|
+
rc_runtime_t runtime;
|
|
1576
|
+
|
|
1577
|
+
rc_runtime_init(&runtime);
|
|
1578
|
+
event_count = 0;
|
|
1579
|
+
|
|
1580
|
+
assert_activate_achievement(&runtime, 1, "0xH0001=10");
|
|
1581
|
+
assert_activate_achievement(&runtime, 2, "0xH0003=10"); /* put two invalid memrefs next to each other */
|
|
1582
|
+
assert_activate_achievement(&runtime, 3, "0xH0002=10");
|
|
1583
|
+
assert_activate_achievement(&runtime, 4, "0xH0001=10"); /* shared reference to invalid memref */
|
|
1584
|
+
assert_activate_lboard(&runtime, 1, "STA:0xH0001=10::SUB:0xH0001=11::CAN:0xH0001=12::VAL:0xH0001");
|
|
1585
|
+
assert_activate_lboard(&runtime, 2, "STA:0xH0002=10::SUB:0xH0002=11::CAN:0xH0002=12::VAL:0xH0002*2");
|
|
1586
|
+
|
|
1587
|
+
/* everything should start in waiting state */
|
|
1588
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
1589
|
+
ASSERT_NUM_EQUALS(runtime.triggers[1].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
1590
|
+
ASSERT_NUM_EQUALS(runtime.triggers[2].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
1591
|
+
ASSERT_NUM_EQUALS(runtime.triggers[3].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
1592
|
+
ASSERT_NUM_EQUALS(runtime.lboards[0].lboard->state, RC_LBOARD_STATE_WAITING);
|
|
1593
|
+
ASSERT_NUM_EQUALS(runtime.lboards[1].lboard->state, RC_LBOARD_STATE_WAITING);
|
|
1594
|
+
|
|
1595
|
+
/* validate_addresses should immediately disable the achievements and raise the event */
|
|
1596
|
+
rc_runtime_validate_addresses(&runtime, event_handler, validate_address_handler);
|
|
1597
|
+
ASSERT_NUM_EQUALS(runtime.triggers[0].trigger->state, RC_TRIGGER_STATE_DISABLED);
|
|
1598
|
+
ASSERT_NUM_EQUALS(runtime.triggers[1].trigger->state, RC_TRIGGER_STATE_DISABLED);
|
|
1599
|
+
ASSERT_NUM_EQUALS(runtime.triggers[2].trigger->state, RC_TRIGGER_STATE_WAITING);
|
|
1600
|
+
ASSERT_NUM_EQUALS(runtime.triggers[3].trigger->state, RC_TRIGGER_STATE_DISABLED);
|
|
1601
|
+
ASSERT_NUM_EQUALS(runtime.lboards[0].lboard->state, RC_LBOARD_STATE_DISABLED);
|
|
1602
|
+
ASSERT_NUM_EQUALS(runtime.lboards[1].lboard->state, RC_LBOARD_STATE_WAITING);
|
|
1603
|
+
|
|
1604
|
+
ASSERT_NUM_EQUALS(event_count, 4);
|
|
1605
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_DISABLED, 1, 1);
|
|
1606
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_DISABLED, 2, 3);
|
|
1607
|
+
assert_event(RC_RUNTIME_EVENT_ACHIEVEMENT_DISABLED, 4, 1);
|
|
1608
|
+
assert_event(RC_RUNTIME_EVENT_LBOARD_DISABLED, 1, 1);
|
|
1609
|
+
|
|
1610
|
+
rc_runtime_destroy(&runtime);
|
|
1611
|
+
}
|
|
1612
|
+
|
|
1613
|
+
void test_runtime(void) {
|
|
1614
|
+
TEST_SUITE_BEGIN();
|
|
1615
|
+
|
|
1616
|
+
/* achievements */
|
|
1617
|
+
TEST(test_two_achievements_activate_and_trigger);
|
|
1618
|
+
TEST(test_deactivate_achievements);
|
|
1619
|
+
TEST(test_achievement_measured);
|
|
1620
|
+
TEST(test_achievement_measured_maxint);
|
|
1621
|
+
TEST(test_two_achievements_differing_resets_in_alts);
|
|
1622
|
+
|
|
1623
|
+
TEST(test_shared_memref);
|
|
1624
|
+
TEST(test_replace_active_trigger);
|
|
1625
|
+
TEST(test_trigger_deactivation);
|
|
1626
|
+
TEST(test_trigger_with_resetif);
|
|
1627
|
+
TEST(test_trigger_with_resetnextif);
|
|
1628
|
+
|
|
1629
|
+
/* achievement events */
|
|
1630
|
+
TEST(test_reset_event);
|
|
1631
|
+
TEST(test_paused_event);
|
|
1632
|
+
TEST(test_primed_event);
|
|
1633
|
+
TEST(test_progress_event);
|
|
1634
|
+
TEST(test_progress_event_as_percent);
|
|
1635
|
+
|
|
1636
|
+
/* leaderboards */
|
|
1637
|
+
TEST(test_lboard);
|
|
1638
|
+
TEST_PARAMS3(test_format_lboard_value, RC_FORMAT_VALUE, 12345, "12,345");
|
|
1639
|
+
TEST_PARAMS3(test_format_lboard_value, RC_FORMAT_VALUE, -12345, "-12,345");
|
|
1640
|
+
TEST_PARAMS3(test_format_lboard_value, RC_FORMAT_VALUE, 0xFFFFFFFF, "-1");
|
|
1641
|
+
TEST_PARAMS3(test_format_lboard_value, RC_FORMAT_SCORE, 12345, "012345");
|
|
1642
|
+
TEST_PARAMS3(test_format_lboard_value, RC_FORMAT_SECONDS, 345, "5:45");
|
|
1643
|
+
TEST_PARAMS3(test_format_lboard_value, RC_FORMAT_CENTISECS, 12345, "2:03.45");
|
|
1644
|
+
TEST_PARAMS3(test_format_lboard_value, RC_FORMAT_FRAMES, 12345, "3:25.75");
|
|
1645
|
+
|
|
1646
|
+
/* rich presence */
|
|
1647
|
+
TEST(test_richpresence);
|
|
1648
|
+
TEST(test_richpresence_starts_with_macro);
|
|
1649
|
+
TEST(test_richpresence_macro_only);
|
|
1650
|
+
TEST(test_richpresence_conditional);
|
|
1651
|
+
TEST(test_richpresence_conditional_with_hits);
|
|
1652
|
+
TEST(test_richpresence_conditional_with_hits_after_match);
|
|
1653
|
+
TEST(test_richpresence_reload);
|
|
1654
|
+
TEST(test_richpresence_reload_addaddress);
|
|
1655
|
+
TEST(test_richpresence_static);
|
|
1656
|
+
TEST(test_richpresence_addsource_chain);
|
|
1657
|
+
|
|
1658
|
+
/* invalidate address */
|
|
1659
|
+
TEST(test_invalidate_address);
|
|
1660
|
+
TEST(test_invalidate_address_no_memrefs);
|
|
1661
|
+
TEST(test_invalidate_address_shared_memref);
|
|
1662
|
+
TEST(test_invalidate_address_leaderboard);
|
|
1663
|
+
|
|
1664
|
+
TEST(test_validate_addresses);
|
|
1665
|
+
|
|
1666
|
+
TEST_SUITE_END();
|
|
1667
|
+
}
|