]> git.donarmstrong.com Git - qmk_firmware.git/blob - keyboards/mitosis/keymaps/datagrok/keymap.c
mitosis:datagrok add layer select, more layouts (#3835)
[qmk_firmware.git] / keyboards / mitosis / keymaps / datagrok / keymap.c
1 #include QMK_KEYBOARD_H
2
3 #ifdef AUDIO_ENABLE
4 #include "audio.h"
5 #ifdef DEFAULT_LAYER_SONGS
6 extern float default_layer_songs[][][];
7 #endif
8 #endif
9
10 enum mitosis_layers
11   {
12     _xQ, // qwerty
13     _xC, // colemak
14     _xD, // dvorak
15     _xW, // workman
16     _xS, // symbols
17     _xN, // numbers
18     _xF  // functions
19   };
20
21 enum mitosis_keycodes
22   {
23     KC_LAYO = SAFE_RANGE
24   };
25
26 // Setting MITOSIS_DATAGROK_BOTTOMSPACE in rules.mk will swap the upper and
27 // lower center four thumb-keys. See keymaps/datagrok/rules.mk.
28 #ifdef MITOSIS_DATAGROK_BOTTOMSPACE
29 #undef LAYOUT
30 #define LAYOUT LAYOUT_bottomspace
31 #endif
32
33 // Fillers to make layering more clear
34 #define _______ KC_TRNS // Transparent
35
36 // I don't use Japanese myself, but I've placed henkan 変換 and muhenkan 無変換
37 // in my layout to act as left and right HYPER
38
39 // Momentary tri-state layers. Mitosis default keymap does this too but employs
40 // new keymappings and a bunch of conditional code. This simpler keymap
41 // accomplishes it but with a small quirk: triggering both layers then releasing
42 // one out-of-order will leave the tri-state triggered until the other is
43 // released. Which doesn't bother me.
44
45 // The weird /*,*/ comments are a hack to get slightly better automatic
46 // tabulation in my editor.
47
48 // We use Space Cadet KC_RSPC to get _ on right shift. See config.h for details.
49
50 const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
51   [_xQ] = LAYOUT(
52       KC_Q,    KC_W,       KC_E,    KC_R,    KC_T,           KC_Y,    KC_U,    KC_I,    KC_O,     KC_P,
53       KC_A,    KC_S,       KC_D,    KC_F,    KC_G,           KC_H,    KC_J,    KC_K,    KC_L,     KC_SCLN,
54       KC_Z,    KC_X,       KC_C,    KC_V,    KC_B,           KC_N,    KC_M,    KC_COMM, KC_DOT,   KC_QUOT,
55       /*,      */ KC_LGUI, KC_LCTL, MO(_xS), KC_BSPC,        KC_SPC,  MO(_xS), KC_RCTL, KC_RGUI,
56       /*,      */ KC_HENK, KC_LALT, MO(_xN), LSFT_T(KC_TAB), KC_RSPC, MO(_xN), KC_RALT, KC_MHEN),
57   [_xC] = LAYOUT(
58       KC_Q,    KC_W,       KC_F,    KC_P,    KC_G,           KC_J,    KC_L,    KC_U,    KC_Y,     KC_SCLN,
59       KC_A,    KC_R,       KC_S,    KC_T,    KC_D,           KC_H,    KC_N,    KC_E,    KC_I,     KC_O,
60       KC_Z,    KC_X,       KC_C,    KC_V,    KC_B,           KC_K,    KC_M,    KC_COMM, KC_DOT,   KC_QUOT,
61       /*,      */ _______, _______, _______, _______,        _______, _______, _______, _______,
62       /*,      */ _______, _______, _______, _______,        _______, _______, _______, _______),
63   [_xD] = LAYOUT(
64       KC_QUOT, KC_COMM,    KC_DOT,  KC_P,    KC_Y,           KC_F,    KC_G,    KC_C,    KC_R,     KC_L,
65       KC_A,    KC_O,       KC_E,    KC_U,    KC_I,           KC_D,    KC_H,    KC_T,    KC_N,     KC_S,
66       KC_SCLN, KC_Q,       KC_J,    KC_K,    KC_X,           KC_B,    KC_M,    KC_W,    KC_V,     KC_Z,
67       /*,      */ _______, _______, _______, _______,        _______, _______, _______, _______,
68       /*,      */ _______, _______, _______, _______,        _______, _______, _______, _______),
69   [_xW] = LAYOUT(
70       KC_Q,    KC_D,       KC_R,    KC_W,    KC_B,           KC_J,    KC_F,    KC_U,    KC_P,     KC_SCLN,
71       KC_A,    KC_S,       KC_H,    KC_T,    KC_G,           KC_Y,    KC_N,    KC_E,    KC_O,     KC_I,
72       KC_Z,    KC_X,       KC_M,    KC_C,    KC_V,           KC_K,    KC_L,    KC_COMM, KC_DOT,   KC_QUOT,
73       /*,      */ _______, _______, _______, _______,        _______, _______, _______, _______,
74       /*,      */ _______, _______, _______, _______,        _______, _______, _______, _______),
75   [_xS] = LAYOUT(
76       KC_ESC,  KC_GRV ,    KC_UP,   KC_EQL , KC_TILD,        KC_PLUS, KC_CIRC, KC_AMPR, KC_PERC,  KC_MINS,
77       _______, KC_LEFT,    KC_DOWN, KC_RGHT, _______,        KC_PIPE, KC_AT,   KC_DLR,  KC_HASH,  KC_ENT,
78       KC_BSLS, KC_LABK,    KC_LCBR, KC_LPRN, KC_LBRC,        KC_RBRC, KC_RPRN, KC_RCBR, KC_RABK,  KC_SLSH,
79       /*,      */ _______, _______, _______, KC_DEL,         _______, _______, _______, _______,
80       /*,      */ _______, _______, TT(_xF), _______,        _______, TT(_xF), _______, _______),
81   [_xN] = LAYOUT(
82       KC_PSCR, KC_F7,      KC_F8,   KC_F9,   KC_F10,         KC_PPLS, KC_7,    KC_8,    KC_9,     KC_PMNS,
83       KC_SLCK, KC_F4,      KC_F5,   KC_F6,   KC_F11,         KC_NLCK, KC_4,    KC_5,    KC_6,     KC_PENT,
84       KC_PAUS, KC_F1,      KC_F2,   KC_F3,   KC_F12,         KC_PAST, KC_1,    KC_2,    KC_3,     KC_PSLS,
85       /*,      */ _______, _______, TT(_xF), _______,        _______, TT(_xF), KC_0,    KC_DOT,
86       /*,      */ _______, _______, _______, _______,        _______, _______, _______, _______),
87   [_xF] = LAYOUT(
88       RESET,   KC_INS,     KC_PGUP, DEBUG,   KC_VOLU,        KC_PPLS, KC_P7,   KC_P8,   KC_P9,    KC_PMNS,
89       CK_TOGG, KC_HOME,    KC_PGDN, KC_END,  KC_VOLD,        KC_NLCK, KC_P4,   KC_P5,   KC_P6,    KC_PENT,
90       KC_LAYO, KC_MPRV,    KC_MPLY, KC_MNXT, KC_MUTE,        KC_PAST, KC_P1,   KC_P2,   KC_P3,    KC_PSLS,
91       /*,      */ CK_UP,   MU_TOG,  _______, _______,        _______, _______, KC_P0,   KC_PDOT,
92       /*,      */ CK_DOWN, MU_MOD,  _______, _______,        _______, _______, _______, _______),
93 };
94 const bool defaultlayers[] = {
95   [_xQ] = true,
96   [_xC] = true,
97   [_xD] = true,
98   [_xW] = true,
99   [_xS] = false,
100   [_xN] = false,
101   [_xF] = false,
102 };
103 const size_t defaultlayers_n = sizeof(defaultlayers) / sizeof(defaultlayers[0]);
104
105 // New keycode KC_LAYO rotates between available default layers (for e.g.,
106 // selecting a base layout). Shift+KC_LAYO makes the current one persistent.
107 bool process_record_layout(uint16_t keycode, keyrecord_t *record) {
108   uint32_t default_layer;
109   uint8_t i;
110   #if defined(AUDIO_ENABLE)
111   float saved_song[][2] = SONG(COIN_SOUND);
112   #endif
113
114   if (keycode != KC_LAYO || !record->event.pressed) {
115     return true;
116   }
117
118   if (get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT))) { // shift pressed
119     // save default layer. whatever the current default layer is, store that
120     eeconfig_update_default_layer(default_layer_state);
121     #if defined(AUDIO_ENABLE)
122         PLAY_SONG(saved_song);
123     #endif
124   } else {
125     // rotate default layer.
126     // find the current default layer
127     default_layer = biton32(default_layer_state);
128     // find next valid default layer
129     for (i = 1; i < defaultlayers_n; i++) {
130       if (defaultlayers[(default_layer + i) % defaultlayers_n]) {
131         break;
132       }
133     }
134     if (i == defaultlayers_n) {
135       // we fell out of the loop without finding another default layer to switch
136       // to.
137       return false;
138     }
139     default_layer = (default_layer + i) % defaultlayers_n;
140     default_layer_set(1U<<default_layer);
141     led_set(host_keyboard_leds());
142     #if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS)
143       PLAY_SONG(default_layer_songs[default_layer]);
144     #endif
145   }
146   return false;
147 }
148
149 // This is a hack to place <question mark> on <shift-comma> and <exclamation
150 // mark> on <shift-period>, when using an operating system configured for a
151 // US/qwerty layout.
152 // cdeq = "comma dot exclamation question"
153 bool comm_shifted = false;
154 bool ques_shifted = false;
155 bool process_record_cdeq(uint16_t keycode, keyrecord_t *record) {
156   uint8_t shifted;
157   uint16_t s_keycode;
158   bool *k_shifted;
159
160   switch (keycode) {
161   case KC_COMM:
162     s_keycode = KC_SLSH;
163     k_shifted = &comm_shifted;
164     break;
165   case KC_DOT:
166     s_keycode = KC_1;
167     k_shifted = &ques_shifted;
168     break;
169   default:
170     return true;
171   }
172
173   shifted = get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT));
174
175   // Keydown. If shift is currently pressed, register its alternate keycode.
176   if (record->event.pressed && shifted) {
177     *k_shifted = true;
178     register_code(s_keycode);
179     return false;
180     // Keyup. If shift was pressed back when the key was pressed, unregister
181     // its alternate keycode.
182   } else if (!(record->event.pressed) && *k_shifted) {
183     *k_shifted = false;
184     unregister_code(s_keycode);
185     return false;
186     // Otherwise, behave as normal.
187   } else {
188     return true;
189   }
190 }
191
192 bool process_record_user(uint16_t keycode, keyrecord_t *record) {
193   return \
194     process_record_cdeq(keycode, record) && \
195     process_record_layout(keycode, record);
196 }
197
198 // Set the bits of A selected by MASK to the corresponding bits of B
199 #define setbits(A, B, MASK) A = (A & (B | ~MASK)) | (B & MASK)
200
201 void led_set_user(uint8_t usb_leds) {
202   // A simple (but technically inaccurate) model of the momentary layer state:
203   // Red layer active -> indicator = red
204   // Blue layer active -> indicator = blue
205   // Purple layer active -> indicator = purple
206   // the Pro Micro tx LED displays Num Lock status.
207   //
208   // Workman layout active -> indicator = green
209   // Workman red layer -> indicator = yellow (red + green)
210   // Workman blue layer -> indicator = cyan (blue + green)
211   // Workman purple layer -> indicator = white (red + blue + green)
212
213   // Bit #            7     6     5     4     3     2     1     0
214   // layer_state: [     | _xF | _xN | _xS | _xW | _xD | _xC | _xQ ]
215   // usb_led      [     |     |     |kana |cmps |scrl |caps | num ]
216   // PORTB:       [  NC |  10 |   9 |   8 |  14 |  16 |  15 |rxled]
217   // PORTC:       [  NC |   5 |     |     |     |     |     |     ]
218   // PORTD:       [   6 |  NC |txled|   4 | tx* | rx* | grn | p29 ]
219   // PORTE:       [     |   7 |     |     |     |     |     |     ]
220   // PORTF:       [  a0 |  a1 | red | blu |     |     |  NC |  NC ]
221   //
222   // PD0 is connected to the pairing switch and p29 on the wireless module.
223   // PF0,PF1,PB7,PC7,PD6 are not broken out by the pro micro board. I don't understand why.
224   // PB1-PB6,PD4,PD5,PD6,PF6,PF7 are not connected to the Mitosis receiver
225   // board. Each may be connected to an LED by way of a resistor (4.7k to
226   // match the others) for a total of 14 additional indicators.
227
228   uint32_t portf_bits = \
229     ((layer_state|default_layer_state)&0b01100000)>>1 | \
230     ((layer_state|default_layer_state)&0b00010000)<<1 | \
231     ((layer_state|default_layer_state)&0b01000000)>>2;
232   uint32_t portd_bits = \
233     (usb_leds&0b1)<<5 | \
234     ((layer_state|default_layer_state)&0b1000)>>2;
235   // negated because for ports 0=LED on.
236   setbits(PORTF, ~portf_bits, 0b00110000);
237   setbits(PORTD, ~portd_bits, 0b00100010);
238 }
239
240 // vim: set sw=2 et: