drashna.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  1. /*
  2. Copyright 2017 Christopher Courtney <drashna@live.com> @drashna
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. #include "drashna.h"
  15. #include "version.h"
  16. #if (__has_include("secrets.h"))
  17. #include "secrets.h"
  18. #else
  19. PROGMEM const char secret[][64] = {
  20. "test1",
  21. "test2",
  22. "test3",
  23. "test4",
  24. "test5"
  25. };
  26. #endif
  27. #ifdef FAUXCLICKY_ENABLE
  28. float fauxclicky_pressed_note[2] = MUSICAL_NOTE(_A6, 2); // (_D4, 0.25);
  29. float fauxclicky_released_note[2] = MUSICAL_NOTE(_A6, 2); // (_C4, 0.125);
  30. #else
  31. float fauxclicky_pressed[][2] = SONG(E__NOTE(_A6)); // change to your tastes
  32. float fauxclicky_released[][2] = SONG(E__NOTE(_A6)); // change to your tastes
  33. #endif
  34. bool faux_click_enabled = true;
  35. #ifdef TAP_DANCE_ENABLE
  36. //define diablo macro timer variables
  37. static uint16_t diablo_timer[4];
  38. static uint8_t diablo_times[] = { 0, 1, 3, 5, 10, 30 };
  39. static uint8_t diablo_key_time[4];
  40. bool check_dtimer(uint8_t dtimer) {
  41. // has the correct number of seconds elapsed (as defined by diablo_times)
  42. return (timer_elapsed(diablo_timer[dtimer]) < (diablo_key_time[dtimer] * 1000)) ? false : true;
  43. };
  44. // Cycle through the times for the macro, starting at 0, for disabled.
  45. // Max of six values, so don't exceed
  46. void diablo_tapdance_master(qk_tap_dance_state_t *state, void *user_data, uint8_t diablo_key) {
  47. if (state->count >= 7) {
  48. diablo_key_time[diablo_key] = diablo_times[0];
  49. reset_tap_dance(state);
  50. }
  51. else {
  52. diablo_key_time[diablo_key] = diablo_times[state->count - 1];
  53. }
  54. }
  55. // Would rather have one function for all of this, but no idea how to do that...
  56. void diablo_tapdance1(qk_tap_dance_state_t *state, void *user_data) {
  57. diablo_tapdance_master(state, user_data, 0);
  58. }
  59. void diablo_tapdance2(qk_tap_dance_state_t *state, void *user_data) {
  60. diablo_tapdance_master(state, user_data, 1);
  61. }
  62. void diablo_tapdance3(qk_tap_dance_state_t *state, void *user_data) {
  63. diablo_tapdance_master(state, user_data, 2);
  64. }
  65. void diablo_tapdance4(qk_tap_dance_state_t *state, void *user_data) {
  66. diablo_tapdance_master(state, user_data, 3);
  67. }
  68. //Tap Dance Definitions
  69. qk_tap_dance_action_t tap_dance_actions[] = {
  70. // tap once to disable, and more to enable timed micros
  71. [TD_D3_1] = ACTION_TAP_DANCE_FN(diablo_tapdance1),
  72. [TD_D3_2] = ACTION_TAP_DANCE_FN(diablo_tapdance2),
  73. [TD_D3_3] = ACTION_TAP_DANCE_FN(diablo_tapdance3),
  74. [TD_D3_4] = ACTION_TAP_DANCE_FN(diablo_tapdance4),
  75. };
  76. #endif
  77. #ifdef AUDIO_ENABLE
  78. float tone_qwerty[][2] = SONG(QWERTY_SOUND);
  79. float tone_dvorak[][2] = SONG(DVORAK_SOUND);
  80. float tone_colemak[][2] = SONG(COLEMAK_SOUND);
  81. float tone_workman[][2] = SONG(PLOVER_SOUND);
  82. float tone_hackstartup[][2] = SONG(ONE_UP_SOUND);
  83. #endif
  84. // Add reconfigurable functions here, for keymap customization
  85. // This allows for a global, userspace functions, and continued
  86. // customization of the keymap. Use _keymap instead of _user
  87. // functions in the keymaps
  88. __attribute__ ((weak))
  89. void matrix_init_keymap(void) {}
  90. __attribute__ ((weak))
  91. void matrix_scan_keymap(void) {}
  92. __attribute__ ((weak))
  93. bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
  94. return true;
  95. }
  96. __attribute__ ((weak))
  97. uint32_t layer_state_set_keymap (uint32_t state) {
  98. return state;
  99. }
  100. __attribute__ ((weak))
  101. void led_set_keymap(uint8_t usb_led) {}
  102. bool is_overwatch = false;
  103. #ifdef RGBLIGHT_ENABLE
  104. bool rgb_layer_change = true;
  105. #endif
  106. // Call user matrix init, set default RGB colors and then
  107. // call the keymap's init function
  108. void matrix_init_user(void) {
  109. #ifdef RGBLIGHT_ENABLE
  110. uint8_t default_layer = eeconfig_read_default_layer();
  111. rgblight_enable();
  112. if (true) {
  113. if (default_layer & (1UL << _COLEMAK)) {
  114. rgblight_set_magenta;
  115. }
  116. else if (default_layer & (1UL << _DVORAK)) {
  117. rgblight_set_green;
  118. }
  119. else if (default_layer & (1UL << _WORKMAN)) {
  120. rgblight_set_purple;
  121. }
  122. else {
  123. rgblight_set_teal;
  124. }
  125. }
  126. else
  127. {
  128. rgblight_set_red;
  129. rgblight_mode(5);
  130. }
  131. #endif
  132. #ifdef AUDIO_ENABLE
  133. // _delay_ms(21); // gets rid of tick
  134. // stop_all_notes();
  135. // PLAY_SONG(tone_hackstartup);
  136. #endif
  137. matrix_init_keymap();
  138. }
  139. #ifdef TAP_DANCE_ENABLE
  140. // Sends the key press to system, but only if on the Diablo layer
  141. void send_diablo_keystroke(uint8_t diablo_key) {
  142. if (biton32(layer_state) == _DIABLO) {
  143. switch (diablo_key) {
  144. case 0:
  145. SEND_STRING("1");
  146. break;
  147. case 1:
  148. SEND_STRING("2");
  149. break;
  150. case 2:
  151. SEND_STRING("3");
  152. break;
  153. case 3:
  154. SEND_STRING("4");
  155. break;
  156. }
  157. }
  158. }
  159. // Checks each of the 4 timers/keys to see if enough time has elapsed
  160. // Runs the "send string" command if enough time has passed, and resets the timer.
  161. void run_diablo_macro_check(void) {
  162. uint8_t dtime;
  163. for (dtime = 0; dtime < 4; dtime++) {
  164. if (check_dtimer(dtime) && diablo_key_time[dtime]) {
  165. diablo_timer[dtime] = timer_read();
  166. send_diablo_keystroke(dtime);
  167. }
  168. }
  169. }
  170. #endif
  171. // No global matrix scan code, so just run keymap's matix
  172. // scan function
  173. void matrix_scan_user(void) {
  174. #ifdef TAP_DANCE_ENABLE // Run Diablo 3 macro checking code.
  175. run_diablo_macro_check();
  176. #endif
  177. matrix_scan_keymap();
  178. }
  179. void led_set_user(uint8_t usb_led) {
  180. led_set_keymap(usb_led);
  181. }
  182. void persistent_default_layer_set(uint16_t default_layer) {
  183. eeconfig_update_default_layer(default_layer);
  184. default_layer_set(default_layer);
  185. }
  186. // Defines actions tor my global custom keycodes. Defined in drashna.h file
  187. // Then runs the _keymap's recod handier if not processed here
  188. bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  189. #ifdef CONSOLE_ENABLE
  190. xprintf("KL: row: %u, column: %u, pressed: %u\n", record->event.key.col, record->event.key.row, record->event.pressed);
  191. #endif
  192. #ifdef AUDIO_ENABLE
  193. if (faux_click_enabled) {
  194. if (record->event.pressed) {
  195. PLAY_SONG(fauxclicky_pressed);
  196. } else {
  197. stop_note(NOTE_A6);
  198. PLAY_SONG(fauxclicky_released);
  199. }
  200. }
  201. #endif
  202. switch (keycode) {
  203. case KC_QWERTY:
  204. if (record->event.pressed) {
  205. #ifdef AUDIO_ENABLE
  206. PLAY_SONG(tone_qwerty);
  207. #endif
  208. persistent_default_layer_set(1UL << _QWERTY);
  209. }
  210. return false;
  211. break;
  212. case KC_COLEMAK:
  213. if (record->event.pressed) {
  214. #ifdef AUDIO_ENABLE
  215. PLAY_SONG(tone_colemak);
  216. #endif
  217. persistent_default_layer_set(1UL << _COLEMAK);
  218. }
  219. return false;
  220. break;
  221. case KC_DVORAK:
  222. if (record->event.pressed) {
  223. #ifdef AUDIO_ENABLE
  224. PLAY_SONG(tone_dvorak);
  225. #endif
  226. persistent_default_layer_set(1UL << _DVORAK);
  227. }
  228. return false;
  229. break;
  230. case KC_WORKMAN:
  231. if (record->event.pressed) {
  232. #ifdef AUDIO_ENABLE
  233. PLAY_SONG(tone_workman);
  234. #endif
  235. persistent_default_layer_set(1UL << _WORKMAN);
  236. }
  237. return false;
  238. break;
  239. case LOWER:
  240. if (record->event.pressed) {
  241. layer_on(_LOWER);
  242. update_tri_layer(_LOWER, _RAISE, _ADJUST);
  243. }
  244. else {
  245. layer_off(_LOWER);
  246. update_tri_layer(_LOWER, _RAISE, _ADJUST);
  247. }
  248. return false;
  249. break;
  250. case RAISE:
  251. if (record->event.pressed) {
  252. layer_on(_RAISE);
  253. update_tri_layer(_LOWER, _RAISE, _ADJUST);
  254. }
  255. else {
  256. layer_off(_RAISE);
  257. update_tri_layer(_LOWER, _RAISE, _ADJUST);
  258. }
  259. return false;
  260. break;
  261. case ADJUST:
  262. if (record->event.pressed) {
  263. layer_on(_ADJUST);
  264. }
  265. else {
  266. layer_off(_ADJUST);
  267. }
  268. return false;
  269. break;
  270. #if !(defined(KEYBOARD_orthodox_rev1) || defined(KEYBOARD_orthodox_rev3) || defined(KEYBOARD_ergodox_ez))
  271. case KC_OVERWATCH:
  272. if (record->event.pressed) {
  273. is_overwatch = !is_overwatch;
  274. }
  275. #ifdef RGBLIGHT_ENABLE
  276. is_overwatch ? rgblight_mode(17) : rgblight_mode(18);
  277. #endif
  278. return false;
  279. break;
  280. case KC_SALT:
  281. if (!record->event.pressed) {
  282. register_code(is_overwatch ? KC_BSPC : KC_ENTER);
  283. unregister_code(is_overwatch ? KC_BSPC : KC_ENTER);
  284. _delay_ms(50);
  285. SEND_STRING("Salt, salt, salt...");
  286. register_code(KC_ENTER);
  287. unregister_code(KC_ENTER);
  288. }
  289. return false;
  290. break;
  291. case KC_MORESALT:
  292. if (!record->event.pressed) {
  293. register_code(is_overwatch ? KC_BSPC : KC_ENTER);
  294. unregister_code(is_overwatch ? KC_BSPC : KC_ENTER);
  295. _delay_ms(50);
  296. SEND_STRING("Please sir, can I have some more salt?!");
  297. register_code(KC_ENTER);
  298. unregister_code(KC_ENTER);
  299. }
  300. return false;
  301. break;
  302. case KC_SALTHARD:
  303. if (!record->event.pressed) {
  304. register_code(is_overwatch ? KC_BSPC : KC_ENTER);
  305. unregister_code(is_overwatch ? KC_BSPC : KC_ENTER);
  306. _delay_ms(50);
  307. SEND_STRING("Your salt only makes me harder, and even more aggressive!");
  308. register_code(KC_ENTER);
  309. unregister_code(KC_ENTER);
  310. }
  311. return false;
  312. break;
  313. case KC_GOODGAME:
  314. if (!record->event.pressed) {
  315. register_code(is_overwatch ? KC_BSPC : KC_ENTER);
  316. unregister_code(is_overwatch ? KC_BSPC : KC_ENTER);
  317. _delay_ms(50);
  318. SEND_STRING("Good game, everyone!");
  319. register_code(KC_ENTER);
  320. unregister_code(KC_ENTER);
  321. }
  322. return false;
  323. break;
  324. case KC_GLHF:
  325. if (!record->event.pressed) {
  326. register_code(is_overwatch ? KC_BSPC : KC_ENTER);
  327. unregister_code(is_overwatch ? KC_BSPC : KC_ENTER);
  328. _delay_ms(50);
  329. SEND_STRING("Good luck, have fun!!!");
  330. register_code(KC_ENTER);
  331. unregister_code(KC_ENTER);
  332. }
  333. return false;
  334. break;
  335. case KC_SYMM:
  336. if (!record->event.pressed) {
  337. register_code(is_overwatch ? KC_BSPC : KC_ENTER);
  338. unregister_code(is_overwatch ? KC_BSPC : KC_ENTER);
  339. _delay_ms(50);
  340. SEND_STRING("Left click to win!");
  341. register_code(KC_ENTER);
  342. unregister_code(KC_ENTER);
  343. }
  344. return false;
  345. break;
  346. case KC_JUSTGAME:
  347. if (!record->event.pressed) {
  348. register_code(is_overwatch ? KC_BSPC : KC_ENTER);
  349. unregister_code(is_overwatch ? KC_BSPC : KC_ENTER);
  350. _delay_ms(50);
  351. SEND_STRING("It may be a game, but if you don't want to actually try, please go play AI, so that people that actually want to take the game seriously and \"get good\" have a place to do so without trolls like you throwing games.");
  352. register_code(KC_ENTER);
  353. unregister_code(KC_ENTER);
  354. }
  355. return false;
  356. break;
  357. case KC_TORB:
  358. if (!record->event.pressed) {
  359. register_code(is_overwatch ? KC_BSPC : KC_ENTER);
  360. unregister_code(is_overwatch ? KC_BSPC : KC_ENTER);
  361. _delay_ms(50);
  362. SEND_STRING("That was positively riveting!");
  363. register_code(KC_ENTER);
  364. unregister_code(KC_ENTER);
  365. }
  366. return false;
  367. break;
  368. case KC_AIM:
  369. if (!record->event.pressed) {
  370. register_code(is_overwatch ? KC_BSPC : KC_ENTER);
  371. unregister_code(is_overwatch ? KC_BSPC : KC_ENTER);
  372. _delay_ms(50);
  373. SEND_STRING("That aim is absolutely amazing. It's almost like you're a machine!" SS_TAP(X_ENTER));
  374. _delay_ms(3000);
  375. register_code(is_overwatch ? KC_BSPC : KC_ENTER);
  376. unregister_code(is_overwatch ? KC_BSPC : KC_ENTER);
  377. SEND_STRING("Wait! That aim is TOO good! You're clearly using an aim hack! CHEATER!" SS_TAP(X_ENTER));
  378. }
  379. return false;
  380. break;
  381. case KC_C9:
  382. if (!record->event.pressed) {
  383. register_code(is_overwatch ? KC_BSPC : KC_ENTER);
  384. unregister_code(is_overwatch ? KC_BSPC : KC_ENTER);
  385. _delay_ms(50);
  386. SEND_STRING("OMG!!! C9!!!");
  387. register_code(KC_ENTER);
  388. unregister_code(KC_ENTER);
  389. }
  390. return false;
  391. break;
  392. case KC_GGEZ:
  393. if (!record->event.pressed) {
  394. register_code(is_overwatch ? KC_BSPC : KC_ENTER);
  395. unregister_code(is_overwatch ? KC_BSPC : KC_ENTER);
  396. _delay_ms(50);
  397. SEND_STRING("That was a fantastic game, though it was a bit easy. Try harder next time!");
  398. register_code(KC_ENTER);
  399. unregister_code(KC_ENTER);
  400. }
  401. return false;
  402. break;
  403. #endif
  404. #ifdef TAP_DANCE_ENABLE
  405. case KC_DIABLO_CLEAR: // reset all Diable timers, disabling them
  406. if (record->event.pressed) {
  407. uint8_t dtime;
  408. for (dtime = 0; dtime < 4; dtime++) {
  409. diablo_key_time[dtime] = diablo_times[0];
  410. }
  411. }
  412. return false;
  413. break;
  414. #endif
  415. case KC_MAKE:
  416. if (!record->event.pressed) {
  417. SEND_STRING("make " QMK_KEYBOARD ":" QMK_KEYMAP
  418. #if (defined(BOOTLOADER_DFU) || defined(BOOTLOADER_LUFA_DFU) || defined(BOOTLOADER_QMK_DFU))
  419. ":dfu"
  420. #elif defined(BOOTLOADER_HALFKAY)
  421. ":teensy"
  422. //#elif defined(BOOTLOADER_CATERINA)
  423. // ":avrdude"
  424. #endif
  425. #ifdef RGBLIGHT_ENABLE
  426. " RGBLIGHT_ENABLE=yes"
  427. #else
  428. " RGBLIGHT_ENABLE=no"
  429. #endif
  430. #ifdef AUDIO_ENABLE
  431. " AUDIO_ENABLE=yes"
  432. #else
  433. " AUDIO_ENABLE=no"
  434. #endif
  435. SS_TAP(X_ENTER));
  436. }
  437. return false;
  438. break;
  439. case KC_RESET:
  440. if (!record->event.pressed) {
  441. #ifdef RGBLIGHT_ENABLE
  442. rgblight_enable();
  443. rgblight_mode(1);
  444. rgblight_setrgb(0xff, 0x00, 0x00);
  445. #endif
  446. reset_keyboard();
  447. }
  448. return false;
  449. break;
  450. case EPRM:
  451. if (record->event.pressed) {
  452. eeconfig_init();
  453. }
  454. return false;
  455. break;
  456. case VRSN:
  457. if (record->event.pressed) {
  458. SEND_STRING(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
  459. }
  460. return false;
  461. break;
  462. case KC_SECRET_1 ... KC_SECRET_5:
  463. if (!record->event.pressed) {
  464. send_string_P(secret[keycode - KC_SECRET_1]);
  465. }
  466. return false;
  467. break;
  468. case KC_FXCL:
  469. if (!record->event.pressed) {
  470. faux_click_enabled = !faux_click_enabled;
  471. }
  472. return false;
  473. break;
  474. case KC_RGB_T: // Because I want the option to go back to normal RGB mode rather than always layer indication
  475. #ifdef RGBLIGHT_ENABLE
  476. if (record->event.pressed) {
  477. rgb_layer_change = !rgb_layer_change;
  478. }
  479. #endif
  480. return false;
  481. break;
  482. #ifdef RGBLIGHT_ENABLE
  483. case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT: // quantum_keycodes.h L400 for definitions
  484. if (record->event.pressed) { //This disrables layer indication, as it's assumed that if you're changing this ... you want that disabled
  485. rgb_layer_change = false;
  486. }
  487. return true;
  488. break;
  489. #endif
  490. }
  491. return process_record_keymap(keycode, record);
  492. }
  493. // Runs state check and changes underglow color and animation
  494. // on layer change, no matter where the change was initiated
  495. // Then runs keymap's layer change check
  496. uint32_t layer_state_set_user(uint32_t state) {
  497. #ifdef RGBLIGHT_ENABLE
  498. uint8_t default_layer = eeconfig_read_default_layer();
  499. if (rgb_layer_change) {
  500. switch (biton32(state)) {
  501. case _NAV:
  502. rgblight_set_blue;
  503. rgblight_mode(1);
  504. break;
  505. case _SYMB:
  506. rgblight_set_blue;
  507. rgblight_mode(2);
  508. break;
  509. case _MOUS:
  510. rgblight_set_yellow;
  511. rgblight_mode(1);
  512. break;
  513. case _MACROS:
  514. rgblight_set_orange;
  515. is_overwatch ? rgblight_mode(17) : rgblight_mode(18);
  516. break;
  517. case _MEDIA:
  518. rgblight_set_green;
  519. rgblight_mode(22);
  520. break;
  521. case _GAMEPAD:
  522. rgblight_set_orange;
  523. rgblight_mode(17);
  524. break;
  525. case _DIABLO:
  526. rgblight_set_red;
  527. rgblight_mode(5);
  528. break;
  529. case _RAISE:
  530. rgblight_set_yellow;
  531. rgblight_mode(5);
  532. break;
  533. case _LOWER:
  534. rgblight_set_orange;
  535. rgblight_mode(5);
  536. break;
  537. case _ADJUST:
  538. rgblight_set_red;
  539. rgblight_mode(23);
  540. break;
  541. case _COVECUBE:
  542. rgblight_set_green;
  543. rgblight_mode(2);
  544. break;
  545. default:
  546. if (default_layer & (1UL << _COLEMAK)) {
  547. rgblight_set_magenta;
  548. }
  549. else if (default_layer & (1UL << _DVORAK)) {
  550. rgblight_set_green;
  551. }
  552. else if (default_layer & (1UL << _WORKMAN)) {
  553. rgblight_set_purple;
  554. }
  555. else {
  556. rgblight_set_teal;
  557. }
  558. rgblight_mode(1);
  559. break;
  560. }
  561. }
  562. #endif
  563. return layer_state_set_keymap (state);
  564. }