Advertisement
Sabersense

prop

Feb 11th, 2023
30
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 26.97 KB | None | 0 0
  1. // sa22c props file, includes 1,2 and 3 button modes. Incorporates multi-blast,
  2. // battle mode and gesture ignitions from fett263 plus on-the-fly volume
  3. // controls and full access to all features with 1,2 or 3 button sabers
  4. //
  5. // New #define SA22C_NO_LOCKUP_HOLD
  6. // reverts to lockup being triggered only by clash + aux in 2-button mode
  7. // Also sets multi-blast to trigger while holding aux and swinging, rather than
  8. // double click and hold
  9. //
  10. // Gesture Controls
  11. // There are four gesture types: swing, stab, twist and thrust. For simplicity,
  12. // using gesture ignition will automatically skip the preon effect.
  13. // Below are the options to add to the config to enable
  14. // the various gestures
  15. //
  16. // #define SA22C_STAB_ON
  17. // #define SA22C_SWING_ON
  18. // #define SA22C_TWIST_ON
  19. // #define SA22C_THRUST_ON
  20. // #define SA22C_TWIST_OFF
  21. // #define SA22C_FORCE_PUSH
  22. //
  23. // #define SA22C_FORCE_PUSH_LENGTH 5
  24. // Allows for adjustment to Push gesture length in millis needed to trigger Force Push
  25. // Recommended range 1 ~ 10, 1 = shortest, easiest to trigger, 10 = longest
  26. //
  27. // If you want the gesture ignition to ALSO enter battle mode automatically
  28. // on ignition, add this define
  29. //
  30. // #define GESTURE_AUTO_BATTLE_MODE
  31. //
  32. // Battle mode by fett263
  33. //
  34. // Once you enter battle mode, button functions will be disabled for lockup
  35. // stab, melt, etc. Blaster blocks and lightning block will continue to be
  36. // triggered by button controls. Automatic lockup/clash detection works
  37. // by measuring delay of the saber blade pulling back from the clash.
  38. // If you clash the blade and it does not pull back during the delay period,
  39. // it is assumed to be a lockup and the lockup effect will show on the blade.
  40. // If you clash the blade and pull away, only the bgn/end lockup effects will show.
  41. //
  42. // You can adjust the threshold of this detection by using
  43. // #define SA22C_LOCKUP_DELAY (insert number here)
  44. // Default value is 200
  45. //
  46. // Battle mode features automatic clash and lockup detection plus a new
  47. // force push mode that will play a force or force push sound with a controlled
  48. // pushing gesture. Automatic clash/lockup uses the pre and post lock effects
  49. // so your blade style and font MUST have those capabilities to support
  50. // battle mode. Kudos to fett263 for his very impressive additions for OS 5
  51. //
  52. // Tightened click timings
  53. // I've shortened the timeout for short and double click detection from 500ms
  54. // to 300ms. I think it feels more responsive this way but still gives enough
  55. // timeout to ensure all button actions can be achieved consistently
  56. // I've included all button timings so they can be easily tweaked to suit
  57. // individual tastes.
  58. //
  59. // Button configs:
  60. //
  61. // 1 Button:
  62. // Activate Muted - double click and hold while OFF
  63. // Activate - short click while OFF
  64. // Play/Stop Music - double click while OFF
  65. // Turn off blade - hold and wait till blade is off while ON
  66. // Next Preset - hold and release while OFF
  67. // Prev Preset - hold and wait while OFF
  68. // Lockup - hold + hit clash while ON
  69. // Stab - thrust forward clash while ON
  70. // Lightning Block - double click and hold while ON
  71. // Melt - hold + thust forward clash while ON
  72. // Drag - hold + hit clash while ON pointing the blade tip down
  73. // Blaster Blocks - short click/double click/triple click while on
  74. // Multi-Blast - hold while swinging for one second and release
  75. // to trigger blaster block, swing saber while in multi-blast mode
  76. // to exit, hold while swinging for one second and release
  77. // Battle Mode - triple-click and hold while on
  78. // Force Effects - hold + twist the hilt while ON (while pointing up)
  79. // Color Change mode - hold + twist the hilt while ON (pointing down)
  80. // Enter Volume - Menu hold + clash while OFF
  81. // Volume UP - hold and release while in Volume Menu
  82. // Volume DOWN - click while in Volume Menu
  83. // Exit Volume Menu - Menu hold + clash while OFF
  84. // Battery Level - triple click while OFF
  85. //
  86. //
  87. // 2 Button:
  88. // POWER
  89. // Activate Muted - double click and hold while OFF
  90. // Activate - short click while OFF
  91. // Play/Stop Music - hold and release while OFF
  92. // Turn off blade - hold and wait till blade is off while ON
  93. // Force Effects - double click while ON
  94. // Volume UP - short click while OFF and in VOLUME MENU
  95. // Prev Preset - hold and wait while OFF
  96. // Color Change mode - hold + toggle AUX while ON
  97. // Lightning Block - double click and hold while ON
  98. // Melt - hold while stabbing (clash with forward motion, horizontal)
  99. // Battle Mode - triple-click and hold for half a second while on
  100. // AUX
  101. // Blaster blocks - short click/double click/triple click while ON
  102. // Multi-Blast - double-click and hold for half a second
  103. // to trigger blaster block, swing saber while in multi-blast mode
  104. // to exit, double-click and hold for half a second
  105. // Next Preset - short click while OFF
  106. // Lockup - hold while ON
  107. // Drag - hold while ON pointing the blade tip down
  108. // Enter VOLUME MENU - long click while OFF
  109. // Volume down - short click while OFF and in VOLUME MENU
  110. // Battery level - hold while off
  111. //
  112. // 3 Button: Same as two button except for the following
  113. //
  114. // AUX2
  115. // Lightning Block - hold while ON
  116. // Battle Mode - double-click and hold while on
  117. // Previous Preset - short click while OFF
  118.  
  119.  
  120. #ifndef PROPS_SABER_SA22C_BUTTONS_H
  121. #define PROPS_SABER_SA22C_BUTTONS_H
  122.  
  123. #include "prop_base.h"
  124. #include "../sound/hybrid_font.h"
  125.  
  126. #undef PROP_TYPE
  127. #define PROP_TYPE SaberSA22CButtons
  128.  
  129. #ifndef MOTION_TIMEOUT
  130. #define MOTION_TIMEOUT 60 * 15 * 1000
  131. #endif
  132.  
  133. #ifndef SA22C_SWING_ON_SPEED
  134. #define SA22C_SWING_ON_SPEED 250
  135. #endif
  136.  
  137. #ifndef SA22C_LOCKUP_DELAY
  138. #define SA22C_LOCKUP_DELAY 200
  139. #endif
  140.  
  141. #ifndef SA22C_FORCE_PUSH_LENGTH
  142. #define SA22C_FORCE_PUSH_LENGTH 5
  143. #endif
  144.  
  145. #ifndef BUTTON_DOUBLE_CLICK_TIMEOUT
  146. #define BUTTON_DOUBLE_CLICK_TIMEOUT 300
  147. #endif
  148.  
  149. #ifndef BUTTON_SHORT_CLICK_TIMEOUT
  150. #define BUTTON_SHORT_CLICK_TIMEOUT 300
  151. #endif
  152.  
  153. #ifndef BUTTON_HELD_TIMEOUT
  154. #define BUTTON_HELD_TIMEOUT 300
  155. #endif
  156.  
  157. #ifndef BUTTON_HELD_MEDIUM_TIMEOUT
  158. #define BUTTON_HELD_MEDIUM_TIMEOUT 1000
  159. #endif
  160.  
  161. #ifndef BUTTON_HELD_LONG_TIMEOUT
  162. #define BUTTON_HELD_LONG_TIMEOUT 2000
  163. #endif
  164.  
  165. #ifdef SA22C_SWING_ON
  166. #define SWING_GESTURE
  167. #endif
  168.  
  169. #ifdef SA22C_STAB_ON
  170. #define STAB_GESTURE
  171. #endif
  172.  
  173. #ifdef SA22C_TWIST_ON
  174. #define TWIST_GESTURE
  175. #endif
  176.  
  177. #ifdef SA22C_THRUST_ON
  178. #define THRUST_GESTURE
  179. #endif
  180.  
  181. #define FORCE_PUSH_CONDITION battle_mode_
  182.  
  183. EFFECT(dim); // for EFFECT_POWERSAVE
  184. EFFECT(battery); // for EFFECT_BATTERY_LEVEL
  185. EFFECT(bmbegin); // for Begin Battle Mode
  186. EFFECT(bmend); // for End Battle Mode
  187. EFFECT(vmbegin); // for Begin Volume Menu
  188. EFFECT(vmend); // for End Volume Menu
  189. EFFECT(volup); // for increse volume
  190. EFFECT(voldown); // for decrease volume
  191. EFFECT(volmin); // for minimum volume reached
  192. EFFECT(volmax); // for maximum volume reached
  193. EFFECT(faston); // for EFFECT_FAST_ON
  194. EFFECT(blstbgn); // for Begin Multi-Blast
  195. EFFECT(blstend); // for End Multi-Blast
  196. EFFECT(push); // for Force Push gesture in Battle Mode
  197.  
  198. // The Saber class implements the basic states and actions
  199. // for the saber.
  200. class SaberSA22CButtons : public PROP_INHERIT_PREFIX PropBase {
  201. public:
  202. SaberSA22CButtons() : PropBase() {}
  203. const char* name() override { return "SaberSA22CButtons"; }
  204.  
  205. void Loop() override {
  206. PropBase::Loop();
  207. DetectTwist();
  208. Vec3 mss = fusor.mss();
  209. if (SaberBase::IsOn()) {
  210. DetectSwing();
  211. if (auto_lockup_on_ &&
  212. !swinging_ &&
  213. fusor.swing_speed() > 120 &&
  214. millis() - clash_impact_millis_ > SA22C_LOCKUP_DELAY &&
  215. SaberBase::Lockup()) {
  216. SaberBase::DoEndLockup();
  217. SaberBase::SetLockup(SaberBase::LOCKUP_NONE);
  218. auto_lockup_on_ = false;
  219. }
  220. if (auto_melt_on_ &&
  221. !swinging_ &&
  222. fusor.swing_speed() > 60 &&
  223. millis() - clash_impact_millis_ > SA22C_LOCKUP_DELAY &&
  224. SaberBase::Lockup()) {
  225. SaberBase::DoEndLockup();
  226. SaberBase::SetLockup(SaberBase::LOCKUP_NONE);
  227. auto_melt_on_ = false;
  228. }
  229.  
  230. // EVENT_PUSH
  231. if (fabs(mss.x) < 3.0 &&
  232. mss.y * mss.y + mss.z * mss.z > 70 &&
  233. fusor.swing_speed() < 30 &&
  234. fabs(fusor.gyro().x) < 10) {
  235. if (millis() - push_begin_millis_ > SA22C_FORCE_PUSH_LENGTH) {
  236. Event(BUTTON_NONE, EVENT_PUSH);
  237. push_begin_millis_ = millis();
  238. }
  239. } else {
  240. push_begin_millis_ = millis();
  241. }
  242.  
  243. } else {
  244. // EVENT_SWING - Swing On gesture control to allow fine tuning of speed needed to ignite
  245. if (millis() - saber_off_time_ < MOTION_TIMEOUT) {
  246. SaberBase::RequestMotion();
  247. if (swinging_ && fusor.swing_speed() < 90) {
  248. swinging_ = false;
  249. }
  250. if (!swinging_ && fusor.swing_speed() > SA22C_SWING_ON_SPEED) {
  251. swinging_ = true;
  252. Event(BUTTON_NONE, EVENT_SWING);
  253. }
  254. }
  255. // EVENT_THRUST
  256. if (mss.y * mss.y + mss.z * mss.z < 16.0 &&
  257. mss.x > 14 &&
  258. fusor.swing_speed() < 150) {
  259. if (millis() - thrust_begin_millis_ > 15) {
  260. Event(BUTTON_NONE, EVENT_THRUST);
  261. thrust_begin_millis_ = millis();
  262. }
  263. } else {
  264. thrust_begin_millis_ = millis();
  265. }
  266. }
  267. }
  268.  
  269. // ************ Taken from earlier prop ******************
  270. // Chris Edit - 1 of 5
  271.  
  272. // Fast On Gesture Ignition
  273. virtual void FastOn() {
  274. if (IsOn()) return;
  275. if (current_style() && current_style()->NoOnOff())
  276. return;
  277. activated_ = millis();
  278. STDOUT.println("Ignition.");
  279. MountSDCard();
  280. EnableAmplifier();
  281. SaberBase::RequestMotion();
  282. // Avoid clashes a little bit while turning on.
  283. // It might be a "clicky" power button...
  284. IgnoreClash(500);
  285. SaberBase::TurnOn();
  286. // Optional effects
  287. SaberBase::DoEffect(EFFECT_FAST_ON, 0);
  288. }
  289.  
  290. // ********************************************************
  291.  
  292.  
  293. // Volume Menu
  294. void VolumeUp() {
  295. STDOUT.println("Volume up");
  296. if (dynamic_mixer.get_volume() < VOLUME) {
  297. dynamic_mixer.set_volume(std::min<int>(VOLUME + VOLUME * 0.1,
  298. dynamic_mixer.get_volume() + VOLUME * 0.10));
  299. if (SFX_volup) {
  300. hybrid_font.PlayCommon(&SFX_volup);
  301. } else {
  302. beeper.Beep(0.5, 2000);
  303. }
  304. STDOUT.print("Volume Up - Current Volume: ");
  305. STDOUT.println(dynamic_mixer.get_volume());
  306. } else {
  307. // Cycle through ends of Volume Menu option
  308. #ifdef VOLUME_MENU_CYCLE
  309. if (!max_vol_reached_) {
  310. if (SFX_volmax) {
  311. hybrid_font.PlayCommon(&SFX_volmax);
  312. } else {
  313. beeper.Beep(0.5, 3000);
  314. }
  315. STDOUT.print("Maximum Volume: ");
  316. max_vol_reached_ = true;
  317. } else {
  318. dynamic_mixer.set_volume(std::max<int>(VOLUME * 0.1,
  319. dynamic_mixer.get_volume() - VOLUME * 0.90));
  320. if (SFX_volmin) {
  321. hybrid_font.PlayCommon(&SFX_volmin);
  322. } else {
  323. beeper.Beep(0.5, 1000);
  324. }
  325. STDOUT.print("Minimum Volume: ");
  326. max_vol_reached_ = false;
  327. }
  328. #else
  329. if (SFX_volmax) {
  330. hybrid_font.PlayCommon(&SFX_volmax);
  331. } else {
  332. beeper.Beep(0.5, 3000);
  333. }
  334. STDOUT.print("Maximum Volume: ");
  335. #endif
  336. }
  337. }
  338.  
  339. void VolumeDown() {
  340. STDOUT.println("Volume Down");
  341. if (dynamic_mixer.get_volume() > (0.10 * VOLUME)) {
  342. dynamic_mixer.set_volume(std::max<int>(VOLUME * 0.1,
  343. dynamic_mixer.get_volume() - VOLUME * 0.10));
  344. if (SFX_voldown) {
  345. hybrid_font.PlayCommon(&SFX_voldown);
  346. } else {
  347. beeper.Beep(0.5, 2000);
  348. }
  349. STDOUT.print("Volume Down - Current Volume: ");
  350. STDOUT.println(dynamic_mixer.get_volume());
  351. } else {
  352. #ifdef VOLUME_MENU_CYCLE
  353. if (!min_vol_reached_) {
  354. if (SFX_volmin) {
  355. hybrid_font.PlayCommon(&SFX_volmin);
  356. } else {
  357. beeper.Beep(0.5, 1000);
  358. }
  359. STDOUT.print("Minimum Volume: ");
  360. min_vol_reached_ = true;
  361. } else {
  362. dynamic_mixer.set_volume(VOLUME);
  363. if (SFX_volmax) {
  364. hybrid_font.PlayCommon(&SFX_volmax);
  365. } else {
  366. beeper.Beep(0.5, 3000);
  367. }
  368. STDOUT.print("Maximum Volume: ");
  369. min_vol_reached_ = false;
  370. }
  371. #else
  372. if (SFX_volmin) {
  373. hybrid_font.PlayCommon(&SFX_volmin);
  374. } else {
  375. beeper.Beep(0.5, 1000);
  376. }
  377. STDOUT.print("Minimum Volume: ");
  378. #endif
  379.  
  380. }
  381. }
  382.  
  383. bool Event2(enum BUTTON button, EVENT event, uint32_t modifiers) override {
  384. switch (EVENTID(button, event, modifiers)) {
  385. case EVENTID(BUTTON_POWER, EVENT_PRESSED, MODE_ON):
  386. case EVENTID(BUTTON_AUX, EVENT_PRESSED, MODE_ON):
  387. case EVENTID(BUTTON_AUX2, EVENT_PRESSED, MODE_ON):
  388. if (accel_.x < -0.15) {
  389. pointing_down_ = true;
  390. } else {
  391. pointing_down_ = false;
  392. }
  393. return true;
  394.  
  395. // Battle Mode
  396. #if NUM_BUTTONS == 3
  397. case EVENTID(BUTTON_AUX2, EVENT_SECOND_HELD, MODE_ON):
  398. #else
  399. case EVENTID(BUTTON_POWER, EVENT_THIRD_HELD, MODE_ON):
  400. #endif
  401. if (!battle_mode_) {
  402. STDOUT.println("Entering Battle Mode");
  403. battle_mode_ = true;
  404. if (SFX_bmbegin) {
  405. hybrid_font.PlayCommon(&SFX_bmbegin);
  406. } else {
  407. hybrid_font.DoEffect(EFFECT_FORCE, 0);
  408. }
  409. } else {
  410. STDOUT.println("Exiting Battle Mode");
  411. battle_mode_ = false;
  412. if (SFX_bmend) {
  413. hybrid_font.PlayCommon(&SFX_bmend);
  414. } else {
  415. beeper.Beep(0.5, 3000);
  416. }
  417. }
  418. return true;
  419.  
  420. // Auto Lockup Mode
  421. case EVENTID(BUTTON_NONE, EVENT_CLASH, MODE_ON):
  422. if (!battle_mode_) return false;
  423. clash_impact_millis_ = millis();
  424. swing_blast_ = false;
  425. if (swinging_) return false;
  426. SaberBase::SetLockup(SaberBase::LOCKUP_NORMAL);
  427. auto_lockup_on_ = true;
  428. SaberBase::DoBeginLockup();
  429. return true;
  430.  
  431. case EVENTID(BUTTON_NONE, EVENT_STAB, MODE_ON):
  432. if (!battle_mode_) return false;
  433. clash_impact_millis_ = millis();
  434. swing_blast_ = false;
  435. if (!swinging_) {
  436. if (fusor.angle1() < - M_PI / 4) {
  437. SaberBase::SetLockup(SaberBase::LOCKUP_DRAG);
  438. } else {
  439. SaberBase::SetLockup(SaberBase::LOCKUP_MELT);
  440. }
  441. auto_melt_on_ = true;
  442. SaberBase::DoBeginLockup();
  443. }
  444. return true;
  445.  
  446. // Gesture Controls
  447. #ifdef SA22C_SWING_ON
  448. case EVENTID(BUTTON_NONE, EVENT_SWING, MODE_OFF):
  449. // Due to motion chip startup on boot creating false ignition we delay Swing On at boot for 3000ms
  450. if (millis() > 3000) {
  451. FastOn();
  452. #ifdef GESTURE_AUTO_BATTLE_MODE
  453. STDOUT.println("Entering Battle Mode");
  454. battle_mode_ = true;
  455. #endif
  456. }
  457. return true;
  458. #endif
  459.  
  460. #ifdef SA22C_TWIST_ON
  461. case EVENTID(BUTTON_NONE, EVENT_TWIST, MODE_OFF):
  462. // Delay twist events to prevent false trigger from over twisting
  463. if (millis() - last_twist_ > 2000 &&
  464. millis() - saber_off_time_ > 1000) {
  465. FastOn();
  466. #ifdef GESTURE_AUTO_BATTLE_MODE
  467. STDOUT.println("Entering Battle Mode");
  468. battle_mode_ = true;
  469. #endif
  470. last_twist_ = millis();
  471. }
  472. return true;
  473. #endif
  474.  
  475. #ifdef SA22C_TWIST_OFF
  476. case EVENTID(BUTTON_NONE, EVENT_TWIST, MODE_ON):
  477. // Delay twist events to prevent false trigger from over twisting
  478. if (millis() - last_twist_ > 3000) {
  479. Off();
  480. last_twist_ = millis();
  481. saber_off_time_ = millis();
  482. battle_mode_ = false;
  483. }
  484. return true;
  485. #endif
  486.  
  487. #ifdef SA22C_STAB_ON
  488. case EVENTID(BUTTON_NONE, EVENT_STAB, MODE_OFF):
  489. if (millis() - saber_off_time_ > 1000) {
  490. FastOn();
  491. #ifdef GESTURE_AUTO_BATTLE_MODE
  492. STDOUT.println("Entering Battle Mode");
  493. battle_mode_ = true;
  494. #endif
  495. }
  496. return true;
  497. #endif
  498.  
  499. #ifdef SA22C_THRUST_ON
  500. case EVENTID(BUTTON_NONE, EVENT_THRUST, MODE_OFF):
  501. if (millis() - saber_off_time_ > 1000) {
  502. FastOn();
  503. #ifdef GESTURE_AUTO_BATTLE_MODE
  504. STDOUT.println("Entering Battle Mode");
  505. battle_mode_ = true;
  506. #endif
  507. }
  508. return true;
  509. #endif
  510.  
  511. #ifdef SA22C_FORCE_PUSH
  512. case EVENTID(BUTTON_NONE, EVENT_PUSH, MODE_ON):
  513. if (FORCE_PUSH_CONDITION &&
  514. millis() - last_push_ > 2000) {
  515. if (SFX_push) {
  516. hybrid_font.PlayCommon(&SFX_push);
  517. } else {
  518. hybrid_font.DoEffect(EFFECT_FORCE, 0);
  519. }
  520. last_push_ = millis();
  521. }
  522. return true;
  523.  
  524. #endif
  525.  
  526. // Saber ON AND Volume Up
  527. case EVENTID(BUTTON_POWER, EVENT_FIRST_SAVED_CLICK_SHORT, MODE_OFF):
  528. if (!mode_volume_) {
  529. On();
  530. } else {
  531. VolumeUp();
  532. }
  533. return true;
  534.  
  535.  
  536. // *******************************************************************************
  537. // Chris Edit - 2 of 5
  538.  
  539. // case EVENTID(BUTTON_POWER, EVENT_FIRST_CLICK_LONG, MODE_OFF):
  540. case EVENTID(BUTTON_POWER, EVENT_SECOND_SAVED_CLICK_SHORT, MODE_OFF):
  541.  
  542.  
  543.  
  544. // 1-button: Next Preset AND Volume Down
  545. #if NUM_BUTTONS == 1
  546. if (!mode_volume_) {
  547. next_preset();
  548. } else {
  549. VolumeDown();
  550. }
  551. return true;
  552. #else
  553. // 2 and 3 button: Start or Stop Track
  554. StartOrStopTrack();
  555. return true;
  556. #endif
  557.  
  558. // 2 and 3 button: Next Preset and Volume Down
  559. case EVENTID(BUTTON_AUX, EVENT_FIRST_CLICK_SHORT, MODE_OFF):
  560. if (!mode_volume_) {
  561. next_preset();
  562. } else {
  563. VolumeDown();
  564. }
  565. return true;
  566.  
  567. #if NUM_BUTTONS == 3
  568. // 3 button: Previous Preset
  569. case EVENTID(BUTTON_AUX2, EVENT_FIRST_CLICK_SHORT, MODE_OFF):
  570. #else
  571.  
  572.  
  573. // *******************************************************************************
  574. // Chris Edit - 3 of 5
  575.  
  576. // 1 and 2 button: Previous Preset
  577. // case EVENTID(BUTTON_POWER, EVENT_FIRST_HELD_LONG, MODE_OFF):
  578. case EVENTID(BUTTON_POWER, EVENT_CLICK_SHORT, MODE_OFF | BUTTON_AUX):
  579.  
  580.  
  581.  
  582. #endif
  583. if (!mode_volume_) {
  584. previous_preset();
  585. }
  586. return true;
  587.  
  588.  
  589.  
  590. // *******************************************************************************
  591. // Chris Edit - 4 of 5
  592.  
  593. // Activate Muted
  594. // case EVENTID(BUTTON_POWER, EVENT_SECOND_HELD, MODE_OFF):
  595. case EVENTID(BUTTON_POWER, EVENT_FIRST_CLICK_LONG, MODE_OFF):
  596.  
  597.  
  598.  
  599. if (SetMute(true)) {
  600. unmute_on_deactivation_ = true;
  601. On();
  602. }
  603. return true;
  604.  
  605. // Turn Blade OFF
  606. #if NUM_BUTTONS > 1
  607. // 2 and 3 button
  608. case EVENTID(BUTTON_POWER, EVENT_FIRST_HELD_MEDIUM, MODE_ON):
  609. #else
  610. // 1 button
  611. case EVENTID(BUTTON_POWER, EVENT_FIRST_HELD_LONG, MODE_ON):
  612. #endif
  613. if (!SaberBase::Lockup()) {
  614. #ifndef DISABLE_COLOR_CHANGE
  615. if (SaberBase::GetColorChangeMode() != SaberBase::COLOR_CHANGE_MODE_NONE) {
  616. // Just exit color change mode.
  617. // Don't turn saber off.
  618. ToggleColorChangeMode();
  619. return true;
  620. }
  621. #endif
  622. if (!battle_mode_) {
  623. Off();
  624. }
  625. }
  626. saber_off_time_ = millis();
  627. battle_mode_ = false;
  628. swing_blast_ = false;
  629. return true;
  630.  
  631. // 1 button Force and Color Change mode
  632. #if NUM_BUTTONS == 1
  633. case EVENTID(BUTTON_NONE, EVENT_TWIST, MODE_ON | BUTTON_POWER):
  634. #ifndef DISABLE_COLOR_CHANGE
  635. if (accel_.x < -0.15) {
  636. ToggleColorChangeMode();
  637. } else {
  638. SaberBase::DoForce();
  639. }
  640. #else
  641. SaberBase::DoForce();
  642. #endif
  643. return true;
  644. #else
  645. // 2 and 3 button Force effect
  646. case EVENTID(BUTTON_POWER, EVENT_SECOND_SAVED_CLICK_SHORT, MODE_ON):
  647. SaberBase::DoForce();
  648. return true;
  649. // 2 and 3 button color change
  650. #ifndef DISABLE_COLOR_CHANGE
  651. case EVENTID(BUTTON_AUX, EVENT_FIRST_CLICK_SHORT, MODE_ON | BUTTON_POWER):
  652. ToggleColorChangeMode();
  653. return true;
  654. #endif
  655. #endif
  656.  
  657. // Blaster Deflection
  658. #if NUM_BUTTONS == 1
  659. // 1 button
  660. case EVENTID(BUTTON_POWER, EVENT_FIRST_SAVED_CLICK_SHORT, MODE_ON):
  661. case EVENTID(BUTTON_POWER, EVENT_SECOND_SAVED_CLICK_SHORT, MODE_ON):
  662. case EVENTID(BUTTON_POWER, EVENT_THIRD_CLICK_SHORT, MODE_ON):
  663. #else
  664. // 2 and 3 button
  665. case EVENTID(BUTTON_AUX, EVENT_FIRST_SAVED_CLICK_SHORT, MODE_ON):
  666. case EVENTID(BUTTON_AUX, EVENT_SECOND_SAVED_CLICK_SHORT, MODE_ON):
  667. case EVENTID(BUTTON_AUX, EVENT_THIRD_CLICK_SHORT, MODE_ON):
  668. #endif
  669. swing_blast_ = false;
  670. SaberBase::DoBlast();
  671. return true;
  672.  
  673. // Multi-Blaster Deflection mode
  674. #if NUM_BUTTONS == 1
  675. // 1 button
  676. case EVENTID(BUTTON_NONE, EVENT_SWING, MODE_ON | BUTTON_POWER):
  677. #else
  678. // 2 and 3 button
  679. #ifndef SA22C_NO_LOCKUP_HOLD
  680. case EVENTID(BUTTON_AUX, EVENT_SECOND_HELD, MODE_ON):
  681. #else
  682. // in SA22C_NO_LOCKUP_HOLD mode, multi-blaster is triggered by holding aux
  683. // while swinging
  684. case EVENTID(BUTTON_NONE, EVENT_SWING, MODE_ON | BUTTON_AUX):
  685. #endif
  686. #endif
  687. swing_blast_ = !swing_blast_;
  688. if (swing_blast_) {
  689. if (SFX_blstbgn) {
  690. hybrid_font.PlayCommon(&SFX_blstbgn);
  691. } else {
  692. hybrid_font.SB_Effect(EFFECT_BLAST, 0);
  693. }
  694. } else {
  695. if (SFX_blstend) {
  696. hybrid_font.PlayCommon(&SFX_blstend);
  697. } else {
  698. hybrid_font.SB_Effect(EFFECT_BLAST, 0);
  699. }
  700. }
  701. return true;
  702.  
  703. case EVENTID(BUTTON_NONE, EVENT_SWING, MODE_ON):
  704. if (swing_blast_) {
  705. SaberBase::DoBlast();
  706. }
  707. return true;
  708.  
  709. // Lockup
  710. #if NUM_BUTTONS == 1
  711. // 1 button lockup
  712. case EVENTID(BUTTON_NONE, EVENT_CLASH, MODE_ON | BUTTON_POWER):
  713. #else
  714. #ifndef SA22C_NO_LOCKUP_HOLD
  715. // 2 and 3 button lockup
  716. case EVENTID(BUTTON_AUX, EVENT_FIRST_HELD, MODE_ON):
  717. #else
  718. case EVENTID(BUTTON_NONE, EVENT_CLASH, MODE_ON | BUTTON_AUX):
  719. #endif
  720. #endif
  721. if (!SaberBase::Lockup() && !battle_mode_) {
  722. if (pointing_down_) {
  723. SaberBase::SetLockup(SaberBase::LOCKUP_DRAG);
  724. } else {
  725. SaberBase::SetLockup(SaberBase::LOCKUP_NORMAL);
  726. }
  727. swing_blast_ = false;
  728. SaberBase::DoBeginLockup();
  729. return true;
  730. }
  731. break;
  732.  
  733. // Lightning Block
  734. #if NUM_BUTTONS < 3
  735. // 1 and 2 button
  736. case EVENTID(BUTTON_POWER, EVENT_SECOND_HELD, MODE_ON):
  737. #else
  738. // 3 button
  739. case EVENTID(BUTTON_AUX2, EVENT_FIRST_HELD, MODE_ON):
  740. #endif
  741. if (!battle_mode_) {
  742. SaberBase::SetLockup(SaberBase::LOCKUP_LIGHTNING_BLOCK);
  743. swing_blast_ = false;
  744. SaberBase::DoBeginLockup();
  745. return true;
  746. }
  747. break;
  748.  
  749. // Melt
  750. case EVENTID(BUTTON_NONE, EVENT_STAB, MODE_ON | BUTTON_POWER):
  751. if (!SaberBase::Lockup() && !battle_mode_) {
  752. SaberBase::SetLockup(SaberBase::LOCKUP_MELT);
  753. swing_blast_ = false;
  754. SaberBase::DoBeginLockup();
  755. return true;
  756. }
  757. break;
  758.  
  759. // Start or Stop Track
  760. #if NUM_BUTTONS == 1
  761. // 1 button
  762. case EVENTID(BUTTON_POWER, EVENT_SECOND_SAVED_CLICK_SHORT, MODE_OFF):
  763. StartOrStopTrack();
  764. return true;
  765. #endif
  766.  
  767. case EVENTID(BUTTON_POWER, EVENT_PRESSED, MODE_OFF):
  768. case EVENTID(BUTTON_AUX, EVENT_PRESSED, MODE_OFF):
  769. case EVENTID(BUTTON_AUX2, EVENT_PRESSED, MODE_OFF):
  770. SaberBase::RequestMotion();
  771. return true;
  772.  
  773. // Enter Volume MENU
  774. #if NUM_BUTTONS == 1
  775. // 1 button
  776. case EVENTID(BUTTON_NONE, EVENT_CLASH, MODE_OFF | BUTTON_POWER):
  777. #else
  778. // 2 and 3 button
  779. case EVENTID(BUTTON_AUX, EVENT_FIRST_CLICK_LONG, MODE_OFF):
  780. #endif
  781. if (!mode_volume_) {
  782. mode_volume_ = true;
  783. if (SFX_vmbegin) {
  784. hybrid_font.PlayCommon(&SFX_vmbegin);
  785. } else {
  786. beeper.Beep(0.5, 3000);
  787. }
  788. STDOUT.println("Enter Volume Menu");
  789. } else {
  790. mode_volume_ = false;
  791. if (SFX_vmend) {
  792. hybrid_font.PlayCommon(&SFX_vmend);
  793. } else {
  794. beeper.Beep(0.5, 3000);
  795. }
  796. STDOUT.println("Exit Volume Menu");
  797. }
  798. return true;
  799.  
  800.  
  801. // Battery level
  802. #if NUM_BUTTONS == 1
  803. // 1 button
  804. case EVENTID(BUTTON_POWER, EVENT_THIRD_SAVED_CLICK_SHORT, MODE_OFF):
  805. #else
  806. // 2 and 3 button
  807. case EVENTID(BUTTON_AUX, EVENT_FIRST_HELD_LONG, MODE_OFF):
  808. #endif
  809. talkie.SayDigit((int)floorf(battery_monitor.battery()));
  810. talkie.Say(spPOINT);
  811. talkie.SayDigit(((int)floorf(battery_monitor.battery() * 10)) % 10);
  812. talkie.SayDigit(((int)floorf(battery_monitor.battery() * 100)) % 10);
  813. talkie.Say(spVOLTS);
  814.  
  815.  
  816.  
  817. // ***********************************************************************************
  818.  
  819. // Chris Edit - 5 of 5
  820. // Add this line to get blade battery display on demand for presets with suitable code added:
  821. SaberBase::DoEffect(EFFECT_BATTERY_LEVEL, 0);
  822.  
  823. // ***********************************************************************************
  824.  
  825.  
  826. return true;
  827.  
  828.  
  829. #ifdef BLADE_DETECT_PIN
  830. case EVENTID(BUTTON_BLADE_DETECT, EVENT_LATCH_ON, MODE_ANY_BUTTON | MODE_ON):
  831. case EVENTID(BUTTON_BLADE_DETECT, EVENT_LATCH_ON, MODE_ANY_BUTTON | MODE_OFF):
  832. // Might need to do something cleaner, but let's try this for now.
  833. blade_detected_ = true;
  834. FindBladeAgain();
  835. SaberBase::DoBladeDetect(true);
  836. return true;
  837.  
  838. case EVENTID(BUTTON_BLADE_DETECT, EVENT_LATCH_OFF, MODE_ANY_BUTTON | MODE_ON):
  839. case EVENTID(BUTTON_BLADE_DETECT, EVENT_LATCH_OFF, MODE_ANY_BUTTON | MODE_OFF):
  840. // Might need to do something cleaner, but let's try this for now.
  841. blade_detected_ = false;
  842. FindBladeAgain();
  843. SaberBase::DoBladeDetect(false);
  844. return true;
  845. #endif
  846.  
  847. // Events that needs to be handled regardless of what other buttons
  848. // are pressed.
  849. case EVENTID(BUTTON_POWER, EVENT_RELEASED, MODE_ANY_BUTTON | MODE_ON):
  850. case EVENTID(BUTTON_AUX, EVENT_RELEASED, MODE_ANY_BUTTON | MODE_ON):
  851. case EVENTID(BUTTON_AUX2, EVENT_RELEASED, MODE_ANY_BUTTON | MODE_ON):
  852. if (SaberBase::Lockup()) {
  853. SaberBase::DoEndLockup();
  854. SaberBase::SetLockup(SaberBase::LOCKUP_NONE);
  855. return true;
  856. }
  857. }
  858. return false;
  859. }
  860.  
  861. void SB_Effect(EffectType effect, float location) override {
  862. switch (effect) {
  863. case EFFECT_POWERSAVE:
  864. if (SFX_dim) {
  865. hybrid_font.PlayCommon(&SFX_dim);
  866. } else {
  867. beeper.Beep(0.5, 3000);
  868. }
  869. return;
  870. case EFFECT_BATTERY_LEVEL:
  871. if (SFX_battery) {
  872. hybrid_font.PlayCommon(&SFX_battery);
  873. } else {
  874. beeper.Beep(0.5, 3000);
  875. }
  876. return;
  877. case EFFECT_FAST_ON:
  878. if (SFX_faston) {
  879. hybrid_font.PlayCommon(&SFX_faston);
  880. }
  881. return;
  882.  
  883. default: break; // avoids compiler warning
  884. }
  885. }
  886.  
  887. private:
  888. bool pointing_down_ = false;
  889. bool swing_blast_ = false;
  890. bool mode_volume_ = false;
  891. bool auto_lockup_on_ = false;
  892. bool auto_melt_on_ = false;
  893. bool battle_mode_ = false;
  894. bool max_vol_reached_ = false;
  895. bool min_vol_reached_ = false;
  896. uint32_t thrust_begin_millis_ = millis();
  897. uint32_t push_begin_millis_ = millis();
  898. uint32_t clash_impact_millis_ = millis();
  899. uint32_t last_twist_ = millis();
  900. uint32_t last_push_ = millis();
  901. uint32_t saber_off_time_ = millis();
  902. };
  903.  
  904. #endif
  905.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement