gemba 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (285) hide show
  1. checksums.yaml +4 -4
  2. data/THIRD_PARTY_NOTICES +37 -2
  3. data/assets/placeholder_boxart.png +0 -0
  4. data/bin/gemba +2 -2
  5. data/ext/gemba/extconf.rb +23 -1
  6. data/ext/gemba/gemba_ext.c +436 -2
  7. data/ext/gemba/gemba_ext.h +2 -0
  8. data/gemba.gemspec +5 -3
  9. data/lib/gemba/achievements/achievement.rb +23 -0
  10. data/lib/gemba/achievements/backend.rb +186 -0
  11. data/lib/gemba/achievements/cache.rb +70 -0
  12. data/lib/gemba/achievements/credentials_presenter.rb +142 -0
  13. data/lib/gemba/achievements/fake_backend.rb +205 -0
  14. data/lib/gemba/achievements/null_backend.rb +11 -0
  15. data/lib/gemba/achievements/offline_backend.rb +168 -0
  16. data/lib/gemba/achievements/retro_achievements/backend.rb +453 -0
  17. data/lib/gemba/achievements/retro_achievements/cli_sync_requester.rb +64 -0
  18. data/lib/gemba/achievements/retro_achievements/ping_worker.rb +27 -0
  19. data/lib/gemba/achievements.rb +19 -0
  20. data/lib/gemba/achievements_window.rb +556 -0
  21. data/lib/gemba/app_controller.rb +1015 -0
  22. data/lib/gemba/bios.rb +54 -0
  23. data/lib/gemba/boxart_fetcher/libretro_backend.rb +39 -0
  24. data/lib/gemba/boxart_fetcher/null_backend.rb +12 -0
  25. data/lib/gemba/boxart_fetcher.rb +79 -0
  26. data/lib/gemba/bus_emitter.rb +13 -0
  27. data/lib/gemba/child_window.rb +24 -1
  28. data/lib/gemba/cli/commands/config_cmd.rb +83 -0
  29. data/lib/gemba/cli/commands/decode.rb +154 -0
  30. data/lib/gemba/cli/commands/patch.rb +78 -0
  31. data/lib/gemba/cli/commands/play.rb +78 -0
  32. data/lib/gemba/cli/commands/record.rb +114 -0
  33. data/lib/gemba/cli/commands/replay.rb +161 -0
  34. data/lib/gemba/cli/commands/retro_achievements.rb +213 -0
  35. data/lib/gemba/cli/commands/version.rb +22 -0
  36. data/lib/gemba/cli.rb +52 -364
  37. data/lib/gemba/config.rb +134 -1
  38. data/lib/gemba/data/gb_games.json +1 -0
  39. data/lib/gemba/data/gb_md5.json +1 -0
  40. data/lib/gemba/data/gba_games.json +1 -0
  41. data/lib/gemba/data/gba_md5.json +1 -0
  42. data/lib/gemba/data/gbc_games.json +1 -0
  43. data/lib/gemba/data/gbc_md5.json +1 -0
  44. data/lib/gemba/emulator_frame.rb +1060 -0
  45. data/lib/gemba/event_bus.rb +48 -0
  46. data/lib/gemba/frame_stack.rb +60 -0
  47. data/lib/gemba/game_index.rb +84 -0
  48. data/lib/gemba/game_picker_frame.rb +268 -0
  49. data/lib/gemba/gamepad_map.rb +103 -0
  50. data/lib/gemba/headless.rb +6 -5
  51. data/lib/gemba/headless_player.rb +33 -3
  52. data/lib/gemba/help_window.rb +61 -0
  53. data/lib/gemba/hotkey_map.rb +3 -1
  54. data/lib/gemba/input_recorder.rb +107 -0
  55. data/lib/gemba/input_replayer.rb +119 -0
  56. data/lib/gemba/keyboard_map.rb +90 -0
  57. data/lib/gemba/locales/en.yml +97 -5
  58. data/lib/gemba/locales/ja.yml +97 -5
  59. data/lib/gemba/main_window.rb +56 -0
  60. data/lib/gemba/modal_stack.rb +81 -0
  61. data/lib/gemba/patcher_window.rb +223 -0
  62. data/lib/gemba/platform/gb.rb +21 -0
  63. data/lib/gemba/platform/gba.rb +21 -0
  64. data/lib/gemba/platform/gbc.rb +23 -0
  65. data/lib/gemba/platform.rb +20 -0
  66. data/lib/gemba/platform_open.rb +19 -0
  67. data/lib/gemba/recorder.rb +4 -3
  68. data/lib/gemba/replay_player.rb +691 -0
  69. data/lib/gemba/rom_info.rb +57 -0
  70. data/lib/gemba/rom_info_window.rb +16 -3
  71. data/lib/gemba/rom_library.rb +106 -0
  72. data/lib/gemba/rom_overrides.rb +47 -0
  73. data/lib/gemba/rom_patcher/bps.rb +161 -0
  74. data/lib/gemba/rom_patcher/ips.rb +101 -0
  75. data/lib/gemba/rom_patcher/ups.rb +118 -0
  76. data/lib/gemba/rom_patcher.rb +109 -0
  77. data/lib/gemba/{rom_loader.rb → rom_resolver.rb} +7 -6
  78. data/lib/gemba/runtime.rb +59 -26
  79. data/lib/gemba/save_state_manager.rb +4 -7
  80. data/lib/gemba/save_state_picker.rb +17 -4
  81. data/lib/gemba/session_logger.rb +64 -0
  82. data/lib/gemba/settings/audio_tab.rb +77 -0
  83. data/lib/gemba/settings/gamepad_tab.rb +351 -0
  84. data/lib/gemba/settings/hotkeys_tab.rb +259 -0
  85. data/lib/gemba/settings/paths.rb +11 -0
  86. data/lib/gemba/settings/recording_tab.rb +83 -0
  87. data/lib/gemba/settings/save_states_tab.rb +91 -0
  88. data/lib/gemba/settings/system_tab.rb +362 -0
  89. data/lib/gemba/settings/video_tab.rb +318 -0
  90. data/lib/gemba/settings_window.rb +162 -1036
  91. data/lib/gemba/version.rb +1 -1
  92. data/lib/gemba/virtual_keyboard.rb +19 -0
  93. data/lib/gemba.rb +2 -12
  94. data/test/achievements_window/test_bulk_sync.rb +218 -0
  95. data/test/achievements_window/test_bus_events.rb +125 -0
  96. data/test/achievements_window/test_close_confirmation.rb +201 -0
  97. data/test/achievements_window/test_initial_state.rb +164 -0
  98. data/test/achievements_window/test_sorting.rb +227 -0
  99. data/test/achievements_window/test_tree_rendering.rb +133 -0
  100. data/test/fixtures/fake_bios.bin +0 -0
  101. data/test/fixtures/pong.gba +0 -0
  102. data/test/fixtures/test.gb +0 -0
  103. data/test/fixtures/test.gbc +0 -0
  104. data/test/fixtures/test_quicksave.ss +0 -0
  105. data/test/screenshots/no_focus.png +0 -0
  106. data/test/shared/teek_test_worker.rb +17 -1
  107. data/test/shared/tk_test_helper.rb +91 -4
  108. data/test/support/achievements_window_helpers.rb +18 -0
  109. data/test/support/fake_core.rb +25 -0
  110. data/test/support/fake_ra_runtime.rb +74 -0
  111. data/test/support/fake_requester.rb +68 -0
  112. data/test/support/player_helpers.rb +20 -5
  113. data/test/test_achievement.rb +32 -0
  114. data/test/{test_player.rb → test_app_controller.rb} +353 -85
  115. data/test/test_bios.rb +123 -0
  116. data/test/test_boxart_fetcher.rb +150 -0
  117. data/test/test_cli.rb +17 -265
  118. data/test/test_cli_config.rb +64 -0
  119. data/test/test_cli_decode.rb +97 -0
  120. data/test/test_cli_patch.rb +58 -0
  121. data/test/test_cli_play.rb +213 -0
  122. data/test/test_cli_ra.rb +175 -0
  123. data/test/test_cli_record.rb +69 -0
  124. data/test/test_cli_replay.rb +72 -0
  125. data/test/test_cli_sync_requester.rb +152 -0
  126. data/test/test_cli_version.rb +27 -0
  127. data/test/test_config.rb +2 -3
  128. data/test/test_config_ra.rb +69 -0
  129. data/test/test_core.rb +62 -1
  130. data/test/test_credentials_presenter.rb +192 -0
  131. data/test/test_event_bus.rb +100 -0
  132. data/test/test_fake_backend_achievements.rb +130 -0
  133. data/test/test_fake_backend_auth.rb +68 -0
  134. data/test/test_game_index.rb +77 -0
  135. data/test/test_game_picker_frame.rb +310 -0
  136. data/test/test_gamepad_map.rb +1 -3
  137. data/test/test_headless_player.rb +17 -3
  138. data/test/test_help_window.rb +82 -0
  139. data/test/test_hotkey_map.rb +22 -1
  140. data/test/test_input_recorder.rb +179 -0
  141. data/test/test_input_replay_determinism.rb +113 -0
  142. data/test/test_input_replayer.rb +162 -0
  143. data/test/test_keyboard_map.rb +1 -3
  144. data/test/test_libretro_backend.rb +41 -0
  145. data/test/test_locale.rb +1 -1
  146. data/test/test_logging.rb +123 -0
  147. data/test/test_null_backend.rb +42 -0
  148. data/test/test_offline_backend.rb +116 -0
  149. data/test/test_overlay_renderer.rb +1 -1
  150. data/test/test_platform.rb +149 -0
  151. data/test/test_ra_backend.rb +313 -0
  152. data/test/test_ra_backend_unlock_gate.rb +56 -0
  153. data/test/test_recorder.rb +0 -3
  154. data/test/test_replay_player.rb +316 -0
  155. data/test/test_rom_info.rb +149 -0
  156. data/test/test_rom_overrides.rb +86 -0
  157. data/test/test_rom_patcher.rb +382 -0
  158. data/test/{test_rom_loader.rb → test_rom_resolver.rb} +25 -26
  159. data/test/test_save_state_manager.rb +2 -4
  160. data/test/test_settings_audio.rb +107 -0
  161. data/test/test_settings_hotkeys.rb +83 -66
  162. data/test/test_settings_recording.rb +49 -0
  163. data/test/test_settings_save_states.rb +97 -0
  164. data/test/test_settings_system.rb +133 -0
  165. data/test/test_settings_video.rb +450 -0
  166. data/test/test_settings_window.rb +76 -507
  167. data/test/test_tip_service.rb +6 -6
  168. data/test/test_toast_overlay.rb +1 -1
  169. data/test/test_virtual_events.rb +156 -0
  170. data/test/test_virtual_keyboard.rb +1 -1
  171. data/vendor/rcheevos/CHANGELOG.md +495 -0
  172. data/vendor/rcheevos/LICENSE +21 -0
  173. data/vendor/rcheevos/Package.swift +33 -0
  174. data/vendor/rcheevos/README.md +67 -0
  175. data/vendor/rcheevos/include/module.modulemap +70 -0
  176. data/vendor/rcheevos/include/rc_api_editor.h +296 -0
  177. data/vendor/rcheevos/include/rc_api_info.h +280 -0
  178. data/vendor/rcheevos/include/rc_api_request.h +77 -0
  179. data/vendor/rcheevos/include/rc_api_runtime.h +417 -0
  180. data/vendor/rcheevos/include/rc_api_user.h +262 -0
  181. data/vendor/rcheevos/include/rc_client.h +877 -0
  182. data/vendor/rcheevos/include/rc_client_raintegration.h +101 -0
  183. data/vendor/rcheevos/include/rc_consoles.h +138 -0
  184. data/vendor/rcheevos/include/rc_error.h +59 -0
  185. data/vendor/rcheevos/include/rc_export.h +100 -0
  186. data/vendor/rcheevos/include/rc_hash.h +200 -0
  187. data/vendor/rcheevos/include/rc_runtime.h +148 -0
  188. data/vendor/rcheevos/include/rc_runtime_types.h +452 -0
  189. data/vendor/rcheevos/include/rc_util.h +51 -0
  190. data/vendor/rcheevos/include/rcheevos.h +8 -0
  191. data/vendor/rcheevos/src/rapi/rc_api_common.c +1379 -0
  192. data/vendor/rcheevos/src/rapi/rc_api_common.h +88 -0
  193. data/vendor/rcheevos/src/rapi/rc_api_editor.c +625 -0
  194. data/vendor/rcheevos/src/rapi/rc_api_info.c +587 -0
  195. data/vendor/rcheevos/src/rapi/rc_api_runtime.c +901 -0
  196. data/vendor/rcheevos/src/rapi/rc_api_user.c +483 -0
  197. data/vendor/rcheevos/src/rc_client.c +6941 -0
  198. data/vendor/rcheevos/src/rc_client_external.c +281 -0
  199. data/vendor/rcheevos/src/rc_client_external.h +177 -0
  200. data/vendor/rcheevos/src/rc_client_external_versions.h +171 -0
  201. data/vendor/rcheevos/src/rc_client_internal.h +409 -0
  202. data/vendor/rcheevos/src/rc_client_raintegration.c +566 -0
  203. data/vendor/rcheevos/src/rc_client_raintegration_internal.h +61 -0
  204. data/vendor/rcheevos/src/rc_client_types.natvis +396 -0
  205. data/vendor/rcheevos/src/rc_compat.c +251 -0
  206. data/vendor/rcheevos/src/rc_compat.h +121 -0
  207. data/vendor/rcheevos/src/rc_libretro.c +915 -0
  208. data/vendor/rcheevos/src/rc_libretro.h +98 -0
  209. data/vendor/rcheevos/src/rc_util.c +199 -0
  210. data/vendor/rcheevos/src/rc_version.c +11 -0
  211. data/vendor/rcheevos/src/rc_version.h +32 -0
  212. data/vendor/rcheevos/src/rcheevos/alloc.c +312 -0
  213. data/vendor/rcheevos/src/rcheevos/condition.c +754 -0
  214. data/vendor/rcheevos/src/rcheevos/condset.c +777 -0
  215. data/vendor/rcheevos/src/rcheevos/consoleinfo.c +1215 -0
  216. data/vendor/rcheevos/src/rcheevos/format.c +330 -0
  217. data/vendor/rcheevos/src/rcheevos/lboard.c +287 -0
  218. data/vendor/rcheevos/src/rcheevos/memref.c +805 -0
  219. data/vendor/rcheevos/src/rcheevos/operand.c +607 -0
  220. data/vendor/rcheevos/src/rcheevos/rc_internal.h +390 -0
  221. data/vendor/rcheevos/src/rcheevos/rc_runtime_types.natvis +541 -0
  222. data/vendor/rcheevos/src/rcheevos/rc_validate.c +1406 -0
  223. data/vendor/rcheevos/src/rcheevos/rc_validate.h +18 -0
  224. data/vendor/rcheevos/src/rcheevos/richpresence.c +922 -0
  225. data/vendor/rcheevos/src/rcheevos/runtime.c +852 -0
  226. data/vendor/rcheevos/src/rcheevos/runtime_progress.c +1073 -0
  227. data/vendor/rcheevos/src/rcheevos/trigger.c +344 -0
  228. data/vendor/rcheevos/src/rcheevos/value.c +935 -0
  229. data/vendor/rcheevos/src/rhash/aes.c +480 -0
  230. data/vendor/rcheevos/src/rhash/aes.h +49 -0
  231. data/vendor/rcheevos/src/rhash/cdreader.c +838 -0
  232. data/vendor/rcheevos/src/rhash/hash.c +1402 -0
  233. data/vendor/rcheevos/src/rhash/hash_disc.c +1340 -0
  234. data/vendor/rcheevos/src/rhash/hash_encrypted.c +566 -0
  235. data/vendor/rcheevos/src/rhash/hash_rom.c +426 -0
  236. data/vendor/rcheevos/src/rhash/hash_zip.c +460 -0
  237. data/vendor/rcheevos/src/rhash/md5.c +382 -0
  238. data/vendor/rcheevos/src/rhash/md5.h +91 -0
  239. data/vendor/rcheevos/src/rhash/rc_hash_internal.h +116 -0
  240. data/vendor/rcheevos/test/libretro.h +205 -0
  241. data/vendor/rcheevos/test/rapi/test_rc_api_common.c +941 -0
  242. data/vendor/rcheevos/test/rapi/test_rc_api_editor.c +931 -0
  243. data/vendor/rcheevos/test/rapi/test_rc_api_info.c +545 -0
  244. data/vendor/rcheevos/test/rapi/test_rc_api_runtime.c +2213 -0
  245. data/vendor/rcheevos/test/rapi/test_rc_api_user.c +998 -0
  246. data/vendor/rcheevos/test/rcheevos/mock_memory.h +32 -0
  247. data/vendor/rcheevos/test/rcheevos/test_condition.c +570 -0
  248. data/vendor/rcheevos/test/rcheevos/test_condset.c +5170 -0
  249. data/vendor/rcheevos/test/rcheevos/test_consoleinfo.c +203 -0
  250. data/vendor/rcheevos/test/rcheevos/test_format.c +112 -0
  251. data/vendor/rcheevos/test/rcheevos/test_lboard.c +746 -0
  252. data/vendor/rcheevos/test/rcheevos/test_memref.c +520 -0
  253. data/vendor/rcheevos/test/rcheevos/test_operand.c +692 -0
  254. data/vendor/rcheevos/test/rcheevos/test_rc_validate.c +502 -0
  255. data/vendor/rcheevos/test/rcheevos/test_richpresence.c +1564 -0
  256. data/vendor/rcheevos/test/rcheevos/test_runtime.c +1667 -0
  257. data/vendor/rcheevos/test/rcheevos/test_runtime_progress.c +1821 -0
  258. data/vendor/rcheevos/test/rcheevos/test_timing.c +166 -0
  259. data/vendor/rcheevos/test/rcheevos/test_trigger.c +2521 -0
  260. data/vendor/rcheevos/test/rcheevos/test_value.c +870 -0
  261. data/vendor/rcheevos/test/rcheevos-test.sln +46 -0
  262. data/vendor/rcheevos/test/rcheevos-test.vcxproj +239 -0
  263. data/vendor/rcheevos/test/rcheevos-test.vcxproj.filters +335 -0
  264. data/vendor/rcheevos/test/rhash/data.c +657 -0
  265. data/vendor/rcheevos/test/rhash/data.h +32 -0
  266. data/vendor/rcheevos/test/rhash/mock_filereader.c +236 -0
  267. data/vendor/rcheevos/test/rhash/mock_filereader.h +31 -0
  268. data/vendor/rcheevos/test/rhash/test_cdreader.c +920 -0
  269. data/vendor/rcheevos/test/rhash/test_hash.c +310 -0
  270. data/vendor/rcheevos/test/rhash/test_hash_disc.c +1450 -0
  271. data/vendor/rcheevos/test/rhash/test_hash_rom.c +899 -0
  272. data/vendor/rcheevos/test/rhash/test_hash_zip.c +551 -0
  273. data/vendor/rcheevos/test/test.c +113 -0
  274. data/vendor/rcheevos/test/test_framework.h +205 -0
  275. data/vendor/rcheevos/test/test_rc_client.c +10509 -0
  276. data/vendor/rcheevos/test/test_rc_client_external.c +2197 -0
  277. data/vendor/rcheevos/test/test_rc_client_raintegration.c +441 -0
  278. data/vendor/rcheevos/test/test_rc_libretro.c +952 -0
  279. data/vendor/rcheevos/test/test_types.natvis +9 -0
  280. data/vendor/rcheevos/validator/validator.c +658 -0
  281. data/vendor/rcheevos/validator/validator.vcxproj +152 -0
  282. data/vendor/rcheevos/validator/validator.vcxproj.filters +82 -0
  283. metadata +274 -11
  284. data/lib/gemba/input_mappings.rb +0 -214
  285. data/lib/gemba/player.rb +0 -1525
@@ -0,0 +1,746 @@
1
+ #include "rc_internal.h"
2
+
3
+ #include "../test_framework.h"
4
+ #include "mock_memory.h"
5
+
6
+ static void _assert_parse_lboard(rc_lboard_t** lboard, void* buffer, const char* memaddr)
7
+ {
8
+ int size;
9
+ unsigned* overflow;
10
+
11
+ size = rc_lboard_size(memaddr);
12
+ ASSERT_NUM_GREATER(size, 0);
13
+
14
+ overflow = (unsigned*)(((char*)buffer) + size);
15
+ *overflow = 0xCDCDCDCD;
16
+
17
+ *lboard = rc_parse_lboard(buffer, memaddr, NULL, 0);
18
+ ASSERT_PTR_NOT_NULL(*lboard);
19
+
20
+ if (*overflow != 0xCDCDCDCD) {
21
+ ASSERT_FAIL("write past end of buffer");
22
+ }
23
+ }
24
+ #define assert_parse_lboard(lboard, buffer, memaddr) ASSERT_HELPER(_assert_parse_lboard(lboard, buffer, memaddr), "assert_parse_lboard")
25
+
26
+ static int evaluate_lboard(rc_lboard_t* lboard, memory_t* memory, int* value) {
27
+ return rc_evaluate_lboard(lboard, value, peek, memory, NULL);
28
+ }
29
+
30
+ static void test_simple_leaderboard() {
31
+ uint8_t ram[] = {0x00, 0x12, 0x34, 0xAB, 0x56};
32
+ memory_t memory;
33
+ rc_lboard_t* lboard;
34
+ char buffer[1024];
35
+ int value;
36
+
37
+ memory.ram = ram;
38
+ memory.size = sizeof(ram);
39
+
40
+ assert_parse_lboard(&lboard, buffer, "STA:0xH00=1::CAN:0xH00=2::SUB:0xH00=3::VAL:0xH02");
41
+ ASSERT_NUM_EQUALS(lboard->state, RC_LBOARD_STATE_WAITING);
42
+
43
+ /* submit is true, but leaderboard has not started */
44
+ ram[0] = 3;
45
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_ACTIVE);
46
+ ASSERT_NUM_EQUALS(value, 0); /* value is only calculated in STARTED and TRIGGERED states */
47
+
48
+ /* cancel is true - still not started */
49
+ ram[0] = 2;
50
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_ACTIVE);
51
+ ASSERT_NUM_EQUALS(value, 0);
52
+
53
+ /* start is true - will activate */
54
+ ram[0] = 1;
55
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
56
+ ASSERT_NUM_EQUALS(value, 0x34);
57
+
58
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
59
+ ASSERT_NUM_EQUALS(value, 0x34);
60
+
61
+ /* cancel is true - will deactivate */
62
+ ram[0] = 2;
63
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_CANCELED);
64
+ ASSERT_NUM_EQUALS(value, 0);
65
+
66
+ /* submit is true, but leaderboard is not active */
67
+ ram[0] = 3;
68
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_ACTIVE);
69
+ ASSERT_NUM_EQUALS(value, 0);
70
+
71
+ /* start is true - will activate */
72
+ ram[0] = 1;
73
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
74
+ ASSERT_NUM_EQUALS(value, 0x34);
75
+
76
+ /* submit is true - will submit */
77
+ ram[0] = 3;
78
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_TRIGGERED);
79
+ ASSERT_NUM_EQUALS(value, 0x34);
80
+ }
81
+
82
+ static void test_start_and_cancel_same_frame() {
83
+ uint8_t ram[] = {0x00, 0x12, 0x34, 0xAB, 0x56};
84
+ memory_t memory;
85
+ rc_lboard_t* lboard;
86
+ char buffer[1024];
87
+ int value;
88
+
89
+ memory.ram = ram;
90
+ memory.size = sizeof(ram);
91
+
92
+ assert_parse_lboard(&lboard, buffer, "STA:0xH00=0::CAN:0xH01=18::SUB:0xH00=3::VAL:0xH02");
93
+ lboard->state = RC_LBOARD_STATE_ACTIVE;
94
+
95
+ /* start and cancel are both true - should not start */
96
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_ACTIVE);
97
+
98
+ /* cancel no longer true - should start */
99
+ ram[1] = 0x13;
100
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
101
+
102
+ /* start and cancel are both true - should cancel */
103
+ ram[1] = 0x12;
104
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_CANCELED);
105
+
106
+ /* cancel no longer true, but start still is - shouldn't activate */
107
+ ram[1] = 0x13;
108
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_INACTIVE);
109
+
110
+ /* start no longer true - can activate */
111
+ ram[0] = 1;
112
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_ACTIVE);
113
+
114
+ /* start true - should start */
115
+ ram[0] = 0;
116
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
117
+ }
118
+
119
+ static void test_start_and_submit_same_frame() {
120
+ uint8_t ram[] = {0x00, 0x12, 0x34, 0xAB, 0x56};
121
+ memory_t memory;
122
+ rc_lboard_t* lboard;
123
+ char buffer[1024];
124
+ int value;
125
+
126
+ memory.ram = ram;
127
+ memory.size = sizeof(ram);
128
+
129
+ assert_parse_lboard(&lboard, buffer, "STA:0xH00=0::CAN:0xH01=10::SUB:0xH01=18::VAL:0xH02");
130
+ lboard->state = RC_LBOARD_STATE_ACTIVE;
131
+
132
+ /* start and submit are both true - should trigger */
133
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_TRIGGERED);
134
+ ASSERT_NUM_EQUALS(value, 0x34);
135
+
136
+ /* disable submit - leaderboard should not start */
137
+ ram[1] = 0;
138
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_INACTIVE);
139
+
140
+ /* disable start - leaderboard can activate */
141
+ ram[0] = 1;
142
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_ACTIVE);
143
+
144
+ /* enable start - leaderboard should start */
145
+ ram[0] = 0;
146
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
147
+ }
148
+
149
+ static void test_start_and_submit_same_frame_hitcount() {
150
+ uint8_t ram[] = {0x00, 0x12, 0x34, 0xAB, 0x56};
151
+ memory_t memory;
152
+ rc_lboard_t* lboard;
153
+ char buffer[1024];
154
+ int value;
155
+
156
+ memory.ram = ram;
157
+ memory.size = sizeof(ram);
158
+
159
+ assert_parse_lboard(&lboard, buffer, "STA:0xH00=0::CAN:0=1::SUB:1=1::VAL:M:0xH02=52");
160
+ lboard->state = RC_LBOARD_STATE_ACTIVE;
161
+
162
+ /* start and submit are both true - should trigger. value logic is true, submit one hit */
163
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_TRIGGERED);
164
+ ASSERT_NUM_EQUALS(value, 1);
165
+
166
+ /* disable start - leaderboard can activate */
167
+ ram[0] = 1;
168
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_ACTIVE);
169
+
170
+ /* reactivate leaderboard - it should immediately submit again. value logic is still true, submit one hit */
171
+ ram[0] = 0;
172
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_TRIGGERED);
173
+ ASSERT_NUM_EQUALS(value, 1);
174
+
175
+ /* disable start - leaderboard can activate */
176
+ ram[0] = 1;
177
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_ACTIVE);
178
+
179
+ /* reactivate leaderboard - it should immediately submit again. value logic is not true, submit zero hits */
180
+ ram[2] = 55;
181
+ ram[0] = 0;
182
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_TRIGGERED);
183
+ ASSERT_NUM_EQUALS(value, 0);
184
+ }
185
+
186
+ static void test_start_and_conditions() {
187
+ uint8_t ram[] = {0x00, 0x12, 0x34, 0xAB, 0x56};
188
+ memory_t memory;
189
+ rc_lboard_t* lboard;
190
+ char buffer[1024];
191
+ int value;
192
+
193
+ memory.ram = ram;
194
+ memory.size = sizeof(ram);
195
+
196
+ assert_parse_lboard(&lboard, buffer, "STA:0xH00=0_0xH01=0::CAN:0xH01=10::SUB:0xH01=18::VAL:0xH02");
197
+ lboard->state = RC_LBOARD_STATE_ACTIVE;
198
+
199
+ /* only first start condition true - should not start */
200
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_ACTIVE);
201
+
202
+ /* only second start condition true - should not start */
203
+ ram[0] = 1;
204
+ ram[1] = 0;
205
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_ACTIVE);
206
+
207
+ /* both conditions true - should start */
208
+ ram[0] = 0;
209
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
210
+ }
211
+
212
+ static void test_start_or_conditions() {
213
+ uint8_t ram[] = {0x00, 0x12, 0x34, 0xAB, 0x56};
214
+ memory_t memory;
215
+ rc_lboard_t* lboard;
216
+ char buffer[1024];
217
+ int value;
218
+
219
+ memory.ram = ram;
220
+ memory.size = sizeof(ram);
221
+
222
+ assert_parse_lboard(&lboard, buffer, "STA:S0xH00=1S0xH01=1::CAN:0xH01=10::SUB:0xH01=18::VAL:0xH02");
223
+ lboard->state = RC_LBOARD_STATE_ACTIVE;
224
+
225
+ /* neither start condition true - should not start */
226
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_ACTIVE);
227
+
228
+ /* only second start condition true - should start */
229
+ ram[1] = 1;
230
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
231
+
232
+ /* reset lboard state */
233
+ ram[1] = 0;
234
+ lboard->state = RC_LBOARD_STATE_ACTIVE;
235
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_ACTIVE);
236
+
237
+ /* only first start condition true - should start */
238
+ ram[0] = 1;
239
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
240
+ }
241
+
242
+ static void test_start_resets_value() {
243
+ uint8_t ram[] = {0x00, 0x12, 0x34, 0xAB, 0x56};
244
+ memory_t memory;
245
+ rc_lboard_t* lboard;
246
+ char buffer[1024];
247
+ int value;
248
+
249
+ memory.ram = ram;
250
+ memory.size = sizeof(ram);
251
+
252
+ assert_parse_lboard(&lboard, buffer, "STA:0xH01=0::CAN:0xH01=10::SUB:0xH01=18::VAL:M:0xH02!=d0xH02");
253
+ lboard->state = RC_LBOARD_STATE_ACTIVE;
254
+
255
+ /* not started */
256
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_ACTIVE);
257
+ ASSERT_NUM_EQUALS(value, 0);
258
+
259
+ /* start condition true - should start */
260
+ ram[1] = 0;
261
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
262
+ ASSERT_NUM_EQUALS(value, 0);
263
+
264
+ /* tally a couple hits */
265
+ ram[2]++;
266
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
267
+ ASSERT_NUM_EQUALS(value, 1);
268
+
269
+ ram[2]++;
270
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
271
+ ASSERT_NUM_EQUALS(value, 2);
272
+
273
+ /* canceled, hitcount kept, but ignored */
274
+ ram[1] = 10;
275
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_CANCELED);
276
+ ASSERT_NUM_EQUALS(value, 0);
277
+
278
+ /* must wait one frame to switch back to active */
279
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_ACTIVE);
280
+ ASSERT_NUM_EQUALS(value, 0);
281
+
282
+ /* restarted, hitcount should be reset */
283
+ ram[1] = 0;
284
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
285
+ ASSERT_NUM_EQUALS(value, 0);
286
+
287
+ /* tally a hit */
288
+ ram[2]++;
289
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
290
+ ASSERT_NUM_EQUALS(value, 1);
291
+ }
292
+
293
+ static void test_cancel_or_conditions() {
294
+ uint8_t ram[] = {0x00, 0x12, 0x34, 0xAB, 0x56};
295
+ memory_t memory;
296
+ rc_lboard_t* lboard;
297
+ char buffer[1024];
298
+ int value;
299
+
300
+ memory.ram = ram;
301
+ memory.size = sizeof(ram);
302
+
303
+ assert_parse_lboard(&lboard, buffer, "STA:0xH00=0::CAN:S0xH01=12S0xH02=12::SUB:0xH00=3::VAL:0xH02");
304
+ lboard->state = RC_LBOARD_STATE_ACTIVE;
305
+
306
+ /* start condition true - should start */
307
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
308
+
309
+ /* second cancel condition true - should cancel */
310
+ ram[2] = 12;
311
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_CANCELED);
312
+
313
+ /* reset lboard state */
314
+ ram[2] = 0;
315
+ lboard->state = RC_LBOARD_STATE_ACTIVE;
316
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
317
+
318
+ /* first cancel condition true - should cancel */
319
+ ram[1] = 12;
320
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_CANCELED);
321
+ }
322
+
323
+ static void test_submit_and_conditions() {
324
+ uint8_t ram[] = {0x00, 0x12, 0x34, 0xAB, 0x56};
325
+ memory_t memory;
326
+ rc_lboard_t* lboard;
327
+ char buffer[1024];
328
+ int value;
329
+
330
+ memory.ram = ram;
331
+ memory.size = sizeof(ram);
332
+
333
+ assert_parse_lboard(&lboard, buffer, "STA:0xH00=0::CAN:0xH01=10::SUB:0xH01=18_0xH03=18::VAL:0xH02");
334
+ lboard->state = RC_LBOARD_STATE_ACTIVE;
335
+
336
+ /* only first submit condition is true - should not submit */
337
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
338
+
339
+ /* only second submit condition true - should not submit */
340
+ ram[1] = 0;
341
+ ram[3] = 18;
342
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
343
+
344
+ /* both conditions true - should submit */
345
+ ram[1] = 18;
346
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_TRIGGERED);
347
+ }
348
+
349
+ static void test_submit_or_conditions() {
350
+ uint8_t ram[] = {0x00, 0x12, 0x34, 0xAB, 0x56};
351
+ memory_t memory;
352
+ rc_lboard_t* lboard;
353
+ char buffer[1024];
354
+ int value;
355
+
356
+ memory.ram = ram;
357
+ memory.size = sizeof(ram);
358
+
359
+ assert_parse_lboard(&lboard, buffer, "STA:0xH00=0::CAN:0xH01=10::SUB:S0xH01=12S0xH03=12::VAL:0xH02");
360
+ lboard->state = RC_LBOARD_STATE_ACTIVE;
361
+
362
+ /* neither start condition true - should not submit */
363
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
364
+
365
+ /* only second submit condition true - should submit */
366
+ ram[1] = 12;
367
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_TRIGGERED);
368
+
369
+ /* reset lboard state */
370
+ ram[1] = 0;
371
+ lboard->state = RC_LBOARD_STATE_ACTIVE;
372
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
373
+
374
+ /* only first submit condition true - should submit */
375
+ ram[3] = 12;
376
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_TRIGGERED);
377
+ }
378
+
379
+ static void test_progress() {
380
+ uint8_t ram[] = {0x00, 0x12, 0x34, 0xAB, 0x56};
381
+ memory_t memory;
382
+ rc_lboard_t* lboard;
383
+ char buffer[1024];
384
+ int value;
385
+
386
+ memory.ram = ram;
387
+ memory.size = sizeof(ram);
388
+
389
+ assert_parse_lboard(&lboard, buffer, "STA:0xH00=0::CAN:0xH00=2::SUB:0xH00=3::PRO:0xH04::VAL:0xH02");
390
+ lboard->state = RC_LBOARD_STATE_ACTIVE;
391
+
392
+ /* start true - should start - value from PRO */
393
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
394
+ ASSERT_NUM_EQUALS(value, 0x56);
395
+
396
+ /* submit true - should trigger - value from VAL */
397
+ ram[0] = 3;
398
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_TRIGGERED);
399
+ ASSERT_NUM_EQUALS(value, 0x34);
400
+ }
401
+
402
+ static void test_value_from_hitcount() {
403
+ uint8_t ram[] = {0x00, 0x12, 0x34, 0xAB, 0x56};
404
+ memory_t memory;
405
+ rc_lboard_t* lboard;
406
+ char buffer[1024];
407
+ int value;
408
+
409
+ memory.ram = ram;
410
+ memory.size = sizeof(ram);
411
+
412
+ assert_parse_lboard(&lboard, buffer, "STA:0xH00=1::CAN:0xH00=2::SUB:0xH00=3::VAL:M:0xH02!=d0xH02");
413
+ lboard->state = RC_LBOARD_STATE_ACTIVE;
414
+
415
+ /* not started, value should not be tallied */
416
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_ACTIVE);
417
+ ASSERT_NUM_EQUALS(value, 0);
418
+
419
+ ram[2] = 3;
420
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_ACTIVE);
421
+ ASSERT_NUM_EQUALS(value, 0);
422
+
423
+ /* started, value will not be tallied as it hasn't changed */
424
+ ram[0] = 1;
425
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
426
+ ASSERT_NUM_EQUALS(value, 0);
427
+
428
+ /* value changed, expect tally */
429
+ ram[2] = 11;
430
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
431
+ ASSERT_NUM_EQUALS(value, 1);
432
+
433
+ /* not changed, no tally */
434
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
435
+ ASSERT_NUM_EQUALS(value, 1);
436
+
437
+ /* changed, tally */
438
+ ram[2] = 12;
439
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
440
+ ASSERT_NUM_EQUALS(value, 2);
441
+
442
+ /* canceled, expect no value */
443
+ ram[0] = 2;
444
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_CANCELED);
445
+ ASSERT_NUM_EQUALS(value, 0);
446
+
447
+ /* waiting to start, expect no value */
448
+ ram[2] = 13;
449
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_ACTIVE);
450
+ ASSERT_NUM_EQUALS(value, 0);
451
+
452
+ /* restarted, tally should be reset */
453
+ ram[0] = 1;
454
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
455
+ ASSERT_NUM_EQUALS(value, 0);
456
+
457
+ /* value changed, expect tally */
458
+ ram[2] = 11;
459
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
460
+ ASSERT_NUM_EQUALS(value, 1);
461
+ }
462
+
463
+ static void test_value_from_addhits() {
464
+ uint8_t ram[] = {0x00, 0x12, 0x34, 0xAB, 0x56};
465
+ memory_t memory;
466
+ rc_lboard_t* lboard;
467
+ char buffer[1024];
468
+ int value;
469
+
470
+ memory.ram = ram;
471
+ memory.size = sizeof(ram);
472
+
473
+ assert_parse_lboard(&lboard, buffer, "STA:0xH00=0::CAN:0xH00=2::SUB:0xH00=3::VAL:C:0xH03=1_M:0xH02=1");
474
+ lboard->state = RC_LBOARD_STATE_ACTIVE;
475
+
476
+ /* started, nothing to tally */
477
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
478
+ ASSERT_NUM_EQUALS(value, 0);
479
+
480
+ /* second value tallied*/
481
+ ram[2] = 1;
482
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
483
+ ASSERT_NUM_EQUALS(value, 1);
484
+
485
+ /* both values tallied */
486
+ ram[3] = 1;
487
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
488
+ ASSERT_NUM_EQUALS(value, 3);
489
+
490
+ /* only first value tallied */
491
+ ram[2] = 12;
492
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
493
+ ASSERT_NUM_EQUALS(value, 4);
494
+
495
+ /* canceled, expect no value */
496
+ ram[0] = 2;
497
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_CANCELED);
498
+ ASSERT_NUM_EQUALS(value, 0);
499
+
500
+ /* waiting to start, expect no value */
501
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_ACTIVE);
502
+ ASSERT_NUM_EQUALS(value, 0);
503
+
504
+ /* restarted, tally should be reset, but first is still true, so it'll be tallied */
505
+ ram[0] = 0;
506
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
507
+ ASSERT_NUM_EQUALS(value, 1);
508
+ }
509
+
510
+ static void test_value_from_float() {
511
+ /* bytes 5-8 are the float value for pi */
512
+ uint8_t ram[] = {0x00, 0x12, 0x34, 0xAB, 0x56, 0xDB, 0x0F, 0x49, 0x40};
513
+ memory_t memory;
514
+ rc_lboard_t* lboard;
515
+ char buffer[1024];
516
+ int value;
517
+
518
+ memory.ram = ram;
519
+ memory.size = sizeof(ram);
520
+
521
+ assert_parse_lboard(&lboard, buffer, "STA:0xH00=0::CAN:0xH00=2::SUB:0xH00=3::VAL:fF0005");
522
+ lboard->state = RC_LBOARD_STATE_ACTIVE;
523
+
524
+ /* started, nothing to tally */
525
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
526
+ ASSERT_NUM_EQUALS(value, 3);
527
+
528
+ /* canceled, expect no value */
529
+ ram[0] = 2;
530
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_CANCELED);
531
+ ASSERT_NUM_EQUALS(value, 0);
532
+
533
+ /* waiting to start, expect no value */
534
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_ACTIVE);
535
+ ASSERT_NUM_EQUALS(value, 0);
536
+
537
+ /* restarted */
538
+ ram[0] = 0;
539
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
540
+ ASSERT_NUM_EQUALS(value, 3);
541
+ }
542
+
543
+ static void test_value_from_float_scaled() {
544
+ /* bytes 5-8 are the float value for pi */
545
+ uint8_t ram[] = {0x00, 0x12, 0x34, 0xAB, 0x56, 0xDB, 0x0F, 0x49, 0x40};
546
+ memory_t memory;
547
+ rc_lboard_t* lboard;
548
+ char buffer[1024];
549
+ int value;
550
+
551
+ memory.ram = ram;
552
+ memory.size = sizeof(ram);
553
+
554
+ assert_parse_lboard(&lboard, buffer, "STA:0xH00=0::CAN:0xH00=2::SUB:0xH00=3::VAL:fF0005*100");
555
+ lboard->state = RC_LBOARD_STATE_ACTIVE;
556
+
557
+ /* started, nothing to tally */
558
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
559
+ ASSERT_NUM_EQUALS(value, 314);
560
+
561
+ /* canceled, expect no value */
562
+ ram[0] = 2;
563
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_CANCELED);
564
+ ASSERT_NUM_EQUALS(value, 0);
565
+
566
+ /* waiting to start, expect no value */
567
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_ACTIVE);
568
+ ASSERT_NUM_EQUALS(value, 0);
569
+
570
+ /* restarted */
571
+ ram[0] = 0;
572
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
573
+ ASSERT_NUM_EQUALS(value, 314);
574
+ }
575
+
576
+ static void test_value_from_division() {
577
+ uint8_t ram[] = { 0x00, 0x12, 0x34, 0xAB, 0x56 };
578
+ memory_t memory;
579
+ rc_lboard_t* lboard;
580
+ char buffer[1024];
581
+ int value;
582
+
583
+ memory.ram = ram;
584
+ memory.size = sizeof(ram);
585
+
586
+ assert_parse_lboard(&lboard, buffer, "STA:0xH00=1::CAN:0xH00=2::SUB:0xH00=3::VAL:M:0xH02/2");
587
+ ASSERT_NUM_EQUALS(lboard->state, RC_LBOARD_STATE_WAITING);
588
+
589
+ /* submit is true, but leaderboard has not started */
590
+ ram[0] = 3;
591
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_ACTIVE);
592
+ ASSERT_NUM_EQUALS(value, 0); /* value is only calculated in STARTED and TRIGGERED states */
593
+
594
+ /* cancel is true - still not started */
595
+ ram[0] = 2;
596
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_ACTIVE);
597
+ ASSERT_NUM_EQUALS(value, 0);
598
+
599
+ /* start is true - will activate */
600
+ ram[0] = 1;
601
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
602
+ ASSERT_NUM_EQUALS(value, 0x1a);
603
+
604
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
605
+ ASSERT_NUM_EQUALS(value, 0x1a);
606
+
607
+ /* cancel is true - will deactivate */
608
+ ram[0] = 2;
609
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_CANCELED);
610
+ ASSERT_NUM_EQUALS(value, 0);
611
+
612
+ /* submit is true, but leaderboard is not active */
613
+ ram[0] = 3;
614
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_ACTIVE);
615
+ ASSERT_NUM_EQUALS(value, 0);
616
+
617
+ /* start is true - will activate */
618
+ ram[0] = 1;
619
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
620
+ ASSERT_NUM_EQUALS(value, 0x1a);
621
+
622
+ /* submit is true - will submit */
623
+ ram[0] = 3;
624
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_TRIGGERED);
625
+ ASSERT_NUM_EQUALS(value, 0x1a);
626
+ }
627
+
628
+ static void test_maximum_value_from_conditions() {
629
+ uint8_t ram[] = {0x00, 0x12, 0x34, 0xAB, 0x56};
630
+ memory_t memory;
631
+ rc_lboard_t* lboard;
632
+ char buffer[1024];
633
+ int value;
634
+
635
+ memory.ram = ram;
636
+ memory.size = sizeof(ram);
637
+
638
+ assert_parse_lboard(&lboard, buffer, "STA:0xH00=0::CAN:0xH00=2::SUB:0xH00=3::VAL:Q:0xH01=1_M:0x 02$Q:0xH01=2_M:0x 03");
639
+ lboard->state = RC_LBOARD_STATE_ACTIVE;
640
+
641
+ /* started, neither value is active */
642
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
643
+ ASSERT_NUM_EQUALS(value, 0);
644
+
645
+ /* first value is active */
646
+ ram[1] = 1;
647
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
648
+ ASSERT_NUM_EQUALS(value, 0xAB34);
649
+
650
+ /* second value is active */
651
+ ram[1] = 2;
652
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
653
+ ASSERT_NUM_EQUALS(value, 0x56AB);
654
+
655
+ /* value updated */
656
+ ram[3] = 0x12;
657
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
658
+ ASSERT_NUM_EQUALS(value, 0x5612);
659
+
660
+ /* neither value is active */
661
+ ram[1] = 3;
662
+ ASSERT_NUM_EQUALS(evaluate_lboard(lboard, &memory, &value), RC_LBOARD_STATE_STARTED);
663
+ ASSERT_NUM_EQUALS(value, 0);
664
+ }
665
+
666
+ static void test_measured_value_and_condition()
667
+ {
668
+ rc_lboard_t* lboard;
669
+ char buffer[1024];
670
+
671
+ /* a Measured is irrelevant in the STA/CAN/SUB conditions, but if present, allow them to be unique */
672
+ assert_parse_lboard(&lboard, buffer, "STA:M:0xH00=0::CAN:M:0xH00=2::SUB:M:0xH00=3::VAL:M:0xH04");
673
+ }
674
+
675
+ static void test_unparsable_lboard(const char* memaddr, int expected_error) {
676
+ ASSERT_NUM_EQUALS(rc_lboard_size(memaddr), expected_error);
677
+ }
678
+
679
+ static void test_unparsable_strings() {
680
+ TEST_PARAMS2(test_unparsable_lboard, "STA:0xH00=0::CAN:0xH00=2::SUB:0xH00=3::PRO:0xH04::VAL:0xH02::GARBAGE", RC_INVALID_LBOARD_FIELD);
681
+ TEST_PARAMS2(test_unparsable_lboard, "CAN:0xH00=2::SUB:0xH00=3::PRO:0xH04::VAL:0xH02", RC_MISSING_START);
682
+ TEST_PARAMS2(test_unparsable_lboard, "STA:0xH00=0::SUB:0xH00=3::PRO:0xH04::VAL:0xH02", RC_MISSING_CANCEL);
683
+ TEST_PARAMS2(test_unparsable_lboard, "STA:0xH00=0::CAN:0xH00=2::PRO:0xH04::VAL:0xH02", RC_MISSING_SUBMIT);
684
+ TEST_PARAMS2(test_unparsable_lboard, "STA:0xH00=0::CAN:0xH00=2::SUB:0xH00=3::PRO:0xH04", RC_MISSING_VALUE);
685
+ TEST_PARAMS2(test_unparsable_lboard, "STA:::CAN:0xH00=2::SUB:0xH00=3::VAL:0xH02", RC_MISSING_START);
686
+ TEST_PARAMS2(test_unparsable_lboard, "STA:0xH00=0::CAN:::SUB:0xH00=3::VAL:0xH02", RC_MISSING_CANCEL);
687
+ TEST_PARAMS2(test_unparsable_lboard, "STA:0xH00=0::CAN:0xH00=2::SUB:::VAL:0xH02", RC_MISSING_SUBMIT);
688
+ TEST_PARAMS2(test_unparsable_lboard, "STA:0xH00=0::CAN:0xH00=2::SUB:0xH00=3::VAL:", RC_MISSING_VALUE);
689
+ TEST_PARAMS2(test_unparsable_lboard, "STA:0xH00=0::CAN:0xH00=2::SUB:0xH00=3::PRO:0xH04::VAL:0xH02::STA:0=0", RC_DUPLICATED_START);
690
+ TEST_PARAMS2(test_unparsable_lboard, "STA:0xH00=0::CAN:0xH00=2::SUB:0xH00=3::PRO:0xH04::VAL:0xH02::CAN:0=0", RC_DUPLICATED_CANCEL);
691
+ TEST_PARAMS2(test_unparsable_lboard, "STA:0xH00=0::CAN:0xH00=2::SUB:0xH00=3::PRO:0xH04::VAL:0xH02::SUB:0=0", RC_DUPLICATED_SUBMIT);
692
+ TEST_PARAMS2(test_unparsable_lboard, "STA:0xH00=0::CAN:0xH00=2::SUB:0xH00=3::PRO:0xH04::VAL:0xH02::VAL:0", RC_DUPLICATED_VALUE);
693
+ TEST_PARAMS2(test_unparsable_lboard, "STA:0xH00=0::CAN:0xH00=2::SUB:0xH00=3::PRO:0xH04::VAL:0xH02::PRO:0", RC_DUPLICATED_PROGRESS);
694
+ TEST_PARAMS2(test_unparsable_lboard, "STA:0xH00=0::CAN:0xH00=2::SUB:0xH00=3::VAL:M:0xH01=1_M:0xH01=2", RC_MULTIPLE_MEASURED);
695
+ TEST_PARAMS2(test_unparsable_lboard, "STA:0xH00=0::CAN:0xH00=2::SUB:0xH00=3::VAL:M:0xH01=1_T:0xH01=2", RC_INVALID_VALUE_FLAG);
696
+ TEST_PARAMS2(test_unparsable_lboard, "STA:0xH00=0::CAN:0xH00=2::SUB:0xH00=3::VAL:R:0xH01=1_0xH01=2", RC_INVALID_VALUE_FLAG);
697
+ TEST_PARAMS2(test_unparsable_lboard, "STA:0xH00=0::CAN:0xH00=2::SUB:0xH00=3::VAL:R:0xH01=1", RC_MISSING_VALUE_MEASURED);
698
+ TEST_PARAMS2(test_unparsable_lboard, "STA:0xH00=0::CAN:0xH00=2::SUB:0xH00=3::VAL:R:0xH01=1$M:0xH03", RC_MISSING_VALUE_MEASURED);
699
+ TEST_PARAMS2(test_unparsable_lboard, "STA:0xH00=0::CAN:0xH00=2::SUB:0xH00=3::VAL:M:0xH02SM:0xH03", RC_INVALID_VALUE_FLAG);
700
+ TEST_PARAMS2(test_unparsable_lboard, "STA:0xH00=A::CAN:0xH00=2::SUB:0xH00=3::VAL:0xH02", RC_INVALID_MEMORY_OPERAND);
701
+
702
+ /* "STA:0xH00=1" is valid, but that leaves the read pointer pointing at the "A", which is not "::", so a generic
703
+ * invalid field error is returned. */
704
+ TEST_PARAMS2(test_unparsable_lboard, "STA:0xH00=1A::CAN:0xH00=2::SUB:0xH00=3::VAL:0xH02", RC_INVALID_LBOARD_FIELD);
705
+
706
+ /* Missing '_' causes "0xH00=10" to be valid, but that leaves the read pointer pointing at the "x", which is not
707
+ * "::", so a generic invalid field error is returned. */
708
+ TEST_PARAMS2(test_unparsable_lboard, "STA:0xH00=10xH01=1::CAN:0xH00=2::SUB:0xH00=3::VAL:0xH02", RC_INVALID_LBOARD_FIELD);
709
+
710
+ /* Garbage following value field (legacy format conversion will return invalid comparison) */
711
+ TEST_PARAMS2(test_unparsable_lboard, "STA:0xH00=1::CAN:0xH00=2::SUB:0xH00=3::VAL:0xH02=1=2", RC_INVALID_COMPARISON);
712
+ TEST_PARAMS2(test_unparsable_lboard, "STA:0xH00=1::CAN:0xH00=2::SUB:0xH00=3::VAL:M:0xH02=1=2", RC_INVALID_LBOARD_FIELD);
713
+ }
714
+
715
+ void test_lboard(void) {
716
+ TEST_SUITE_BEGIN();
717
+
718
+ TEST(test_simple_leaderboard);
719
+ TEST(test_start_and_cancel_same_frame);
720
+ TEST(test_start_and_submit_same_frame);
721
+ TEST(test_start_and_submit_same_frame_hitcount);
722
+
723
+ TEST(test_start_and_conditions);
724
+ TEST(test_start_or_conditions);
725
+
726
+ TEST(test_start_resets_value);
727
+
728
+ TEST(test_cancel_or_conditions);
729
+
730
+ TEST(test_submit_and_conditions);
731
+ TEST(test_submit_or_conditions);
732
+
733
+ TEST(test_progress);
734
+
735
+ TEST(test_value_from_hitcount);
736
+ TEST(test_value_from_addhits);
737
+ TEST(test_value_from_float);
738
+ TEST(test_value_from_float_scaled);
739
+ TEST(test_value_from_division);
740
+ TEST(test_maximum_value_from_conditions);
741
+ TEST(test_measured_value_and_condition);
742
+
743
+ test_unparsable_strings();
744
+
745
+ TEST_SUITE_END();
746
+ }