]> git.donarmstrong.com Git - qmk_firmware.git/blob - keyboards/planck/keymaps/cbbrowne/keymap.c
eb8d422f2d3bddab9049ffb05e4ff6ad1b16e955
[qmk_firmware.git] / keyboards / planck / keymaps / cbbrowne / keymap.c
1 #include "planck.h"
2 #ifdef BACKLIGHT_ENABLE
3 #include "backlight.h"
4 #endif
5 #include "config.h"
6 #include "quantum.h"
7 #include "version.h"
8
9 /* Each layer is given a name to aid in readability, which is then
10    used in the keymap matrix below.  The underscores do not denote 
11    anything - you can have a layer called STUFF or any other name.
12
13    Layer names don't all need to be of the same length, obviously, and
14    you could also skip them entirely and just use numbers, though that
15    means needing to manage the numbers.
16
17    It is preferable to keep the symbols short so that a line worth of
18    key mappings fits compactly onto a line of code. */
19
20 /* This was originally based on planck/keymaps/default/default.c, and
21    then cbbrowne has revised things */
22
23 /* Things I did not like about the default mapping 
24
25    - I found control too hard to get to.  I use it more than Tab, so
26      switched it there.
27    - Having dash on [lower-j] is a bit nonintuitive, but may be OK
28    - I'll bet I should switch ESC/TAB
29    - I'm suspicious that I want to shift M(0) from [4][1] to [4][2],
30      and shift ESC off the first column so KC_LCTL and KC_LALT can
31      be on the first column.
32    - I needed to swap ' and ENTER
33
34    - All of the above are done :-)
35
36    - Dropped out support for Dvorak and friends.  They aren't 
37      improvements to me
38 */
39
40
41 /* Some interesting things implemented
42
43    - There is a macro that writes out "cbbrowne" just to show that I
44      could
45    - There is a (somewhat cruddy) linear congruential random number
46      generator.
47      - I seed it somewhat with clock info to make it look more random
48    - There are two macros that use the random number generators
49      - one, M_RANDDIGIT, generates a random digit based on state
50        of the random number generator
51      - the other, M_RANDLETTER, generates a random letter based on state
52        of the random number generator
53      - in both, note the use of register_code()/unregister_code()
54        to indicate the desired key
55    - I do indeed want a sweet number pad!
56 */
57
58 /* Other things to do...
59
60    - Need to think about what zsh and readline actions I use lots
61    - Ought to ensure that Control-Alt-Delete is convenient enough
62    - How about Alt-F1 thru Alt-F8?  Not yet...
63    - What's the keystroke to get from X to console these days?
64    - A layer for doing console switching would not be a bad idea
65
66    - I'm messing with jeremy-dev's keymap that shifts everything
67      outwards.  Gotta figure out how to make it sensible...
68 */
69
70 enum layers {
71   _QWERTY = 0,  /* Qwerty mapping */
72   _LOWER, /* Lower layer, where top line has symbols !@#$%^&*() */
73   _RAISE, /* Raised layer, where top line has digits 1234567890 */
74   _KEYPAD, /* Key pad */
75   _ADJUST, /* Special Adjust layer coming via tri-placement */
76
77 };
78
79 enum my_keycodes {
80   MY_ABVE = SAFE_RANGE,
81   MY_BELW,
82   MY_TERM,
83   MY_DEQL, // /=
84   MY_MEQL, // *=
85   MY_SEQL, // -=
86   MY_PEQL, // +=
87   MY_NEQL, // !=
88   MY_LTGT, // <>
89   MY_DPIP, // ||
90   MY_DAMP, // &&
91 };
92
93 enum macro_id {
94   M_LED = 0,
95   M_USERNAME,
96   M_RANDDIGIT,
97   M_RANDLETTER,
98   M_VERSION,
99   MACRO_UPPER,
100   MACRO_LOWER,
101 };
102
103 #define M_LOWER M(MACRO_LOWER)
104 #define M_UPPER M(MACRO_UPPER)
105 #define ROT_LED M(M_LED)   /* Rotate LED */
106 #define QWERTY DF(_QWERTY)   /* Switch to QWERTY layout */
107 #define KEYPAD DF(_KEYPAD)   /* Switch to keypad */
108 #define USERNAME M(M_USERNAME) /* shortcut for username */
109 #define RANDDIG M(M_RANDDIGIT)
110 #define RANDALP M(M_RANDLETTER)
111 #define CTLENTER MT(MOD_RCTL, KC_ENT)
112 #define SHIFTQUOTE MT(MOD_RSFT, KC_QUOT)
113 #define ALTRIGHT MT(MOD_LALT, KC_RGHT)
114 #define MVERSION M(M_VERSION)
115 #define ALTSLASH LALT(KC_SLSH)
116
117
118 /* Note that Planck has dimensions 4 rows x 12 columns */
119
120 const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
121 [_QWERTY] = { /* Qwerty */
122   {KC_ESC,  KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,    KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_BSPC},
123   {KC_LCTL, KC_A,    KC_S,    KC_D,    KC_F,    KC_G,    KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, CTLENTER},
124   {KC_LSFT, KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,    KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, SHIFTQUOTE },
125   {KC_TAB,  KC_LALT, ROT_LED, KC_LGUI, M_LOWER, KC_SPC,  KC_SPC,  M_UPPER, KC_LEFT, KC_DOWN, KC_UP,   ALTRIGHT}
126   /* Note that KC_SPC is recorded TWICE, so that either matrix position can activate it */
127 },
128 [_RAISE] = { /* RAISE */
129   {KC_GRV,  KC_1,    KC_2,    KC_3,    KC_4,    KC_5,    KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    KC_BSPC},
130   {_______, KC_4,    KC_5,    KC_6,    _______, _______, _______,   KC_MINS, KC_EQL,  KC_LBRC, KC_RBRC, KC_BSLS},
131   {_______, KC_7,    KC_8,    KC_9,    _______, _______, _______,  QWERTY,  KEYPAD,  KEYPAD,  ALTSLASH,_______},
132   {_______, KC_0, _______, _______, _______, _______, _______, _______, KC_PGDN, KC_HOME, KC_END,  KC_PGUP}
133 },
134 [_LOWER] = { /* LOWER */
135   {KC_TILD, KC_EXLM, KC_AT,   KC_HASH, KC_DLR,  KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC},
136   {_______, KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_F6,   KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE},
137   {_______, KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  KC_F12,  QWERTY,  KEYPAD,  KEYPAD, ALTSLASH,   _______},
138   {_______, KEYPAD, _______, _______, _______, _______, _______, _______, KC_PGDN, KC_HOME,  KC_END, KC_PGUP}
139     },
140 [_KEYPAD] = { /* Key Pad */
141   {KC_ESC,  USERNAME,    MVERSION,   KC_F10,   KC_F11,  KC_F12,   KC_PGUP, KC_KP_ENTER, KC_7, KC_8, KC_9, KC_BSPC},
142   {KC_LCTL, RANDDIG,   KC_F5,   KC_F6,    KC_F7,   KC_F8,    KC_PGDN, KC_KP_MINUS, KC_4, KC_5, KC_6, KC_PIPE},
143   {KC_LSFT, RANDALP,   KC_F1,   KC_F2,    KC_F3,   KC_F4,    KC_DEL,  KC_KP_PLUS,  KC_1, KC_2,  KC_3, KC_ENTER},
144   {KC_TAB,  KC_LALT, ROT_LED, KC_LGUI,  M_LOWER,  KC_SPC,    KC_SPC,  QWERTY,   KC_LEFT, KC_DOWN, KC_UP,  KC_RIGHT}
145 },
146
147 [_ADJUST] = { /* Adjustments - gonna shift the wild tools in here */
148   {ROT_LED,USERNAME,MVERSION, _______, _______, _______, _______, _______, _______, _______, _______, _______ },
149   {_______, RANDDIG, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ },
150   {_______, RANDALP, _______, _______, _______,   RESET,   RESET, _______, _______, _______, _______, _______ },
151   {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ }
152 }
153 };
154
155
156 /* What is fn_actions actually used for??? */
157 const uint16_t PROGMEM fn_actions[] = {
158 };
159
160 /* This bit of logic seeds a wee linear congruential random number generator */
161 /* lots of prime numbers everywhere... */
162 static uint16_t random_value = 157;
163
164 const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
165 {
166   uint8_t clockbyte=0;
167   clockbyte = TCNT1 % 256;
168   uint8_t rval;
169   // MACRODOWN only works in this function
170   switch(id) {
171   case M_LED:
172     if (record->event.pressed) {
173       register_code(KC_RSFT);
174 #ifdef BACKLIGHT_ENABLE
175       backlight_step();
176 #endif
177     } else {
178       unregister_code(KC_RSFT);
179     }
180     break;          
181   case M_USERNAME:
182     if (record->event.pressed) {
183       SEND_STRING("cbbrowne");
184     }
185     break;
186   case M_VERSION:
187     if (record->event.pressed) {
188       SEND_STRING(QMK_KEYBOARD "/" QMK_KEYMAP "@" QMK_VERSION "@" QMK_BUILDDATE);
189     }
190     break;
191   case M_RANDDIGIT:
192     /* Generate, based on random number generator, a keystroke for
193        a numeric digit chosen at random */
194     random_value = ((random_value + randadd) * randmul) % randmod;
195     if (record->event.pressed) {
196       /* Here, we mix the LCRNG with low bits from one of the system
197          clocks via XOR in the theory that this may be more random
198          than either separately */ 
199       rval = (random_value ^ clockbyte) % 10;
200       /* Note that KC_1 thru KC_0 are a contiguous range */
201       register_code (KC_1 + rval);
202       unregister_code (KC_1 + rval);
203     }
204     break;
205   case M_RANDLETTER:
206     /* Generate, based on random number generator, a keystroke for
207        a letter chosen at random */
208     /* Here, we mix the LCRNG with low bits from one of the system
209        clocks via XOR in the theory that this may be more random
210        than either separately */ 
211     random_value = ((random_value + randadd) * randmul) % randmod;
212     if (record->event.pressed) {
213       rval = (random_value ^ clockbyte) % 26;
214       register_code (KC_A + rval);
215       unregister_code (KC_A + rval);
216     }
217     break;
218   case MACRO_UPPER:
219     if (record->event.pressed)
220       {
221         layer_on(_RAISE);
222 #ifdef BACKLIGHT_BREATHING
223         breathing_period_set(2);
224         breathing_pulse();
225 #endif
226         update_tri_layer(_LOWER, _RAISE, _ADJUST);
227       }
228     else
229       {
230         layer_off(_RAISE);
231         update_tri_layer(_LOWER, _RAISE, _ADJUST);
232       }
233     break;
234   case MACRO_LOWER:
235     if (record->event.pressed)
236       {
237         layer_on(_LOWER);
238 #ifdef BACKLIGHT_BREATHING
239         breathing_period_set(2);
240         breathing_pulse();
241 #endif
242         update_tri_layer(_LOWER, _RAISE, _ADJUST);
243       }
244     else
245       {
246         layer_off(_LOWER);
247         update_tri_layer(_LOWER, _RAISE, _ADJUST);
248       }
249     break;
250     
251   }
252   return MACRO_NONE;
253 };
254
255 void press_key(uint16_t key) {
256   register_code(key);
257   unregister_code(key);
258 }
259
260 void press_two_keys(uint16_t key1, uint16_t key2) {
261   register_code(key1);
262   register_code(key2);
263   unregister_code(key2);
264   unregister_code(key1);
265 }
266
267 void press_three_keys(uint16_t key1, uint16_t key2, uint16_t key3) {
268   register_code(key1);
269   register_code(key2);
270   register_code(key3);
271   unregister_code(key3);
272   unregister_code(key2);
273   unregister_code(key1);
274 }
275
276 bool process_record_user(uint16_t keycode, keyrecord_t *record) {
277   switch (keycode) {
278     case MY_BELW:
279       if (record->event.pressed) {
280         press_two_keys(KC_LGUI, KC_RGHT);
281         press_key(KC_ENT);
282       }
283
284       return false;
285
286     case MY_ABVE:
287       if (record->event.pressed) {
288         press_two_keys(KC_LGUI, KC_LEFT);
289         press_key(KC_ENT);
290         press_key(KC_UP);
291       }
292
293       return false;
294
295     case MY_TERM:
296       if (record->event.pressed) {
297         press_three_keys(KC_LGUI, KC_LSFT, KC_ENT);
298       }
299
300       return false;
301
302     case MY_DEQL: // /=
303       if (record->event.pressed) {
304         press_key(KC_SLSH);
305         press_key(KC_EQL);
306       }
307
308       return false;
309
310     case MY_MEQL: // *=
311       if (record->event.pressed) {
312         press_two_keys(KC_LSFT, KC_ASTR);
313         press_key(KC_EQL);
314       }
315
316       return false;
317
318     case MY_SEQL: // -=
319       if (record->event.pressed) {
320         press_key(KC_MINS);
321         press_key(KC_EQL);
322       }
323
324       return false;
325
326     case MY_PEQL: // +=
327       if (record->event.pressed) {
328         press_two_keys(KC_LSFT, KC_PLUS);
329         press_key(KC_EQL);
330       }
331
332       return false;
333
334     case MY_NEQL: // !=
335       if (record->event.pressed) {
336         press_two_keys(KC_LSFT, KC_EXLM);
337         press_key(KC_EQL);
338       }
339
340       return false;
341
342     case MY_LTGT: // <>
343       if (record->event.pressed) {
344         press_two_keys(KC_LSFT, KC_LABK);
345         press_two_keys(KC_LSFT, KC_RABK);
346       }
347
348       return false;
349
350     case MY_DPIP: // ||
351       if (record->event.pressed) {
352         press_two_keys(KC_LSFT, KC_PIPE);
353         press_two_keys(KC_LSFT, KC_PIPE);
354       }
355
356       return false;
357
358     case MY_DAMP: // &&
359       if (record->event.pressed) {
360         press_two_keys(KC_LSFT, KC_AMPR);
361         press_two_keys(KC_LSFT, KC_AMPR);
362       }
363
364       return false;
365   }
366
367   return true;
368 }
369