drashna.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  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. // wait_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. wait_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. wait_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. wait_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. wait_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. wait_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. wait_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. wait_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. wait_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. wait_ms(50);
  373. SEND_STRING("That aim is absolutely amazing. It's almost like you're a machine!" SS_TAP(X_ENTER));
  374. wait_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. wait_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. wait_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. SS_TAP(X_ENTER));
  426. }
  427. return false;
  428. break;
  429. case KC_RESET:
  430. if (!record->event.pressed) {
  431. #ifdef RGBLIGHT_ENABLE
  432. rgblight_enable();
  433. rgblight_mode(1);
  434. rgblight_setrgb(0xff, 0x00, 0x00);
  435. #endif
  436. reset_keyboard();
  437. }
  438. return false;
  439. break;
  440. case EPRM:
  441. if (record->event.pressed) {
  442. eeconfig_init();
  443. }
  444. return false;
  445. break;
  446. case VRSN:
  447. if (record->event.pressed) {
  448. SEND_STRING(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION);
  449. }
  450. return false;
  451. break;
  452. case KC_SECRET_1 ... KC_SECRET_5:
  453. if (!record->event.pressed) {
  454. send_string_P(secret[keycode - KC_SECRET_1]);
  455. }
  456. return false;
  457. break;
  458. case KC_FXCL:
  459. if (!record->event.pressed) {
  460. faux_click_enabled = !faux_click_enabled;
  461. }
  462. return false;
  463. break;
  464. case KC_RGB_T: // Because I want the option to go back to normal RGB mode rather than always layer indication
  465. #ifdef RGBLIGHT_ENABLE
  466. if (record->event.pressed) {
  467. rgb_layer_change = !rgb_layer_change;
  468. }
  469. #endif
  470. return false;
  471. break;
  472. #ifdef RGBLIGHT_ENABLE
  473. case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT: // quantum_keycodes.h L400 for definitions
  474. if (record->event.pressed) { //This disrables layer indication, as it's assumed that if you're changing this ... you want that disabled
  475. rgb_layer_change = false;
  476. }
  477. return true;
  478. break;
  479. #endif
  480. }
  481. return process_record_keymap(keycode, record);
  482. }
  483. // Runs state check and changes underglow color and animation
  484. // on layer change, no matter where the change was initiated
  485. // Then runs keymap's layer change check
  486. uint32_t layer_state_set_user(uint32_t state) {
  487. #ifdef RGBLIGHT_ENABLE
  488. uint8_t default_layer = eeconfig_read_default_layer();
  489. if (rgb_layer_change) {
  490. switch (biton32(state)) {
  491. case _NAV:
  492. rgblight_set_blue;
  493. rgblight_mode(1);
  494. break;
  495. case _SYMB:
  496. rgblight_set_blue;
  497. rgblight_mode(2);
  498. break;
  499. case _MOUS:
  500. rgblight_set_yellow;
  501. rgblight_mode(1);
  502. break;
  503. case _MACROS:
  504. rgblight_set_orange;
  505. is_overwatch ? rgblight_mode(17) : rgblight_mode(18);
  506. break;
  507. case _MEDIA:
  508. rgblight_set_green;
  509. rgblight_mode(22);
  510. break;
  511. case _GAMEPAD:
  512. rgblight_set_orange;
  513. rgblight_mode(17);
  514. break;
  515. case _DIABLO:
  516. rgblight_set_red;
  517. rgblight_mode(5);
  518. break;
  519. case _RAISE:
  520. rgblight_set_yellow;
  521. rgblight_mode(5);
  522. break;
  523. case _LOWER:
  524. rgblight_set_orange;
  525. rgblight_mode(5);
  526. break;
  527. case _ADJUST:
  528. rgblight_set_red;
  529. rgblight_mode(23);
  530. break;
  531. case _COVECUBE:
  532. rgblight_set_green;
  533. rgblight_mode(2);
  534. break;
  535. default:
  536. if (default_layer & (1UL << _COLEMAK)) {
  537. rgblight_set_magenta;
  538. }
  539. else if (default_layer & (1UL << _DVORAK)) {
  540. rgblight_set_green;
  541. }
  542. else if (default_layer & (1UL << _WORKMAN)) {
  543. rgblight_set_purple;
  544. }
  545. else {
  546. rgblight_set_teal;
  547. }
  548. rgblight_mode(1);
  549. break;
  550. }
  551. }
  552. #endif
  553. return layer_state_set_keymap (state);
  554. }