keymap.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. /* Copyright 2022 Christopher Swenson
  2. *
  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. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include QMK_KEYBOARD_H
  17. enum planck_layers {
  18. _ENIGMA,
  19. _QWERTY,
  20. _FN,
  21. _LOWER,
  22. _RAISE
  23. };
  24. enum planck_normal_keycodes {
  25. QWERTY = SAFE_RANGE,
  26. ENIGMA,
  27. EN_A,
  28. EN_B,
  29. EN_C,
  30. EN_D,
  31. EN_E,
  32. EN_F,
  33. EN_G,
  34. EN_H,
  35. EN_I,
  36. EN_J,
  37. EN_K,
  38. EN_L,
  39. EN_M,
  40. EN_N,
  41. EN_O,
  42. EN_P,
  43. EN_Q,
  44. EN_R,
  45. EN_S,
  46. EN_T,
  47. EN_U,
  48. EN_V,
  49. EN_W,
  50. EN_X,
  51. EN_Y,
  52. EN_Z,
  53. EN_RES,
  54. EN_TEST,
  55. EN_DIAG,
  56. EN_BSPC,
  57. EN_SREF,
  58. EN_SROT,
  59. EN_SPOS,
  60. EN_SRIN,
  61. EN_SPLU
  62. };
  63. const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  64. /* Enigma
  65. * ,-----------------------------------------------------------------------------------.
  66. * | Esc | Q | W | E | R | T | Y | U | I | O | P | Bksp |
  67. * |------+------+------+------+------+-------------+------+------+------+------+------|
  68. * | Tab | A | S | D | F | G | H | J | K | L | ; | " |
  69. * |------+------+------+------+------+------|------+------+------+------+------+------|
  70. * | Shift| Z | X | C | V | B | N | M | , | . | / |Enter |
  71. * |------+------+------+------+------+------+------+------+------+------+------+------|
  72. * | Ctrl | Fn | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right |
  73. * `-----------------------------------------------------------------------------------'
  74. */
  75. [_ENIGMA] = LAYOUT_planck_mit(
  76. QK_GESC, EN_Q, EN_W, EN_E, EN_R, EN_T, EN_Y, EN_U, EN_I, EN_O, EN_P, KC_BSPC,
  77. KC_TAB, EN_A, EN_S, EN_D, EN_F, EN_G, EN_H, EN_J, EN_K, EN_L, KC_SCLN, KC_QUOT,
  78. KC_LSFT, EN_Z, EN_X, EN_C, EN_V, EN_B, EN_N, EN_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT,
  79. KC_LCTL, MO(_FN), KC_LGUI, KC_LALT, MO(_LOWER), KC_SPC, MO(_RAISE), KC_LEFT, KC_DOWN, KC_UP, KC_RGHT
  80. ),
  81. /* Qwerty
  82. * ,-----------------------------------------------------------------------------------.
  83. * | Esc | Q | W | E | R | T | Y | U | I | O | P | Bksp |
  84. * |------+------+------+------+------+-------------+------+------+------+------+------|
  85. * | Tab | A | S | D | F | G | H | J | K | L | ; | " |
  86. * |------+------+------+------+------+------|------+------+------+------+------+------|
  87. * | Shift| Z | X | C | V | B | N | M | , | . | / |Enter |
  88. * |------+------+------+------+------+------+------+------+------+------+------+------|
  89. * | Ctrl | Fn | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right |
  90. * `-----------------------------------------------------------------------------------'
  91. */
  92. [_QWERTY] = LAYOUT_planck_mit(
  93. QK_GESC, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC,
  94. KC_TAB, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT,
  95. KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_ENT,
  96. KC_LCTL, MO(_FN), KC_LGUI, KC_LALT, MO(_LOWER), KC_SPC, MO(_RAISE), KC_LEFT, KC_DOWN, KC_UP, KC_RGHT
  97. ),
  98. /* Function
  99. * ,-----------------------------------------------------------------------------------.
  100. * | Boot | Reset| Diag | | | | | | | | Test |Revers|
  101. * |------+------+------+------+------+-------------+------+------+------+------+------|
  102. * | | | | | | | | | | | | |
  103. * |------+------+------+------+------+------|------+------+------+------+------+------|
  104. * | |Reflec|Rotors|Posn.s|Rings |Plugs | | |Enigma|Qwerty| | |
  105. * |------+------+------+------+------+------+------+------+------+------+------+------|
  106. * | | | | | | | | | | | |
  107. * `-----------------------------------------------------------------------------------'
  108. */
  109. [_FN] = LAYOUT_planck_mit(
  110. QK_BOOT, EN_RES, EN_DIAG, _______, _______, _______, _______, _______, _______, _______, EN_TEST, EN_BSPC,
  111. _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
  112. _______, EN_SREF, EN_SROT, EN_SPOS, EN_SRIN, EN_SPLU, _______, _______, QWERTY, ENIGMA, _______, _______,
  113. _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
  114. ),
  115. /* Lower
  116. * ,-----------------------------------------------------------------------------------.
  117. * | ~ | ! | @ | # | $ | % | ^ | & | * | ( | ) | Bksp |
  118. * |------+------+------+------+------+-------------+------+------+------+------+------|
  119. * | | | | | | | | _ | + | { | } | | |
  120. * |------+------+------+------+------+------|------+------+------+------+------+------|
  121. * | Shift| | | | | | | | | | | |
  122. * |------+------+------+------+------+------+------+------+------+------+------+------|
  123. * | Ctrl | Fn | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right |
  124. * `-----------------------------------------------------------------------------------'
  125. */
  126. [_LOWER] = LAYOUT_planck_mit(
  127. KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC,
  128. _______, _______, _______, _______, _______, _______, _______, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE,
  129. KC_LSFT, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
  130. KC_LCTL, _______, KC_LGUI, KC_LALT, _______, KC_SPC, _______, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT
  131. ),
  132. /* RAISE
  133. * ,-----------------------------------------------------------------------------------.
  134. * | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | Bksp |
  135. * |------+------+------+------+------+-------------+------+------+------+------+------|
  136. * | | | | | | | | - | = | [ | ] | \ |
  137. * |------+------+------+------+------+------|------+------+------+------+------+------|
  138. * | Shift| | | | | | | | | | | |
  139. * |------+------+------+------+------+------+------+------+------+------+------+------|
  140. * | Ctrl | Fn | Alt | GUI |Lower | Space |Raise | Left | Down | Up |Right |
  141. * `-----------------------------------------------------------------------------------'
  142. */
  143. [_RAISE] = LAYOUT_planck_mit(
  144. KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC,
  145. _______, _______, _______, _______, _______, _______, _______, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS,
  146. KC_LSFT, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
  147. KC_LCTL, _______, KC_LGUI, KC_LALT, _______, KC_SPC, _______, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT
  148. ),
  149. };
  150. char rotor_definitions[5][26] = {
  151. "EKMFLGDQVZNTOWYHXUSPAIBRCJ",
  152. "AJDKSIRUXBLHWTMCQGZNPYFVOE",
  153. "BDFHJLCPRTXVZNYEIWGAKMUSQO",
  154. "ESOVPZJAYQUIRHXLNFTGKDCMWB",
  155. "VZBRGITYUPSDNHLXAWMJQOFECK"
  156. };
  157. char reflector_definitions[3][26] = {
  158. "EJMZALYXVBWFCRQUONTSPIKHGD",
  159. "YRUHQSLDPXNGOKMIEBFZCWVJAT",
  160. "FVPJIAOYEDRZXWGCTKUQSBNMHL"
  161. };
  162. char notch[5] = "QEVJZ";
  163. typedef struct Settings {
  164. char rotor_order[3];
  165. char rotor_rings[3];
  166. char rotor_positions[3];
  167. char plugs[25];
  168. int plug_count;
  169. char reflector;
  170. } Settings;
  171. typedef struct KeyboardState {
  172. bool is_setting_reflector;
  173. bool is_setting_rotors;
  174. bool is_setting_rotor_positions;
  175. bool is_setting_rotor_rings;
  176. bool is_setting_plugs;
  177. char setting_progress[26];
  178. int setting_index;
  179. Settings current_settings;
  180. Settings default_settings;
  181. } KeyboardState;
  182. int bound(int letter) {
  183. return ((letter % 26) + 26) % 26;
  184. }
  185. char to_char(int letter) {
  186. return 'A' + letter;
  187. }
  188. int to_int(char letter) {
  189. return letter - 'A';
  190. }
  191. char encipher(char letter, Settings *settings) {
  192. int rotor_2_step = settings->rotor_positions[2] == notch[settings->rotor_order[2] - 1];
  193. int rotor_1_step = settings->rotor_positions[1] == notch[settings->rotor_order[1] - 1];
  194. // Advance the third rotor
  195. settings->rotor_positions[2]++;
  196. if (settings->rotor_positions[2] > 'Z') {
  197. settings->rotor_positions[2] -= 26;
  198. }
  199. // Maybe advance the second rotor, including double steps
  200. if (rotor_2_step || rotor_1_step) {
  201. settings->rotor_positions[1]++;
  202. if (settings->rotor_positions[1] > 'Z') {
  203. settings->rotor_positions[1] -= 26;
  204. }
  205. }
  206. // Maybe advance the first rotor
  207. if (rotor_1_step) {
  208. settings->rotor_positions[0]++;
  209. if (settings->rotor_positions[0] > 'Z') {
  210. settings->rotor_positions[0] -= 26;
  211. }
  212. }
  213. // Swap letters on plugboard
  214. for (int i = 0; i < settings->plug_count * 2; i += 2) {
  215. if (letter == settings->plugs[i]) {
  216. letter = settings->plugs[i + 1];
  217. } else if (letter == settings->plugs[i + 1]) {
  218. letter = settings->plugs[i];
  219. }
  220. }
  221. // Rotors (right to left)
  222. for (int rotor_index = 2; rotor_index >= 0; rotor_index--) {
  223. char *rotor_definition = rotor_definitions[settings->rotor_order[rotor_index] - 1];
  224. int position = to_int(settings->rotor_positions[rotor_index]);
  225. int ring = to_int(settings->rotor_rings[rotor_index]);
  226. int char_index = to_int(letter);
  227. letter = to_char(bound(
  228. to_int(rotor_definition[bound(char_index + position - ring)]) + ring - position
  229. ));
  230. }
  231. // Swap via reflector
  232. letter = reflector_definitions[to_int(settings->reflector)][to_int(letter)];
  233. // Rotors in reverse (left to right)
  234. for (int rotor_index = 0; rotor_index < 3; rotor_index++) {
  235. char *rotor_definition = rotor_definitions[settings->rotor_order[rotor_index] - 1];
  236. int position = to_int(settings->rotor_positions[rotor_index]);
  237. int ring = to_int(settings->rotor_rings[rotor_index]);
  238. int search_index;
  239. for (search_index = 0; search_index < 26; search_index++) {
  240. if (
  241. rotor_definition[search_index]
  242. == to_char(bound(to_int(letter) - ring + position))
  243. ) {
  244. break;
  245. }
  246. }
  247. letter = to_char(bound(search_index - position + ring));
  248. }
  249. // Plugboard again
  250. for (int i = 0; i < settings->plug_count * 2; i += 2) {
  251. if (letter == settings->plugs[i]) {
  252. letter = settings->plugs[i + 1];
  253. } else if (letter == settings->plugs[i + 1]) {
  254. letter = settings->plugs[i];
  255. }
  256. }
  257. return letter;
  258. }
  259. void init_enigma_default(Settings *settings) {
  260. settings->rotor_order[0] = 1;
  261. settings->rotor_rings[0] = 'A';
  262. settings->rotor_positions[0] = 'A';
  263. settings->rotor_order[1] = 2;
  264. settings->rotor_rings[1] = 'A';
  265. settings->rotor_positions[1] = 'A';
  266. settings->rotor_order[2] = 3;
  267. settings->rotor_rings[2] = 'A';
  268. settings->rotor_positions[2] = 'A';
  269. strcpy(settings->plugs, "");
  270. settings->plug_count = 0;
  271. settings->reflector = 'B';
  272. }
  273. void copy_settings(Settings *from, Settings *to) {
  274. to->rotor_order[0] = from->rotor_order[0];
  275. to->rotor_rings[0] = from->rotor_rings[0];
  276. to->rotor_positions[0] = from->rotor_positions[0];
  277. to->rotor_order[1] = from->rotor_order[1];
  278. to->rotor_rings[1] = from->rotor_rings[1];
  279. to->rotor_positions[1] = from->rotor_positions[1];
  280. to->rotor_order[2] = from->rotor_order[2];
  281. to->rotor_rings[2] = from->rotor_rings[2];
  282. to->rotor_positions[2] = from->rotor_positions[2];
  283. strncpy(to->plugs, from->plugs, from->plug_count * 2);
  284. to->plug_count = from->plug_count;
  285. to->reflector = from->reflector;
  286. }
  287. char *rotor_name(int rotor_number) {
  288. if (rotor_number == 1) {
  289. return "I";
  290. } else if (rotor_number == 2) {
  291. return "II";
  292. } else if (rotor_number == 3) {
  293. return "III";
  294. } else if (rotor_number == 4) {
  295. return "IV";
  296. } else if (rotor_number == 5) {
  297. return "V";
  298. }
  299. return "?";
  300. }
  301. void rotors_reverse(Settings *settings) {
  302. int rotor_2_step = settings->rotor_positions[2]
  303. == to_char(bound(to_int(notch[settings->rotor_order[2] - 1]) + 1));
  304. int rotor_1_step = settings->rotor_positions[1]
  305. == to_char(bound(to_int(notch[settings->rotor_order[1] - 1]) + 1));
  306. // Reverse third rotor
  307. settings->rotor_positions[2]--;
  308. if (settings->rotor_positions[2] < 'A') {
  309. settings->rotor_positions[2] += 26;
  310. }
  311. // Maybe reverse second rotor (including double steps)
  312. if (rotor_2_step || rotor_1_step) {
  313. settings->rotor_positions[1]--;
  314. if (settings->rotor_positions[1] < 'A') {
  315. settings->rotor_positions[1] += 26;
  316. }
  317. }
  318. // Maybe recerse first rotor
  319. if (rotor_1_step) {
  320. settings->rotor_positions[0]--;
  321. if (settings->rotor_positions[0] < 'A') {
  322. settings->rotor_positions[0] += 26;
  323. }
  324. }
  325. }
  326. void reset_settings(KeyboardState *state) {
  327. copy_settings(&state->default_settings, &state->current_settings);
  328. }
  329. void set_layer(uint8_t default_layer) {
  330. default_layer_set((layer_state_t)1 << default_layer);
  331. }
  332. void set_backlight(uint8_t mode, uint8_t hue, uint8_t sat, uint8_t val) {
  333. #ifdef RGBLIGHT_ENABLE
  334. rgblight_enable_noeeprom();
  335. rgblight_mode_noeeprom(mode);
  336. rgblight_sethsv_noeeprom(hue, sat, val);
  337. #endif
  338. }
  339. void clear_working_settings(KeyboardState *state) {
  340. state->is_setting_reflector = false;
  341. state->is_setting_rotors = false;
  342. state->is_setting_rotor_positions = false;
  343. state->is_setting_rotor_rings = false;
  344. state->is_setting_plugs = false;
  345. state->setting_index = 0;
  346. set_layer(_ENIGMA);
  347. set_backlight(RGBLIGHT_MODE_STATIC_LIGHT, HSV_RED);
  348. }
  349. void send_settings_string(Settings *settings) {
  350. send_char(settings->reflector);
  351. send_string(". ");
  352. send_string(rotor_name(settings->rotor_order[0]));
  353. send_char(settings->rotor_rings[0]);
  354. send_string("-");
  355. send_string(rotor_name(settings->rotor_order[1]));
  356. send_char(settings->rotor_rings[1]);
  357. send_string("-");
  358. send_string(rotor_name(settings->rotor_order[2]));
  359. send_char(settings->rotor_rings[2]);
  360. send_string(" (");
  361. send_char(settings->rotor_positions[0]);
  362. send_string(", ");
  363. send_char(settings->rotor_positions[1]);
  364. send_string(", ");
  365. send_char(settings->rotor_positions[2]);
  366. send_string(") ");
  367. for (int i = 0; i < settings->plug_count; i++) {
  368. send_char(settings->plugs[i * 2]);
  369. send_char(settings->plugs[i * 2 + 1]);
  370. send_string(" ");
  371. }
  372. send_string("\n");
  373. }
  374. void perform_test(Settings *settings) {
  375. for (int i = 0; i < 1000; i++) {
  376. send_char(encipher('A', settings) - ('A' - 'a'));
  377. }
  378. }
  379. void commit_plug_settings(KeyboardState *state) {
  380. state->default_settings.plug_count = state->setting_index / 2;
  381. for (int i = 0; i < state->default_settings.plug_count; i++) {
  382. state->default_settings.plugs[i * 2] = state->setting_progress[i * 2];
  383. state->default_settings.plugs[i * 2 + 1] = state->setting_progress[i * 2 + 1];
  384. }
  385. reset_settings(state);
  386. clear_working_settings(state);
  387. }
  388. void handle_set_reflector(char letter, KeyboardState *state) {
  389. if (letter >= 'A' && letter <= 'C') {
  390. state->default_settings.reflector = letter;
  391. reset_settings(state);
  392. clear_working_settings(state);
  393. }
  394. }
  395. bool handle_set_rotor(char letter, KeyboardState *state) {
  396. bool is_valid = letter >= 'A' && letter <= 'E' && state->setting_index < 3;
  397. if (is_valid) {
  398. state->setting_progress[state->setting_index] = to_int(letter) + 1;
  399. state->setting_index += 1;
  400. if (state->setting_index == 3) {
  401. state->default_settings.rotor_order[0] = state->setting_progress[0];
  402. state->default_settings.rotor_order[1] = state->setting_progress[1];
  403. state->default_settings.rotor_order[2] = state->setting_progress[2];
  404. reset_settings(state);
  405. clear_working_settings(state);
  406. }
  407. }
  408. return is_valid;
  409. }
  410. bool handle_set_rotor_position(char letter, KeyboardState *state) {
  411. bool is_valid = state->setting_index < 3; // Guaranteed to be A-Z already
  412. if (is_valid) {
  413. state->setting_progress[state->setting_index] = letter;
  414. state->setting_index += 1;
  415. if (state->setting_index == 3) {
  416. state->default_settings.rotor_positions[0] = state->setting_progress[0];
  417. state->default_settings.rotor_positions[1] = state->setting_progress[1];
  418. state->default_settings.rotor_positions[2] = state->setting_progress[2];
  419. reset_settings(state);
  420. clear_working_settings(state);
  421. }
  422. }
  423. return is_valid;
  424. }
  425. bool handle_set_rotor_ring(char letter, KeyboardState *state) {
  426. bool is_valid = state->setting_index < 3;
  427. if (is_valid) {
  428. state->setting_progress[state->setting_index] = letter;
  429. state->setting_index += 1;
  430. if (state->setting_index == 3) {
  431. state->default_settings.rotor_rings[0] = state->setting_progress[0];
  432. state->default_settings.rotor_rings[1] = state->setting_progress[1];
  433. state->default_settings.rotor_rings[2] = state->setting_progress[2];
  434. reset_settings(state);
  435. clear_working_settings(state);
  436. }
  437. }
  438. return is_valid;
  439. }
  440. bool handle_set_plug(char letter, KeyboardState *state) {
  441. bool is_valid = state->setting_index < 26;
  442. if (is_valid) {
  443. state->setting_progress[state->setting_index] = letter;
  444. state->setting_index += 1;
  445. }
  446. return is_valid;
  447. }
  448. void handle_enigma_keypress(char letter, bool any_mods, KeyboardState *state) {
  449. bool settings_valid = true;
  450. if (letter) {
  451. if (any_mods) {
  452. tap_code(KC_A + to_int(letter));
  453. } else if (state->is_setting_reflector) {
  454. handle_set_reflector(letter, state);
  455. } else if (state->is_setting_rotors) {
  456. settings_valid = handle_set_rotor(letter, state);
  457. } else if (state->is_setting_rotor_positions) {
  458. settings_valid = handle_set_rotor_position(letter, state);
  459. } else if (state->is_setting_rotor_rings) {
  460. settings_valid = handle_set_rotor_ring(letter, state);
  461. } else if (state->is_setting_plugs) {
  462. settings_valid = handle_set_plug(letter, state);
  463. } else {
  464. char c2 = encipher(letter, &state->current_settings);
  465. send_char(c2 - ('A' - 'a'));
  466. }
  467. }
  468. if (!settings_valid) {
  469. clear_working_settings(state);
  470. }
  471. }
  472. KeyboardState STATE;
  473. void keyboard_pre_init_user(void) {
  474. init_enigma_default(&STATE.default_settings);
  475. init_enigma_default(&STATE.current_settings);
  476. clear_working_settings(&STATE);
  477. }
  478. bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  479. uint8_t letter_index;
  480. bool letter_found = false;
  481. if (record->event.pressed) {
  482. switch (keycode) {
  483. case QWERTY:
  484. set_layer(_QWERTY);
  485. set_backlight(RGBLIGHT_MODE_RAINBOW_SWIRL + 4, HSV_PURPLE);
  486. break;
  487. case ENIGMA:
  488. set_layer(_ENIGMA);
  489. set_backlight(RGBLIGHT_MODE_STATIC_LIGHT, HSV_RED);
  490. break;
  491. case EN_SREF:
  492. reset_settings(&STATE);
  493. STATE.is_setting_reflector = true;
  494. set_layer(_ENIGMA);
  495. set_backlight(RGBLIGHT_MODE_SNAKE, HSV_RED);
  496. break;
  497. case EN_SROT:
  498. reset_settings(&STATE);
  499. STATE.is_setting_rotors = true;
  500. STATE.setting_index = 0;
  501. set_layer(_ENIGMA);
  502. set_backlight(RGBLIGHT_MODE_SNAKE, 10, 255, 255);
  503. break;
  504. case EN_SPOS:
  505. reset_settings(&STATE);
  506. STATE.is_setting_rotor_positions = true;
  507. STATE.setting_index = 0;
  508. set_layer(_ENIGMA);
  509. set_backlight(RGBLIGHT_MODE_SNAKE, HSV_ORANGE);
  510. break;
  511. case EN_SRIN:
  512. reset_settings(&STATE);
  513. STATE.is_setting_rotor_rings = true;
  514. STATE.setting_index = 0;
  515. set_layer(_ENIGMA);
  516. set_backlight(RGBLIGHT_MODE_SNAKE, HSV_GREEN);
  517. break;
  518. case EN_SPLU:
  519. reset_settings(&STATE);
  520. STATE.is_setting_plugs = true;
  521. STATE.setting_index = 0;
  522. set_layer(_ENIGMA);
  523. set_backlight(RGBLIGHT_MODE_SNAKE, HSV_BLUE);
  524. break;
  525. case QK_GESC:
  526. if (
  527. STATE.is_setting_reflector
  528. || STATE.is_setting_rotors
  529. || STATE.is_setting_rotor_positions
  530. || STATE.is_setting_rotor_rings
  531. || STATE.is_setting_plugs
  532. ) {
  533. clear_working_settings(&STATE);
  534. return false;
  535. }
  536. break;
  537. case KC_ENT:
  538. if (STATE.is_setting_plugs) {
  539. commit_plug_settings(&STATE);
  540. return false;
  541. }
  542. break;
  543. case EN_A ... EN_Z:
  544. letter_index = keycode - EN_A;
  545. letter_found = true;
  546. break;
  547. case EN_RES:
  548. reset_settings(&STATE);
  549. break;
  550. case EN_TEST:
  551. perform_test(&STATE.current_settings);
  552. break;
  553. case EN_DIAG:
  554. send_settings_string(&STATE.current_settings);
  555. break;
  556. case EN_BSPC:
  557. rotors_reverse(&STATE.current_settings);
  558. tap_code(KC_BSPC);
  559. break;
  560. }
  561. }
  562. char letter = letter_found ? 'A' + letter_index : 0;
  563. uint8_t mods = get_mods();
  564. bool any_mods = (mods & MOD_MASK_CTRL) || (mods & MOD_MASK_ALT) || (mods & MOD_MASK_GUI);
  565. handle_enigma_keypress(letter, any_mods, &STATE);
  566. return true;
  567. }
  568. void keyboard_post_init_user(void) {
  569. set_layer(_QWERTY);
  570. set_backlight(RGBLIGHT_MODE_RAINBOW_SWIRL + 4, HSV_PURPLE);
  571. }