summaryrefslogtreecommitdiffstats
path: root/keyboards/mitosis/keymaps/datagrok/keymap.c
blob: fc08d36ce02d9b6cabeb0df1e43170680ee2ede0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include QMK_KEYBOARD_H

enum mitosis_layers
{
    _xQ, // qwerty
    _xW, // workman
    _xS, // symbols
    _xN, // numbers
    _xF  // functions
};

// Fillers to make layering more clear
#define XXXXXXX KC_NO   // No-op (no key in this location on Mitosis' fake matrix)
#define _______ KC_TRNS // Transparent, because I haven't decided a mapping yet
#define KC_LMTA KC_LALT // For fun, name the mods like the space cadet keyboard does
#define KC_RMTA KC_RALT // META
#define KC_LSUP KC_LGUI // SUPER
#define KC_RSUP KC_RGUI //
#define KC_RHYP KC_INT4 // HYPER (actually muhenkan 無変換 and henkan 変換)
#define KC_LHYP KC_INT5 // or NFER/XFER.

// Momentary tri-state layers. Mitosis default keymap does this too but employs
// new keymappings and a bunch of conditional code. This simpler keymap
// accomplishes it, but with a small quirk: triggering both layers then
// releasing one out-of-order will leave the tri-state triggered until the
// other is released. Which doesn't bother me.

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  [_xQ] = LAYOUT(
    KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,          KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,
    KC_A,    KC_S,    KC_D,    KC_F,    KC_G,          KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN,
    KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,          KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_QUOT,
             KC_LSUP, KC_LCTL, MO(_xN), SFT_T(KC_TAB), KC_RSFT, MO(_xN), KC_RCTL, KC_RSUP,
             KC_LHYP, KC_LMTA, MO(_xS), KC_BSPC,       KC_SPC,  MO(_xS), KC_RMTA, KC_RHYP
  ),
  [_xW] = LAYOUT(
    KC_Q,    KC_D,    KC_R,    KC_W,    KC_B,    KC_J,    KC_F,    KC_U,    KC_P,    KC_SCLN,
    KC_A,    KC_S,    KC_H,    KC_T,    KC_G,    KC_Y,    KC_N,    KC_E,    KC_O,    KC_I,
    KC_Z,    KC_X,    KC_M,    KC_C,    KC_V,    KC_K,    KC_L,    KC_COMM, KC_DOT,  KC_QUOT,
             _______, _______, _______, _______, _______, _______, _______, _______,
             _______, _______, _______, _______, _______, _______, _______, _______
  ),
  [_xS] = LAYOUT(
    KC_ESC,  _______, KC_UP,   _______, _______, KC_AT,   KC_HASH, KC_DLR,  KC_PERC, KC_TILD,
    KC_TAB,  KC_LEFT, KC_DOWN, KC_RGHT, _______, KC_CIRC, KC_AMPR, KC_PIPE, KC_GRV,  KC_UNDS,
    KC_BSLS, KC_RPRN, KC_RCBR, KC_RBRC, KC_RABK, KC_LABK, KC_LBRC, KC_LCBR, KC_LPRN, KC_SLSH,
             _______, _______, MO(_xF), _______, _______, MO(_xF), _______, _______,
             _______, _______, _______, KC_DEL,  KC_ENT,  _______, _______, _______
  ),
  [_xN] = LAYOUT(
    _______, _______, _______, _______, KC_NLCK, KC_PSLS, KC_P7,   KC_P8,   KC_P9,   KC_P0,
    _______, _______, _______, _______, _______, KC_PAST, KC_P4,   KC_P5,   KC_P6,   KC_PPLS,
    _______, _______, _______, _______, _______, KC_PMNS, KC_P1,   KC_P2,   KC_P3,   KC_PEQL,
             _______, _______, _______, _______, _______, _______, _______, _______,
             _______, _______, MO(_xF), _______, KC_PENT, MO(_xF), _______, _______
  ),
  [_xF] = LAYOUT(
    _______, _______, KC_PGUP, _______, KC_VOLU, KC_F13,  KC_F7,   KC_F8,   KC_F9,   KC_F10,
    _______, KC_HOME, KC_PGDN, KC_END,  KC_VOLD, KC_F14,  KC_F4,   KC_F5,   KC_F6,   KC_F11,
    TG(_xW), KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_F15,  KC_F1,   KC_F2,   KC_F3,   KC_F12,
             _______, _______, _______, _______, _______, _______, _______, _______,
             _______, _______, _______, _______, _______, _______, _______, _______
  ),
};

// This is a hack to place <question mark> on <shift-comma> and <exclaimation
// mark> on <shift-period>, when using an operating system configured for a
// US/qwerty layout.
bool comm_shifted = false;
bool ques_shifted = false;
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  uint8_t shifted;
  uint16_t s_keycode;
  bool *k_shifted;

  switch (keycode) {
    case KC_COMM:
      s_keycode = KC_SLSH;
      k_shifted = &comm_shifted;
      break;
    case KC_DOT:
      s_keycode = KC_1;
      k_shifted = &ques_shifted;
      break;
    default:
      return true;
  }

  shifted = get_mods() & (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT));

  // Keydown. If shift is currently pressed, register its alternate keycode.
  if (record->event.pressed && shifted) {
    *k_shifted = true;
    register_code(s_keycode);
    return false;
    // Keyup. If shift was pressed back when the key was pressed, unregister
    // its alternate keycode.
  } else if (!(record->event.pressed) && *k_shifted) {
    *k_shifted = false;
    unregister_code(s_keycode);
    return false;
    // Otherwise, behave as normal.
  } else {
    return true;
  }
}

// Set the bits of A selected by MASK to the corresponding bits of B
#define setbits(A, B, MASK) A = (A & (B | ~MASK)) | (B & MASK)
void matrix_scan_user(void) {
  //
  // Bit #            7     6     5     4     3     2     1     0
  // layer_state: [     |     |     | _xF | _xN | _xS | _xQ | _xW ]
  // usb_led      [     |     |     |kana |cmps |scrl |caps | num ]
  // PORTB:       [  NC |  10 |   9 |   8 |  14 |  16 |  15 |rxled]
  // PORTC:       [  NC |   5 |     |     |     |     |     |     ]
  // PORTD:       [   6 |  NC |txled|   4 | tx* | rx* | grn | p29 ]
  // PORTE:       [     |   7 |     |     |     |     |     |     ]
  // PORTF:       [  a0 |  a1 | red | blu |     |     |  NC |  NC ]
  //
  // PD0 is connected to the pairing switch and p29 on the wireless module.
  // PF0,PF1,PB7,PC7,PD6 are not broken out by the pro micro board. I don't understand why.
  // PB1-PB6,PD4,PD5,PD6,PF6,PF7 are not connected to the Mitosis receiver
  // board. Each may be connected to an LED by way of a resistor (4.7k to
  // match the others) for a total of 14 additional indicators.

  // A simple (but technically inaccurate) model of the momentary layer state:
  // Fn1 key makes _xS active; indicator = red
  // Fn2 key makes _xN active; indicator = blue
  // Both keys make _xF active; indicator = purple
  // Toggling QWERTY mode makes indicator include green, so (red/blue/purple becomes yellow/cyan/white)

  // negated because for ports 0=LED on.
  uint32_t portf_bits = ~(layer_state|layer_state<<1|(layer_state&0b100)<<3);
  setbits(PORTF, portf_bits, 0b00110000);
  setbits(PORTD, ~layer_state, 0b00000010);
}

// vim: set sw=2 et: