arkag.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  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() {
  18. if (typing_speed < TYPING_SPEED_MAX_VALUE) typing_speed += (TYPING_SPEED_MAX_VALUE / 50);
  19. }
  20. void velocikey_decelerate() {
  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 matrix_init_user(void) {
  275. current_os = eeprom_read_byte(EECONFIG_USERSPACE);
  276. set_os(current_os, false);
  277. }
  278. LEADER_EXTERNS();
  279. void matrix_scan_user(void) {
  280. check_state();
  281. flash_rgb();
  282. fade_rgb();
  283. LEADER_DICTIONARY() {
  284. leading = false;
  285. leader_end();
  286. // begin OS functions
  287. SEQ_TWO_KEYS(KC_P, KC_B) {
  288. if (current_os == OS_WIN) {
  289. long_keystroke(2, (uint16_t[]){KC_LGUI, KC_PAUSE});
  290. } else {
  291. return;
  292. }
  293. }
  294. SEQ_TWO_KEYS(KC_S, KC_S) {
  295. if (current_os == OS_MAC) {
  296. long_keystroke(3, (uint16_t[]){KC_LGUI, KC_LSFT, KC_4});
  297. } else if (current_os == OS_WIN) {
  298. long_keystroke(3, (uint16_t[]){KC_LGUI, KC_LSFT, KC_S});
  299. } else {
  300. return;
  301. }
  302. }
  303. SEQ_THREE_KEYS(KC_C, KC_A, KC_D) {
  304. if (current_os == OS_WIN) {
  305. long_keystroke(3, (uint16_t[]){KC_LCTL, KC_LALT, KC_DEL});
  306. } else {
  307. }
  308. }
  309. SEQ_THREE_KEYS(KC_C, KC_A, KC_E) {
  310. if (current_os == OS_WIN) {
  311. long_keystroke(3, (uint16_t[]){KC_LCTL, KC_LALT, KC_END});
  312. } else {
  313. }
  314. }
  315. // end OS functions
  316. // begin format functions
  317. SEQ_ONE_KEY(KC_B) {
  318. surround_type(2, KC_8, true);
  319. }
  320. SEQ_ONE_KEY(KC_I) {
  321. surround_type(2, KC_MINS, true);
  322. }
  323. SEQ_ONE_KEY(KC_U) {
  324. surround_type(4, KC_MINS, true);
  325. }
  326. SEQ_ONE_KEY(KC_S) {
  327. surround_type(4, KC_GRAVE, true);
  328. }
  329. SEQ_ONE_KEY(KC_C) {
  330. register_unicode(0x00E7); // ç
  331. }
  332. SEQ_TWO_KEYS(KC_A, KC_V) {
  333. surround_type(2, KC_QUOT, true);
  334. pair_surround_type(2, KC_LCBR, true);
  335. surround_type(2, KC_SPC, false);
  336. }
  337. SEQ_TWO_KEYS(KC_M, KC_L) {
  338. pair_surround_type(1, KC_LBRC, false);
  339. SEND_STRING("LINK_NAME");
  340. tap_code(KC_RGHT);
  341. pair_surround_type(1, KC_LPRN, true);
  342. pri_mod_keystroke(KC_V);
  343. }
  344. SEQ_TWO_KEYS(KC_C, KC_C) {
  345. surround_type(2, KC_GRAVE, false);
  346. }
  347. SEQ_THREE_KEYS(KC_C, KC_C, KC_C) {
  348. surround_type(6, KC_GRAVE, false);
  349. }
  350. SEQ_ONE_KEY(KC_E) {
  351. register_unicode(0x00E8); // è
  352. }
  353. SEQ_TWO_KEYS(KC_E, KC_E) {
  354. register_unicode(0x00E9); // é
  355. }
  356. // end format functions
  357. // start fancy functions
  358. SEQ_TWO_KEYS(KC_V, KC_P) {
  359. SEND_STRING("ggvG}x:set paste\ni");
  360. pri_mod_keystroke(KC_V);
  361. }
  362. SEQ_THREE_KEYS(KC_C, KC_C, KC_ENT) {
  363. surround_type(6, KC_GRAVE, false);
  364. pri_mod_keystroke(KC_V);
  365. multi_tap(3, KC_RGHT, false);
  366. tap_code(KC_ENTER);
  367. }
  368. SEQ_THREE_KEYS(KC_T, KC_C, KC_ENT) {
  369. multi_tap(3, KC_GRAVE, false);
  370. pri_mod_keystroke(KC_V);
  371. multi_tap(2, KC_ENTER, false);
  372. }
  373. // end fancy functions
  374. // start typing functions
  375. SEQ_TWO_KEYS(KC_T, KC_M) {
  376. register_unicode(0x2122); // ™
  377. }
  378. SEQ_TWO_KEYS(KC_D, KC_D) {
  379. SEND_STRING(".\\Administrator");
  380. }
  381. SEQ_THREE_KEYS(KC_D, KC_D, KC_D) {
  382. SEND_STRING(".\\Administrator");
  383. tap_code(KC_TAB);
  384. pri_mod_keystroke(KC_V);
  385. tap_code(KC_ENTER);
  386. }
  387. SEQ_THREE_KEYS(KC_L, KC_O, KC_D) {
  388. send_unicode_string("ಠ__ಠ");
  389. }
  390. SEQ_THREE_KEYS(KC_M, KC_A, KC_P) {
  391. SEND_STRING("https://github.com/qmk/qmk_firmware/tree/master/users/arkag");
  392. }
  393. SEQ_TWO_KEYS(KC_F, KC_F) {
  394. send_unicode_string("(╯‵Д′)╯彡┻━┻");
  395. }
  396. SEQ_THREE_KEYS(KC_F, KC_F, KC_F) {
  397. send_unicode_string("┬─┬ノ( º _ º ノ)");
  398. }
  399. SEQ_THREE_KEYS(KC_L, KC_O, KC_L) {
  400. send_unicode_string("( ͡° ͜ʖ ͡°)");
  401. }
  402. SEQ_THREE_KEYS(KC_S, KC_S, KC_S) {
  403. send_unicode_string("¯\\_(ツ)_/¯");
  404. }
  405. // end typing functions
  406. }
  407. }
  408. bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  409. if (aesthetic) {
  410. switch (keycode) {
  411. case KC_A ... KC_0:
  412. case KC_SPACE ... KC_SLASH:
  413. if (record->event.pressed) {
  414. state = active;
  415. velocikey_accelerate();
  416. tap_code(keycode);
  417. tap_code(KC_SPACE);
  418. }
  419. return false;
  420. case KC_BACKSPACE:
  421. if (record->event.pressed) {
  422. state = active;
  423. velocikey_accelerate();
  424. tap_code(keycode);
  425. tap_code(keycode);
  426. }
  427. return false;
  428. default: // Do nothing
  429. break;
  430. }
  431. }
  432. if (shifty) {
  433. switch (keycode) {
  434. case KC_A ... KC_Z:
  435. if (record->event.pressed) {
  436. shift_int += (rand() % 5);
  437. int shift = ((shift_int % 2) == 1) ? true : false;
  438. state = active;
  439. velocikey_accelerate();
  440. (shift) ? register_code(KC_LSFT) : NULL;
  441. tap_code(keycode);
  442. (shift) ? unregister_code(KC_LSFT) : NULL;
  443. }
  444. return false;
  445. case KC_SPC:
  446. if (record->event.pressed) {
  447. state = active;
  448. velocikey_accelerate();
  449. tap_code(keycode);
  450. }
  451. return false;
  452. default: // Do nothing
  453. break;
  454. }
  455. }
  456. switch (keycode) {
  457. #ifdef AUDIO_ENABLE
  458. case M_USSR:
  459. PLAY_SONG(song_ussr);
  460. return false;
  461. #endif
  462. case M_OS:
  463. if (record->event.pressed){
  464. set_os((current_os+1) % _OS_COUNT, true);
  465. }
  466. return false;
  467. case M_DASH:
  468. if (record->event.pressed){
  469. register_unicode(0x2014); // —
  470. }
  471. return false;
  472. case M_LMHYP:
  473. case M_EHYPR:
  474. (keycode = M_LMHYP) ? (record->event.pressed) ? layer_on(_ARROW) : layer_off(_ARROW) : NULL;
  475. meh_hyper(record->event.pressed);
  476. return false;
  477. case M_SFTY:
  478. if(record->event.pressed){
  479. num_extra_flashes_off = (shifty) ? 1 : 0;
  480. shifty = !shifty;
  481. flash_color = underglow;
  482. flash_state = flash_off;
  483. return false;
  484. }
  485. case M_AEST:
  486. if(record->event.pressed){
  487. num_extra_flashes_off = (aesthetic) ? 1 : 0;
  488. aesthetic = !aesthetic;
  489. flash_color = underglow;
  490. flash_state = flash_off;
  491. return false;
  492. }
  493. default:
  494. if (record->event.pressed) {
  495. state = active;
  496. velocikey_accelerate();
  497. }
  498. return true;
  499. }
  500. }