mirror of
https://github.com/qmk/qmk_firmware.git
synced 2024-12-12 04:40:58 +00:00
127 lines
3.6 KiB
Python
127 lines
3.6 KiB
Python
from milc import cli
|
|
|
|
from qmk.path import normpath
|
|
from qmk.commands import dump_lines
|
|
from qmk.lighting import load_lighting_spec
|
|
from qmk.constants import GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE
|
|
|
|
PREFIX_MAP = {
|
|
'rgblight': {
|
|
'ifdef': 'RGBLIGHT_EFFECT',
|
|
'def': 'RGBLIGHT_MODE',
|
|
},
|
|
'rgb_matrix': {
|
|
'ifdef': 'ENABLE_RGB_MATRIX',
|
|
'def': 'RGB_MATRIX',
|
|
},
|
|
'led_matrix': {
|
|
'ifdef': 'ENABLE_LED_MATRIX',
|
|
'def': 'LED_MATRIX',
|
|
},
|
|
}
|
|
|
|
|
|
def _always_enabled(id):
|
|
"""Assumption that first effect is always enabled
|
|
"""
|
|
return id == '0x00'
|
|
|
|
|
|
def _wrap_ifdef(line, define):
|
|
return f'''
|
|
#ifdef {define}
|
|
{line}
|
|
#endif'''
|
|
|
|
|
|
def _append_lighting_map(lines, feature, spec):
|
|
"""Translate effect to 'constant id'->'firmware id' lookup table
|
|
"""
|
|
groups = spec.get('groups', {})
|
|
ifdef_prefix = PREFIX_MAP[feature]['ifdef']
|
|
def_prefix = PREFIX_MAP[feature]['def']
|
|
|
|
lines.append(f'static const uint8_t {feature}_effect_map[][2] PROGMEM = {{')
|
|
for id, obj in spec.get('effects', {}).items():
|
|
define = obj['define']
|
|
offset = f' + {obj["offset"]}' if obj['offset'] else ''
|
|
|
|
line = f'{{ {id}, {def_prefix}_{define}{offset}}},'
|
|
|
|
if not _always_enabled(id):
|
|
line = _wrap_ifdef(line, f'{ifdef_prefix}_{define}')
|
|
|
|
group = groups.get(obj.get('group', None), {}).get('define', None)
|
|
if group:
|
|
line = _wrap_ifdef(line, group)
|
|
|
|
lines.append(line)
|
|
|
|
lines.append('};')
|
|
|
|
# add helper funcs
|
|
lines.append(
|
|
f'''
|
|
uint8_t {feature}_effect_to_id(uint8_t val) {{
|
|
for(uint8_t i = 0; i < ARRAY_SIZE({feature}_effect_map); i++) {{
|
|
if (pgm_read_byte(&{feature}_effect_map[i][1]) == val)
|
|
return pgm_read_byte(&{feature}_effect_map[i][0]);
|
|
}}
|
|
return 0xFF;
|
|
}}
|
|
|
|
uint8_t {feature}_id_to_effect(uint8_t val) {{
|
|
for(uint8_t i = 0; i < ARRAY_SIZE({feature}_effect_map); i++) {{
|
|
if (pgm_read_byte(&{feature}_effect_map[i][0]) == val)
|
|
return pgm_read_byte(&{feature}_effect_map[i][1]);
|
|
}}
|
|
return 0xFF;
|
|
}}'''
|
|
)
|
|
|
|
|
|
def _append_lighting_bit_field(lines, feature, spec):
|
|
"""Translate effect to bit of bit-field
|
|
"""
|
|
groups = spec.get('groups', {})
|
|
ifdef_prefix = PREFIX_MAP[feature]['ifdef']
|
|
|
|
lines.append(f'enum {{ ENABLED_{feature.upper()}_EFFECTS = 0')
|
|
for id, obj in spec.get('effects', {}).items():
|
|
define = obj['define']
|
|
|
|
line = f' | (1ULL << {id})'
|
|
|
|
if not _always_enabled(id):
|
|
line = _wrap_ifdef(line, f'{ifdef_prefix}_{define}')
|
|
|
|
group = groups.get(obj.get('group', None), {}).get('define', None)
|
|
if group:
|
|
line = _wrap_ifdef(line, group)
|
|
|
|
lines.append(line)
|
|
|
|
lines.append('};')
|
|
|
|
|
|
def _append_lighting_mapping(lines, feature):
|
|
"""Generate lookup table and bit-field of effect
|
|
"""
|
|
spec = load_lighting_spec(feature)
|
|
|
|
_append_lighting_bit_field(lines, feature, spec)
|
|
_append_lighting_map(lines, feature, spec)
|
|
|
|
|
|
@cli.argument('-o', '--output', arg_only=True, type=normpath, help='File to write to')
|
|
@cli.argument('-q', '--quiet', arg_only=True, action='store_true', help='Quiet mode, only output error messages')
|
|
@cli.argument('-f', '--feature', required=True, help='Feature to generate map', choices=PREFIX_MAP.keys())
|
|
@cli.subcommand('Generates effect header.')
|
|
def generate_lighting_map(cli):
|
|
# Preamble
|
|
lines = [GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE, '#pragma once', '// clang-format off']
|
|
|
|
_append_lighting_mapping(lines, cli.args.feature)
|
|
|
|
dump_lines(cli.args.output, lines, cli.args.quiet)
|