generate_lighting.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. from milc import cli
  2. from qmk.path import normpath
  3. from qmk.commands import dump_lines
  4. from qmk.xap.common import load_lighting_spec
  5. from qmk.constants import GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE
  6. PREFIX_MAP = {
  7. 'rgblight': {
  8. 'ifdef': 'RGBLIGHT_EFFECT',
  9. 'def': 'RGBLIGHT_MODE',
  10. },
  11. 'rgb_matrix': {
  12. 'ifdef': 'ENABLE_RGB_MATRIX',
  13. 'def': 'RGB_MATRIX',
  14. },
  15. 'led_matrix': {
  16. 'ifdef': 'ENABLE_LED_MATRIX',
  17. 'def': 'LED_MATRIX',
  18. },
  19. }
  20. def _append_lighting_map(lines, feature, spec):
  21. """TODO:
  22. """
  23. groups = spec.get('groups', {})
  24. ifdef_prefix = PREFIX_MAP[feature]['ifdef']
  25. def_prefix = PREFIX_MAP[feature]['def']
  26. lines.append(f'static uint8_t {feature}_effect_map[][2] = {{')
  27. for id, obj in spec.get('effects', {}).items():
  28. define = obj['define']
  29. offset = f' + {obj["offset"]}' if obj['offset'] else ''
  30. line = f'''
  31. #ifdef {ifdef_prefix}_{define}
  32. {{ {id}, {def_prefix}_{define}{offset}}},
  33. #endif'''
  34. group = groups.get(obj.get('group', None), {}).get('define', None)
  35. if group:
  36. line = f'''
  37. #ifdef {group}
  38. {line}
  39. #endif'''
  40. lines.append(line)
  41. lines.append('};')
  42. # add helper funcs
  43. lines.append(
  44. f'''
  45. uint8_t {feature}2xap(uint8_t val) {{
  46. for(uint8_t i = 0; i < ARRAY_SIZE({feature}_effect_map); i++) {{
  47. if ({feature}_effect_map[i][1] == val)
  48. return {feature}_effect_map[i][0];
  49. }}
  50. return 0xFF;
  51. }}
  52. uint8_t xap2{feature}(uint8_t val) {{
  53. for(uint8_t i = 0; i < ARRAY_SIZE({feature}_effect_map); i++) {{
  54. if ({feature}_effect_map[i][0] == val)
  55. return {feature}_effect_map[i][1];
  56. }}
  57. return 0xFF;
  58. }}'''
  59. )
  60. def _append_lighting_bitmask(lines, feature, spec):
  61. """TODO:
  62. """
  63. groups = spec.get('groups', {})
  64. ifdef_prefix = PREFIX_MAP[feature]['ifdef']
  65. lines.append(f'enum {{ ENABLED_{feature.upper()}_EFFECTS = 0')
  66. for id, obj in spec.get('effects', {}).items():
  67. define = obj['define']
  68. line = f'''
  69. #ifdef {ifdef_prefix}_{define}
  70. | (1ULL << {id})
  71. #endif'''
  72. group = groups.get(obj.get('group', None), {}).get('define', None)
  73. if group:
  74. line = f'''
  75. #ifdef {group}
  76. {line}
  77. #endif'''
  78. lines.append(line)
  79. lines.append('};')
  80. def _append_lighting_mapping(lines):
  81. """TODO:
  82. """
  83. # TODO: remove bodge for always enabled effects
  84. lines.append('''
  85. #define RGBLIGHT_EFFECT_STATIC_LIGHT
  86. #define ENABLE_RGB_MATRIX_SOLID_COLOR
  87. #define ENABLE_LED_MATRIX_SOLID
  88. ''')
  89. for feature in PREFIX_MAP.keys():
  90. spec = load_lighting_spec(feature)
  91. lines.append(f'#ifdef {feature.upper()}_ENABLE')
  92. _append_lighting_map(lines, feature, spec)
  93. _append_lighting_bitmask(lines, feature, spec)
  94. lines.append(f'#endif //{feature.upper()}_ENABLE')
  95. @cli.argument('-o', '--output', arg_only=True, type=normpath, help='File to write to')
  96. @cli.argument('-q', '--quiet', arg_only=True, action='store_true', help="Quiet mode, only output error messages")
  97. @cli.subcommand('Generates effect header.')
  98. def xap_generate_lighting_map(cli):
  99. # Preamble
  100. lines = [GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE, '#pragma once', '// clang-format off']
  101. _append_lighting_mapping(lines)
  102. dump_lines(cli.args.output, lines, cli.args.quiet)