[Keymap] Add enigma keymap for contra keyboard (#17829)
This commit is contained in:
		
							parent
							
								
									d2aa8e6bb8
								
							
						
					
					
						commit
						d1096ad440
					
				
					 5 changed files with 689 additions and 8 deletions
				
			
		
							
								
								
									
										625
									
								
								keyboards/contra/keymaps/enigma/keymap.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										625
									
								
								keyboards/contra/keymaps/enigma/keymap.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,625 @@
 | 
			
		|||
/* Copyright 2022 Christopher Swenson
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include QMK_KEYBOARD_H
 | 
			
		||||
 | 
			
		||||
enum planck_layers {
 | 
			
		||||
    _ENIGMA,
 | 
			
		||||
    _QWERTY,
 | 
			
		||||
    _FN,
 | 
			
		||||
    _LOWER,
 | 
			
		||||
    _RAISE
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum planck_normal_keycodes {
 | 
			
		||||
    QWERTY = SAFE_RANGE,
 | 
			
		||||
    ENIGMA,
 | 
			
		||||
    EN_A,
 | 
			
		||||
    EN_B,
 | 
			
		||||
    EN_C,
 | 
			
		||||
    EN_D,
 | 
			
		||||
    EN_E,
 | 
			
		||||
    EN_F,
 | 
			
		||||
    EN_G,
 | 
			
		||||
    EN_H,
 | 
			
		||||
    EN_I,
 | 
			
		||||
    EN_J,
 | 
			
		||||
    EN_K,
 | 
			
		||||
    EN_L,
 | 
			
		||||
    EN_M,
 | 
			
		||||
    EN_N,
 | 
			
		||||
    EN_O,
 | 
			
		||||
    EN_P,
 | 
			
		||||
    EN_Q,
 | 
			
		||||
    EN_R,
 | 
			
		||||
    EN_S,
 | 
			
		||||
    EN_T,
 | 
			
		||||
    EN_U,
 | 
			
		||||
    EN_V,
 | 
			
		||||
    EN_W,
 | 
			
		||||
    EN_X,
 | 
			
		||||
    EN_Y,
 | 
			
		||||
    EN_Z,
 | 
			
		||||
    EN_RES,
 | 
			
		||||
    EN_TEST,
 | 
			
		||||
    EN_DIAG,
 | 
			
		||||
    EN_BSPC,
 | 
			
		||||
    EN_SREF,
 | 
			
		||||
    EN_SROT,
 | 
			
		||||
    EN_SPOS,
 | 
			
		||||
    EN_SRIN,
 | 
			
		||||
    EN_SPLU
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 | 
			
		||||
    /* Enigma
 | 
			
		||||
    * ,-----------------------------------------------------------------------------------.
 | 
			
		||||
    * | Esc  |   Q  |   W  |   E  |   R  |   T  |   Y  |   U  |   I  |   O  |   P  | Bksp |
 | 
			
		||||
    * |------+------+------+------+------+-------------+------+------+------+------+------|
 | 
			
		||||
    * | Tab  |   A  |   S  |   D  |   F  |   G  |   H  |   J  |   K  |   L  |   ;  |  "   |
 | 
			
		||||
    * |------+------+------+------+------+------|------+------+------+------+------+------|
 | 
			
		||||
    * | Shift|   Z  |   X  |   C  |   V  |   B  |   N  |   M  |   ,  |   .  |   /  |Enter |
 | 
			
		||||
    * |------+------+------+------+------+------+------+------+------+------+------+------|
 | 
			
		||||
    * | Ctrl |  Fn  | Alt  | GUI  |Lower |    Space    |Raise | Left | Down |  Up  |Right |
 | 
			
		||||
    * `-----------------------------------------------------------------------------------'
 | 
			
		||||
    */
 | 
			
		||||
    [_ENIGMA] = LAYOUT_planck_mit(
 | 
			
		||||
        QK_GESC, EN_Q,    EN_W,    EN_E,    EN_R,       EN_T,    EN_Y, EN_U,       EN_I,    EN_O,    EN_P,    KC_BSPC,
 | 
			
		||||
        KC_TAB,  EN_A,    EN_S,    EN_D,    EN_F,       EN_G,    EN_H, EN_J,       EN_K,    EN_L,    KC_SCLN, KC_QUOT,
 | 
			
		||||
        KC_LSFT, EN_Z,    EN_X,    EN_C,    EN_V,       EN_B,    EN_N, EN_M,       KC_COMM, KC_DOT,  KC_SLSH, KC_ENT,
 | 
			
		||||
        KC_LCTL, MO(_FN), KC_LGUI, KC_LALT, MO(_LOWER),    KC_SPC,     MO(_RAISE), KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT
 | 
			
		||||
    ),
 | 
			
		||||
    /* Qwerty
 | 
			
		||||
    * ,-----------------------------------------------------------------------------------.
 | 
			
		||||
    * | Esc  |   Q  |   W  |   E  |   R  |   T  |   Y  |   U  |   I  |   O  |   P  | Bksp |
 | 
			
		||||
    * |------+------+------+------+------+-------------+------+------+------+------+------|
 | 
			
		||||
    * | Tab  |   A  |   S  |   D  |   F  |   G  |   H  |   J  |   K  |   L  |   ;  |  "   |
 | 
			
		||||
    * |------+------+------+------+------+------|------+------+------+------+------+------|
 | 
			
		||||
    * | Shift|   Z  |   X  |   C  |   V  |   B  |   N  |   M  |   ,  |   .  |   /  |Enter |
 | 
			
		||||
    * |------+------+------+------+------+------+------+------+------+------+------+------|
 | 
			
		||||
    * | Ctrl |  Fn  | Alt  | GUI  |Lower |    Space    |Raise | Left | Down |  Up  |Right |
 | 
			
		||||
    * `-----------------------------------------------------------------------------------'
 | 
			
		||||
    */
 | 
			
		||||
    [_QWERTY] = LAYOUT_planck_mit(
 | 
			
		||||
        QK_GESC, KC_Q,    KC_W,    KC_E,    KC_R,      KC_T,    KC_Y,    KC_U,       KC_I,    KC_O,    KC_P,    KC_BSPC,
 | 
			
		||||
        KC_TAB,  KC_A,    KC_S,    KC_D,    KC_F,      KC_G,    KC_H,    KC_J,       KC_K,    KC_L,    KC_SCLN, KC_QUOT,
 | 
			
		||||
        KC_LSFT, KC_Z,    KC_X,    KC_C,    KC_V,      KC_B,    KC_N,    KC_M,       KC_COMM, KC_DOT,  KC_SLSH, KC_ENT,
 | 
			
		||||
        KC_LCTL, MO(_FN), KC_LGUI, KC_LALT, MO(_LOWER),    KC_SPC,       MO(_RAISE), KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT
 | 
			
		||||
    ),
 | 
			
		||||
    /* Function
 | 
			
		||||
    * ,-----------------------------------------------------------------------------------.
 | 
			
		||||
    * | Boot | Reset| Diag |      |      |      |      |      |      |      | Test |Revers|
 | 
			
		||||
    * |------+------+------+------+------+-------------+------+------+------+------+------|
 | 
			
		||||
    * |      |      |      |      |      |      |      |      |      |      |      |      |
 | 
			
		||||
    * |------+------+------+------+------+------|------+------+------+------+------+------|
 | 
			
		||||
    * |      |Reflec|Rotors|Posn.s|Rings |Plugs |      |      |Enigma|Qwerty|      |      |
 | 
			
		||||
    * |------+------+------+------+------+------+------+------+------+------+------+------|
 | 
			
		||||
    * |      |      |      |      |      |             |      |      |      |      |      |
 | 
			
		||||
    * `-----------------------------------------------------------------------------------'
 | 
			
		||||
    */
 | 
			
		||||
    [_FN] = LAYOUT_planck_mit(
 | 
			
		||||
        QK_BOOT, EN_RES,  EN_DIAG, _______, _______, _______, _______, _______, _______, _______, EN_TEST, EN_BSPC,
 | 
			
		||||
        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
 | 
			
		||||
        _______, EN_SREF, EN_SROT, EN_SPOS, EN_SRIN, EN_SPLU, _______, _______, QWERTY,  ENIGMA,  _______, _______,
 | 
			
		||||
        _______, _______, _______, _______, _______,      _______,     _______, _______, _______, _______, _______
 | 
			
		||||
    ),
 | 
			
		||||
    /* Lower
 | 
			
		||||
    * ,-----------------------------------------------------------------------------------.
 | 
			
		||||
    * | ~    |   !  |   @  |   #  |   $  |   %  |   ^  |   &  |   *  |   (  |   )  | Bksp |
 | 
			
		||||
    * |------+------+------+------+------+-------------+------+------+------+------+------|
 | 
			
		||||
    * |      |      |      |      |      |      |      |   _  |   +  |   {  |   }  |  |   |
 | 
			
		||||
    * |------+------+------+------+------+------|------+------+------+------+------+------|
 | 
			
		||||
    * | Shift|      |      |      |      |      |      |      |      |      |      |      |
 | 
			
		||||
    * |------+------+------+------+------+------+------+------+------+------+------+------|
 | 
			
		||||
    * | Ctrl |  Fn  | Alt  | GUI  |Lower |    Space    |Raise | Left | Down |  Up  |Right |
 | 
			
		||||
    * `-----------------------------------------------------------------------------------'
 | 
			
		||||
    */
 | 
			
		||||
    [_LOWER] = LAYOUT_planck_mit(
 | 
			
		||||
        KC_TILD, KC_EXLM, KC_AT,   KC_HASH, KC_DLR,  KC_PERC, KC_CIRC, KC_AMPR,  KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC, 
 | 
			
		||||
        _______, _______, _______, _______, _______, _______, _______, KC_UNDS,  KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE, 
 | 
			
		||||
        KC_LSFT, _______, _______, _______, _______, _______, _______,  _______, _______, _______, _______, _______, 
 | 
			
		||||
        KC_LCTL, _______, KC_LGUI, KC_LALT, _______,       KC_SPC,      _______, KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT
 | 
			
		||||
    ),
 | 
			
		||||
    /* RAISE
 | 
			
		||||
    * ,-----------------------------------------------------------------------------------.
 | 
			
		||||
    * | `    |   1  |   2  |   3  |   4  |   5  |   6  |   7  |   8  |   9  |   0  | Bksp |
 | 
			
		||||
    * |------+------+------+------+------+-------------+------+------+------+------+------|
 | 
			
		||||
    * |      |      |      |      |      |      |      |   -  |   =  |   [  |   ]  |  \   |
 | 
			
		||||
    * |------+------+------+------+------+------|------+------+------+------+------+------|
 | 
			
		||||
    * | Shift|      |      |      |      |      |      |      |      |      |      |      |
 | 
			
		||||
    * |------+------+------+------+------+------+------+------+------+------+------+------|
 | 
			
		||||
    * | Ctrl |  Fn  | Alt  | GUI  |Lower |    Space    |Raise | Left | Down |  Up  |Right |
 | 
			
		||||
    * `-----------------------------------------------------------------------------------'
 | 
			
		||||
    */
 | 
			
		||||
    [_RAISE] = LAYOUT_planck_mit(
 | 
			
		||||
        KC_GRV,  KC_1,    KC_2,    KC_3,    KC_4,    KC_5,    KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    KC_BSPC, 
 | 
			
		||||
        _______, _______, _______, _______, _______, _______, _______, KC_MINS, KC_EQL,  KC_LBRC, KC_RBRC, KC_BSLS, 
 | 
			
		||||
        KC_LSFT, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, 
 | 
			
		||||
        KC_LCTL, _______, KC_LGUI, KC_LALT, _______,      KC_SPC,      _______, KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT
 | 
			
		||||
    ),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
char rotor_definitions[5][26] = {
 | 
			
		||||
    "EKMFLGDQVZNTOWYHXUSPAIBRCJ",
 | 
			
		||||
    "AJDKSIRUXBLHWTMCQGZNPYFVOE",
 | 
			
		||||
    "BDFHJLCPRTXVZNYEIWGAKMUSQO",
 | 
			
		||||
    "ESOVPZJAYQUIRHXLNFTGKDCMWB",
 | 
			
		||||
    "VZBRGITYUPSDNHLXAWMJQOFECK" 
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
char reflector_definitions[3][26] = {
 | 
			
		||||
    "EJMZALYXVBWFCRQUONTSPIKHGD",
 | 
			
		||||
    "YRUHQSLDPXNGOKMIEBFZCWVJAT",
 | 
			
		||||
    "FVPJIAOYEDRZXWGCTKUQSBNMHL"
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
char notch[5] = "QEVJZ";
 | 
			
		||||
 | 
			
		||||
typedef struct Settings {
 | 
			
		||||
    char rotor_order[3];
 | 
			
		||||
    char rotor_rings[3];
 | 
			
		||||
    char rotor_positions[3];
 | 
			
		||||
    char plugs[25];
 | 
			
		||||
    int plug_count;
 | 
			
		||||
    char reflector;
 | 
			
		||||
} Settings;
 | 
			
		||||
 | 
			
		||||
typedef struct KeyboardState {
 | 
			
		||||
    bool is_setting_reflector;
 | 
			
		||||
    bool is_setting_rotors;
 | 
			
		||||
    bool is_setting_rotor_positions;
 | 
			
		||||
    bool is_setting_rotor_rings;
 | 
			
		||||
    bool is_setting_plugs;
 | 
			
		||||
    char setting_progress[26];
 | 
			
		||||
    int setting_index;
 | 
			
		||||
    Settings current_settings;
 | 
			
		||||
    Settings default_settings;
 | 
			
		||||
} KeyboardState;
 | 
			
		||||
 | 
			
		||||
int bound(int letter) {
 | 
			
		||||
    return ((letter % 26) + 26) % 26;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char to_char(int letter) {
 | 
			
		||||
    return 'A' + letter;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int to_int(char letter) {
 | 
			
		||||
    return letter - 'A';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char encipher(char letter, Settings *settings) {
 | 
			
		||||
    int rotor_2_step = settings->rotor_positions[2] == notch[settings->rotor_order[2] - 1];
 | 
			
		||||
    int rotor_1_step = settings->rotor_positions[1] == notch[settings->rotor_order[1] - 1];
 | 
			
		||||
      
 | 
			
		||||
    // Advance the third rotor
 | 
			
		||||
    settings->rotor_positions[2]++;
 | 
			
		||||
    if (settings->rotor_positions[2] > 'Z') {
 | 
			
		||||
      settings->rotor_positions[2] -= 26;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Maybe advance the second rotor, including double steps
 | 
			
		||||
    if (rotor_2_step || rotor_1_step) {
 | 
			
		||||
        settings->rotor_positions[1]++;
 | 
			
		||||
        if (settings->rotor_positions[1] > 'Z') {
 | 
			
		||||
            settings->rotor_positions[1] -= 26;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Maybe advance the first rotor
 | 
			
		||||
    if (rotor_1_step) {
 | 
			
		||||
        settings->rotor_positions[0]++;
 | 
			
		||||
        if (settings->rotor_positions[0] > 'Z') {
 | 
			
		||||
            settings->rotor_positions[0] -= 26;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Swap letters on plugboard
 | 
			
		||||
    for (int i = 0; i < settings->plug_count * 2; i += 2) {
 | 
			
		||||
        if (letter == settings->plugs[i]) {
 | 
			
		||||
            letter = settings->plugs[i + 1];
 | 
			
		||||
        } else if (letter == settings->plugs[i + 1]) {
 | 
			
		||||
            letter = settings->plugs[i];
 | 
			
		||||
        }  
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Rotors (right to left)
 | 
			
		||||
    for (int rotor_index = 2; rotor_index >= 0; rotor_index--) {
 | 
			
		||||
        char *rotor_definition = rotor_definitions[settings->rotor_order[rotor_index] - 1];
 | 
			
		||||
        int position = to_int(settings->rotor_positions[rotor_index]);
 | 
			
		||||
        int ring = to_int(settings->rotor_rings[rotor_index]);
 | 
			
		||||
        int char_index = to_int(letter);
 | 
			
		||||
        letter = to_char(bound(
 | 
			
		||||
            to_int(rotor_definition[bound(char_index + position - ring)]) + ring - position
 | 
			
		||||
        ));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Swap via reflector
 | 
			
		||||
    letter = reflector_definitions[to_int(settings->reflector)][to_int(letter)];
 | 
			
		||||
 | 
			
		||||
    // Rotors in reverse (left to right)
 | 
			
		||||
    for (int rotor_index = 0; rotor_index < 3; rotor_index++) {
 | 
			
		||||
        char *rotor_definition = rotor_definitions[settings->rotor_order[rotor_index] - 1];
 | 
			
		||||
        int position = to_int(settings->rotor_positions[rotor_index]);
 | 
			
		||||
        int ring = to_int(settings->rotor_rings[rotor_index]);
 | 
			
		||||
        int search_index;
 | 
			
		||||
        for (search_index = 0; search_index < 26; search_index++) {
 | 
			
		||||
            if (
 | 
			
		||||
                rotor_definition[search_index] 
 | 
			
		||||
                == to_char(bound(to_int(letter) - ring + position))
 | 
			
		||||
            ) {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        letter = to_char(bound(search_index - position + ring));
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Plugboard again
 | 
			
		||||
    for (int i = 0; i < settings->plug_count * 2; i += 2) {
 | 
			
		||||
        if (letter == settings->plugs[i]) {
 | 
			
		||||
            letter = settings->plugs[i + 1];
 | 
			
		||||
        } else if (letter == settings->plugs[i + 1]) {
 | 
			
		||||
            letter = settings->plugs[i];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return letter;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void init_enigma_default(Settings *settings) {
 | 
			
		||||
    settings->rotor_order[0] = 1;
 | 
			
		||||
    settings->rotor_rings[0] = 'A';
 | 
			
		||||
    settings->rotor_positions[0] = 'A';
 | 
			
		||||
 | 
			
		||||
    settings->rotor_order[1] = 2;
 | 
			
		||||
    settings->rotor_rings[1] = 'A';
 | 
			
		||||
    settings->rotor_positions[1] = 'A';
 | 
			
		||||
 | 
			
		||||
    settings->rotor_order[2] =  3;
 | 
			
		||||
    settings->rotor_rings[2] = 'A';
 | 
			
		||||
    settings->rotor_positions[2] = 'A';
 | 
			
		||||
 | 
			
		||||
    strcpy(settings->plugs, "");
 | 
			
		||||
    settings->plug_count = 0;
 | 
			
		||||
 | 
			
		||||
    settings->reflector = 'B';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void copy_settings(Settings *from, Settings *to) {
 | 
			
		||||
    to->rotor_order[0] = from->rotor_order[0];
 | 
			
		||||
    to->rotor_rings[0] = from->rotor_rings[0];
 | 
			
		||||
    to->rotor_positions[0] = from->rotor_positions[0];
 | 
			
		||||
 | 
			
		||||
    to->rotor_order[1] = from->rotor_order[1];
 | 
			
		||||
    to->rotor_rings[1] = from->rotor_rings[1];
 | 
			
		||||
    to->rotor_positions[1] = from->rotor_positions[1];
 | 
			
		||||
 | 
			
		||||
    to->rotor_order[2] = from->rotor_order[2];
 | 
			
		||||
    to->rotor_rings[2] = from->rotor_rings[2];
 | 
			
		||||
    to->rotor_positions[2] = from->rotor_positions[2];
 | 
			
		||||
 | 
			
		||||
    strncpy(to->plugs, from->plugs, from->plug_count * 2);
 | 
			
		||||
    to->plug_count = from->plug_count;
 | 
			
		||||
 | 
			
		||||
    to->reflector = from->reflector;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *rotor_name(int rotor_number) {
 | 
			
		||||
    if (rotor_number == 1) {
 | 
			
		||||
        return "I";
 | 
			
		||||
    } else if (rotor_number == 2) {
 | 
			
		||||
        return "II";
 | 
			
		||||
    } else if (rotor_number == 3) {
 | 
			
		||||
        return "III";
 | 
			
		||||
    } else if (rotor_number == 4) {
 | 
			
		||||
        return "IV";
 | 
			
		||||
    } else if (rotor_number == 5) {
 | 
			
		||||
        return "V";
 | 
			
		||||
    }
 | 
			
		||||
    return "?";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void rotors_reverse(Settings *settings) {
 | 
			
		||||
    int rotor_2_step = settings->rotor_positions[2] 
 | 
			
		||||
        == to_char(bound(to_int(notch[settings->rotor_order[2] - 1]) + 1));
 | 
			
		||||
    int rotor_1_step = settings->rotor_positions[1] 
 | 
			
		||||
        == to_char(bound(to_int(notch[settings->rotor_order[1] - 1]) + 1));
 | 
			
		||||
      
 | 
			
		||||
    // Reverse third rotor
 | 
			
		||||
    settings->rotor_positions[2]--;
 | 
			
		||||
    if (settings->rotor_positions[2] < 'A') {
 | 
			
		||||
        settings->rotor_positions[2] += 26;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Maybe reverse second rotor (including double steps)
 | 
			
		||||
    if (rotor_2_step || rotor_1_step) {
 | 
			
		||||
        settings->rotor_positions[1]--;
 | 
			
		||||
        if (settings->rotor_positions[1] < 'A') {
 | 
			
		||||
            settings->rotor_positions[1] += 26;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Maybe recerse first rotor
 | 
			
		||||
    if (rotor_1_step) {
 | 
			
		||||
        settings->rotor_positions[0]--;
 | 
			
		||||
        if (settings->rotor_positions[0] < 'A') {
 | 
			
		||||
            settings->rotor_positions[0] += 26;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void reset_settings(KeyboardState *state) {
 | 
			
		||||
  copy_settings(&state->default_settings, &state->current_settings);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void set_layer(uint8_t default_layer) {
 | 
			
		||||
    default_layer_set((layer_state_t)1 << default_layer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void set_backlight(uint8_t mode, uint8_t hue, uint8_t sat, uint8_t val) {
 | 
			
		||||
    #ifdef RGBLIGHT_ENABLE
 | 
			
		||||
        rgblight_enable_noeeprom(); 
 | 
			
		||||
        rgblight_mode_noeeprom(mode);
 | 
			
		||||
        rgblight_sethsv_noeeprom(hue, sat, val);
 | 
			
		||||
    #endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void clear_working_settings(KeyboardState *state) {
 | 
			
		||||
    state->is_setting_reflector = false;
 | 
			
		||||
    state->is_setting_rotors = false;
 | 
			
		||||
    state->is_setting_rotor_positions = false;
 | 
			
		||||
    state->is_setting_rotor_rings = false;
 | 
			
		||||
    state->is_setting_plugs = false;
 | 
			
		||||
    state->setting_index = 0;
 | 
			
		||||
    set_layer(_ENIGMA);
 | 
			
		||||
    set_backlight(RGBLIGHT_MODE_STATIC_LIGHT, HSV_RED);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void send_settings_string(Settings *settings) {
 | 
			
		||||
    send_char(settings->reflector);
 | 
			
		||||
    send_string(". ");
 | 
			
		||||
    send_string(rotor_name(settings->rotor_order[0]));
 | 
			
		||||
    send_char(settings->rotor_rings[0]);
 | 
			
		||||
    send_string("-");
 | 
			
		||||
    send_string(rotor_name(settings->rotor_order[1]));
 | 
			
		||||
    send_char(settings->rotor_rings[1]);
 | 
			
		||||
    send_string("-");
 | 
			
		||||
    send_string(rotor_name(settings->rotor_order[2]));
 | 
			
		||||
    send_char(settings->rotor_rings[2]);
 | 
			
		||||
    send_string(" (");
 | 
			
		||||
    send_char(settings->rotor_positions[0]);
 | 
			
		||||
    send_string(", ");
 | 
			
		||||
    send_char(settings->rotor_positions[1]);
 | 
			
		||||
    send_string(", ");
 | 
			
		||||
    send_char(settings->rotor_positions[2]);
 | 
			
		||||
    send_string(") ");
 | 
			
		||||
    for (int i = 0; i < settings->plug_count; i++) {
 | 
			
		||||
        send_char(settings->plugs[i * 2]);
 | 
			
		||||
        send_char(settings->plugs[i * 2 + 1]);
 | 
			
		||||
        send_string(" ");
 | 
			
		||||
    }
 | 
			
		||||
    send_string("\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void perform_test(Settings *settings) {
 | 
			
		||||
    for (int i = 0; i < 1000; i++) {
 | 
			
		||||
        send_char(encipher('A', settings) - ('A' - 'a'));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void commit_plug_settings(KeyboardState *state) {
 | 
			
		||||
    state->default_settings.plug_count = state->setting_index / 2; 
 | 
			
		||||
    for (int i = 0; i < state->default_settings.plug_count; i++) {
 | 
			
		||||
        state->default_settings.plugs[i * 2] = state->setting_progress[i * 2];
 | 
			
		||||
        state->default_settings.plugs[i * 2 + 1] = state->setting_progress[i * 2 + 1];
 | 
			
		||||
    }
 | 
			
		||||
    reset_settings(state);
 | 
			
		||||
    clear_working_settings(state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void handle_set_reflector(char letter, KeyboardState *state) {
 | 
			
		||||
    if (letter >= 'A' && letter <= 'C') {
 | 
			
		||||
        state->default_settings.reflector = letter;
 | 
			
		||||
        reset_settings(state);
 | 
			
		||||
        clear_working_settings(state);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool handle_set_rotor(char letter, KeyboardState *state) {
 | 
			
		||||
    bool is_valid = letter >= 'A' && letter <= 'E' && state->setting_index < 3;
 | 
			
		||||
    if (is_valid) {
 | 
			
		||||
        state->setting_progress[state->setting_index] = to_int(letter) + 1;
 | 
			
		||||
        state->setting_index += 1;
 | 
			
		||||
        if (state->setting_index == 3) {
 | 
			
		||||
            state->default_settings.rotor_order[0] = state->setting_progress[0];
 | 
			
		||||
            state->default_settings.rotor_order[1] = state->setting_progress[1];
 | 
			
		||||
            state->default_settings.rotor_order[2] = state->setting_progress[2];
 | 
			
		||||
            reset_settings(state);
 | 
			
		||||
            clear_working_settings(state);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return is_valid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool handle_set_rotor_position(char letter, KeyboardState *state) {
 | 
			
		||||
    bool is_valid = state->setting_index < 3; // Guaranteed to be A-Z already
 | 
			
		||||
    if (is_valid) {
 | 
			
		||||
        state->setting_progress[state->setting_index] = letter;
 | 
			
		||||
        state->setting_index += 1;
 | 
			
		||||
        if (state->setting_index == 3) {
 | 
			
		||||
            state->default_settings.rotor_positions[0] = state->setting_progress[0];
 | 
			
		||||
            state->default_settings.rotor_positions[1] = state->setting_progress[1];
 | 
			
		||||
            state->default_settings.rotor_positions[2] = state->setting_progress[2]; 
 | 
			
		||||
            reset_settings(state);
 | 
			
		||||
            clear_working_settings(state);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return is_valid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool handle_set_rotor_ring(char letter, KeyboardState *state) {
 | 
			
		||||
    bool is_valid = state->setting_index < 3;
 | 
			
		||||
    if (is_valid) {
 | 
			
		||||
        state->setting_progress[state->setting_index] = letter;
 | 
			
		||||
        state->setting_index += 1;
 | 
			
		||||
        if (state->setting_index == 3) {
 | 
			
		||||
            state->default_settings.rotor_rings[0] = state->setting_progress[0];
 | 
			
		||||
            state->default_settings.rotor_rings[1] = state->setting_progress[1];
 | 
			
		||||
            state->default_settings.rotor_rings[2] = state->setting_progress[2];
 | 
			
		||||
            reset_settings(state);
 | 
			
		||||
            clear_working_settings(state);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return is_valid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool handle_set_plug(char letter, KeyboardState *state) {
 | 
			
		||||
    bool is_valid = state->setting_index < 26;
 | 
			
		||||
    if (is_valid) {
 | 
			
		||||
        state->setting_progress[state->setting_index] = letter;
 | 
			
		||||
        state->setting_index += 1;
 | 
			
		||||
    }
 | 
			
		||||
    return is_valid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void handle_enigma_keypress(char letter, bool any_mods, KeyboardState *state) {
 | 
			
		||||
    bool settings_valid = true;
 | 
			
		||||
    if (letter) {
 | 
			
		||||
        if (any_mods) {
 | 
			
		||||
            tap_code(KC_A + to_int(letter));
 | 
			
		||||
        } else if (state->is_setting_reflector) {
 | 
			
		||||
            handle_set_reflector(letter, state);
 | 
			
		||||
        } else if (state->is_setting_rotors) {
 | 
			
		||||
            settings_valid = handle_set_rotor(letter, state);
 | 
			
		||||
        } else if (state->is_setting_rotor_positions) {
 | 
			
		||||
            settings_valid = handle_set_rotor_position(letter, state);
 | 
			
		||||
        } else if (state->is_setting_rotor_rings) {
 | 
			
		||||
            settings_valid = handle_set_rotor_ring(letter, state);
 | 
			
		||||
        } else if (state->is_setting_plugs) {
 | 
			
		||||
            settings_valid = handle_set_plug(letter, state);
 | 
			
		||||
        } else {
 | 
			
		||||
            char c2 = encipher(letter, &state->current_settings);
 | 
			
		||||
            send_char(c2 - ('A' - 'a'));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    if (!settings_valid) {
 | 
			
		||||
        clear_working_settings(state);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
KeyboardState STATE;
 | 
			
		||||
 | 
			
		||||
void keyboard_pre_init_user(void) {
 | 
			
		||||
    init_enigma_default(&STATE.default_settings);
 | 
			
		||||
    init_enigma_default(&STATE.current_settings);
 | 
			
		||||
    clear_working_settings(&STATE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
 | 
			
		||||
    uint8_t letter_index;
 | 
			
		||||
    bool letter_found = false;
 | 
			
		||||
    if (record->event.pressed) {
 | 
			
		||||
        switch (keycode) {
 | 
			
		||||
          case QWERTY:
 | 
			
		||||
              set_layer(_QWERTY);
 | 
			
		||||
              set_backlight(RGBLIGHT_MODE_RAINBOW_SWIRL + 4, HSV_PURPLE);
 | 
			
		||||
              break;
 | 
			
		||||
          case ENIGMA:
 | 
			
		||||
              set_layer(_ENIGMA);
 | 
			
		||||
              set_backlight(RGBLIGHT_MODE_STATIC_LIGHT, HSV_RED);
 | 
			
		||||
              break;
 | 
			
		||||
          case EN_SREF:
 | 
			
		||||
              reset_settings(&STATE);
 | 
			
		||||
              STATE.is_setting_reflector = true;
 | 
			
		||||
              set_layer(_ENIGMA);
 | 
			
		||||
              set_backlight(RGBLIGHT_MODE_SNAKE, HSV_RED);
 | 
			
		||||
              break;
 | 
			
		||||
          case EN_SROT:
 | 
			
		||||
              reset_settings(&STATE);
 | 
			
		||||
              STATE.is_setting_rotors = true;
 | 
			
		||||
              STATE.setting_index = 0;
 | 
			
		||||
              set_layer(_ENIGMA);
 | 
			
		||||
              set_backlight(RGBLIGHT_MODE_SNAKE, 10, 255, 255);
 | 
			
		||||
              break;
 | 
			
		||||
          case EN_SPOS:
 | 
			
		||||
              reset_settings(&STATE);
 | 
			
		||||
              STATE.is_setting_rotor_positions = true;
 | 
			
		||||
              STATE.setting_index = 0;
 | 
			
		||||
              set_layer(_ENIGMA);
 | 
			
		||||
              set_backlight(RGBLIGHT_MODE_SNAKE, HSV_ORANGE);
 | 
			
		||||
              break;
 | 
			
		||||
          case EN_SRIN:
 | 
			
		||||
              reset_settings(&STATE);
 | 
			
		||||
              STATE.is_setting_rotor_rings = true;
 | 
			
		||||
              STATE.setting_index = 0;
 | 
			
		||||
              set_layer(_ENIGMA);
 | 
			
		||||
              set_backlight(RGBLIGHT_MODE_SNAKE, HSV_GREEN);
 | 
			
		||||
              break;
 | 
			
		||||
          case EN_SPLU:
 | 
			
		||||
              reset_settings(&STATE);
 | 
			
		||||
              STATE.is_setting_plugs = true;
 | 
			
		||||
              STATE.setting_index = 0;
 | 
			
		||||
              set_layer(_ENIGMA);
 | 
			
		||||
              set_backlight(RGBLIGHT_MODE_SNAKE, HSV_BLUE);
 | 
			
		||||
              break;
 | 
			
		||||
          case QK_GESC:
 | 
			
		||||
              if (
 | 
			
		||||
                  STATE.is_setting_reflector
 | 
			
		||||
                  || STATE.is_setting_rotors
 | 
			
		||||
                  || STATE.is_setting_rotor_positions
 | 
			
		||||
                  || STATE.is_setting_rotor_rings
 | 
			
		||||
                  || STATE.is_setting_plugs
 | 
			
		||||
              ) {
 | 
			
		||||
                  clear_working_settings(&STATE);
 | 
			
		||||
                  return false;
 | 
			
		||||
              }
 | 
			
		||||
              break;
 | 
			
		||||
          case KC_ENT:
 | 
			
		||||
              if (STATE.is_setting_plugs) { 
 | 
			
		||||
                  commit_plug_settings(&STATE);
 | 
			
		||||
                  return false;
 | 
			
		||||
              }
 | 
			
		||||
              break;
 | 
			
		||||
          case EN_A ... EN_Z:
 | 
			
		||||
              letter_index = keycode - EN_A;
 | 
			
		||||
              letter_found = true;
 | 
			
		||||
              break;
 | 
			
		||||
          case EN_RES:
 | 
			
		||||
              reset_settings(&STATE);
 | 
			
		||||
              break;
 | 
			
		||||
          case EN_TEST:
 | 
			
		||||
              perform_test(&STATE.current_settings);
 | 
			
		||||
              break;
 | 
			
		||||
          case EN_DIAG:
 | 
			
		||||
              send_settings_string(&STATE.current_settings);
 | 
			
		||||
              break;
 | 
			
		||||
          case EN_BSPC:
 | 
			
		||||
              rotors_reverse(&STATE.current_settings);
 | 
			
		||||
              tap_code(KC_BSPC);
 | 
			
		||||
              break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    char letter = letter_found ? 'A' + letter_index : 0;
 | 
			
		||||
    uint8_t mods = get_mods();
 | 
			
		||||
    bool any_mods = (mods & MOD_MASK_CTRL) || (mods & MOD_MASK_ALT) || (mods & MOD_MASK_GUI);
 | 
			
		||||
    handle_enigma_keypress(letter, any_mods, &STATE);
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void keyboard_post_init_user(void) {
 | 
			
		||||
    set_layer(_QWERTY);
 | 
			
		||||
    set_backlight(RGBLIGHT_MODE_RAINBOW_SWIRL + 4, HSV_PURPLE);
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue