From 5f6ec37b7dfb33f79a8815af42dd41baeabed383 Mon Sep 17 00:00:00 2001 From: Travis Date: Wed, 3 Aug 2022 16:10:46 +1000 Subject: [Keymap] Add TravisHi keymap for SplitKB Kyria (#17858) * Init commit * Prep for MVP * Add F Fixes (thanks F!) * Fix some incorrect layer summons * Create readme (remove comments from code) * Update OLED indicators (test) * Add more OLED updates * Add more layouts * Update readme and small tweaks * Update layers and prep for LED layers * Fix a trapped layer issue * Test animations * Add a happy frog animation to right screen * Add bulk work * Move fren readme image * Can't save images * Update FPS layout * Update Symbols layer * Update readme * Update readme (future comments move to readme) * Remove superfluous comments & add Licence * Add licence update --- keyboards/splitkb/kyria/keymaps/travishi/config.h | 42 ++ keyboards/splitkb/kyria/keymaps/travishi/keymap.c | 423 +++++++++++++++++++++ keyboards/splitkb/kyria/keymaps/travishi/readme.md | 99 +++++ keyboards/splitkb/kyria/keymaps/travishi/rules.mk | 12 + 4 files changed, 576 insertions(+) create mode 100644 keyboards/splitkb/kyria/keymaps/travishi/config.h create mode 100644 keyboards/splitkb/kyria/keymaps/travishi/keymap.c create mode 100644 keyboards/splitkb/kyria/keymaps/travishi/readme.md create mode 100644 keyboards/splitkb/kyria/keymaps/travishi/rules.mk (limited to 'keyboards/splitkb') diff --git a/keyboards/splitkb/kyria/keymaps/travishi/config.h b/keyboards/splitkb/kyria/keymaps/travishi/config.h new file mode 100644 index 0000000000..c579a76ecc --- /dev/null +++ b/keyboards/splitkb/kyria/keymaps/travishi/config.h @@ -0,0 +1,42 @@ +/* Copyright 2022 TravisHi + * + * 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 . + */ + +#pragma once + +#ifdef OLED_ENABLE + #define OLED_DISPLAY_128X64 +#endif + +#ifdef RGBLIGHT_ENABLE + #define RGBLIGHT_LAYERS + #define RGBLIGHT_HUE_STEP 8 + #define RGBLIGHT_SAT_STEP 8 + #define RGBLIGHT_VAL_STEP 8 + #define RGBLIGHT_SLEEP +#endif + +// The Leader key allows to flexibly assign macros to key sequences. +#define LEADER_PER_KEY_TIMING +#define LEADER_TIMEOUT 350 + +#define TAPPING_TERM 200 + +// Allows to use either side as the master. Look at the documentation for info: +// https://docs.qmk.fm/#/config_options?id=setting-handedness +#define EE_HANDS + +// Allows media codes to properly register in macros and rotary encoder code +#define TAP_CODE_DELAY 10 diff --git a/keyboards/splitkb/kyria/keymaps/travishi/keymap.c b/keyboards/splitkb/kyria/keymaps/travishi/keymap.c new file mode 100644 index 0000000000..e91d16b8f9 --- /dev/null +++ b/keyboards/splitkb/kyria/keymaps/travishi/keymap.c @@ -0,0 +1,423 @@ +/* Copyright 2022 TravisHi + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +enum layers { + DVORAK = 0, + QWERTY, + LAYERS, + NUMSYM, + FPSGAMES, +}; + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + +/* + * Base Layer: DVORAK + * + * ,-------------------------------------------. ,-------------------------------------------. + * | ESC | ' " | , < | . | P | Y | | F | G | C | R | L |L_Qwerty| + * |--------+------+------+------+------+------| |------+------+------+------+------+--------| + * | Tab | A | O | E | U | I | | D | H | T | N | S | - | + * |--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------| + * | LShift | : ; | Q | J | K | X |LCtrl | | | Win |L_Lay | B | M | W | V | Z | RShift | + * `----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------' + * | Left |Right |L_NumS| Space| Bksp | |R_Alt | ENTER| Del | Up | Down | + * | | | | | | | | | | | | + * `----------------------------------' `----------------------------------' + */ + [DVORAK] = LAYOUT( + KC_ESC, KC_QUOT, KC_COMM, KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, DF(QWERTY), + KC_TAB, KC_A, KC_O, KC_E, KC_U, KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_MINS, + KC_LSFT, KC_SCLN, KC_Q, KC_J, KC_K, KC_X, KC_LCTL, XXXXXXX, KC_LWIN, DF(LAYERS), KC_B, KC_M, KC_W, KC_V, KC_Z, KC_RSFT, + KC_LEFT, KC_RGHT, MO(NUMSYM), KC_SPC, KC_BSPC, KC_RALT, KC_ENT, KC_DEL, KC_UP, KC_DOWN + ), + + + + + +/* + * Base Layer: QWERTY + * + * ,-------------------------------------------. ,-------------------------------------------. + * | ESC | Q | W | E | R | T | | Y | U | I | O | P |L_Dvorak| + * |--------+------+------+------+------+------| |------+------+------+------+------+--------| + * | Tab | A | S | D | F | G | | H | J | K | L | ; : | | + * |--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------| + * | LShift | Z | X | C | V | B |LCtrl | | | Win |L_Lay | N | M | , < | . > | / ? | RShift | + * `----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------' + * | Left |Right |L_NumS| Space| Bksp | | RAlt | ENTER| Del | Up | Down | + * | | | | | | | | | | | | + * `----------------------------------' `----------------------------------' + */ + [QWERTY] = LAYOUT( + KC_ESC, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, DF(DVORAK), + KC_TAB, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, XXXXXXX, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_LCTL, XXXXXXX, KC_LWIN, DF(LAYERS), KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, + KC_LEFT, KC_RGHT, MO(NUMSYM), KC_SPC, KC_BSPC, KC_RALT, KC_ENT, KC_DEL, KC_UP, KC_DOWN + ), + + + + + +/* + * Base Layer: FPSGAMES + * + * ,-------------------------------------------. ,-------------------------------------------. + * | ESC | 1 | Q | W | E | R | | Y | U | I | O | P |L_Dvorak| + * |--------+------+------+------+------+------| |------+------+------+------+------+--------| + * | Tab | 2 | A | S | D | F | | H | K | J | L | ; | | + * |--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------| + * | LShift | 3 | Z | X | C | V | |L_NumS| | |L_Lay | N | M | , < | . > | / ? | | + * `----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------' + * | | | LCtrl| Space| LAlt | | | | Mute |Vol U |Vol D | + * | | | | | | | | | | | | + * `----------------------------------' `----------------------------------' + */ + [FPSGAMES] = LAYOUT( + KC_ESC, KC_1, KC_Q, KC_W, KC_E, KC_R, KC_Y, KC_U, KC_I, KC_O, KC_P, DF(DVORAK), + KC_TAB, KC_2, KC_A, KC_S, KC_D, KC_F, KC_H, KC_J, KC_K, KC_L, KC_SCLN, XXXXXXX, + KC_LSFT, KC_3, KC_Z, KC_X, KC_C, KC_V, XXXXXXX, MO(NUMSYM), XXXXXXX, DF(LAYERS), KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, XXXXXXX, + XXXXXXX, XXXXXXX, KC_LCTL, KC_SPC, KC_LALT, XXXXXXX, XXXXXXX, KC_MUTE, KC_VOLU, KC_VOLD + ), + + + + + +/* + * MO Layer: Numbers, symbols & Vol control + * + * ,-------------------------------------------. ,-------------------------------------------. + * | ` | ! | @ | # | $ | % | | ^ | & | * | ( | ) | + | + * |--------+------+------+------+------+------| |------+------+------+------+------+--------| + * | ~ | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | = | + * |--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------| + * | | | \ | : | ; | - | [ | { | ( | | ) | } | ] | _ | , | . | / | ? | + * `----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------' + * | Left |Right | |LShift| Home | | End | | Mute |Vol U |Vol D | + * | | | | | | | | | | | | + * `----------------------------------' `----------------------------------' + */ + [NUMSYM] = LAYOUT( + KC_GRV, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_PLUS, + KC_TILD, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_EQL, + KC_PIPE, KC_BSLS, KC_COLN, KC_SCLN, KC_MINS, KC_LBRC, KC_LCBR, KC_LPRN, KC_RPRN, KC_RCBR, KC_RBRC, KC_UNDS, KC_COMM, KC_DOT, KC_SLSH, KC_QUES, + KC_LEFT, KC_RGHT, XXXXXXX, KC_LSFT, KC_HOME, KC_END, XXXXXXX, KC_MUTE, KC_VOLU, KC_VOLD + ), + + + + + +/* + * Adjust Layer: Layer index + * + * ,-------------------------------------------. ,-------------------------------------------. + * | | | |FPSGames|Dvorak| | | | | | | |L_Dvorak| + * |--------+------+------+------+------+------| |------+------+------+------+------+--------| + * | | | | |QWERTY| | | | | | | | | + * |--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------| + * | | | | |NUMSYM| | | | | | | | | | | | | + * `----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------' + * | | | | | | | | | | | | + * | | | | | | | | | | | | + * `----------------------------------' `----------------------------------' + */ + [LAYERS] = LAYOUT( + _______, _______, _______, DF(FPSGAMES), DF(DVORAK), _______, _______, _______, _______, _______, _______, DF(DVORAK), + _______, _______, _______, _______, DF(QWERTY), _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, MO(NUMSYM), _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ + ), + +}; + +// END LAYERS + + + + + +/////////////////////////// +// OLED Display settings +#ifdef OLED_ENABLE + + + + +// WPM-responsive animation stuff here +# define IDLE_FRAMES 2 +# define IDLE_SPEED 20 // below this wpm value your animation will idle + +// #define PREP_FRAMES 1 // uncomment if >1 + +# define TAP_FRAMES 2 +# define TAP_SPEED 40 // above this wpm value typing animation to trigger + +# define ANIM_FRAME_DURATION 200 // how long each frame lasts in ms +// #define SLEEP_TIMER 60000 // should sleep after this period of 0 wpm, needs fixing +# define ANIM_SIZE 1024 // number of bytes in array, minimize for adequate firmware size, max is 1024 + +uint32_t anim_timer = 0; +uint32_t anim_sleep = 0; +uint8_t current_idle_frame = 0; +// uint8_t current_prep_frame = 0; // uncomment if PREP_FRAMES >1 +uint8_t current_tap_frame = 0; + +// Code containing pixel art, contains: +// 5 idle frames, 1 prep frame, and 2 tap frames + +// To make your own pixel art: +// save a png/jpeg of an 128x32 image (resource: https://www.pixilart.com/draw ) +// follow this guide up to and including "CONVERT YOUR IMAGE" https://docs.splitkb.com/hc/en-us/articles/360013811280-How-do-I-convert-an-image-for-use-on-an-OLED-display- +// replace numbers in brackets with your own +// if you start getting errors when compiling make sure you didn't accedentally delete a bracket + + +static void render_anim(void) { + static const char PROGMEM idle[IDLE_FRAMES][ANIM_SIZE] = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0x40, +0x40, 0x60, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0xc0, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x60, 0x30, +0x18, 0x0c, 0x06, 0x02, 0xc2, 0x42, 0x62, 0x22, 0x22, 0x24, 0x2f, 0x39, 0x31, 0x60, 0xe0, 0x10, +0x10, 0x08, 0x88, 0xcc, 0x44, 0x66, 0x23, 0x21, 0x31, 0x10, 0x98, 0x89, 0x8b, 0x0e, 0x08, 0x10, +0x20, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x10, 0x60, 0x18, +0xe4, 0x1a, 0xe4, 0x1a, 0xcc, 0x30, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x78, 0x08, 0x08, 0x0c, 0x84, 0x9f, 0xe0, 0xb0, +0x98, 0x08, 0x0c, 0x04, 0x04, 0x04, 0xe6, 0xe2, 0xf2, 0xf2, 0xb2, 0xb3, 0xe1, 0xe1, 0xc1, 0x81, +0xe3, 0xbf, 0x81, 0xc0, 0x40, 0x40, 0x60, 0xa0, 0xbe, 0x3f, 0x1b, 0x9b, 0x8f, 0xcf, 0x66, 0x32, +0x9e, 0xb1, 0x40, 0x40, 0xc0, 0x00, 0x00, 0x80, 0xc0, 0x60, 0x30, 0x18, 0x0f, 0x08, 0x08, 0x10, +0xd0, 0x70, 0x08, 0x0e, 0x02, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x01, 0x01, 0x01, 0x01, 0x11, 0x11, 0x89, 0xcb, 0x4b, 0x4b, 0x8b, 0x87, 0x91, 0x4b, 0x45, +0xe0, 0xa0, 0xb0, 0xd0, 0x51, 0x79, 0xad, 0xb4, 0xd6, 0x5a, 0x6b, 0x2d, 0x34, 0x96, 0xfb, 0xa9, +0xbd, 0x46, 0x66, 0x33, 0x19, 0x0c, 0x07, 0x01, 0x00, 0x00, 0x00, 0x80, 0xc0, 0x70, 0x1c, 0x07, +0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, +0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0c, 0x38, 0xe0, 0x80, 0xc0, 0x40, 0x60, 0x20, 0x20, 0x20, +0x20, 0x20, 0x60, 0xc0, 0x80, 0x80, 0x80, 0x87, 0x8c, 0x88, 0x99, 0xd2, 0x5a, 0x6a, 0x29, 0x2d, +0x34, 0x94, 0x96, 0x9a, 0xcb, 0x49, 0x69, 0x2c, 0xb4, 0x96, 0x9a, 0x8b, 0x4d, 0x45, 0x46, 0x42, +0x21, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0e, 0x0b, 0x09, 0x04, 0x04, 0x04, 0x04, +0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x1e, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x06, 0x0e, 0x0a, 0x1a, 0x1b, 0x35, 0x65, 0x45, +0x45, 0xc3, 0x82, 0x82, 0x81, 0x01, 0x01, 0x01, 0x00, 0x10, 0xf0, 0xf8, 0xf8, 0x78, 0x18, 0x00, +0x00, 0x80, 0xe0, 0xf0, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0xc0, 0x20, 0x50, 0x10, 0xa0, 0x20, 0x40, +0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, +0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, +0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x06, +0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x08, 0x08, 0x18, 0x10, 0x10, 0x30, 0x20, 0x20, 0x60, +0x40, 0x80, 0x80, 0xc0, 0x41, 0x63, 0x26, 0x3c, 0x10, 0x48, 0x88, 0xab, 0x29, 0x70, 0xc0, 0x88, +0x8e, 0xcf, 0x47, 0x43, 0x41, 0x40, 0x60, 0x20, 0x20, 0x20, 0x30, 0x10, 0x10, 0x18, 0x08, 0x08, +0x0c, 0x05, 0x06, 0x02, 0x0c, 0x19, 0x3c, 0x29, 0x6a, 0x44, 0x44, 0xc5, 0x84, 0x04, 0x02, 0x01, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x04, 0x0b, 0x0b, 0x36, 0x28, 0x2f, 0x2c, 0x29, 0x1a, 0x1c, 0x18, 0x1d, 0x16, 0x0a, 0x07, +0x01, 0x02, 0x02, 0x06, 0x06, 0x0e, 0x0e, 0x1e, 0x1c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x03, +0x02, 0x02, 0x06, 0x04, 0x04, 0x04, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x18, 0x10, 0x10, 0x10}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0x40, +0x40, 0x60, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0xc0, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x60, 0x30, +0x18, 0x0c, 0x06, 0x02, 0xc2, 0x42, 0x62, 0x22, 0x22, 0x24, 0x2f, 0x39, 0x31, 0x60, 0xe0, 0x10, +0x10, 0x08, 0x88, 0xcc, 0x44, 0x66, 0x23, 0x21, 0x31, 0x10, 0x98, 0x89, 0x8b, 0x0e, 0x08, 0x10, +0x20, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x98, 0x66, 0x0d, 0x72, 0x0d, 0x72, 0x0c, 0x30, 0x08, +0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x78, 0x08, 0x08, 0x0c, 0x84, 0x9f, 0xe0, 0xb0, +0x98, 0x08, 0x0c, 0x04, 0x04, 0x04, 0xe6, 0xe2, 0xf2, 0xf2, 0xb2, 0xb3, 0xe1, 0xe1, 0xc1, 0x81, +0xe3, 0xbf, 0x81, 0xc0, 0x40, 0x40, 0x60, 0xa0, 0xbe, 0x3f, 0x1b, 0x9b, 0x8f, 0xcf, 0x66, 0x32, +0x9e, 0xb1, 0x40, 0x40, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x07, 0x04, 0xf8, 0x08, 0x08, 0x04, 0x04, +0x07, 0x0c, 0xf8, 0x80, 0x00, 0xfc, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x01, 0x01, 0x01, 0x01, 0x11, 0x11, 0x89, 0xcb, 0x4b, 0x4b, 0x8b, 0x87, 0x91, 0x4b, 0x45, +0xe0, 0xa0, 0xb0, 0xd0, 0x51, 0x79, 0xad, 0xb4, 0xd6, 0x5a, 0x6b, 0x2d, 0x34, 0x96, 0xfb, 0x29, +0x3d, 0x16, 0x16, 0x13, 0x11, 0x10, 0x30, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, +0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x38, 0xe0, 0x00, 0x00, +0x00, 0x00, 0x00, 0x07, 0x3c, 0xe7, 0x8c, 0x38, 0xe0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, +0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x87, 0x8c, 0x88, 0x99, 0xd2, 0x5a, 0x6a, 0x29, 0x2d, +0x34, 0x94, 0x96, 0x9a, 0xcb, 0x49, 0x69, 0x2c, 0xb4, 0x96, 0x9a, 0x8b, 0x4d, 0x45, 0x46, 0x42, +0x20, 0x20, 0x20, 0x60, 0x40, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x04, 0x04, +0x0a, 0x12, 0x22, 0x21, 0x41, 0x81, 0x01, 0x00, 0x00, 0x04, 0x1c, 0xfc, 0x3c, 0x0c, 0x00, 0x00, +0x00, 0x00, 0x00, 0xc0, 0xf0, 0xf8, 0xf0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x3c, +0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x82, 0x87, 0x85, 0x8d, 0x49, 0x49, 0x49, +0x6c, 0x24, 0x24, 0x24, 0x24, 0x14, 0x14, 0x16, 0x12, 0x0a, 0x0a, 0x0a, 0x0b, 0x05, 0x05, 0x05, +0x05, 0x03, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x02, 0x02, 0x06, 0x04, 0x04, 0x0c, 0x08, +0x18, 0x20, 0xe0, 0xf0, 0x90, 0x18, 0xc9, 0x0e, 0x44, 0x92, 0x22, 0x2a, 0x4a, 0x9c, 0xb0, 0xe0, +0x60, 0x04, 0x07, 0x87, 0x83, 0x81, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, +0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, +0x04, 0x03, 0x03, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x40, 0x80, 0x80, 0x80, +0x80, 0xc0, 0x40, 0x40, 0x40, 0x40, 0x60, 0x20, 0x20, 0x20, 0x30, 0x10, 0x10, 0x18, 0x08, 0x08, +0x0c, 0x05, 0x02, 0x02, 0x0d, 0x1a, 0x3b, 0x2b, 0x6a, 0x46, 0x47, 0xc6, 0x87, 0x05, 0x02, 0x01, +0x00, 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x03, 0x07, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, +0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x04, 0x0a, 0x0a, 0x32, 0x22, 0x25, 0x29, 0x21, 0x15, 0x10, 0x15, 0x10, 0x12, 0x08, 0x05, +0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x03, +0x02, 0x02, 0x06, 0x04, 0x04, 0x04, 0x0c, 0x08, 0x08, 0x08, 0x08, 0x08, 0x18, 0x10, 0x10, 0x10} +}; + + + + // assumes 1 frame prep stage + void animation_phase(void) { + current_idle_frame = (current_idle_frame + 1) % IDLE_FRAMES; + oled_write_raw_P(idle[abs((IDLE_FRAMES - 1) - current_idle_frame)], ANIM_SIZE); + } + + if (get_current_wpm() != 000) { + oled_on(); // not essential but turns on animation OLED with any alpha keypress + if (timer_elapsed32(anim_timer) > ANIM_FRAME_DURATION) { + anim_timer = timer_read32(); + animation_phase(); + } + anim_sleep = timer_read32(); + } + else { + + if (timer_elapsed32(anim_timer) > ANIM_FRAME_DURATION) { + anim_timer = timer_read32(); + animation_phase(); + } + + } +} + + + + + + + +oled_rotation_t oled_init_user(oled_rotation_t rotation) { + return OLED_ROTATION_180; +} + + +static void render_keymap(void) { + // Host Keyboard Layer Status + oled_write_P(PSTR("Layer: "), false); + switch (get_highest_layer(default_layer_state)) { + case DVORAK: + oled_write_P(PSTR("Dvorak\n\n"), false); + oled_write_P(PSTR("' , . p y f g c r l \n"), false); + oled_write_P(PSTR("a o e i u d h t n s \n"), false); + oled_write_P(PSTR("; q j k x b m w v z \n"), false); + break; + case QWERTY: + oled_write_P(PSTR("Qwerty\n\n"), false); + oled_write_P(PSTR("q w e r t y u i o p \n"), false); + oled_write_P(PSTR("a s d f g h j k l ; \n"), false); + oled_write_P(PSTR("z x c v b n m , . / \n"), false); + break; + case NUMSYM: + oled_write_P(PSTR("Num & Sym\n\n"), false); + oled_write_P(PSTR("`12345 | 67890= \n"), false); + oled_write_P(PSTR("~!@#$P | ^&*()+ \n"), false); + oled_write_P(PSTR("|\\:;-[{ }]_,./? \n"), false); + break; + case FPSGAMES: + oled_write_P(PSTR("FPS Games \n\n"), false); + oled_write_P(PSTR("1 q W e r | \n"), false); + oled_write_P(PSTR("2 A S D f | \n"), false); + oled_write_P(PSTR("3 z x c v | \n"), false); + break; + case LAYERS: + oled_write_P(PSTR("Index Layer\n\n"), false); + oled_write_P(PSTR("- - G D - | - - - - - \n"), false); + oled_write_P(PSTR("- - - Q - | - - - - - \n"), false); + oled_write_P(PSTR("- - - N - | - - - - - \n"), false); + break; + default: + oled_write_P(PSTR("ERR No Layer!\n"), false); + } +} + + + +// Host Keyboard LED Status +/* +static void render_indicator_status(void) { + led_t led_state = host_keyboard_led_state(); + oled_write_P(led_state.num_lock ? PSTR("NUM ") : PSTR(" "), false); + oled_write_P(led_state.caps_lock ? PSTR("CAPS ") : PSTR(" "), false); + oled_write_P(led_state.scroll_lock ? PSTR("SCRLCK ") : PSTR(" "), false); +} +*/ + +bool oled_task_user(void) { + if (is_keyboard_master()) { + render_keymap(); + } else { + //render_indicator_status(); + //oled_write_P(PSTR(" Kyria rev1.4\n\n"), false); + render_anim(); // renders pixelart + } + return false; +} +#endif \ No newline at end of file diff --git a/keyboards/splitkb/kyria/keymaps/travishi/readme.md b/keyboards/splitkb/kyria/keymaps/travishi/readme.md new file mode 100644 index 0000000000..c7b1f6dd1a --- /dev/null +++ b/keyboards/splitkb/kyria/keymaps/travishi/readme.md @@ -0,0 +1,99 @@ +# Introduction +This keyboard layout centers around Dvorak, harnesing the power of the Kyria thumb +clusters and layers to reduce finger and wrist movement. + +## IMPORTANT NOTE +This keymap will only work if you have all the kyria keys available! If you've used 2u keys on the thumb cluster, or have broken off a column, this layout will not work! + +--- + +## Features +- **Dvorak:** So you don't have to leave the home row so much. +- **Qwerty:** So you don't have to remap common programs. +- **Custom FPS gaming layer:** Because the WASD stagger is so extreme on the Kyria. +- **A number layer:** To access numbers, symbols and volume controls. +- **Index Layer:** To help navigate thru base layers without wasting accessible keys. +- And a very *very* rare **fren** to tag along on your adventures. + +## Guiding ideology +- Use lower thumb keys as much as possible. +- Minimise home row departure. +- Minimize or eliminate non home row pinkie finger use. +- Create macros for very common key shortcuts (ctrl + c/v/s, ctrl+shift+home etc.). +- Create macros for very common commands (git status, git pull, git push etc.). +- Use hints to indicate current layer (rgb lighting/OLED display). +- Allow graceful layer handling (emergency return to default layer/layer index layer). +--- + + +# Current Layers +- Base1: dvorak +- Base2: qwerty +- Base3: Gaming layer (WASD is too staggered on Kyria) +- MO layer: Number, Symbol & volume control layer + +## Future Layers + +- F keys +- FE macros +- Git macros + +--- + + +# Issues +### Major +- [x] None + +### Minor +- [ ] Backlight LEDs dont indicate layer +- [ ] Not fully using thumb clusters +- [ ] Function keys and indicators missing (NUM, CAPS, SCROLL) +- [ ] No Macro layers + +--- + +# Helpful Links + +- QMK Docs https://docs.qmk.fm/#/ +- [Keymap diagram editor for the Kyria](http://www.keyboard-layout-editor.com/##@_name=Kyria%3B&@_y:0.25&x:3&a:7%3B&=&_x:9%3B&=%3B&@_y:-0.75&x:2%3B&=&_x:1%3B&=&_x:7%3B&=&_x:1%3B&=%3B&@_y:-0.875&x:5%3B&=&_x:5%3B&=%3B&@_y:-0.625%3B&=&=&_x:13%3B&=&=%3B&@_y:-0.75&x:3%3B&=&_x:9%3B&=%3B&@_y:-0.75&x:2%3B&=&_x:1%3B&=&_x:7%3B&=&_x:1%3B&=%3B&@_y:-0.875&x:5%3B&=&_x:5%3B&=%3B&@_y:-0.625%3B&=&=&_x:13%3B&=&=%3B&@_y:-0.75&x:3%3B&=&_x:9%3B&=%3B&@_y:-0.75&x:2%3B&=&_x:1%3B&=&_x:7%3B&=&_x:1%3B&=%3B&@_y:-0.875&x:5%3B&=&_x:5%3B&=%3B&@_y:-0.625%3B&=&=&_x:13%3B&=&=%3B&@_y:-0.5&x:2.5%3B&=&_x:10%3B&=%3B&@_rx:4&ry:8.175&y:-4.675000000000001&x:-0.5%3B&=%3B&@_rx:13&y:-4.675000000000001&x:-0.5%3B&=%3B&@_r:15&rx:4&y:-4.675000000000001&x:-0.5%3B&=%3B&@_r:30&y:-2&x:-0.5%3B&=%3B&@_x:-0.5%3B&=%3B&@_r:45&y:-2&x:-0.5%3B&=%3B&@_x:-0.5%3B&=%3B&@_r:-45&rx:13&y:-5.675000000000001&x:-0.5%3B&=%3B&@_x:-0.5%3B&=%3B&@_r:-30&y:-2&x:-0.5%3B&=%3B&@_x:-0.5%3B&=%3B&@_r:-15&y:-1&x:-0.5%3B&=) +- [Thomas' Guide for creating OLED images](https://docs.splitkb.com/hc/en-us/articles/360013811280) +- [Image converter](https://javl.github.io/image2cpp/) + +--- + +## Useful notes +Various useful info for setting up your own keyboard layout. + +### Install QMK Tool steps +[QMK Setup (Windows)](https://docs.qmk.fm/#/newbs_getting_started) +- Install QMK MSYS, +- Install Toolbox, +- Using QMK MSYS, follow the setup guide, then `cd` to where you've cloned the `qmk_firmware` folder, +- `qmk compile` to generate your .hex file (it should be located in the `qmk_firmware` folder), +- Using QMK Toolbox, flash the .hex file to your keyboard halves (drag your hex file into the toolbox window, press the reset button on the keyboard, the toolbox should detect this, then press flash. You need to reset each half separately). +- Congrats, all done! + + +--- +### Layer template +``` +// * ,-------------------------------------------. ,-------------------------------------------. +// * | | | | | | | | | | | | | | +// * |--------+------+------+------+------+------| |------+------+------+------+------+--------| +// * | | | | | | | | | | | | | | +// * |--------+------+------+------+------+------+-------------. ,-------------+------+------+------+------+------+--------| +// * | | | | | | | | | | | | | | | | | | +// * `----------------------+------+------+------+------+------| |------+------+------+------+------+----------------------' +// * | | | | | | | | | | | | +// * | | | | | | | | | | | | +// * `----------------------------------' `----------------------------------' +// */ +// [_LAYERINDEX] = LAYOUT( +// _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, +// _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, +// _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, +// _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ +// ), +``` + diff --git a/keyboards/splitkb/kyria/keymaps/travishi/rules.mk b/keyboards/splitkb/kyria/keymaps/travishi/rules.mk new file mode 100644 index 0000000000..a1564cfe4b --- /dev/null +++ b/keyboards/splitkb/kyria/keymaps/travishi/rules.mk @@ -0,0 +1,12 @@ +# Enabled features +LEADER_ENABLE = yes +RGBLIGHT_ENABLE = yes +OLED_ENABLE = yes +OLED_DRIVER = SSD1306 # Enables the use of OLED displays + +WPM_ENABLE = yes + + +# Disabled features +ENCODER_ENABLE = no # Enables the use of one or more encoders +MOUSEKEY_ENABLE = no \ No newline at end of file -- cgit v1.2.3