arkag.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  1. #include "arkag.h"
  2. /*
  3. Current Layout and Keeb:
  4. https://github.com/arkag/qmk_firmware/blob/master/keyboards/mechmini/v2/keymaps/arkag/keymap.c
  5. */
  6. // Start: Written by konstantin: vomindoraan
  7. #include <ctype.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. void send_unicode_hex_string(const char *str) {
  11. if (!str) { return; } // Saftey net
  12. while (*str) {
  13. // Find the next code point (token) in the string
  14. for (; *str == ' '; str++);
  15. size_t n = strcspn(str, " "); // Length of the current token
  16. char code_point[n+1];
  17. strncpy(code_point, str, n);
  18. code_point[n] = '\0'; // Make sure it's null-terminated
  19. // Normalize the code point: make all hex digits lowercase
  20. for (char *p = code_point; *p; p++) {
  21. *p = tolower(*p);
  22. }
  23. // Send the code point as a Unicode input string
  24. unicode_input_start();
  25. send_string(code_point);
  26. unicode_input_finish();
  27. str += n; // Move to the first ' ' (or '\0') after the current token
  28. }
  29. }
  30. // End: Written by konstantin: vomindoraan
  31. // Start: Written by Chris Lewis
  32. #ifndef MIN
  33. #define MIN(a,b) (((a)<(b))?(a):(b))
  34. #endif
  35. #ifndef MAX
  36. #define MAX(a,b) (((a)>(b))?(a):(b))
  37. #endif
  38. #define TYPING_SPEED_MAX_VALUE 200
  39. uint8_t typing_speed = 0;
  40. void velocikey_accelerate() {
  41. if (typing_speed < TYPING_SPEED_MAX_VALUE) typing_speed += (TYPING_SPEED_MAX_VALUE / 50);
  42. }
  43. void velocikey_decelerate() {
  44. static uint16_t decay_timer = 0;
  45. if (timer_elapsed(decay_timer) > 500 || decay_timer == 0) {
  46. if (typing_speed > 0) typing_speed -= 1;
  47. //Decay a little faster at half of max speed
  48. if (typing_speed > TYPING_SPEED_MAX_VALUE / 2) typing_speed -= 1;
  49. //Decay even faster at 3/4 of max speed
  50. if (typing_speed > TYPING_SPEED_MAX_VALUE / 4 * 3) typing_speed -= 3;
  51. decay_timer = timer_read();
  52. }
  53. }
  54. uint8_t velocikey_match_speed(uint8_t minValue, uint8_t maxValue) {
  55. return MAX(minValue, maxValue - (maxValue - minValue) * ((float)typing_speed / TYPING_SPEED_MAX_VALUE));
  56. }
  57. // End: Written by Chris Lewis
  58. uint8_t current_os,
  59. mod_primary_mask,
  60. fade_interval,
  61. num_extra_flashes_off = 0;
  62. Color underglow,
  63. flash_color,
  64. saved_color,
  65. hsv_none = {0,0,0};
  66. flashState flash_state = no_flash;
  67. fadeState fade_state = add_fade;
  68. activityState state = boot;
  69. void set_color (Color new, bool update) {
  70. rgblight_sethsv_eeprom_helper(new.h, new.s, new.v, update);
  71. }
  72. void save_color(Color to_save) {
  73. saved_color = to_save;
  74. }
  75. void reset_color(void) {
  76. underglow = saved_color;
  77. }
  78. Color mod_color(Color current_color, bool should_add, uint8_t change_amount) {
  79. save_color(underglow);
  80. int addlim = 359 - change_amount;
  81. int sublim = change_amount;
  82. int leftovers;
  83. if (should_add) {
  84. if (current_color.h <= addlim) {
  85. current_color.h += change_amount;
  86. } else {
  87. leftovers = (359 + change_amount) % 359;
  88. current_color.h = 0 + leftovers;
  89. }
  90. } else {
  91. if (current_color.h >= sublim) {
  92. current_color.h -= change_amount;
  93. } else {
  94. leftovers = change_amount - current_color.h;
  95. current_color.h = 359 - leftovers;
  96. }
  97. }
  98. return current_color;
  99. }
  100. void check_state (void) {
  101. static uint16_t active_timer;
  102. if (!active_timer) {active_timer = timer_read();}
  103. static bool activated, deactivated, slept;
  104. switch (state) {
  105. case active:
  106. if (!activated) {
  107. if (slept) {rgblight_mode_noeeprom(1);}
  108. activated = true;
  109. deactivated = false;
  110. slept = false;
  111. }
  112. fade_interval = velocikey_match_speed(1, 25);
  113. if (timer_elapsed(active_timer) < INACTIVE_DELAY) {return;}
  114. active_timer = timer_read();
  115. state = inactive;
  116. return;
  117. case inactive:
  118. if (!deactivated) {
  119. deactivated = true;
  120. activated = false;
  121. slept = false;
  122. }
  123. velocikey_decelerate();
  124. fade_interval = velocikey_match_speed(1, 25);
  125. if (timer_elapsed(active_timer) < SLEEP_DELAY) {return;}
  126. state = sleeping;
  127. return;
  128. case sleeping:
  129. if (!slept) {
  130. rgblight_mode_noeeprom(4);
  131. slept = true;
  132. activated = false;
  133. deactivated = false;
  134. }
  135. return;
  136. case boot:
  137. return;
  138. }
  139. }
  140. void fade_rgb (void) {
  141. static uint16_t fade_timer;
  142. if (state == boot) {return;}
  143. if (!fade_timer) {fade_timer = timer_read();}
  144. if (timer_elapsed(fade_timer) < fade_interval) {return;}
  145. switch (fade_state) {
  146. case add_fade:
  147. if (underglow.h == 359) {
  148. fade_state = sub_fade;
  149. return;
  150. }
  151. underglow.h = underglow.h + 1;
  152. break;
  153. case sub_fade:
  154. if (underglow.h == 0) {
  155. fade_state = add_fade;
  156. return;
  157. }
  158. underglow.h = underglow.h - 1;
  159. break;
  160. }
  161. fade_timer = timer_read();
  162. if (flash_state == no_flash) {
  163. set_color(underglow, false);
  164. }
  165. }
  166. void flash_rgb (void) {
  167. static uint16_t flash_timer;
  168. switch(flash_state) {
  169. case no_flash:
  170. return;
  171. case flash_off:
  172. if (!flash_timer) {flash_timer = timer_read();}
  173. if (timer_elapsed(flash_timer) >= LED_FLASH_DELAY) {
  174. set_color(hsv_none, false);
  175. flash_timer = timer_read();
  176. flash_state = flash_on;
  177. }
  178. return;
  179. case flash_on:
  180. if (timer_elapsed(flash_timer) >= LED_FLASH_DELAY) {
  181. set_color(flash_color, false);
  182. flash_timer = timer_read();
  183. if (num_extra_flashes_off > 0) {
  184. flash_state = flash_off;
  185. num_extra_flashes_off--;
  186. } else {
  187. set_color(underglow, false);
  188. flash_state = no_flash;
  189. }
  190. }
  191. return;
  192. }
  193. }
  194. void set_os (uint8_t os, bool update) {
  195. current_os = os;
  196. if (update) {
  197. eeprom_update_byte(EECONFIG_USERSPACE, current_os);
  198. }
  199. switch (os) {
  200. case OS_MAC:
  201. set_unicode_input_mode(UC_OSX);
  202. underglow = (Color){ 300, 255, 255 };
  203. mod_primary_mask = MOD_GUI_MASK;
  204. break;
  205. case OS_WIN:
  206. set_unicode_input_mode(UC_WINC);
  207. underglow = (Color){ 180, 255, 255 };
  208. mod_primary_mask = MOD_CTL_MASK;
  209. break;
  210. case OS_NIX:
  211. set_unicode_input_mode(UC_LNX);
  212. underglow = (Color){ 60, 255, 255 };
  213. mod_primary_mask = MOD_CTL_MASK;
  214. break;
  215. default:
  216. underglow = (Color){ 0, 0, 255 };
  217. mod_primary_mask = MOD_CTL_MASK;
  218. }
  219. set_color(underglow, update);
  220. flash_color = underglow;
  221. flash_state = flash_off;
  222. state = boot;
  223. num_extra_flashes_off = 1;
  224. }
  225. void tap_key(uint8_t keycode) {
  226. register_code(keycode);
  227. unregister_code(keycode);
  228. }
  229. // register GUI if Mac or Ctrl if other
  230. void pri_mod(bool press) {
  231. if (press) {
  232. if (current_os == OS_MAC) {
  233. register_code(KC_LGUI);
  234. } else {
  235. register_code(KC_LCTL);
  236. }
  237. } else {
  238. if (current_os == OS_MAC) {
  239. unregister_code(KC_LGUI);
  240. } else {
  241. unregister_code(KC_LCTL);
  242. }
  243. }
  244. }
  245. // register Ctrl if Mac or GUI if other
  246. void sec_mod(bool press) {
  247. if (press) {
  248. if (current_os == OS_MAC) {
  249. register_code(KC_LCTL);
  250. } else {
  251. register_code(KC_LGUI);
  252. }
  253. } else {
  254. if (current_os == OS_MAC) {
  255. unregister_code(KC_LCTL);
  256. } else {
  257. unregister_code(KC_LGUI);
  258. }
  259. }
  260. }
  261. void surround_type(uint8_t num_of_chars, uint16_t keycode, bool use_shift) {
  262. if (use_shift) {
  263. register_code(KC_LSFT);
  264. }
  265. for (int i = 0; i < num_of_chars; i++) {
  266. tap_key(keycode);
  267. }
  268. if (use_shift) {
  269. unregister_code(KC_LSFT);
  270. }
  271. for (int i = 0; i < (num_of_chars/2); i++) {
  272. tap_key(KC_LEFT);
  273. }
  274. }
  275. void long_keystroke(size_t num_of_keys, uint16_t keys[]) {
  276. for (int i = 0; i < num_of_keys-1; i++) {
  277. register_code(keys[i]);
  278. }
  279. tap_key(keys[num_of_keys-1]);
  280. for (int i = 0; i < num_of_keys-1; i++) {
  281. unregister_code(keys[i]);
  282. }
  283. }
  284. void dance_grv (qk_tap_dance_state_t *state, void *user_data) {
  285. if (state->count == 1) {
  286. tap_key(KC_GRV);
  287. } else if (state->count == 2) {
  288. surround_type(2, KC_GRAVE, false);
  289. } else {
  290. surround_type(6, KC_GRAVE, false);
  291. }
  292. }
  293. void dance_quot (qk_tap_dance_state_t *state, void *user_data) {
  294. if (state->count == 1) {
  295. tap_key(KC_QUOT);
  296. } else if (state->count == 2) {
  297. surround_type(2, KC_QUOTE, false);
  298. } else if (state->count == 3) {
  299. surround_type(2, KC_QUOTE, true);
  300. }
  301. }
  302. void dance_strk (qk_tap_dance_state_t *state, void *user_data) {
  303. if (state->count == 1) {
  304. surround_type(4, KC_TILDE, true);
  305. } else if (state->count == 2) {
  306. if (current_os == OS_MAC) {
  307. long_keystroke(3, (uint16_t[]){KC_LGUI, KC_LSFT, KC_4});
  308. } else if (current_os == OS_WIN) {
  309. long_keystroke(3, (uint16_t[]){KC_LGUI, KC_LSFT, KC_S});
  310. } else {
  311. return;
  312. }
  313. }
  314. }
  315. void dance_3 (qk_tap_dance_state_t *state, void *user_data) {
  316. if (state->count == 1) {
  317. tap_key(KC_3);
  318. } else if (state->count == 2) {
  319. send_unicode_hex_string("00E8");
  320. } else if (state->count == 3) {
  321. send_unicode_hex_string("00E9");
  322. }
  323. }
  324. void dance_c (qk_tap_dance_state_t *state, void *user_data) {
  325. if (state->count == 1) {
  326. tap_key(KC_C);
  327. } else if (state->count == 2) {
  328. send_unicode_hex_string("00E7");
  329. }
  330. }
  331. void matrix_init_user(void) {
  332. current_os = eeprom_read_byte(EECONFIG_USERSPACE);
  333. set_os(current_os, false);
  334. }
  335. void matrix_scan_user(void) {
  336. check_state();
  337. flash_rgb();
  338. fade_rgb();
  339. }
  340. bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  341. switch (keycode) {
  342. case M_PMOD:
  343. if (record->event.pressed) {
  344. pri_mod(true);
  345. } else {
  346. pri_mod(false);
  347. }
  348. return false;
  349. case M_SMOD:
  350. if (record->event.pressed) {
  351. sec_mod(true);
  352. } else {
  353. sec_mod(false);
  354. }
  355. return false;
  356. case M_P_B:
  357. if (record->event.pressed) {
  358. if (current_os == OS_WIN) {
  359. SEND_STRING(SS_DOWN(X_LGUI) SS_TAP(X_PAUSE) SS_UP(X_LGUI));
  360. } else {
  361. }
  362. }
  363. return false;
  364. case M_C_A_D:
  365. if (record->event.pressed) {
  366. if (current_os == OS_WIN) {
  367. SEND_STRING(SS_DOWN(X_LCTRL) SS_DOWN(X_LALT) SS_TAP(X_DELETE) SS_UP(X_LALT) SS_UP(X_LCTRL));
  368. } else {
  369. }
  370. }
  371. return false;
  372. case M_CALC:
  373. if (record->event.pressed) {
  374. if (current_os == OS_WIN) {
  375. SEND_STRING(SS_TAP(X_CALCULATOR));
  376. } else if (current_os == OS_MAC) {
  377. SEND_STRING(SS_DOWN(X_LGUI) SS_TAP(X_SPACE) SS_UP(X_LGUI) "calculator" SS_TAP(X_ENTER));
  378. }
  379. }
  380. return false;
  381. case M_OS:
  382. if (record->event.pressed) {
  383. set_os((current_os+1) % _OS_COUNT, true);
  384. }
  385. return false;
  386. case M_LOD:
  387. if (record->event.pressed) {
  388. send_unicode_hex_string("0CA0 005F 005F 0CA0");
  389. }
  390. return false;
  391. case M_LENNY:
  392. if (record->event.pressed) {
  393. send_unicode_hex_string("0028 0020 0361 00B0 0020 035C 0296 0020 0361 00B0 0029");
  394. }
  395. return false;
  396. case M_TF:
  397. if (record->event.pressed) {
  398. send_unicode_hex_string("0028 256F 2035 0414 2032 0029 256F 5F61 253B 2501 253B");
  399. }
  400. return false;
  401. case M_UF:
  402. if (record->event.pressed) {
  403. send_unicode_hex_string("252C 2500 252C 30CE 0028 0020 00BA 0020 005F 0020 00BA 0020 30CE 0029");
  404. }
  405. return false;
  406. case M_SHRUG:
  407. if (record->event.pressed) {
  408. send_unicode_hex_string("00AF 005C 005F 0028 30C4 0029 005F 002F 00AF");
  409. }
  410. return false;
  411. case M_TM:
  412. if (record->event.pressed) {
  413. send_unicode_hex_string("2122");
  414. }
  415. return false;
  416. case M_REPO:
  417. if (record->event.pressed) {
  418. SEND_STRING("https://github.com/qmk/qmk_firmware/tree/master/users/arkag");
  419. }
  420. return false;
  421. case M_GGT:
  422. if (record->event.pressed) {
  423. SEND_STRING("@GrahamGoldenTech.com");
  424. }
  425. return false;
  426. case M_SNIPT:
  427. if (record->event.pressed) {
  428. surround_type(6, KC_GRAVE, false);
  429. pri_mod(true);
  430. tap_key(KC_V);
  431. pri_mod(false);
  432. tap_key(KC_RGHT);
  433. tap_key(KC_RGHT);
  434. tap_key(KC_RGHT);
  435. tap_key(KC_ENTER);
  436. }
  437. return false;
  438. case M_BOLD:
  439. if (record->event.pressed) {
  440. surround_type(4, KC_8, true);
  441. }
  442. return false;
  443. case M_ITAL:
  444. if (record->event.pressed) {
  445. surround_type(2, KC_8, true);
  446. }
  447. return false;
  448. case M_ULIN:
  449. if (record->event.pressed) {
  450. surround_type(4, KC_MINS, true);
  451. }
  452. return false;
  453. case KC_LSFT:
  454. if (record->event.pressed) {
  455. save_color(underglow);
  456. underglow = mod_color(underglow, true, 75);
  457. SEND_STRING(SS_DOWN(X_LSHIFT));
  458. } else {
  459. reset_color();
  460. SEND_STRING(SS_UP(X_LSHIFT));
  461. }
  462. return false;
  463. case MEDIA:
  464. case LAZY:
  465. case KEEB:
  466. case RAISE:
  467. case LOWER:
  468. return true;
  469. default:
  470. if (record->event.pressed) {
  471. state = active;
  472. velocikey_accelerate();
  473. }
  474. return true;
  475. }
  476. }
  477. uint32_t layer_state_set_user(uint32_t state) {
  478. switch (biton32(state)) {
  479. case _LAZY:
  480. save_color(underglow);
  481. underglow = mod_color(underglow, true, 50);
  482. break;
  483. case _MEDIA:
  484. save_color(underglow);
  485. underglow = mod_color(underglow, true, 150);
  486. break;
  487. case _KEEB:
  488. save_color(underglow);
  489. underglow = mod_color(underglow, false, 150);
  490. break;
  491. case _LOWER:
  492. save_color(underglow);
  493. underglow = mod_color(underglow, false, 100);
  494. break;
  495. case _RAISE:
  496. save_color(underglow);
  497. underglow = mod_color(underglow, true, 100);
  498. break;
  499. default:
  500. reset_color();
  501. break;
  502. }
  503. set_color(underglow, false);
  504. return state;
  505. }
  506. //Tap Dance Definitions
  507. qk_tap_dance_action_t tap_dance_actions[] = {
  508. [TD_3_GRV_ACT] = ACTION_TAP_DANCE_FN (dance_3),
  509. [TD_C_CED] = ACTION_TAP_DANCE_FN (dance_c),
  510. [TD_GRV_3GRV] = ACTION_TAP_DANCE_FN (dance_grv),
  511. [TD_SING_DOUB] = ACTION_TAP_DANCE_FN (dance_quot),
  512. [TD_STRK_SHOT] = ACTION_TAP_DANCE_FN (dance_strk),
  513. [TD_HYPH_UNDR] = ACTION_TAP_DANCE_DOUBLE (KC_MINS, LSFT(KC_MINS)),
  514. [TD_BRCK_PARN_O] = ACTION_TAP_DANCE_DOUBLE (KC_LBRC, LSFT(KC_9)),
  515. [TD_BRCK_PARN_C] = ACTION_TAP_DANCE_DOUBLE (KC_RBRC, LSFT(KC_0)),
  516. [TD_LALT_RALT] = ACTION_TAP_DANCE_DOUBLE (KC_LALT, KC_RALT),
  517. };