CLI-ify rgblight_breathing_table_calc.c (#11174)

Co-authored-by: Takeshi ISHII <2170248+mtei@users.noreply.github.com>
Co-authored-by: Zach White <skullydazed@drpepper.org>
This commit is contained in:
Ryan 2020-12-16 14:24:42 +11:00 committed by GitHub
parent 3925ff5342
commit 37fb14f1b5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 203 additions and 506 deletions

View file

@ -296,6 +296,16 @@ This command allows you to generate QMK documentation locally. It can be uses fo
qmk generate-docs qmk generate-docs
``` ```
## `qmk generate-rgb-breathe-table`
This command generates a lookup table (LUT) header file for the [RGB Lighting](feature_rgblight.md) feature's breathing animation. Place this file in your keyboard or keymap directory as `rgblight_breathe_table.h` to override the default LUT in `quantum/`.
**Usage**:
```
qmk generate-rgb-breathe-table [-q] [-o OUTPUT] [-m MAX] [-c CENTER]
```
## `qmk kle2json` ## `qmk kle2json`
This command allows you to convert from raw KLE data to QMK Configurator JSON. It accepts either an absolute file path, or a file name in the current directory. By default it will not overwrite `info.json` if it is already present. Use the `-f` or `--force` flag to overwrite. This command allows you to convert from raw KLE data to QMK Configurator JSON. It accepts either an absolute file path, or a file name in the current directory. By default it will not overwrite `info.json` if it is already present. Use the `-f` or `--force` flag to overwrite.

View file

@ -1,2 +1,3 @@
from . import api from . import api
from . import docs from . import docs
from . import rgb_breathe_table

View file

@ -0,0 +1,79 @@
"""Generate rgblight_breathe_table.h
"""
import math
from argparse import ArgumentTypeError
from milc import cli
import qmk.path
def breathing_center(value):
value = float(value)
if value >= 1 and value <= 2.7:
return value
else:
raise ArgumentTypeError('Breathing center must be between 1 and 2.7')
def breathing_max(value):
value = int(value)
if value in range(0, 256):
return value
else:
raise ArgumentTypeError('Breathing max must be between 0 and 255')
@cli.argument('-c', '--center', arg_only=True, type=breathing_center, default=1.85, help='The breathing center value, from 1 to 2.7. Default: 1.85')
@cli.argument('-m', '--max', arg_only=True, type=breathing_max, default=255, help='The breathing maximum value, from 0 to 255. Default: 255')
@cli.argument('-o', '--output', arg_only=True, type=qmk.path.normpath, help='File to write to')
@cli.argument('-q', '--quiet', arg_only=True, action='store_true', help='Quiet mode, only output error messages')
@cli.subcommand('Generates an RGB Light breathing table header.')
def generate_rgb_breathe_table(cli):
"""Generate a rgblight_breathe_table.h file containing a breathing LUT for RGB Lighting (Underglow) feature.
"""
breathe_values = [0] * 256
for pos in range(0, 256):
breathe_values[pos] = (int)((math.exp(math.sin((pos/255) * math.pi)) - cli.args.center / math.e) * (cli.args.max / (math.e - 1 / math.e))) # noqa: yapf insists there be no whitespace around /
values_template = ''
for s in range(0, 3):
step = 1 << s
values_template += '#if RGBLIGHT_BREATHE_TABLE_SIZE == {}\n'.format(256 >> s)
for pos in range(0, 256, step):
values_template += ' ' if pos % 8 == 0 else ''
values_template += '0x{:02X}'.format(breathe_values[pos])
values_template += ',' if (pos + step) < 256 else ''
values_template += '\n' if (pos+step) % 8 == 0 else ' ' # noqa: yapf insists there be no whitespace around +
values_template += '#endif'
values_template += '\n\n' if s < 2 else ''
table_template = '''#pragma once
#define RGBLIGHT_EFFECT_BREATHE_TABLE
// clang-format off
// Breathing center: {0:.2f}
// Breathing max: {1:d}
const uint8_t PROGMEM rgblight_effect_breathe_table[] = {{
{2}
}};
static const int table_scale = 256 / sizeof(rgblight_effect_breathe_table);
'''.format(cli.args.center, cli.args.max, values_template)
if cli.args.output:
cli.args.output.parent.mkdir(parents=True, exist_ok=True)
if cli.args.output.exists():
cli.args.output.replace(cli.args.output.name + '.bak')
cli.args.output.write_text(table_template)
if not cli.args.quiet:
cli.log.info('Wrote header to %s.', cli.args.output)
else:
print(table_template)

View file

@ -190,3 +190,10 @@ def test_clean():
result = check_subcommand('clean', '-a') result = check_subcommand('clean', '-a')
check_returncode(result) check_returncode(result)
assert result.stdout.count('done') == 2 assert result.stdout.count('done') == 2
def test_generate_rgb_breathe_table():
result = check_subcommand("generate-rgb-breathe-table", "-c", "1.2", "-m", "127")
check_returncode(result)
assert 'Breathing center: 1.2' in result.stdout
assert 'Breathing max: 127' in result.stdout

View file

@ -1,468 +1,117 @@
#ifndef RGBLIGHT_EFFECT_BREATHE_TABLE #pragma once
#define RGBLIGHT_EFFECT_BREATHE_TABLE #define RGBLIGHT_EFFECT_BREATHE_TABLE
const uint8_t rgblight_effect_breathe_table[] PROGMEM = { // clang-format off
/* #define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85 */
/* #define RGBLIGHT_EFFECT_BREATHE_MAX 255 */
// Breathing center: 1.85
// Breathing max: 255
const uint8_t PROGMEM rgblight_effect_breathe_table[] = {
#if RGBLIGHT_BREATHE_TABLE_SIZE == 256 #if RGBLIGHT_BREATHE_TABLE_SIZE == 256
0x22, 0x22, 0x23, 0x25, 0x26, 0x28, 0x29, 0x2A, 0x2C,
0x23, 0x2D, 0x2F, 0x30, 0x32, 0x33, 0x35, 0x36, 0x38,
0x25, 0x3A, 0x3B, 0x3D, 0x3E, 0x40, 0x42, 0x43, 0x45,
0x26, 0x47, 0x49, 0x4A, 0x4C, 0x4E, 0x50, 0x51, 0x53,
0x28, 0x55, 0x57, 0x59, 0x5A, 0x5C, 0x5E, 0x60, 0x62,
0x29, 0x64, 0x66, 0x68, 0x69, 0x6B, 0x6D, 0x6F, 0x71,
0x2a, 0x73, 0x75, 0x77, 0x79, 0x7B, 0x7D, 0x7F, 0x81,
0x2c, 0x83, 0x85, 0x87, 0x89, 0x8A, 0x8C, 0x8E, 0x90,
0x2d, 0x92, 0x94, 0x96, 0x98, 0x9A, 0x9C, 0x9E, 0x9F,
0x2f, 0xA1, 0xA3, 0xA5, 0xA7, 0xA8, 0xAA, 0xAC, 0xAE,
0x30, 0xAF, 0xB1, 0xB3, 0xB4, 0xB6, 0xB8, 0xB9, 0xBB,
0x32, 0xBC, 0xBE, 0xBF, 0xC1, 0xC2, 0xC3, 0xC5, 0xC6,
0x33, 0xC7, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xD0,
0x35, 0xD1, 0xD2, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
0x36, 0xD7, 0xD8, 0xD9, 0xD9, 0xDA, 0xDA, 0xDB, 0xDB,
0x38, 0xDB, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDD, 0xDD,
0x3a, 0xDD, 0xDD, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDB,
0x3b, 0xDB, 0xDB, 0xDA, 0xDA, 0xD9, 0xD9, 0xD8, 0xD7,
0x3d, 0xD7, 0xD6, 0xD5, 0xD4, 0xD3, 0xD2, 0xD2, 0xD1,
0x3e, 0xD0, 0xCE, 0xCD, 0xCC, 0xCB, 0xCA, 0xC9, 0xC7,
0x40, 0xC6, 0xC5, 0xC3, 0xC2, 0xC1, 0xBF, 0xBE, 0xBC,
0x42, 0xBB, 0xB9, 0xB8, 0xB6, 0xB4, 0xB3, 0xB1, 0xAF,
0x43, 0xAE, 0xAC, 0xAA, 0xA8, 0xA7, 0xA5, 0xA3, 0xA1,
0x45, 0x9F, 0x9E, 0x9C, 0x9A, 0x98, 0x96, 0x94, 0x92,
0x47, 0x90, 0x8E, 0x8C, 0x8A, 0x89, 0x87, 0x85, 0x83,
0x49, 0x81, 0x7F, 0x7D, 0x7B, 0x79, 0x77, 0x75, 0x73,
0x4a, 0x71, 0x6F, 0x6D, 0x6B, 0x69, 0x68, 0x66, 0x64,
0x4c, 0x62, 0x60, 0x5E, 0x5C, 0x5A, 0x59, 0x57, 0x55,
0x4e, 0x53, 0x51, 0x50, 0x4E, 0x4C, 0x4A, 0x49, 0x47,
0x50, 0x45, 0x43, 0x42, 0x40, 0x3E, 0x3D, 0x3B, 0x3A,
0x51, 0x38, 0x36, 0x35, 0x33, 0x32, 0x30, 0x2F, 0x2D,
0x53, 0x2C, 0x2A, 0x29, 0x28, 0x26, 0x25, 0x23, 0x22
0x55, #endif
0x57,
0x59,
0x5a,
0x5c,
0x5e,
0x60,
0x62,
0x64,
0x66,
0x68,
0x69,
0x6b,
0x6d,
0x6f,
0x71,
0x73,
0x75,
0x77,
0x79,
0x7b,
0x7d,
0x7f,
0x81,
0x83,
0x85,
0x87,
0x89,
0x8a,
0x8c,
0x8e,
0x90,
0x92,
0x94,
0x96,
0x98,
0x9a,
0x9c,
0x9e,
0x9f,
0xa1,
0xa3,
0xa5,
0xa7,
0xa8,
0xaa,
0xac,
0xae,
0xaf,
0xb1,
0xb3,
0xb4,
0xb6,
0xb8,
0xb9,
0xbb,
0xbc,
0xbe,
0xbf,
0xc1,
0xc2,
0xc3,
0xc5,
0xc6,
0xc7,
0xc9,
0xca,
0xcb,
0xcc,
0xcd,
0xce,
0xd0,
0xd1,
0xd2,
0xd2,
0xd3,
0xd4,
0xd5,
0xd6,
0xd7,
0xd7,
0xd8,
0xd9,
0xd9,
0xda,
0xda,
0xdb,
0xdb,
0xdb,
0xdc,
0xdc,
0xdc,
0xdc,
0xdc,
0xdd,
0xdd,
0xdd,
0xdd,
0xdc,
0xdc,
0xdc,
0xdc,
0xdc,
0xdb,
0xdb,
0xdb,
0xda,
0xda,
0xd9,
0xd9,
0xd8,
0xd7,
0xd7,
0xd6,
0xd5,
0xd4,
0xd3,
0xd2,
0xd2,
0xd1,
0xd0,
0xce,
0xcd,
0xcc,
0xcb,
0xca,
0xc9,
0xc7,
0xc6,
0xc5,
0xc3,
0xc2,
0xc1,
0xbf,
0xbe,
0xbc,
0xbb,
0xb9,
0xb8,
0xb6,
0xb4,
0xb3,
0xb1,
0xaf,
0xae,
0xac,
0xaa,
0xa8,
0xa7,
0xa5,
0xa3,
0xa1,
0x9f,
0x9e,
0x9c,
0x9a,
0x98,
0x96,
0x94,
0x92,
0x90,
0x8e,
0x8c,
0x8a,
0x89,
0x87,
0x85,
0x83,
0x81,
0x7f,
0x7d,
0x7b,
0x79,
0x77,
0x75,
0x73,
0x71,
0x6f,
0x6d,
0x6b,
0x69,
0x68,
0x66,
0x64,
0x62,
0x60,
0x5e,
0x5c,
0x5a,
0x59,
0x57,
0x55,
0x53,
0x51,
0x50,
0x4e,
0x4c,
0x4a,
0x49,
0x47,
0x45,
0x43,
0x42,
0x40,
0x3e,
0x3d,
0x3b,
0x3a,
0x38,
0x36,
0x35,
0x33,
0x32,
0x30,
0x2f,
0x2d,
0x2c,
0x2a,
0x29,
0x28,
0x26,
0x25,
0x23,
0x22
#endif /* 256 bytes table */
#if RGBLIGHT_BREATHE_TABLE_SIZE == 128 #if RGBLIGHT_BREATHE_TABLE_SIZE == 128
0x22, 0x22, 0x25, 0x28, 0x2A,
0x25, 0x2D, 0x30, 0x33, 0x36,
0x28, 0x3A, 0x3D, 0x40, 0x43,
0x2a, 0x47, 0x4A, 0x4E, 0x51,
0x2d, 0x55, 0x59, 0x5C, 0x60,
0x30, 0x64, 0x68, 0x6B, 0x6F,
0x33, 0x73, 0x77, 0x7B, 0x7F,
0x36, 0x83, 0x87, 0x8A, 0x8E,
0x3a, 0x92, 0x96, 0x9A, 0x9E,
0x3d, 0xA1, 0xA5, 0xA8, 0xAC,
0x40, 0xAF, 0xB3, 0xB6, 0xB9,
0x43, 0xBC, 0xBF, 0xC2, 0xC5,
0x47, 0xC7, 0xCA, 0xCC, 0xCE,
0x4a, 0xD1, 0xD2, 0xD4, 0xD6,
0x4e, 0xD7, 0xD9, 0xDA, 0xDB,
0x51, 0xDB, 0xDC, 0xDC, 0xDD,
0x55, 0xDD, 0xDC, 0xDC, 0xDC,
0x59, 0xDB, 0xDA, 0xD9, 0xD8,
0x5c, 0xD7, 0xD5, 0xD3, 0xD2,
0x60, 0xD0, 0xCD, 0xCB, 0xC9,
0x64, 0xC6, 0xC3, 0xC1, 0xBE,
0x68, 0xBB, 0xB8, 0xB4, 0xB1,
0x6b, 0xAE, 0xAA, 0xA7, 0xA3,
0x6f, 0x9F, 0x9C, 0x98, 0x94,
0x73, 0x90, 0x8C, 0x89, 0x85,
0x77, 0x81, 0x7D, 0x79, 0x75,
0x7b, 0x71, 0x6D, 0x69, 0x66,
0x7f, 0x62, 0x5E, 0x5A, 0x57,
0x83, 0x53, 0x50, 0x4C, 0x49,
0x87, 0x45, 0x42, 0x3E, 0x3B,
0x8a, 0x38, 0x35, 0x32, 0x2F,
0x8e, 0x2C, 0x29, 0x26, 0x23
0x92, #endif
0x96,
0x9a,
0x9e,
0xa1,
0xa5,
0xa8,
0xac,
0xaf,
0xb3,
0xb6,
0xb9,
0xbc,
0xbf,
0xc2,
0xc5,
0xc7,
0xca,
0xcc,
0xce,
0xd1,
0xd2,
0xd4,
0xd6,
0xd7,
0xd9,
0xda,
0xdb,
0xdb,
0xdc,
0xdc,
0xdd,
0xdd,
0xdc,
0xdc,
0xdc,
0xdb,
0xda,
0xd9,
0xd8,
0xd7,
0xd5,
0xd3,
0xd2,
0xd0,
0xcd,
0xcb,
0xc9,
0xc6,
0xc3,
0xc1,
0xbe,
0xbb,
0xb8,
0xb4,
0xb1,
0xae,
0xaa,
0xa7,
0xa3,
0x9f,
0x9c,
0x98,
0x94,
0x90,
0x8c,
0x89,
0x85,
0x81,
0x7d,
0x79,
0x75,
0x71,
0x6d,
0x69,
0x66,
0x62,
0x5e,
0x5a,
0x57,
0x53,
0x50,
0x4c,
0x49,
0x45,
0x42,
0x3e,
0x3b,
0x38,
0x35,
0x32,
0x2f,
0x2c,
0x29,
0x26,
0x23
#endif /* 128 bytes table */
#if RGBLIGHT_BREATHE_TABLE_SIZE == 64 #if RGBLIGHT_BREATHE_TABLE_SIZE == 64
0x22, 0x22, 0x28,
0x28, 0x2D, 0x33,
0x2d, 0x3A, 0x40,
0x33, 0x47, 0x4E,
0x3a, 0x55, 0x5C,
0x40, 0x64, 0x6B,
0x47, 0x73, 0x7B,
0x4e, 0x83, 0x8A,
0x55, 0x92, 0x9A,
0x5c, 0xA1, 0xA8,
0x64, 0xAF, 0xB6,
0x6b, 0xBC, 0xC2,
0x73, 0xC7, 0xCC,
0x7b, 0xD1, 0xD4,
0x83, 0xD7, 0xDA,
0x8a, 0xDB, 0xDC,
0x92, 0xDD, 0xDC,
0x9a, 0xDB, 0xD9,
0xa1, 0xD7, 0xD3,
0xa8, 0xD0, 0xCB,
0xaf, 0xC6, 0xC1,
0xb6, 0xBB, 0xB4,
0xbc, 0xAE, 0xA7,
0xc2, 0x9F, 0x98,
0xc7, 0x90, 0x89,
0xcc, 0x81, 0x79,
0xd1, 0x71, 0x69,
0xd4, 0x62, 0x5A,
0xd7, 0x53, 0x4C,
0xda, 0x45, 0x3E,
0xdb, 0x38, 0x32,
0xdc, 0x2C, 0x26
0xdd, #endif
0xdc,
0xdb,
0xd9,
0xd7,
0xd3,
0xd0,
0xcb,
0xc6,
0xc1,
0xbb,
0xb4,
0xae,
0xa7,
0x9f,
0x98,
0x90,
0x89,
0x81,
0x79,
0x71,
0x69,
0x62,
0x5a,
0x53,
0x4c,
0x45,
0x3e,
0x38,
0x32,
0x2c,
0x26
#endif /* 64 bytes table */
}; };
static const int table_scale = 256 / sizeof(rgblight_effect_breathe_table); static const int table_scale = 256 / sizeof(rgblight_effect_breathe_table);
#endif /* RGBLIGHT_EFFECT_BREATHE_TABLE */

View file

@ -1,49 +0,0 @@
//
// calculate rgblight_effect_breathe_table[] values
//
// this is host program for quantum/rgblight.c:void rgblight_effect_breathing();
//
// example:
// $ edit util/rgblight_breathing_table_calc.c
// $ cc -o util/rgblight_breathing_table_calc util/rgblight_breathing_table_calc.c
// $ ./util/rgblight_breathing_table_calc > keyboards/KEYBOARD_NAME/keymaps/KEYMAP_NAME/rgblight_breathe_table.h
//
#include <stdio.h>
#include <math.h>
#include <stdint.h>
/// customize breeathing effect part ///////////////////////////
#define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85 // 1 to 2.7
#define RGBLIGHT_EFFECT_BREATHE_MAX 255 // 0 to 255
////////////////////////////////////////////////////////////////
int main(void) {
int pos, step;
int table[256];
for (pos = 0; pos < 256; pos ++ ) {
table[pos] = (uint8_t)(
(exp(sin((pos/255.0)*M_PI))- RGBLIGHT_EFFECT_BREATHE_CENTER/M_E)
* (RGBLIGHT_EFFECT_BREATHE_MAX/(M_E-1/M_E))
);
}
printf("#ifndef RGBLIGHT_EFFECT_BREATHE_TABLE\n");
printf("#define RGBLIGHT_EFFECT_BREATHE_TABLE\n\n");
printf("const uint8_t rgblight_effect_breathe_table[] PROGMEM = {\n");
printf(" /* #define RGBLIGHT_EFFECT_BREATHE_CENTER %.2f */\n", RGBLIGHT_EFFECT_BREATHE_CENTER);
printf(" /* #define RGBLIGHT_EFFECT_BREATHE_MAX %d */\n", RGBLIGHT_EFFECT_BREATHE_MAX);
for (int s = 0, step = (1<<s); s < 3 ; s += 1, step = (1<<s) ) {
printf("\n #if RGBLIGHT_BREATHE_TABLE_SIZE == %d\n",
s == 0 ? 256:(s== 1 ? 128: 64));
for (pos = 0; pos < 256; pos += step ) {
printf(" 0x%x%s", table[pos], (pos+step)>=256?"":"," );
if ((pos+step) % 8 == 0)
printf("\n");
}
printf(" #endif /* %d bytes table */\n", s == 0 ? 256:(s== 1 ? 128: 64));
}
printf("};\n");
printf("\nstatic const int table_scale = 256/sizeof(rgblight_effect_breathe_table);\n");
printf("\n#endif /* RGBLIGHT_EFFECT_BREATHE_TABLE */\n");
return 0;
}