arkag.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  1. #include "arkag.h"
  2. #include "eeprom.h"
  3. /*
  4. Current Layout and Keeb:
  5. https://github.com/arkag/qmk_firmware/blob/master/keyboards/mechmini/v2/keymaps/arkag/keymap.c
  6. */
  7. #include <stdbool.h>
  8. // Start: Written by Chris Lewis
  9. #ifndef MIN
  10. #define MIN(a,b) (((a)<(b))?(a):(b))
  11. #endif
  12. #ifndef MAX
  13. #define MAX(a,b) (((a)>(b))?(a):(b))
  14. #endif
  15. #define TYPING_SPEED_MAX_VALUE 200
  16. uint8_t typing_speed = 0;
  17. void velocikey_accelerate(void) {
  18. if (typing_speed < TYPING_SPEED_MAX_VALUE) typing_speed += (TYPING_SPEED_MAX_VALUE / 50);
  19. }
  20. void velocikey_decelerate(void) {
  21. static uint16_t decay_timer = 0;
  22. if (timer_elapsed(decay_timer) > 500 || decay_timer == 0) {
  23. if (typing_speed > 0) typing_speed -= 1;
  24. //Decay a little faster at half of max speed
  25. if (typing_speed > TYPING_SPEED_MAX_VALUE / 2) typing_speed -= 1;
  26. //Decay even faster at 3/4 of max speed
  27. if (typing_speed > TYPING_SPEED_MAX_VALUE / 4 * 3) typing_speed -= 3;
  28. decay_timer = timer_read();
  29. }
  30. }
  31. uint8_t velocikey_match_speed(uint8_t minValue, uint8_t maxValue) {
  32. return MAX(minValue, maxValue - (maxValue - minValue) * ((float)typing_speed / TYPING_SPEED_MAX_VALUE));
  33. }
  34. // End: Written by Chris Lewis
  35. static int shift_int = 0;
  36. uint8_t current_os,
  37. mod_primary_mask,
  38. fade_interval,
  39. num_extra_flashes_off = 0;
  40. Color underglow,
  41. flash_color,
  42. saved_color,
  43. hsv_none = {0,0,0};
  44. flashState flash_state = no_flash;
  45. fadeState fade_state = add_fade;
  46. activityState state = boot;
  47. bool aesthetic = false,
  48. shifty = false;
  49. float song_ussr[][2] = SONG(USSR_ANTHEM);
  50. void set_color (Color new, bool update) {
  51. rgblight_sethsv_eeprom_helper(new.h, new.s, new.v, update);
  52. }
  53. void save_color(Color to_save) {
  54. saved_color = to_save;
  55. }
  56. void reset_color(void) {
  57. underglow = saved_color;
  58. }
  59. Color mod_color(Color current_color, bool should_add, uint8_t change_amount) {
  60. save_color(underglow);
  61. int addlim = HUE_MAX - change_amount;
  62. int sublim = change_amount;
  63. int leftovers;
  64. if (should_add) {
  65. if (current_color.h <= addlim) {
  66. current_color.h += change_amount;
  67. } else {
  68. leftovers = (HUE_MAX + change_amount) % HUE_MAX;
  69. current_color.h = 0 + leftovers;
  70. }
  71. } else {
  72. if (current_color.h >= sublim) {
  73. current_color.h -= change_amount;
  74. } else {
  75. leftovers = change_amount - current_color.h;
  76. current_color.h = HUE_MAX - leftovers;
  77. }
  78. }
  79. return current_color;
  80. }
  81. void check_state (void) {
  82. static uint16_t active_timer;
  83. if (!active_timer) {active_timer = timer_read();}
  84. static bool activated, deactivated, slept;
  85. switch (state) {
  86. case active:
  87. if (!activated) {
  88. if (slept) {rgblight_mode_noeeprom(1);}
  89. activated = true;
  90. deactivated = false;
  91. }
  92. fade_interval = velocikey_match_speed(1, 25);
  93. if (timer_elapsed(active_timer) < INACTIVE_DELAY) {return;}
  94. active_timer = timer_read();
  95. state = inactive;
  96. return;
  97. case inactive:
  98. if (!deactivated) {
  99. deactivated = true;
  100. activated = false;
  101. }
  102. velocikey_decelerate();
  103. fade_interval = velocikey_match_speed(1, 25);
  104. return;
  105. case boot:
  106. return;
  107. }
  108. }
  109. void fade_rgb (void) {
  110. static uint16_t fade_timer;
  111. if (state == boot) {return;}
  112. if (!fade_timer) {fade_timer = timer_read();}
  113. if (timer_elapsed(fade_timer) < fade_interval) {return;}
  114. switch (fade_state) {
  115. case add_fade:
  116. if (underglow.h == HUE_MAX) {
  117. fade_state = sub_fade;
  118. return;
  119. }
  120. underglow.h = underglow.h + 1;
  121. break;
  122. case sub_fade:
  123. if (underglow.h == 0) {
  124. fade_state = add_fade;
  125. return;
  126. }
  127. underglow.h = underglow.h - 1;
  128. break;
  129. }
  130. fade_timer = timer_read();
  131. if (flash_state == no_flash) {
  132. set_color(underglow, false);
  133. }
  134. }
  135. void flash_rgb (void) {
  136. static uint16_t flash_timer;
  137. switch(flash_state) {
  138. case no_flash:
  139. return;
  140. case flash_off:
  141. if (!flash_timer) {flash_timer = timer_read();}
  142. if (timer_elapsed(flash_timer) >= LED_FLASH_DELAY) {
  143. set_color(hsv_none, false);
  144. flash_timer = timer_read();
  145. flash_state = flash_on;
  146. }
  147. return;
  148. case flash_on:
  149. if (timer_elapsed(flash_timer) >= LED_FLASH_DELAY) {
  150. set_color(flash_color, false);
  151. flash_timer = timer_read();
  152. if (num_extra_flashes_off > 0) {
  153. flash_state = flash_off;
  154. num_extra_flashes_off--;
  155. } else {
  156. set_color(underglow, false);
  157. flash_state = no_flash;
  158. }
  159. }
  160. return;
  161. }
  162. }
  163. void set_os (uint8_t os, bool update) {
  164. current_os = os;
  165. if (update) {
  166. eeprom_update_byte(EECONFIG_USERSPACE, current_os);
  167. }
  168. switch (os) {
  169. case OS_MAC:
  170. set_unicode_input_mode(UNICODE_MODE_MACOS);
  171. underglow = (Color){ 213, 255, 255 };
  172. break;
  173. case OS_WIN:
  174. set_unicode_input_mode(UNICODE_MODE_WINCOMPOSE);
  175. underglow = (Color){ 128, 255, 255 };
  176. break;
  177. case OS_NIX:
  178. set_unicode_input_mode(UNICODE_MODE_LINUX);
  179. underglow = (Color){ 43, 255, 255 };
  180. break;
  181. default:
  182. underglow = (Color){ 0, 0, 255 };
  183. }
  184. set_color(underglow, update);
  185. flash_color = underglow;
  186. flash_state = flash_off;
  187. state = boot;
  188. num_extra_flashes_off = 1;
  189. }
  190. // register GUI if Mac or Ctrl if other
  191. void pri_mod(bool press) {
  192. if (press) {
  193. if (current_os == OS_MAC) {
  194. register_code(KC_LGUI);
  195. } else {
  196. register_code(KC_LCTL);
  197. }
  198. } else {
  199. if (current_os == OS_MAC) {
  200. unregister_code(KC_LGUI);
  201. } else {
  202. unregister_code(KC_LCTL);
  203. }
  204. }
  205. }
  206. // register Ctrl if Mac or GUI if other
  207. void sec_mod(bool press) {
  208. if (press) {
  209. if (current_os == OS_MAC) {
  210. register_code(KC_LCTL);
  211. } else {
  212. register_code(KC_LGUI);
  213. }
  214. } else {
  215. if (current_os == OS_MAC) {
  216. unregister_code(KC_LCTL);
  217. } else {
  218. unregister_code(KC_LGUI);
  219. }
  220. }
  221. }
  222. // register Meh if Win or Hyper if other
  223. // KC_MEH/HYPR registers both sides, causes issues with some apps
  224. // I'll do it myself, then
  225. void meh_hyper(bool press) {
  226. if (current_os == OS_WIN) {
  227. (press) ? register_mods(L_BIT_MEH) : unregister_mods(L_BIT_MEH);
  228. } else {
  229. (press) ? register_mods(L_BIT_HYPR) : unregister_mods(L_BIT_HYPR);
  230. }
  231. }
  232. void multi_tap(uint8_t num_of_chars, uint16_t keycode, bool use_shift) {
  233. if (use_shift) {
  234. register_code(KC_LSFT);
  235. }
  236. for (int i = 0; i < num_of_chars; i++) {
  237. tap_code(keycode);
  238. }
  239. if (use_shift) {
  240. unregister_code(KC_LSFT);
  241. }
  242. }
  243. void pair_surround_type(uint8_t num_of_chars, uint16_t keycode, bool use_shift) {
  244. for (int i = 0; i < num_of_chars; i++) {
  245. (use_shift) ? register_mods(MOD_BIT( KC_LSFT)) : NULL;
  246. tap_code(keycode);
  247. tap_code((keycode == KC_LCBR) ? KC_RCBR : (keycode == KC_LBRC) ? KC_RBRC : (keycode == KC_LPRN) ? KC_RPRN : KC_NO);
  248. (use_shift) ? unregister_mods(MOD_BIT( KC_LSFT)) : NULL;
  249. tap_code(KC_LEFT);
  250. }
  251. }
  252. void surround_type(uint8_t num_of_chars, uint16_t keycode, bool use_shift) {
  253. for (int i = 0; i < num_of_chars; i++) {
  254. (use_shift) ? register_mods(MOD_BIT( KC_LSFT)) : NULL;
  255. tap_code(keycode);
  256. (use_shift) ? unregister_mods(MOD_BIT( KC_LSFT)) : NULL;
  257. }
  258. multi_tap(num_of_chars / 2, KC_LEFT, false);
  259. }
  260. void long_keystroke(size_t num_of_keys, uint16_t keys[]) {
  261. for (int i = 0; i < num_of_keys-1; i++) {
  262. register_code(keys[i]);
  263. }
  264. tap_code(keys[num_of_keys-1]);
  265. for (int i = 0; i < num_of_keys-1; i++) {
  266. unregister_code(keys[i]);
  267. }
  268. }
  269. void pri_mod_keystroke(uint16_t key) {
  270. pri_mod(true);
  271. tap_code(key);
  272. pri_mod(false);
  273. }
  274. void leader_end_user(void) {
  275. // begin OS functions
  276. if (leader_sequence_two_keys(KC_P, KC_B)) {
  277. if (current_os == OS_WIN) {
  278. long_keystroke(2, (uint16_t[]){KC_LGUI, KC_PAUSE});
  279. } else {
  280. return;
  281. }
  282. }
  283. if (leader_sequence_two_keys(KC_S, KC_S)) {
  284. if (current_os == OS_MAC) {
  285. long_keystroke(3, (uint16_t[]){KC_LGUI, KC_LSFT, KC_4});
  286. } else if (current_os == OS_WIN) {
  287. long_keystroke(3, (uint16_t[]){KC_LGUI, KC_LSFT, KC_S});
  288. } else {
  289. return;
  290. }
  291. }
  292. if (leader_sequence_three_keys(KC_C, KC_A, KC_D)) {
  293. if (current_os == OS_WIN) {
  294. long_keystroke(3, (uint16_t[]){KC_LCTL, KC_LALT, KC_DEL});
  295. } else {
  296. }
  297. }
  298. if (leader_sequence_three_keys(KC_C, KC_A, KC_E)) {
  299. if (current_os == OS_WIN) {
  300. long_keystroke(3, (uint16_t[]){KC_LCTL, KC_LALT, KC_END});
  301. } else {
  302. }
  303. }
  304. // end OS functions
  305. // begin format functions
  306. if (leader_sequence_one_key(KC_B)) {
  307. surround_type(2, KC_8, true);
  308. }
  309. if (leader_sequence_one_key(KC_I)) {
  310. surround_type(2, KC_MINS, true);
  311. }
  312. if (leader_sequence_one_key(KC_U)) {
  313. surround_type(4, KC_MINS, true);
  314. }
  315. if (leader_sequence_one_key(KC_S)) {
  316. surround_type(4, KC_GRAVE, true);
  317. }
  318. if (leader_sequence_one_key(KC_C)) {
  319. register_unicode(0x00E7); // ç
  320. }
  321. if (leader_sequence_two_keys(KC_A, KC_V)) {
  322. surround_type(2, KC_QUOT, true);
  323. pair_surround_type(2, KC_LCBR, true);
  324. surround_type(2, KC_SPC, false);
  325. }
  326. if (leader_sequence_two_keys(KC_M, KC_L)) {
  327. pair_surround_type(1, KC_LBRC, false);
  328. SEND_STRING("LINK_NAME");
  329. tap_code(KC_RGHT);
  330. pair_surround_type(1, KC_LPRN, true);
  331. pri_mod_keystroke(KC_V);
  332. }
  333. if (leader_sequence_two_keys(KC_C, KC_C)) {
  334. surround_type(2, KC_GRAVE, false);
  335. }
  336. if (leader_sequence_three_keys(KC_C, KC_C, KC_C)) {
  337. surround_type(6, KC_GRAVE, false);
  338. }
  339. if (leader_sequence_one_key(KC_E)) {
  340. register_unicode(0x00E8); // è
  341. }
  342. if (leader_sequence_two_keys(KC_E, KC_E)) {
  343. register_unicode(0x00E9); // é
  344. }
  345. // end format functions
  346. // start fancy functions
  347. if (leader_sequence_two_keys(KC_V, KC_P)) {
  348. SEND_STRING("ggvG}x:set paste\ni");
  349. pri_mod_keystroke(KC_V);
  350. }
  351. if (leader_sequence_three_keys(KC_C, KC_C, KC_ENT)) {
  352. surround_type(6, KC_GRAVE, false);
  353. pri_mod_keystroke(KC_V);
  354. multi_tap(3, KC_RGHT, false);
  355. tap_code(KC_ENTER);
  356. }
  357. if (leader_sequence_three_keys(KC_T, KC_C, KC_ENT)) {
  358. multi_tap(3, KC_GRAVE, false);
  359. pri_mod_keystroke(KC_V);
  360. multi_tap(2, KC_ENTER, false);
  361. }
  362. // end fancy functions
  363. // start typing functions
  364. if (leader_sequence_two_keys(KC_T, KC_M)) {
  365. register_unicode(0x2122); // ™
  366. }
  367. if (leader_sequence_two_keys(KC_D, KC_D)) {
  368. SEND_STRING(".\\Administrator");
  369. }
  370. if (leader_sequence_three_keys(KC_D, KC_D, KC_D)) {
  371. SEND_STRING(".\\Administrator");
  372. tap_code(KC_TAB);
  373. pri_mod_keystroke(KC_V);
  374. tap_code(KC_ENTER);
  375. }
  376. if (leader_sequence_three_keys(KC_L, KC_O, KC_D)) {
  377. send_unicode_string("ಠ__ಠ");
  378. }
  379. if (leader_sequence_three_keys(KC_M, KC_A, KC_P)) {
  380. SEND_STRING("https://github.com/qmk/qmk_firmware/tree/master/users/arkag");
  381. }
  382. if (leader_sequence_two_keys(KC_F, KC_F)) {
  383. send_unicode_string("(╯‵Д′)╯彡┻━┻");
  384. }
  385. if (leader_sequence_three_keys(KC_F, KC_F, KC_F)) {
  386. send_unicode_string("┬─┬ノ( º _ º ノ)");
  387. }
  388. if (leader_sequence_three_keys(KC_L, KC_O, KC_L)) {
  389. send_unicode_string("( ͡° ͜ʖ ͡°)");
  390. }
  391. if (leader_sequence_three_keys(KC_S, KC_S, KC_S)) {
  392. send_unicode_string("¯\\_(ツ)_/¯");
  393. }
  394. // end typing functions
  395. }
  396. void matrix_init_user(void) {
  397. current_os = eeprom_read_byte(EECONFIG_USERSPACE);
  398. set_os(current_os, false);
  399. }
  400. void matrix_scan_user(void) {
  401. check_state();
  402. flash_rgb();
  403. fade_rgb();
  404. }
  405. bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  406. if (aesthetic) {
  407. switch (keycode) {
  408. case KC_A ... KC_0:
  409. case KC_SPACE ... KC_SLASH:
  410. if (record->event.pressed) {
  411. state = active;
  412. velocikey_accelerate();
  413. tap_code(keycode);
  414. tap_code(KC_SPACE);
  415. }
  416. return false;
  417. case KC_BACKSPACE:
  418. if (record->event.pressed) {
  419. state = active;
  420. velocikey_accelerate();
  421. tap_code(keycode);
  422. tap_code(keycode);
  423. }
  424. return false;
  425. default: // Do nothing
  426. break;
  427. }
  428. }
  429. if (shifty) {
  430. switch (keycode) {
  431. case KC_A ... KC_Z:
  432. if (record->event.pressed) {
  433. shift_int += (rand() % 5);
  434. int shift = ((shift_int % 2) == 1) ? true : false;
  435. state = active;
  436. velocikey_accelerate();
  437. (shift) ? register_code(KC_LSFT) : NULL;
  438. tap_code(keycode);
  439. (shift) ? unregister_code(KC_LSFT) : NULL;
  440. }
  441. return false;
  442. case KC_SPC:
  443. if (record->event.pressed) {
  444. state = active;
  445. velocikey_accelerate();
  446. tap_code(keycode);
  447. }
  448. return false;
  449. default: // Do nothing
  450. break;
  451. }
  452. }
  453. switch (keycode) {
  454. #ifdef AUDIO_ENABLE
  455. case M_USSR:
  456. PLAY_SONG(song_ussr);
  457. return false;
  458. #endif
  459. case M_OS:
  460. if (record->event.pressed){
  461. set_os((current_os+1) % _OS_COUNT, true);
  462. }
  463. return false;
  464. case M_DASH:
  465. if (record->event.pressed){
  466. register_unicode(0x2014); // —
  467. }
  468. return false;
  469. case M_LMHYP:
  470. case M_EHYPR:
  471. (keycode = M_LMHYP) ? (record->event.pressed) ? layer_on(_ARROW) : layer_off(_ARROW) : NULL;
  472. meh_hyper(record->event.pressed);
  473. return false;
  474. case M_SFTY:
  475. if(record->event.pressed){
  476. num_extra_flashes_off = (shifty) ? 1 : 0;
  477. shifty = !shifty;
  478. flash_color = underglow;
  479. flash_state = flash_off;
  480. return false;
  481. }
  482. case M_AEST:
  483. if(record->event.pressed){
  484. num_extra_flashes_off = (aesthetic) ? 1 : 0;
  485. aesthetic = !aesthetic;
  486. flash_color = underglow;
  487. flash_state = flash_off;
  488. return false;
  489. }
  490. default:
  491. if (record->event.pressed) {
  492. state = active;
  493. velocikey_accelerate();
  494. }
  495. return true;
  496. }
  497. }