sweep.c (13339B)
1 /* Copyright 2022 splitkb.com <support@splitkb.com> 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 17 #include "quantum.h" 18 19 // The first four layers gets a name for readability, which is then used in the OLED below. 20 enum layers { 21 _DEFAULT, 22 _LOWER, 23 _RAISE, 24 _ADJUST 25 }; 26 27 #ifdef OLED_ENABLE 28 // NOTE: Most of the OLED code was originally written by Soundmonster for the Corne, 29 // and has been copied directly from `crkbd/soundmonster/keymap.c` 30 31 oled_rotation_t oled_init_kb(oled_rotation_t rotation) { 32 return OLED_ROTATION_270; 33 } 34 35 void render_space(void) { 36 oled_write_P(PSTR(" "), false); 37 } 38 39 void render_mod_status_gui_alt(uint8_t modifiers) { 40 static const char PROGMEM gui_off_1[] = {0x85, 0x86, 0}; 41 static const char PROGMEM gui_off_2[] = {0xa5, 0xa6, 0}; 42 static const char PROGMEM gui_on_1[] = {0x8d, 0x8e, 0}; 43 static const char PROGMEM gui_on_2[] = {0xad, 0xae, 0}; 44 45 static const char PROGMEM alt_off_1[] = {0x87, 0x88, 0}; 46 static const char PROGMEM alt_off_2[] = {0xa7, 0xa8, 0}; 47 static const char PROGMEM alt_on_1[] = {0x8f, 0x90, 0}; 48 static const char PROGMEM alt_on_2[] = {0xaf, 0xb0, 0}; 49 50 // fillers between the modifier icons bleed into the icon frames 51 static const char PROGMEM off_off_1[] = {0xc5, 0}; 52 static const char PROGMEM off_off_2[] = {0xc6, 0}; 53 static const char PROGMEM on_off_1[] = {0xc7, 0}; 54 static const char PROGMEM on_off_2[] = {0xc8, 0}; 55 static const char PROGMEM off_on_1[] = {0xc9, 0}; 56 static const char PROGMEM off_on_2[] = {0xca, 0}; 57 static const char PROGMEM on_on_1[] = {0xcb, 0}; 58 static const char PROGMEM on_on_2[] = {0xcc, 0}; 59 60 if(modifiers & MOD_MASK_GUI) { 61 oled_write_P(gui_on_1, false); 62 } else { 63 oled_write_P(gui_off_1, false); 64 } 65 66 if ((modifiers & MOD_MASK_GUI) && (modifiers & MOD_MASK_ALT)) { 67 oled_write_P(on_on_1, false); 68 } else if(modifiers & MOD_MASK_GUI) { 69 oled_write_P(on_off_1, false); 70 } else if(modifiers & MOD_MASK_ALT) { 71 oled_write_P(off_on_1, false); 72 } else { 73 oled_write_P(off_off_1, false); 74 } 75 76 if(modifiers & MOD_MASK_ALT) { 77 oled_write_P(alt_on_1, false); 78 } else { 79 oled_write_P(alt_off_1, false); 80 } 81 82 if(modifiers & MOD_MASK_GUI) { 83 oled_write_P(gui_on_2, false); 84 } else { 85 oled_write_P(gui_off_2, false); 86 } 87 88 if ((modifiers & MOD_MASK_GUI) && (modifiers & MOD_MASK_ALT)) { 89 oled_write_P(on_on_2, false); 90 } else if(modifiers & MOD_MASK_GUI) { 91 oled_write_P(on_off_2, false); 92 } else if(modifiers & MOD_MASK_ALT) { 93 oled_write_P(off_on_2, false); 94 } else { 95 oled_write_P(off_off_2, false); 96 } 97 98 if(modifiers & MOD_MASK_ALT) { 99 oled_write_P(alt_on_2, false); 100 } else { 101 oled_write_P(alt_off_2, false); 102 } 103 } 104 105 void render_mod_status_ctrl_shift(uint8_t modifiers) { 106 static const char PROGMEM ctrl_off_1[] = {0x89, 0x8a, 0}; 107 static const char PROGMEM ctrl_off_2[] = {0xa9, 0xaa, 0}; 108 static const char PROGMEM ctrl_on_1[] = {0x91, 0x92, 0}; 109 static const char PROGMEM ctrl_on_2[] = {0xb1, 0xb2, 0}; 110 111 static const char PROGMEM shift_off_1[] = {0x8b, 0x8c, 0}; 112 static const char PROGMEM shift_off_2[] = {0xab, 0xac, 0}; 113 static const char PROGMEM shift_on_1[] = {0xcd, 0xce, 0}; 114 static const char PROGMEM shift_on_2[] = {0xcf, 0xd0, 0}; 115 116 // fillers between the modifier icons bleed into the icon frames 117 static const char PROGMEM off_off_1[] = {0xc5, 0}; 118 static const char PROGMEM off_off_2[] = {0xc6, 0}; 119 static const char PROGMEM on_off_1[] = {0xc7, 0}; 120 static const char PROGMEM on_off_2[] = {0xc8, 0}; 121 static const char PROGMEM off_on_1[] = {0xc9, 0}; 122 static const char PROGMEM off_on_2[] = {0xca, 0}; 123 static const char PROGMEM on_on_1[] = {0xcb, 0}; 124 static const char PROGMEM on_on_2[] = {0xcc, 0}; 125 126 if(modifiers & MOD_MASK_CTRL) { 127 oled_write_P(ctrl_on_1, false); 128 } else { 129 oled_write_P(ctrl_off_1, false); 130 } 131 132 if ((modifiers & MOD_MASK_CTRL) && (modifiers & MOD_MASK_SHIFT)) { 133 oled_write_P(on_on_1, false); 134 } else if(modifiers & MOD_MASK_CTRL) { 135 oled_write_P(on_off_1, false); 136 } else if(modifiers & MOD_MASK_SHIFT) { 137 oled_write_P(off_on_1, false); 138 } else { 139 oled_write_P(off_off_1, false); 140 } 141 142 if(modifiers & MOD_MASK_SHIFT) { 143 oled_write_P(shift_on_1, false); 144 } else { 145 oled_write_P(shift_off_1, false); 146 } 147 148 if(modifiers & MOD_MASK_CTRL) { 149 oled_write_P(ctrl_on_2, false); 150 } else { 151 oled_write_P(ctrl_off_2, false); 152 } 153 154 if ((modifiers & MOD_MASK_CTRL) && (modifiers & MOD_MASK_SHIFT)) { 155 oled_write_P(on_on_2, false); 156 } else if(modifiers & MOD_MASK_CTRL) { 157 oled_write_P(on_off_2, false); 158 } else if(modifiers & MOD_MASK_SHIFT) { 159 oled_write_P(off_on_2, false); 160 } else { 161 oled_write_P(off_off_2, false); 162 } 163 164 if(modifiers & MOD_MASK_SHIFT) { 165 oled_write_P(shift_on_2, false); 166 } else { 167 oled_write_P(shift_off_2, false); 168 } 169 } 170 171 void render_logo(void) { 172 static const char PROGMEM aurora_logo[] = { 173 0x00, 0x00, 0x00, 0xe0, 0x00, 0xf8, 0xc0, 0xf8, 0xe0, 0xc0, 0xfc, 0x00, 0x7e, 0x18, 0x00, 0x80, 174 0x00, 0x02, 0x80, 0xf0, 0x00, 0xc0, 0x80, 0xf8, 0xc0, 0xe0, 0x70, 0x60, 0x3c, 0x38, 0x3c, 0x1c, 175 0x00, 0x3f, 0x0c, 0x0f, 0x1f, 0x03, 0x07, 0x01, 0xc3, 0x00, 0xe0, 0x80, 0x00, 0xe0, 0x80, 0xf8, 176 0x80, 0xc0, 0xf7, 0xc7, 0x6f, 0x7b, 0x39, 0x30, 0x00, 0x80, 0x00, 0xc0, 0x00, 0xc0, 0xc2, 0xe0, 177 0x00, 0x40, 0x38, 0x30, 0x38, 0x1e, 0x18, 0x1e, 0x0f, 0x0c, 0x07, 0x07, 0x07, 0x03, 0x03, 0x21, 178 0x21, 0x31, 0x30, 0x18, 0x18, 0x1c, 0x08, 0x0c, 0x0e, 0x07, 0x06, 0x07, 0x03, 0xc3, 0x03, 0x01, 179 0x4c, 0xcc, 0xc2, 0xc2, 0x41, 0x49, 0x09, 0x2b, 0x2a, 0x6a, 0x6e, 0x24, 0x24, 0x04, 0x92, 0x92, 180 0xb1, 0xf1, 0xf1, 0xf2, 0xe6, 0xa4, 0xa4, 0x04, 0x04, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28 181 }; 182 oled_write_raw_P(aurora_logo, sizeof(aurora_logo)); 183 oled_set_cursor(0, 4); 184 } 185 186 void render_logo_text(void) { 187 oled_write_P(PSTR("sweep"), false); 188 } 189 190 void render_kb_LED_state(void) { 191 // Host Keyboard LED Status 192 led_t led_usb_state = host_keyboard_led_state(); 193 oled_write_P(led_usb_state.num_lock ? PSTR("N ") : PSTR(" "), false); 194 oled_write_P(led_usb_state.caps_lock ? PSTR("C ") : PSTR(" "), false); 195 oled_write_P(led_usb_state.scroll_lock ? PSTR("S ") : PSTR(" "), false); 196 } 197 198 void render_layer_state(void) { 199 static const char PROGMEM default_layer[] = { 200 0x20, 0x94, 0x95, 0x96, 0x20, 201 0x20, 0xb4, 0xb5, 0xb6, 0x20, 202 0x20, 0xd4, 0xd5, 0xd6, 0x20, 0}; 203 static const char PROGMEM raise_layer[] = { 204 0x20, 0x97, 0x98, 0x99, 0x20, 205 0x20, 0xb7, 0xb8, 0xb9, 0x20, 206 0x20, 0xd7, 0xd8, 0xd9, 0x20, 0}; 207 static const char PROGMEM lower_layer[] = { 208 0x20, 0x9a, 0x9b, 0x9c, 0x20, 209 0x20, 0xba, 0xbb, 0xbc, 0x20, 210 0x20, 0xda, 0xdb, 0xdc, 0x20, 0}; 211 static const char PROGMEM adjust_layer[] = { 212 0x20, 0x9d, 0x9e, 0x9f, 0x20, 213 0x20, 0xbd, 0xbe, 0xbf, 0x20, 214 0x20, 0xdd, 0xde, 0xdf, 0x20, 0}; 215 216 switch (get_highest_layer(layer_state | default_layer_state)) { 217 case _LOWER: 218 oled_write_P(lower_layer, false); 219 break; 220 case _RAISE: 221 oled_write_P(raise_layer, false); 222 break; 223 case _ADJUST: 224 oled_write_P(adjust_layer, false); 225 break; 226 default: 227 oled_write_P(default_layer, false); 228 } 229 } 230 231 232 bool oled_task_kb(void) { 233 if (!oled_task_user()) { 234 return false; 235 } 236 if (is_keyboard_master()) { 237 // Renders the current keyboard state (layers and mods) 238 render_logo(); 239 render_logo_text(); 240 render_space(); 241 render_layer_state(); 242 render_space(); 243 render_mod_status_gui_alt(get_mods()|get_oneshot_mods()); 244 render_mod_status_ctrl_shift(get_mods()|get_oneshot_mods()); 245 render_kb_LED_state(); 246 } else { 247 // clang-format off 248 static const char PROGMEM aurora_art[] = { 249 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1c, 0x08, 0x00, 0x00, 250 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 251 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x40, 252 0xe0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0x80, 253 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x80, 0x00, 0xf0, 0x00, 0x00, 0xc0, 254 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 255 0x81, 0x00, 0xc0, 0x00, 0xfe, 0x00, 0xfc, 0x00, 0xff, 0x20, 0xff, 0xf0, 0x0f, 0xf0, 0x00, 0xff, 256 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0xf8, 0x00, 0x00, 0xf8, 257 0xff, 0x10, 0xff, 0x84, 0xff, 0x60, 0xff, 0x36, 0xff, 0x0f, 0xff, 0x3f, 0x00, 0x5f, 0x00, 0x05, 258 0x80, 0x00, 0x80, 0x00, 0xc0, 0x38, 0x00, 0xec, 0xf0, 0x00, 0xfb, 0x80, 0xff, 0xf0, 0xff, 0xef, 259 0xff, 0xe8, 0xff, 0x03, 0xff, 0x0c, 0xff, 0x00, 0xff, 0x00, 0x03, 0x00, 0x00, 0xf8, 0x00, 0x80, 260 0xff, 0x20, 0xff, 0xd0, 0xff, 0xe0, 0xfe, 0xf8, 0xff, 0xfc, 0xff, 0xff, 0x0f, 0xff, 0x01, 0x3f, 261 0xff, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x03, 0x00, 0xfe, 0x80, 0xfe, 0x00, 0xc0, 0xff, 0xc4, 0xfb, 262 0xff, 0xfe, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0x07, 0xff, 0x03, 0x3f, 0x00, 0x0f, 0xc0, 0x00, 263 0x00, 0x00, 0xb8, 0x00, 0xff, 0x40, 0xbe, 0xf0, 0xff, 0xf1, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 264 0x1f, 0xff, 0x67, 0x00, 0xef, 0x00, 0x1f, 0x00, 0x00, 0x07, 0x00, 0x00, 0xe0, 0x00, 0xff, 0xf0, 265 0xff, 0x88, 0xff, 0xc4, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0x7f, 0x0f, 0xff, 266 0x00, 0x07, 0xfe, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xc0, 0x3f, 0xf8, 0xe7, 0xff, 267 0xff, 0xff, 0xff, 0x1f, 0xff, 0xff, 0x1f, 0x3f, 0x01, 0xff, 0x0b, 0x00, 0xff, 0x00, 0x00, 0x05, 268 0x00, 0x00, 0x00, 0xe0, 0x00, 0xf8, 0x60, 0x80, 0xfe, 0xe3, 0xfc, 0xff, 0x1e, 0xff, 0xff, 0x23, 269 0xff, 0x09, 0xff, 0x20, 0x00, 0x3f, 0x02, 0x00, 0x00, 0x0f, 0x00, 0x40, 0x00, 0xc0, 0x00, 0xfc, 270 0xe0, 0xfc, 0xf0, 0xff, 0xff, 0x7f, 0xfc, 0xff, 0x0f, 0xff, 0x07, 0x1f, 0x00, 0x01, 0x0f, 0x00, 271 0x0f, 0x00, 0x81, 0x70, 0x0c, 0xf0, 0x80, 0x00, 0x00, 0xe4, 0xf8, 0xe6, 0x70, 0x3f, 0xcf, 0xff, 272 0x1f, 0xff, 0x48, 0xff, 0x0f, 0x00, 0x07, 0x00, 0x00, 0x43, 0x60, 0xf8, 0xf0, 0xfe, 0x38, 0xfe, 273 0x00, 0xfc, 0x03, 0x00, 0xc8, 0x72, 0xcf, 0xfc, 0x00, 0x03, 0x0f, 0x01, 0xe0, 0x1c, 0xe0, 0x03, 274 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x06, 0xf9, 0x00, 0x03, 0x00, 0x07, 275 0xff, 0x00, 0x10, 0x12, 0xc9, 0xf0, 0xcf, 0xb4, 0x7f, 0x80, 0xe0, 0x1e, 0x01, 0x40, 0x65, 0x5e, 276 0xe0, 0x00, 0x00, 0xf0, 0x0c, 0xf0, 0x00, 0x80, 0x7e, 0x01, 0x80, 0x93, 0xfc, 0xc0, 0x00, 0x00, 277 0x00, 0x00, 0x00, 0x00, 0x89, 0x18, 0x2c, 0x46, 0x00, 0x07, 0x21, 0x10, 0x10, 0x80, 0x09, 0x13, 278 0x31, 0xbf, 0xff, 0x00, 0x08, 0x1a, 0xf7, 0x0f, 0x00, 0x00, 0x44, 0x45, 0x34, 0xbf, 0xb8, 0x00, 279 0x10, 0xf0, 0x08, 0xf4, 0x18, 0x11, 0xfc, 0x18, 0xfb, 0x0e, 0x10, 0xf8, 0x04, 0xf8, 0x10, 0x20, 280 0x18, 0x09, 0xff, 0x0c, 0xea, 0x1f, 0x28, 0x60, 0x30, 0xf8, 0x20, 0xc0, 0x42, 0x33, 0x21, 0x00 281 }; 282 // clang-format on 283 oled_write_raw_P(aurora_art, sizeof(aurora_art)); 284 } 285 return false; 286 } 287 #endif 288 289 #ifdef ENCODER_ENABLE 290 bool encoder_update_kb(uint8_t index, bool clockwise) { 291 if (!encoder_update_user(index, clockwise)) { 292 return false; 293 } 294 // 0 and 1 are left-half encoders, 295 // 2 and 3 are right-half encoders 296 if (index == 0) { 297 // Volume control 298 if (clockwise) { 299 tap_code(KC_VOLU); 300 } else { 301 tap_code(KC_VOLD); 302 } 303 } else if (index == 1) { 304 // Volume control 305 if (clockwise) { 306 tap_code(KC_VOLU); 307 } else { 308 tap_code(KC_VOLD); 309 } 310 } else if (index == 2) { 311 // Page up/Page down 312 if (clockwise) { 313 tap_code(KC_PGDN); 314 } else { 315 tap_code(KC_PGUP); 316 } 317 } else if (index == 3) { 318 // Page up/Page down 319 if (clockwise) { 320 tap_code(KC_PGDN); 321 } else { 322 tap_code(KC_PGUP); 323 } 324 } 325 return true; 326 } 327 #endif