arkag.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  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(UC_OSX);
  171. underglow = (Color){ 213, 255, 255 };
  172. break;
  173. case OS_WIN:
  174. set_unicode_input_mode(UC_WINC);
  175. underglow = (Color){ 128, 255, 255 };
  176. break;
  177. case OS_NIX:
  178. set_unicode_input_mode(UC_LNX);
  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_THREE_KEYS(KC_C, KC_C, KC_ENT) {
  359. surround_type(6, KC_GRAVE, false);
  360. pri_mod_keystroke(KC_V);
  361. multi_tap(3, KC_RGHT, false);
  362. tap_code(KC_ENTER);
  363. }
  364. SEQ_THREE_KEYS(KC_T, KC_C, KC_ENT) {
  365. multi_tap(3, KC_GRAVE, false);
  366. pri_mod_keystroke(KC_V);
  367. multi_tap(2, KC_ENTER, false);
  368. }
  369. // end fancy functions
  370. // start typing functions
  371. SEQ_TWO_KEYS(KC_T, KC_M) {
  372. register_unicode(0x2122); // ™
  373. }
  374. SEQ_TWO_KEYS(KC_D, KC_D) {
  375. SEND_STRING(".\\Administrator");
  376. }
  377. SEQ_THREE_KEYS(KC_D, KC_D, KC_D) {
  378. SEND_STRING(".\\Administrator");
  379. tap_code(KC_TAB);
  380. pri_mod_keystroke(KC_V);
  381. tap_code(KC_ENTER);
  382. }
  383. SEQ_THREE_KEYS(KC_L, KC_O, KC_D) {
  384. send_unicode_string("ಠ__ಠ");
  385. }
  386. SEQ_THREE_KEYS(KC_M, KC_A, KC_P) {
  387. SEND_STRING("https://github.com/qmk/qmk_firmware/tree/master/users/arkag");
  388. }
  389. SEQ_TWO_KEYS(KC_F, KC_F) {
  390. send_unicode_string("(╯‵Д′)╯彡┻━┻");
  391. }
  392. SEQ_THREE_KEYS(KC_F, KC_F, KC_F) {
  393. send_unicode_string("┬─┬ノ( º _ º ノ)");
  394. }
  395. SEQ_THREE_KEYS(KC_L, KC_O, KC_L) {
  396. send_unicode_string("( ͡° ͜ʖ ͡°)");
  397. }
  398. SEQ_THREE_KEYS(KC_S, KC_S, KC_S) {
  399. send_unicode_string("¯\\_(ツ)_/¯");
  400. }
  401. // end typing functions
  402. }
  403. }
  404. bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  405. if (aesthetic) {
  406. switch (keycode) {
  407. case KC_A ... KC_0:
  408. case KC_SPACE ... KC_SLASH:
  409. if (record->event.pressed) {
  410. state = active;
  411. velocikey_accelerate();
  412. tap_code(keycode);
  413. tap_code(KC_SPACE);
  414. }
  415. return false;
  416. case KC_BSPACE:
  417. if (record->event.pressed) {
  418. state = active;
  419. velocikey_accelerate();
  420. tap_code(keycode);
  421. tap_code(keycode);
  422. }
  423. return false;
  424. default: // Do nothing
  425. break;
  426. }
  427. }
  428. if (shifty) {
  429. switch (keycode) {
  430. case KC_A ... KC_Z:
  431. if (record->event.pressed) {
  432. shift_int += (rand() % 5);
  433. int shift = ((shift_int % 2) == 1) ? true : false;
  434. state = active;
  435. velocikey_accelerate();
  436. (shift) ? register_code(KC_LSFT) : NULL;
  437. tap_code(keycode);
  438. (shift) ? unregister_code(KC_LSFT) : NULL;
  439. }
  440. return false;
  441. case KC_SPC:
  442. if (record->event.pressed) {
  443. state = active;
  444. velocikey_accelerate();
  445. tap_code(keycode);
  446. }
  447. return false;
  448. default: // Do nothing
  449. break;
  450. }
  451. }
  452. switch (keycode) {
  453. #ifdef AUDIO_ENABLE
  454. case M_USSR:
  455. PLAY_SONG(song_ussr);
  456. return false;
  457. #endif
  458. case M_OS:
  459. if (record->event.pressed){
  460. set_os((current_os+1) % _OS_COUNT, true);
  461. }
  462. return false;
  463. case M_DASH:
  464. if (record->event.pressed){
  465. register_unicode(0x2014); // —
  466. }
  467. return false;
  468. case M_LMHYP:
  469. case M_EHYPR:
  470. (keycode = M_LMHYP) ? (record->event.pressed) ? layer_on(_ARROW) : layer_off(_ARROW) : NULL;
  471. meh_hyper(record->event.pressed);
  472. return false;
  473. case M_SFTY:
  474. if(record->event.pressed){
  475. num_extra_flashes_off = (shifty) ? 1 : 0;
  476. shifty = !shifty;
  477. flash_color = underglow;
  478. flash_state = flash_off;
  479. return false;
  480. }
  481. case M_AEST:
  482. if(record->event.pressed){
  483. num_extra_flashes_off = (aesthetic) ? 1 : 0;
  484. aesthetic = !aesthetic;
  485. flash_color = underglow;
  486. flash_state = flash_off;
  487. return false;
  488. }
  489. default:
  490. if (record->event.pressed) {
  491. state = active;
  492. velocikey_accelerate();
  493. }
  494. return true;
  495. }
  496. }