Merge remote-tracking branch 'origin/master' into develop

daktil_manuform
QMK Bot 2021-09-11 07:32:58 +00:00
commit e1540a41b7
7 changed files with 1359 additions and 68 deletions

View File

@ -45,12 +45,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define RGBLIGHT_ANIMATIONS #define RGBLIGHT_ANIMATIONS
#define RGB_DI_PIN A4 #define RGB_DI_PIN A4
#define RGBLED_NUM 16 #define RGBLED_NUM 16
#define RGBLIGHT_LIMIT_VAL 128
#define RGBLIGHT_VAL_STEP 8 #define RGBLIGHT_VAL_STEP 8
#define RGBLIGHT_SLEEP #define RGBLIGHT_SLEEP
// OLED stuff // OLED stuff
#define OLED_DISPLAY_128X64 #define OLED_DISPLAY_128X64
#define OLED_FONT_H "custom_font.h"
// Allows for rotary encoder volume control // Allows for rotary encoder volume control
#define TAP_CODE_DELAY 20 #define TAP_CODE_DELAY 20

View File

@ -0,0 +1,244 @@
/*
Copyright 2021 Seth Bonner <fl3tching101@gmail.com>
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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "progmem.h"
static const unsigned char PROGMEM font[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0x00,
0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 0x00,
0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0x00,
0x18, 0x3C, 0x7E, 0x3C, 0x18, 0x00,
0x1C, 0x57, 0x7D, 0x57, 0x1C, 0x00,
0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 0x00,
0x00, 0x18, 0x3C, 0x18, 0x00, 0x00,
0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 0x00,
0x00, 0x18, 0x24, 0x18, 0x00, 0x00,
0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 0x00,
0x30, 0x48, 0x3A, 0x06, 0x0E, 0x00,
0x26, 0x29, 0x79, 0x29, 0x26, 0x00,
0x40, 0x7F, 0x05, 0x05, 0x07, 0x00,
0x40, 0x7F, 0x05, 0x25, 0x3F, 0x00,
0x5A, 0x3C, 0xE7, 0x3C, 0x5A, 0x00,
0x7F, 0x3E, 0x1C, 0x1C, 0x08, 0x00,
0x08, 0x1C, 0x1C, 0x3E, 0x7F, 0x00,
0x14, 0x22, 0x7F, 0x22, 0x14, 0x00,
0x5F, 0x5F, 0x00, 0x5F, 0x5F, 0x00,
0x06, 0x09, 0x7F, 0x01, 0x7F, 0x00,
0x00, 0x66, 0x89, 0x95, 0x6A, 0x00,
0x60, 0x60, 0x60, 0x60, 0x60, 0x00,
0x94, 0xA2, 0xFF, 0xA2, 0x94, 0x00,
0x08, 0x04, 0x7E, 0x04, 0x08, 0x00,
0x10, 0x20, 0x7E, 0x20, 0x10, 0x00,
0x08, 0x08, 0x2A, 0x1C, 0x08, 0x00,
0x08, 0x1C, 0x2A, 0x08, 0x08, 0x00,
0x1E, 0x10, 0x10, 0x10, 0x10, 0x00,
0x0C, 0x1E, 0x0C, 0x1E, 0x0C, 0x00,
0x30, 0x38, 0x3E, 0x38, 0x30, 0x00,
0x06, 0x0E, 0x3E, 0x0E, 0x06, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x5F, 0x00, 0x00, 0x00,
0x00, 0x07, 0x00, 0x07, 0x00, 0x00,
0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00,
0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00,
0x23, 0x13, 0x08, 0x64, 0x62, 0x00,
0x36, 0x49, 0x56, 0x20, 0x50, 0x00,
0x00, 0x08, 0x07, 0x03, 0x00, 0x00,
0x00, 0x1C, 0x22, 0x41, 0x00, 0x00,
0x00, 0x41, 0x22, 0x1C, 0x00, 0x00,
0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x00,
0x08, 0x08, 0x3E, 0x08, 0x08, 0x00,
0x00, 0x80, 0x70, 0x30, 0x00, 0x00,
0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
0x00, 0x00, 0x60, 0x60, 0x00, 0x00,
0x20, 0x10, 0x08, 0x04, 0x02, 0x00,
0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00,
0x00, 0x42, 0x7F, 0x40, 0x00, 0x00,
0x72, 0x49, 0x49, 0x49, 0x46, 0x00,
0x21, 0x41, 0x49, 0x4D, 0x33, 0x00,
0x18, 0x14, 0x12, 0x7F, 0x10, 0x00,
0x27, 0x45, 0x45, 0x45, 0x39, 0x00,
0x3C, 0x4A, 0x49, 0x49, 0x31, 0x00,
0x41, 0x21, 0x11, 0x09, 0x07, 0x00,
0x36, 0x49, 0x49, 0x49, 0x36, 0x00,
0x46, 0x49, 0x49, 0x29, 0x1E, 0x00,
0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x00, 0x40, 0x34, 0x00, 0x00, 0x00,
0x00, 0x08, 0x14, 0x22, 0x41, 0x00,
0x14, 0x14, 0x14, 0x14, 0x14, 0x00,
0x00, 0x41, 0x22, 0x14, 0x08, 0x00,
0x02, 0x01, 0x59, 0x09, 0x06, 0x00,
0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x00,
0x7C, 0x12, 0x11, 0x12, 0x7C, 0x00,
0x7F, 0x49, 0x49, 0x49, 0x36, 0x00,
0x3E, 0x41, 0x41, 0x41, 0x22, 0x00,
0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00,
0x7F, 0x49, 0x49, 0x49, 0x41, 0x00,
0x7F, 0x09, 0x09, 0x09, 0x01, 0x00,
0x3E, 0x41, 0x41, 0x51, 0x73, 0x00,
0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00,
0x00, 0x41, 0x7F, 0x41, 0x00, 0x00,
0x20, 0x40, 0x41, 0x3F, 0x01, 0x00,
0x7F, 0x08, 0x14, 0x22, 0x41, 0x00,
0x7F, 0x40, 0x40, 0x40, 0x40, 0x00,
0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x00,
0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00,
0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00,
0x7F, 0x09, 0x09, 0x09, 0x06, 0x00,
0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00,
0x7F, 0x09, 0x19, 0x29, 0x46, 0x00,
0x26, 0x49, 0x49, 0x49, 0x32, 0x00,
0x03, 0x01, 0x7F, 0x01, 0x03, 0x00,
0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00,
0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00,
0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00,
0x63, 0x14, 0x08, 0x14, 0x63, 0x00,
0x03, 0x04, 0x78, 0x04, 0x03, 0x00,
0x61, 0x59, 0x49, 0x4D, 0x43, 0x00,
0x00, 0x7F, 0x41, 0x41, 0x41, 0x00,
0x02, 0x04, 0x08, 0x10, 0x20, 0x00,
0x00, 0x41, 0x41, 0x41, 0x7F, 0x00,
0x04, 0x02, 0x01, 0x02, 0x04, 0x00,
0x40, 0x40, 0x40, 0x40, 0x40, 0x00,
0x00, 0x03, 0x07, 0x08, 0x00, 0x00,
0x20, 0x54, 0x54, 0x78, 0x40, 0x00,
0x7F, 0x28, 0x44, 0x44, 0x38, 0x00,
0x38, 0x44, 0x44, 0x44, 0x28, 0x00,
0x38, 0x44, 0x44, 0x28, 0x7F, 0x00,
0x38, 0x54, 0x54, 0x54, 0x18, 0x00,
0x00, 0x08, 0x7E, 0x09, 0x02, 0x00,
0x18, 0x24, 0x24, 0x1C, 0x78, 0x00,
0x7F, 0x08, 0x04, 0x04, 0x78, 0x00,
0x00, 0x44, 0x7D, 0x40, 0x00, 0x00,
0x20, 0x40, 0x40, 0x3D, 0x00, 0x00,
0x7F, 0x10, 0x28, 0x44, 0x00, 0x00,
0x00, 0x41, 0x7F, 0x40, 0x00, 0x00,
0x7C, 0x04, 0x78, 0x04, 0x78, 0x00,
0x7C, 0x08, 0x04, 0x04, 0x78, 0x00,
0x38, 0x44, 0x44, 0x44, 0x38, 0x00,
0xFC, 0x18, 0x24, 0x24, 0x18, 0x00,
0x18, 0x24, 0x24, 0x18, 0xFC, 0x00,
0x7C, 0x08, 0x04, 0x04, 0x08, 0x00,
0x48, 0x54, 0x54, 0x54, 0x24, 0x00,
0x04, 0x04, 0x3F, 0x44, 0x24, 0x00,
0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00,
0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00,
0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00,
0x44, 0x28, 0x10, 0x28, 0x44, 0x00,
0x4C, 0x10, 0x10, 0x10, 0x7C, 0x00,
0x44, 0x64, 0x54, 0x4C, 0x44, 0x00,
0x00, 0x08, 0x36, 0x41, 0x00, 0x00,
0x00, 0x00, 0x77, 0x00, 0x00, 0x00,
0x00, 0x41, 0x36, 0x08, 0x00, 0x00,
0x02, 0x01, 0x02, 0x04, 0x02, 0x00,
0x3C, 0x26, 0x23, 0x26, 0x3C, 0x00,
0x02, 0x1E, 0xF2, 0x86, 0x84, 0x8C,
0x98, 0xD0, 0x70, 0x60, 0x40, 0x60,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x60, 0x40, 0x40, 0x40,
0x40, 0x40, 0x80, 0x80, 0x00, 0x00,
0x10, 0x10, 0x10, 0x34, 0x24, 0x24,
0x00, 0x44, 0x44, 0x48, 0x08, 0x08,
0x10, 0x14, 0x14, 0x20, 0x24, 0x24,
0x00, 0x0C, 0x0C, 0x70, 0x70, 0x70,
0x00, 0x1E, 0x1E, 0x1E, 0x1E, 0x00,
0x00, 0x60, 0x60, 0x06, 0x06, 0x00,
0x00, 0x30, 0x30, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 0x03,
0x00, 0x60, 0x60, 0x60, 0x60, 0x60,
0x00, 0x83, 0x83, 0x80, 0x18, 0x18,
0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F,
0xF0, 0xF0, 0xF0, 0xF0, 0x00, 0x00,
0x38, 0x38, 0x38, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0E, 0x0E, 0x0E, 0x00,
0x00, 0x00, 0x00, 0xE0, 0xE0, 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, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x7E, 0x81, 0x81, 0x81, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
0x24, 0x26, 0x42, 0x42, 0x44, 0x24,
0x18, 0x00, 0x00, 0x81, 0x81, 0x42,
0x66, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x78, 0x4F, 0x61, 0x21, 0x31,
0x19, 0x0B, 0x0E, 0x06, 0x02, 0x06,
0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x04, 0x06, 0x02, 0x02, 0x02,
0x02, 0x02, 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, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

View File

@ -0,0 +1,407 @@
/* Copyright 2021 Seth Bonner <fl3tching101@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "keycode_lookup.h"
#include "print.h"
#include "via.h"
#define num_keycodes (sizeof(lookup_table)/sizeof(lookup_table[0]))
static char UNKNOWN_KEYCODE[] = "UNKNOWN";
int cmp(const void *v1, const void *v2)
{
const lookup_table_t *c1 = v1;
const lookup_table_t *c2 = v2;
return (c1->keycode - c2->keycode);
}
/*
Returns a pointer to a string containing the string describing the keycode, such as those found here:
https://beta.docs.qmk.fm/using-qmk/simple-keycodes/keycodes
Will return a string that says "UNKNOWN" if the keycode cannot be found.
*/
char* translate_keycode_to_string(uint16_t code)
{
lookup_table_t * result = NULL;
lookup_table_t target = {.key_string = "", .keycode = code};
char * return_p;
result = bsearch(&target, lookup_table, num_keycodes, sizeof(lookup_table_t), cmp);
if(result != NULL)
{
return_p = result->key_string;
}
else
{
return_p = UNKNOWN_KEYCODE;
}
return (return_p);
}
lookup_table_t lookup_table[366] =
{
{"KC_NO", KC_NO},
{"KC_TRNS", KC_TRNS},
{"KC_A", KC_A},
{"KC_B", KC_B},
{"KC_C", KC_C},
{"KC_D", KC_D},
{"KC_E", KC_E},
{"KC_F", KC_F},
{"KC_G", KC_G},
{"KC_H", KC_H},
{"KC_I", KC_I},
{"KC_J", KC_J},
{"KC_K", KC_K},
{"KC_L", KC_L},
{"KC_M", KC_M},
{"KC_N", KC_N},
{"KC_O", KC_O},
{"KC_P", KC_P},
{"KC_Q", KC_Q},
{"KC_R", KC_R},
{"KC_S", KC_S},
{"KC_T", KC_T},
{"KC_U", KC_U},
{"KC_V", KC_V},
{"KC_W", KC_W},
{"KC_X", KC_X},
{"KC_Y", KC_Y},
{"KC_Z", KC_Z},
{"KC_1", KC_1},
{"KC_2", KC_2},
{"KC_3", KC_3},
{"KC_4", KC_4},
{"KC_5", KC_5},
{"KC_6", KC_6},
{"KC_7", KC_7},
{"KC_8", KC_8},
{"KC_9", KC_9},
{"KC_0", KC_0},
{"KC_ENT", KC_ENT},
{"KC_ESC", KC_ESC},
{"KC_BSPC", KC_BSPC},
{"KC_TAB", KC_TAB},
{"KC_SPC", KC_SPC},
{"KC_MINS", KC_MINS},
{"KC_EQL", KC_EQL},
{"KC_LBRC", KC_LBRC},
{"KC_RBRC", KC_RBRC},
{"KC_BSLS", KC_BSLS},
{"KC_NUHS", KC_NUHS},
{"KC_SCLN", KC_SCLN},
{"KC_QUOT", KC_QUOT},
{"KC_GRV", KC_GRV},
{"KC_ZKHK", KC_ZKHK},
{"KC_COMM", KC_COMM},
{"KC_DOT", KC_DOT},
{"KC_SLSH", KC_SLSH},
{"KC_CAPS", KC_CAPS},
{"KC_F1", KC_F1},
{"KC_F2", KC_F2},
{"KC_F3", KC_F3},
{"KC_F4", KC_F4},
{"KC_F5", KC_F5},
{"KC_F6", KC_F6},
{"KC_F7", KC_F7},
{"KC_F8", KC_F8},
{"KC_F9", KC_F9},
{"KC_F10", KC_F10},
{"KC_F11", KC_F11},
{"KC_F12", KC_F12},
{"KC_PSCR", KC_PSCR},
{"KC_SLCK", KC_SLCK},
{"KC_PAUS", KC_PAUS},
{"KC_INS", KC_INS},
{"KC_HOME", KC_HOME},
{"KC_PGUP", KC_PGUP},
{"KC_DEL", KC_DEL},
{"KC_END", KC_END},
{"KC_PGDN", KC_PGDN},
{"KC_RGHT", KC_RGHT},
{"KC_LEFT", KC_LEFT},
{"KC_DOWN", KC_DOWN},
{"KC_UP", KC_UP},
{"KC_NLCK", KC_NLCK},
{"KC_PSLS", KC_PSLS},
{"KC_PAST", KC_PAST},
{"KC_PMNS", KC_PMNS},
{"KC_PPLS", KC_PPLS},
{"KC_PENT", KC_PENT},
{"KC_P1", KC_P1},
{"KC_P2", KC_P2},
{"KC_P3", KC_P3},
{"KC_P4", KC_P4},
{"KC_P5", KC_P5},
{"KC_P6", KC_P6},
{"KC_P7", KC_P7},
{"KC_P8", KC_P8},
{"KC_P9", KC_P9},
{"KC_P0", KC_P0},
{"KC_PDOT", KC_PDOT},
{"KC_NUBS", KC_NUBS},
{"KC_APP", KC_APP},
{"KC_POWER", KC_POWER},
{"KC_PEQL", KC_PEQL},
{"KC_F13", KC_F13},
{"KC_F14", KC_F14},
{"KC_F15", KC_F15},
{"KC_F16", KC_F16},
{"KC_F17", KC_F17},
{"KC_F18", KC_F18},
{"KC_F19", KC_F19},
{"KC_F20", KC_F20},
{"KC_F21", KC_F21},
{"KC_F22", KC_F22},
{"KC_F23", KC_F23},
{"KC_F24", KC_F24},
{"KC_EXECUTE", KC_EXECUTE},
{"KC_HELP", KC_HELP},
{"KC_MENU", KC_MENU},
{"KC_SELECT", KC_SELECT},
{"KC_STOP", KC_STOP},
{"KC_AGAIN", KC_AGAIN},
{"KC_UNDO", KC_UNDO},
{"KC_CUT", KC_CUT},
{"KC_COPY", KC_COPY},
{"KC_PASTE", KC_PASTE},
{"KC_FIND", KC_FIND},
{"KC_LCAP", KC_LCAP},
{"KC_LNUM", KC_LNUM},
{"KC_LSCR", KC_LSCR},
{"KC_PCMM", KC_PCMM},
{"KC_KP_EQUAL_AS400", KC_KP_EQUAL_AS400},
{"KC_RO", KC_RO},
{"KC_KANA", KC_KANA},
{"KC_JYEN", KC_JYEN},
{"KC_HENK", KC_HENK},
{"KC_MHEN", KC_MHEN},
{"KC_INT6", KC_INT6},
{"KC_INT7", KC_INT7},
{"KC_INT8", KC_INT8},
{"KC_INT9", KC_INT9},
{"KC_HAEN", KC_HAEN},
{"KC_HANJ", KC_HANJ},
{"KC_LANG3", KC_LANG3},
{"KC_LANG4", KC_LANG4},
{"KC_LANG5", KC_LANG5},
{"KC_LANG6", KC_LANG6},
{"KC_LANG7", KC_LANG7},
{"KC_LANG8", KC_LANG8},
{"KC_LANG9", KC_LANG9},
{"KC_ERAS", KC_ERAS},
{"KC_SYSREQ", KC_SYSREQ},
{"KC_CANCEL", KC_CANCEL},
{"KC_CLR", KC_CLR},
{"KC_CLEAR", KC_CLEAR},
{"KC_PRIOR", KC_PRIOR},
{"KC_OUT", KC_OUT},
{"KC_OPER", KC_OPER},
{"KC_CLEAR_AGAIN", KC_CLEAR_AGAIN},
{"KC_CRSEL", KC_CRSEL},
{"KC_EXSEL", KC_EXSEL},
{"KC_PWR", KC_PWR},
{"KC_SLEP", KC_SLEP},
{"KC_WAKE", KC_WAKE},
{"KC_MUTE", KC_MUTE},
{"KC_VOLU", KC_VOLU},
{"KC_VOLD", KC_VOLD},
{"KC_MNXT", KC_MNXT},
{"KC_MPRV", KC_MPRV},
{"KC_MSTP", KC_MSTP},
{"KC_MPLY", KC_MPLY},
{"KC_MSEL", KC_MSEL},
{"KC_EJCT", KC_EJCT},
{"KC_MAIL", KC_MAIL},
{"KC_CALC", KC_CALC},
{"KC_MYCM", KC_MYCM},
{"KC_WWW_SEARCH", KC_WWW_SEARCH},
{"KC_WWW_HOME", KC_WWW_HOME},
{"KC_WWW_BACK", KC_WWW_BACK},
{"KC_WWW_FORWARD", KC_WWW_FORWARD},
{"KC_WWW_STOP", KC_WWW_STOP},
{"KC_WWW_REFRESH", KC_WWW_REFRESH},
{"KC_WWW_FAVORITES", KC_WWW_FAVORITES},
{"KC_MFFD", KC_MFFD},
{"KC_MRWD", KC_MRWD},
{"KC_BRIU", KC_BRIU},
{"KC_BRID", KC_BRID},
{"KC_FN0", KC_FN0},
{"KC_FN1", KC_FN1},
{"KC_FN2", KC_FN2},
{"KC_FN3", KC_FN3},
{"KC_FN4", KC_FN4},
{"KC_FN5", KC_FN5},
{"KC_FN6", KC_FN6},
{"KC_FN7", KC_FN7},
{"KC_FN8", KC_FN8},
{"KC_FN9", KC_FN9},
{"KC_FN10", KC_FN10},
{"KC_FN11", KC_FN11},
{"KC_FN12", KC_FN12},
{"KC_FN13", KC_FN13},
{"KC_FN14", KC_FN14},
{"KC_FN15", KC_FN15},
{"KC_FN16", KC_FN16},
{"KC_FN17", KC_FN17},
{"KC_FN18", KC_FN18},
{"KC_FN19", KC_FN19},
{"KC_FN20", KC_FN20},
{"KC_FN21", KC_FN21},
{"KC_FN22", KC_FN22},
{"KC_FN23", KC_FN23},
{"KC_FN24", KC_FN24},
{"KC_FN25", KC_FN25},
{"KC_FN26", KC_FN26},
{"KC_FN27", KC_FN27},
{"KC_FN28", KC_FN28},
{"KC_FN29", KC_FN29},
{"KC_FN30", KC_FN30},
{"KC_FN31", KC_FN31},
{"KC_LCTL", KC_LCTL},
{"KC_LSFT", KC_LSFT},
{"KC_LALT", KC_LALT},
{"KC_LGUI", KC_LGUI},
{"KC_RCTL", KC_RCTL},
{"KC_RSFT", KC_RSFT},
{"KC_RALT", KC_RALT},
{"KC_RGUI", KC_RGUI},
{"KC_MS_UP", KC_MS_UP},
{"KC_MS_DOWN", KC_MS_DOWN},
{"KC_MS_LEFT", KC_MS_LEFT},
{"KC_MS_RIGHT", KC_MS_RIGHT},
{"KC_MS_BTN1", KC_MS_BTN1},
{"KC_MS_BTN2", KC_MS_BTN2},
{"KC_MS_BTN3", KC_MS_BTN3},
{"KC_MS_BTN4", KC_MS_BTN4},
{"KC_MS_BTN5", KC_MS_BTN5},
{"KC_MS_WH_UP", KC_MS_WH_UP},
{"KC_MS_WH_DOWN", KC_MS_WH_DOWN},
{"KC_MS_WH_LEFT", KC_MS_WH_LEFT},
{"KC_MS_WH_RIGHT", KC_MS_WH_RIGHT},
{"KC_MS_ACCEL0", KC_MS_ACCEL0},
{"KC_MS_ACCEL1", KC_MS_ACCEL1},
{"KC_MS_ACCEL2", KC_MS_ACCEL2},
{"KC_EXLM", KC_EXLM},
{"KC_AT", KC_AT},
{"KC_HASH", KC_HASH},
{"KC_DLR", KC_DLR},
{"KC_PERC", KC_PERC},
{"KC_CIRC", KC_CIRC},
{"KC_AMPR", KC_AMPR},
{"KC_ASTR", KC_ASTR},
{"KC_LPRN", KC_LPRN},
{"KC_RPRN", KC_RPRN},
{"KC_UNDS", KC_UNDS},
{"KC_PLUS", KC_PLUS},
{"KC_LCBR", KC_LCBR},
{"KC_RCBR", KC_RCBR},
{"KC_PIPE", KC_PIPE},
{"KC_COLN", KC_COLN},
{"KC_DQUO", KC_DQUO},
{"KC_TILD", KC_TILD},
{"KC_LT", KC_LT},
{"KC_GT", KC_GT},
{"KC_QUES", KC_QUES},
{"RESET", RESET},
{"DEBUG", DEBUG},
{"MAGIC_TOGGLE_NKRO", MAGIC_TOGGLE_NKRO},
{"KC_GESC", KC_GESC},
{"AU_ON", AU_ON},
{"AU_OFF", AU_OFF},
{"AU_TOG", AU_TOG},
{"CLICKY_TOGGLE", CLICKY_TOGGLE},
{"CLICKY_ENABLE", CLICKY_ENABLE},
{"CLICKY_DISABLE", CLICKY_DISABLE},
{"CLICKY_UP", CLICKY_UP},
{"CLICKY_DOWN", CLICKY_DOWN},
{"CLICKY_RESET", CLICKY_RESET},
{"MU_ON", MU_ON},
{"MU_OFF", MU_OFF},
{"MU_TOG", MU_TOG},
{"MU_MOD", MU_MOD},
{"BL_ON", BL_ON},
{"BL_OFF", BL_OFF},
{"BL_DEC", BL_DEC},
{"BL_INC", BL_INC},
{"BL_TOGG", BL_TOGG},
{"BL_STEP", BL_STEP},
{"BL_BRTG", BL_BRTG},
{"RGB_TOG", RGB_TOG},
{"RGB_MOD", RGB_MOD},
{"RGB_RMOD", RGB_RMOD},
{"RGB_HUI", RGB_HUI},
{"RGB_HUD", RGB_HUD},
{"RGB_SAI", RGB_SAI},
{"RGB_SAD", RGB_SAD},
{"RGB_VAI", RGB_VAI},
{"RGB_VAD", RGB_VAD},
{"RGB_SPI", RGB_SPI},
{"RGB_SPD", RGB_SPD},
{"RGB_M_P", RGB_M_P},
{"RGB_M_B", RGB_M_B},
{"RGB_M_R", RGB_M_R},
{"RGB_M_SW", RGB_M_SW},
{"RGB_M_SN", RGB_M_SN},
{"RGB_M_K", RGB_M_K},
{"RGB_M_X", RGB_M_X},
{"RGB_M_G", RGB_M_G},
{"KC_LSPO", KC_LSPO},
{"KC_RSPC", KC_RSPC},
{"KC_SFTENT", KC_SFTENT},
{"KC_LCPO", KC_LCPO},
{"KC_RCPC", KC_RCPC},
{"KC_LAPO", KC_LAPO},
{"KC_RAPC", KC_RAPC},
{"FN_MO13", FN_MO13},
{"FN_MO23", FN_MO23},
{"MACRO00", MACRO00},
{"MACRO01", MACRO01},
{"MACRO02", MACRO02},
{"MACRO03", MACRO03},
{"MACRO04", MACRO04},
{"MACRO05", MACRO05},
{"MACRO06", MACRO06},
{"MACRO07", MACRO07},
{"MACRO08", MACRO08},
{"MACRO09", MACRO09},
{"MACRO10", MACRO10},
{"MACRO11", MACRO11},
{"MACRO12", MACRO12},
{"MACRO13", MACRO13},
{"MACRO14", MACRO14},
{"MACRO15", MACRO15},
{"USER00", USER00},
{"USER01", USER01},
{"USER02", USER02},
{"USER03", USER03},
{"USER04", USER04},
{"USER05", USER05},
{"USER06", USER06},
{"USER07", USER07},
{"USER08", USER08},
{"USER09", USER09},
{"USER10", USER10},
{"USER11", USER11},
{"USER12", USER12},
{"USER13", USER13},
{"USER14", USER14},
{"USER15", USER15}
};

View File

@ -0,0 +1,29 @@
/* Copyright 2021 Seth Bonner <fl3tching101@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "quantum.h"
typedef struct
{
char key_string[17];
uint16_t keycode;
} lookup_table_t;
char* translate_keycode_to_string(uint16_t code);
extern lookup_table_t lookup_table[366];

View File

@ -12,29 +12,41 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include QMK_KEYBOARD_H #include QMK_KEYBOARD_H
#include "keycode_lookup.h"
#include <string.h>
#ifdef CONSOLE_ENABLE
#include "print.h"
#endif
// Each layer gets a name for readability, which is then used in the keymap matrix below. // Each layer gets a name for readability, which is then used in the keymap matrix below.
// The underscores don't mean anything - you can have a layer called STUFF or any other name. // The underscores don't mean anything - you can have a layer called STUFF or any other name.
// Layer names don't all need to be of the same length, obviously, and you can also skip them // Layer names don't all need to be of the same length, obviously, and you can also skip them
// entirely and just use numbers. // entirely and just use numbers.
#define _BASE 0 #define _BASE 0
#define _SPEC 1 // Special layer
// Use the following format to create custom key codes to make macros out of and such // Use the following format to create custom key codes to make macros out of and such
/*
enum custom_keycodes { enum custom_keycodes {
FOO = SAFE_RANGE, KC_EXAM = SAFE_RANGE // "Examine" key code to show the keycode of a key pressed afterwards on the OLED
}; };
*/
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_BASE] = LAYOUT_default( [_BASE] = LAYOUT_default(
RGB_MODE_FORWARD, KC_NUMLOCK, RGB_MODE_FORWARD, KC_NUMLOCK,
KC_KP_7, KC_KP_8, KC_KP_9, KC_DELETE, KC_KP_7, KC_KP_8, KC_KP_9, KC_DELETE,
KC_KP_4, KC_KP_5, KC_KP_6, KC_END, KC_KP_4, KC_KP_5, KC_KP_6, KC_END,
KC_KP_1, KC_KP_2, KC_KP_3, KC_AUDIO_VOL_UP, KC_KP_1, KC_KP_2, KC_KP_3, KC_F13,
KC_KP_0, RGB_TOG, KC_AUDIO_MUTE, KC_AUDIO_VOL_DOWN KC_KP_0, MO(1), KC_KP_DOT, KC_KP_ENTER
) ),
[_SPEC] = LAYOUT_default(
RGB_MODE_REVERSE, KC_AUDIO_MUTE,
KC_NO, KC_NO, KC_NO, KC_EXAM,
KC_NO, KC_NO, KC_NO, KC_NO,
RESET, RGB_TOG, RGB_SPI, RGB_SPD,
KC_NO, _______, KC_NO, KC_NO
)
}; };
bool encoder_update_user(uint8_t index, bool clockwise){ bool encoder_update_user(uint8_t index, bool clockwise){
@ -56,35 +68,321 @@ bool encoder_update_user(uint8_t index, bool clockwise){
#ifdef OLED_ENABLE #ifdef OLED_ENABLE
static void render_logo(void) { #define ANIM_FRAMES 3
static const char PROGMEM qmk_logo[] = { #define ANIM_FRAME_DURATION 110 // Number of milliseconds per frame (no faster than 110ms, last line struggles)
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, #define BACKGROUND_FRAMES 21
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, #define ROCKET_CENTER_POS 3
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0x00 #define SPLASH_DUR 100 // Measured in frames, see above for frame length (note, 231 is used as a key value later on, CTRL+F for uses of this to make sure everything is good)
};
oled_write(qmk_logo, false); uint32_t anim_timer = 0;
uint8_t current_frame = 0;
uint8_t rocket_y_position = 3;
uint8_t rocket_pos_change = 0;
uint8_t background_frame = 0;
uint8_t splash_dur_counter = 0;
bool examine_engaged = false;
uint16_t examined_keycode = KC_NO;
char lastKeycodeString[32] = { 0 };
const char star_background [8] [21] =
{
{0x88, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x00, 0x93},
{0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8E, 0x00, 0x00},
{0x00, 0x8F, 0x00, 0x00, 0x8A, 0x00, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x8B, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00},
{0x8D, 0x00, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x00, 0x00, 0x00, 0x00, 0x8F, 0x8B, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x8A, 0x00, 0x00, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x8F, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x8C, 0x00, 0x00, 0x8F, 0x00, 0x89, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x8F},
{0x00, 0x8B, 0x00, 0x00, 0x91, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x8E, 0x00, 0x00, 0x90, 0x00, 0x00, 0x8C, 0x00, 0x00},
};
static void oled_write_ln_centered(const char * data, bool inverted)
{
if(strlen(data) >= 21) // If more than 1 line of text is passed in, return without doing anything
{
return;
}
// Character buffer to build up the string in
char line_buf[21];
// Amount to offset string from left side
uint8_t offset = (21 - strlen(data))/2;
// Formatted string centering... look, it works, don't ask how...
snprintf(line_buf, 21, "%*s%s%*s\0", offset, "", data, offset, ""); // Centers data within 21 character buffer with null termination
oled_write_ln(line_buf, inverted);
}
// Prints the exhaust characters in an order determined by the phase for animation purposes
// startX - The x axis starting point in characters for the exhaust (3 behind the rocket)
// startY - The y axis starting point in characters for the exhaust (middle of the rocket)
// phase - The "phase" of the animation, no real rhyme or reason to the exact number, but each frame move +1 to make the animation work
static void render_exhaust(uint8_t startX, uint8_t startY, uint8_t phase)
{
oled_set_cursor(startX, startY);
oled_write_char(0x85 + (phase % 3), false);
phase++;
oled_write_char(0x85 + (phase % 3), false);
phase++;
oled_write_char(0x85 + (phase % 3), false);
}
// Renders the "stars" behind the rocket
// startY - The starting Y location (in characters) of the rocket so that stars aren't rendered on top of the rocket
static void render_stars(uint8_t startY, uint8_t phase)
{
// Line 0
oled_set_cursor(0, 0);
for(int i = 0; i < 21; i++)
{
oled_write_char(star_background[0][(i + phase) % 21], false);
}
// Line 1
oled_set_cursor(0, 1);
for(int i = 0; i < 21; i++)
{
oled_write_char(star_background[1][(i + phase) % 21], false);
}
// Line 2
oled_set_cursor(0, 2);
for(int i = 0; i < 21; i++)
{
oled_write_char(star_background[2][(i + phase) % 21], false);
}
// Line 3
oled_set_cursor(0, 3);
for(int i = 0; i < 21; i++)
{
oled_write_char(star_background[3][(i + phase) % 21], false);
}
// Line 4
oled_set_cursor(0, 4);
for(int i = 0; i < 21; i++)
{
oled_write_char(star_background[4][(i + phase) % 21], false);
}
// Line 5
oled_set_cursor(0, 5);
for(int i = 0; i < 21; i++)
{
oled_write_char(star_background[5][(i + phase) % 21], false);
}
// Line 6
oled_set_cursor(0, 6);
for(int i = 0; i < 21; i++)
{
oled_write_char(star_background[6][(i + phase) % 21], false);
}
// Line 7
oled_set_cursor(0, 7);
for(int i = 0; i < 21; i++)
{
oled_write_char(star_background[7][(i + phase) % 21], false);
}
}
static void render_logo(uint8_t startX, uint8_t startY)
{
oled_set_cursor(startX, startY);
oled_write_char(0x80, false);
oled_write_char(0x81, false);
oled_write_char(0x82, false);
oled_write_char(0x83, false);
oled_write_char(0x84, false);
oled_set_cursor(startX, startY + 1);
oled_write_char(0xA0, false);
oled_write_char(0xA1, false);
oled_write_char(0xA2, false);
oled_write_char(0xA3, false);
oled_write_char(0xA4, false);
oled_write_char(0xA5, false);
oled_set_cursor(startX, startY + 2);
oled_write_char(0xC0, false);
oled_write_char(0xC1, false);
oled_write_char(0xC2, false);
oled_write_char(0xC3, false);
oled_write_char(0xC4, false);
} }
oled_rotation_t oled_init_user(oled_rotation_t rotation) { return OLED_ROTATION_180; } oled_rotation_t oled_init_user(oled_rotation_t rotation) { return OLED_ROTATION_180; }
void oled_task_user(void) { void oled_task_user(void)
uint8_t light_level = rgblight_get_val(); {
light_level = (uint8_t)(100.0 * ((float)light_level/(float)RGBLIGHT_LIMIT_VAL)); // Convert to % // Playing the animation
char c_light_level[3]; if((timer_elapsed32(anim_timer) > ANIM_FRAME_DURATION) && (splash_dur_counter < SPLASH_DUR))
itoa(light_level, c_light_level, 10); {
anim_timer = timer_read32(); // read the current timer value
current_frame = (current_frame + 1) % ANIM_FRAMES; // Frame in the exhaust animation
background_frame = (background_frame + 1) % BACKGROUND_FRAMES; // Frame in the star animation
render_logo(); // Render the QMK logo // Move the rocket up and down
oled_write_ln(PSTR(""), false); // Add a newline if((rocket_pos_change / 9) == 0)
// Host Keyboard LED Status {
led_t led_state = host_keyboard_led_state(); rocket_y_position = ROCKET_CENTER_POS;
oled_write(led_state.num_lock ? PSTR(" |NUM|") : PSTR(" | |"), false); }
oled_write(led_state.caps_lock ? PSTR("|CAP|") : PSTR("| |"), false); else if((rocket_pos_change / 9) == 1)
oled_write(led_state.scroll_lock ? PSTR("|SCR| ") : PSTR("| | "), false); {
rocket_y_position = ROCKET_CENTER_POS + 1;
}
else if((rocket_pos_change / 9) == 2)
{
rocket_y_position = ROCKET_CENTER_POS;
}
if((rocket_pos_change / 9) == 3)
{
rocket_y_position = ROCKET_CENTER_POS - 1;
}
oled_write_ln(PSTR(""), false); // Add a newline // Renders the scene piece by piece
oled_write(PSTR(" BKLT: "), false); render_stars(8, background_frame); // Render star background
oled_write(c_light_level, false); render_exhaust(6, rocket_y_position + 1, current_frame); // Render exhaust
oled_write_ln(PSTR("% "), false); render_logo(9, rocket_y_position); // Render the rocket
// Timing for rocket position change
if(rocket_pos_change < 36)
{
rocket_pos_change++;
}
else
{
rocket_pos_change = 0;
}
splash_dur_counter++;
}
else if((splash_dur_counter >= SPLASH_DUR) && (splash_dur_counter != 231)) // Should only run once at end of splash screen duration
{
splash_dur_counter = 231; // Nice known value
oled_clear(); // Clear the screen
}
// After the splash screen
if(splash_dur_counter == 231)
{
uint8_t light_level = rgblight_get_val();
light_level = (uint8_t)(100.0 * ((float)light_level/(float)RGBLIGHT_LIMIT_VAL)); // Convert to %
char c_light_level[3];
itoa(light_level, c_light_level, 10);
// Display lock LED statuses
led_t led_state = host_keyboard_led_state();
if(led_state.num_lock)
{
oled_write(PSTR(" |"), false);
oled_write(PSTR("NUM"), true);
oled_write(PSTR("|"), false);
}
else
{
oled_write(PSTR(" |NUM|"), false);
}
if(led_state.caps_lock)
{
oled_write(PSTR("|"), false);
oled_write(PSTR("CAP"), true);
oled_write(PSTR("|"), false);
}
else
{
oled_write(PSTR("|CAP|"), false);
}
if(led_state.scroll_lock)
{
oled_write(PSTR("|"), false);
oled_write(PSTR("SCR"), true);
oled_write(PSTR("| "), false);
}
else
{
oled_write(PSTR("|SCR| "), false);
}
// Print the examine info
if(examine_engaged == true)
{
oled_set_cursor(0, 2);
oled_write_ln(PSTR(" Keycode: "), false);
oled_write_ln_centered(lastKeycodeString, false);
}
else
{
oled_set_cursor(0, 2);
oled_write_ln(PSTR(" "), false);
oled_write_ln(PSTR(" "), false);
}
// Print the backlight % bottom right
oled_set_cursor(11, 7);
oled_write(PSTR("BKLT: "), false);
oled_write(c_light_level, false);
oled_write(PSTR("%"), false);
// Print the layer number in bottom left
oled_set_cursor(0, 7);
oled_write(PSTR("L: "), false);
switch (get_highest_layer(layer_state))
{
case 0:
oled_write(PSTR("0"), false);
break;
case 1:
oled_write(PSTR("1"), false);
break;
case 2:
oled_write(PSTR("2"), false);
break;
case 3:
oled_write(PSTR("3"), false);
break;
default:
oled_write(PSTR("Und"), false);
break;
}
}
}
// Process the extra/extended keycode functionality
bool process_record_user(uint16_t keycode, keyrecord_t *record)
{
bool ret = true; // True will allow QMK to process the key as usual after the function runs, false skips QMK processing after this function runs
switch (keycode)
{
case KC_EXAM:
if(record->event.pressed) // On pressed, flip bool examine_engaged
{
if(examine_engaged == false)
{
examine_engaged = true;
}
else
{
examine_engaged = false;
}
ret = false;
}
else // On release do nothing
{
ret = false;
}
break;
default: // For any key other than EX, simply let QMK process after saving away what it was
memset(lastKeycodeString, 0, sizeof(lastKeycodeString));
memcpy(lastKeycodeString, translate_keycode_to_string(keycode), sizeof(((lookup_table_t *)0)->key_string));
ret = true;
break;
}
return ret;
} }
#endif #endif

View File

@ -12,29 +12,41 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include QMK_KEYBOARD_H #include QMK_KEYBOARD_H
#include "keycode_lookup.h"
#include <string.h>
#ifdef CONSOLE_ENABLE
#include "print.h"
#endif
// Each layer gets a name for readability, which is then used in the keymap matrix below. // Each layer gets a name for readability, which is then used in the keymap matrix below.
// The underscores don't mean anything - you can have a layer called STUFF or any other name. // The underscores don't mean anything - you can have a layer called STUFF or any other name.
// Layer names don't all need to be of the same length, obviously, and you can also skip them // Layer names don't all need to be of the same length, obviously, and you can also skip them
// entirely and just use numbers. // entirely and just use numbers.
#define _BASE 0 #define _BASE 0
#define _SPEC 1 // Special layer
// Use the following format to create custom key codes to make macros out of and such // Use the following format to create custom key codes to make macros out of and such
/*
enum custom_keycodes { enum custom_keycodes {
FOO = SAFE_RANGE, KC_EXAM = SAFE_RANGE // "Examine" key code to show the keycode of a key pressed afterwards on the OLED
}; };
*/
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_BASE] = LAYOUT_default( [_BASE] = LAYOUT_default(
RGB_MODE_FORWARD, KC_NUMLOCK, RGB_MODE_FORWARD, KC_NUMLOCK,
KC_KP_7, KC_KP_8, KC_KP_9, KC_DELETE, KC_KP_7, KC_KP_8, KC_KP_9, KC_DELETE,
KC_KP_4, KC_KP_5, KC_KP_6, KC_END, KC_KP_4, KC_KP_5, KC_KP_6, KC_END,
KC_KP_1, KC_KP_2, KC_KP_3, KC_AUDIO_VOL_UP, KC_KP_1, KC_KP_2, KC_KP_3, KC_F13,
KC_KP_0, RGB_TOG, KC_AUDIO_MUTE, KC_AUDIO_VOL_DOWN KC_KP_0, MO(1), KC_KP_DOT, KC_KP_ENTER
) ),
[_SPEC] = LAYOUT_default(
RGB_MODE_REVERSE, KC_AUDIO_MUTE,
KC_NO, KC_NO, KC_NO, KC_EXAM,
KC_NO, KC_NO, KC_NO, KC_NO,
RESET, RGB_TOG, RGB_SPI, RGB_SPD,
KC_NO, _______, KC_NO, KC_NO
)
}; };
bool encoder_update_user(uint8_t index, bool clockwise){ bool encoder_update_user(uint8_t index, bool clockwise){
@ -56,35 +68,321 @@ bool encoder_update_user(uint8_t index, bool clockwise){
#ifdef OLED_ENABLE #ifdef OLED_ENABLE
static void render_logo(void) { #define ANIM_FRAMES 3
static const char PROGMEM qmk_logo[] = { #define ANIM_FRAME_DURATION 110 // Number of milliseconds per frame (no faster than 110ms, last line struggles)
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, #define BACKGROUND_FRAMES 21
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, #define ROCKET_CENTER_POS 3
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0x00 #define SPLASH_DUR 100 // Measured in frames, see above for frame length (note, 231 is used as a key value later on, CTRL+F for uses of this to make sure everything is good)
};
oled_write(qmk_logo, false); uint32_t anim_timer = 0;
uint8_t current_frame = 0;
uint8_t rocket_y_position = 3;
uint8_t rocket_pos_change = 0;
uint8_t background_frame = 0;
uint8_t splash_dur_counter = 0;
bool examine_engaged = false;
uint16_t examined_keycode = KC_NO;
char lastKeycodeString[32] = { 0 };
const char star_background [8] [21] =
{
{0x88, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x00, 0x93},
{0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8E, 0x00, 0x00},
{0x00, 0x8F, 0x00, 0x00, 0x8A, 0x00, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x8B, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x00, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00},
{0x8D, 0x00, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x00, 0x00, 0x00, 0x00, 0x8F, 0x8B, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x8A, 0x00, 0x00, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x00, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x8F, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x8C, 0x00, 0x00, 0x8F, 0x00, 0x89, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x8F},
{0x00, 0x8B, 0x00, 0x00, 0x91, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x8E, 0x00, 0x00, 0x90, 0x00, 0x00, 0x8C, 0x00, 0x00},
};
static void oled_write_ln_centered(const char * data, bool inverted)
{
if(strlen(data) >= 21) // If more than 1 line of text is passed in, return without doing anything
{
return;
}
// Character buffer to build up the string in
char line_buf[21];
// Amount to offset string from left side
uint8_t offset = (21 - strlen(data))/2;
// Formatted string centering... look, it works, don't ask how...
snprintf(line_buf, 21, "%*s%s%*s\0", offset, "", data, offset, ""); // Centers data within 21 character buffer with null termination
oled_write_ln(line_buf, inverted);
}
// Prints the exhaust characters in an order determined by the phase for animation purposes
// startX - The x axis starting point in characters for the exhaust (3 behind the rocket)
// startY - The y axis starting point in characters for the exhaust (middle of the rocket)
// phase - The "phase" of the animation, no real rhyme or reason to the exact number, but each frame move +1 to make the animation work
static void render_exhaust(uint8_t startX, uint8_t startY, uint8_t phase)
{
oled_set_cursor(startX, startY);
oled_write_char(0x85 + (phase % 3), false);
phase++;
oled_write_char(0x85 + (phase % 3), false);
phase++;
oled_write_char(0x85 + (phase % 3), false);
}
// Renders the "stars" behind the rocket
// startY - The starting Y location (in characters) of the rocket so that stars aren't rendered on top of the rocket
static void render_stars(uint8_t startY, uint8_t phase)
{
// Line 0
oled_set_cursor(0, 0);
for(int i = 0; i < 21; i++)
{
oled_write_char(star_background[0][(i + phase) % 21], false);
}
// Line 1
oled_set_cursor(0, 1);
for(int i = 0; i < 21; i++)
{
oled_write_char(star_background[1][(i + phase) % 21], false);
}
// Line 2
oled_set_cursor(0, 2);
for(int i = 0; i < 21; i++)
{
oled_write_char(star_background[2][(i + phase) % 21], false);
}
// Line 3
oled_set_cursor(0, 3);
for(int i = 0; i < 21; i++)
{
oled_write_char(star_background[3][(i + phase) % 21], false);
}
// Line 4
oled_set_cursor(0, 4);
for(int i = 0; i < 21; i++)
{
oled_write_char(star_background[4][(i + phase) % 21], false);
}
// Line 5
oled_set_cursor(0, 5);
for(int i = 0; i < 21; i++)
{
oled_write_char(star_background[5][(i + phase) % 21], false);
}
// Line 6
oled_set_cursor(0, 6);
for(int i = 0; i < 21; i++)
{
oled_write_char(star_background[6][(i + phase) % 21], false);
}
// Line 7
oled_set_cursor(0, 7);
for(int i = 0; i < 21; i++)
{
oled_write_char(star_background[7][(i + phase) % 21], false);
}
}
static void render_logo(uint8_t startX, uint8_t startY)
{
oled_set_cursor(startX, startY);
oled_write_char(0x80, false);
oled_write_char(0x81, false);
oled_write_char(0x82, false);
oled_write_char(0x83, false);
oled_write_char(0x84, false);
oled_set_cursor(startX, startY + 1);
oled_write_char(0xA0, false);
oled_write_char(0xA1, false);
oled_write_char(0xA2, false);
oled_write_char(0xA3, false);
oled_write_char(0xA4, false);
oled_write_char(0xA5, false);
oled_set_cursor(startX, startY + 2);
oled_write_char(0xC0, false);
oled_write_char(0xC1, false);
oled_write_char(0xC2, false);
oled_write_char(0xC3, false);
oled_write_char(0xC4, false);
} }
oled_rotation_t oled_init_user(oled_rotation_t rotation) { return OLED_ROTATION_180; } oled_rotation_t oled_init_user(oled_rotation_t rotation) { return OLED_ROTATION_180; }
void oled_task_user(void) { void oled_task_user(void)
uint8_t light_level = rgblight_get_val(); {
light_level = (uint8_t)(100.0 * ((float)light_level/(float)RGBLIGHT_LIMIT_VAL)); // Convert to % // Playing the animation
char c_light_level[3]; if((timer_elapsed32(anim_timer) > ANIM_FRAME_DURATION) && (splash_dur_counter < SPLASH_DUR))
itoa(light_level, c_light_level, 10); {
anim_timer = timer_read32(); // read the current timer value
current_frame = (current_frame + 1) % ANIM_FRAMES; // Frame in the exhaust animation
background_frame = (background_frame + 1) % BACKGROUND_FRAMES; // Frame in the star animation
render_logo(); // Render the QMK logo // Move the rocket up and down
oled_write_ln(PSTR(""), false); // Add a newline if((rocket_pos_change / 9) == 0)
// Host Keyboard LED Status {
led_t led_state = host_keyboard_led_state(); rocket_y_position = ROCKET_CENTER_POS;
oled_write(led_state.num_lock ? PSTR(" |NUM|") : PSTR(" | |"), false); }
oled_write(led_state.caps_lock ? PSTR("|CAP|") : PSTR("| |"), false); else if((rocket_pos_change / 9) == 1)
oled_write(led_state.scroll_lock ? PSTR("|SCR| ") : PSTR("| | "), false); {
rocket_y_position = ROCKET_CENTER_POS + 1;
}
else if((rocket_pos_change / 9) == 2)
{
rocket_y_position = ROCKET_CENTER_POS;
}
if((rocket_pos_change / 9) == 3)
{
rocket_y_position = ROCKET_CENTER_POS - 1;
}
oled_write_ln(PSTR(""), false); // Add a newline // Renders the scene piece by piece
oled_write(PSTR(" BKLT: "), false); render_stars(8, background_frame); // Render star background
oled_write(c_light_level, false); render_exhaust(6, rocket_y_position + 1, current_frame); // Render exhaust
oled_write_ln(PSTR("% "), false); render_logo(9, rocket_y_position); // Render the rocket
// Timing for rocket position change
if(rocket_pos_change < 36)
{
rocket_pos_change++;
}
else
{
rocket_pos_change = 0;
}
splash_dur_counter++;
}
else if((splash_dur_counter >= SPLASH_DUR) && (splash_dur_counter != 231)) // Should only run once at end of splash screen duration
{
splash_dur_counter = 231; // Nice known value
oled_clear(); // Clear the screen
}
// After the splash screen
if(splash_dur_counter == 231)
{
uint8_t light_level = rgblight_get_val();
light_level = (uint8_t)(100.0 * ((float)light_level/(float)RGBLIGHT_LIMIT_VAL)); // Convert to %
char c_light_level[3];
itoa(light_level, c_light_level, 10);
// Display lock LED statuses
led_t led_state = host_keyboard_led_state();
if(led_state.num_lock)
{
oled_write(PSTR(" |"), false);
oled_write(PSTR("NUM"), true);
oled_write(PSTR("|"), false);
}
else
{
oled_write(PSTR(" |NUM|"), false);
}
if(led_state.caps_lock)
{
oled_write(PSTR("|"), false);
oled_write(PSTR("CAP"), true);
oled_write(PSTR("|"), false);
}
else
{
oled_write(PSTR("|CAP|"), false);
}
if(led_state.scroll_lock)
{
oled_write(PSTR("|"), false);
oled_write(PSTR("SCR"), true);
oled_write(PSTR("| "), false);
}
else
{
oled_write(PSTR("|SCR| "), false);
}
// Print the examine info
if(examine_engaged == true)
{
oled_set_cursor(0, 2);
oled_write_ln(PSTR(" Keycode: "), false);
oled_write_ln_centered(lastKeycodeString, false);
}
else
{
oled_set_cursor(0, 2);
oled_write_ln(PSTR(" "), false);
oled_write_ln(PSTR(" "), false);
}
// Print the backlight % bottom right
oled_set_cursor(11, 7);
oled_write(PSTR("BKLT: "), false);
oled_write(c_light_level, false);
oled_write(PSTR("%"), false);
// Print the layer number in bottom left
oled_set_cursor(0, 7);
oled_write(PSTR("L: "), false);
switch (get_highest_layer(layer_state))
{
case 0:
oled_write(PSTR("0"), false);
break;
case 1:
oled_write(PSTR("1"), false);
break;
case 2:
oled_write(PSTR("2"), false);
break;
case 3:
oled_write(PSTR("3"), false);
break;
default:
oled_write(PSTR("Und"), false);
break;
}
}
}
// Process the extra/extended keycode functionality
bool process_record_user(uint16_t keycode, keyrecord_t *record)
{
bool ret = true; // True will allow QMK to process the key as usual after the function runs, false skips QMK processing after this function runs
switch (keycode)
{
case KC_EXAM:
if(record->event.pressed) // On pressed, flip bool examine_engaged
{
if(examine_engaged == false)
{
examine_engaged = true;
}
else
{
examine_engaged = false;
}
ret = false;
}
else // On release do nothing
{
ret = false;
}
break;
default: // For any key other than EX, simply let QMK process after saving away what it was
memset(lastKeycodeString, 0, sizeof(lastKeycodeString));
memcpy(lastKeycodeString, translate_keycode_to_string(keycode), sizeof(((lookup_table_t *)0)->key_string));
ret = true;
break;
}
return ret;
} }
#endif #endif

View File

@ -2,7 +2,18 @@
MCU = STM32F103 MCU = STM32F103
# Bootloader selection # Bootloader selection
BOOTLOADER = stm32duino # BOOTLOADER = stm32duino
# Custom loader configuration
MCU_LDSCRIPT = STM32F103xB_stm32duino_bootloader
OPT_DEFS += -DBOOTLOADER_STM32DUINO
BOARD = STM32_F103_STM32DUINO
STM32_BOOTLOADER_ADDRESS = 0x80000000
DFU_ARGS = -d 1EAF:0003 -a 2 -R
DFU_SUFFIX_ARGS = -v 1EAF -p 0003
# Extra include
SRC += keycode_lookup.c
# Build Options # Build Options
# change yes to no to disable # change yes to no to disable
@ -24,5 +35,9 @@ OLED_ENABLE = yes
OLED_DRIVER = SSD1306 OLED_DRIVER = SSD1306
ENCODER_ENABLE = yes ENCODER_ENABLE = yes
RAW_ENABLE = yes # Enables HID RAW communication between the board and the PC
# Enter lower-power sleep mode when on the ChibiOS idle thread # Enter lower-power sleep mode when on the ChibiOS idle thread
OPT_DEFS += -DCORTEX_ENABLE_WFI_IDLE=TRUE OPT_DEFS += -DCORTEX_ENABLE_WFI_IDLE=TRUE
LTO_ENABLE = yes