From f4171412a676ae3cbd1cd50e859a7deb1a554e15 Mon Sep 17 00:00:00 2001 From: Pascal Getreuer <50221757+getreuer@users.noreply.github.com> Date: Sun, 11 May 2025 16:30:19 -0700 Subject: [PATCH] Enable community modules to define LED matrix and RGB matrix effects. (#25187) Co-authored-by: Joel Challis --- builddefs/build_keyboard.mk | 13 +++- data/constants/module_hooks/1.1.1.hjson | 3 + docs/features/community_modules.md | 8 ++ keyboards/handwired/onekey/info.json | 12 +++ .../cm_flow_led_matrix_effect/config.h | 16 ++++ .../cm_flow_led_matrix_effect/keymap.c | 27 +++++++ .../cm_flow_led_matrix_effect/keymap.json | 3 + .../cm_flow_rgb_matrix_effect/config.h | 16 ++++ .../cm_flow_rgb_matrix_effect/keymap.c | 27 +++++++ .../cm_flow_rgb_matrix_effect/keymap.json | 3 + .../qmk/cli/generate/community_modules.py | 75 ++++++++++--------- .../led_matrix_module.inc | 58 ++++++++++++++ .../flow_led_matrix_effect/qmk_module.json | 8 ++ .../flow_rgb_matrix_effect/qmk_module.json | 8 ++ .../rgb_matrix_module.inc | 64 ++++++++++++++++ quantum/led_matrix/led_matrix.c | 12 +++ quantum/led_matrix/led_matrix.h | 6 ++ quantum/rgb_matrix/rgb_matrix.c | 12 +++ quantum/rgb_matrix/rgb_matrix.h | 6 ++ 19 files changed, 339 insertions(+), 38 deletions(-) create mode 100644 data/constants/module_hooks/1.1.1.hjson create mode 100644 keyboards/handwired/onekey/keymaps/cm_flow_led_matrix_effect/config.h create mode 100644 keyboards/handwired/onekey/keymaps/cm_flow_led_matrix_effect/keymap.c create mode 100644 keyboards/handwired/onekey/keymaps/cm_flow_led_matrix_effect/keymap.json create mode 100644 keyboards/handwired/onekey/keymaps/cm_flow_rgb_matrix_effect/config.h create mode 100644 keyboards/handwired/onekey/keymaps/cm_flow_rgb_matrix_effect/keymap.c create mode 100644 keyboards/handwired/onekey/keymaps/cm_flow_rgb_matrix_effect/keymap.json create mode 100644 modules/qmk/flow_led_matrix_effect/led_matrix_module.inc create mode 100644 modules/qmk/flow_led_matrix_effect/qmk_module.json create mode 100644 modules/qmk/flow_rgb_matrix_effect/qmk_module.json create mode 100644 modules/qmk/flow_rgb_matrix_effect/rgb_matrix_module.inc diff --git a/builddefs/build_keyboard.mk b/builddefs/build_keyboard.mk index 514191b17d4..c2c47c00fb8 100644 --- a/builddefs/build_keyboard.mk +++ b/builddefs/build_keyboard.mk @@ -274,10 +274,19 @@ $(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.h: $(KEYMAP_JSON) $(D $(eval CMD=$(QMK_BIN) generate-community-modules-introspection-h -kb $(KEYBOARD) --quiet --output $(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.h $(KEYMAP_JSON)) @$(BUILD_CMD) +$(INTERMEDIATE_OUTPUT)/src/led_matrix_community_modules.inc: $(KEYMAP_JSON) $(DD_CONFIG_FILES) + @$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD) + $(eval CMD=$(QMK_BIN) generate-led-matrix-community-modules-inc -kb $(KEYBOARD) --quiet --output $(INTERMEDIATE_OUTPUT)/src/led_matrix_community_modules.inc $(KEYMAP_JSON)) + @$(BUILD_CMD) + +$(INTERMEDIATE_OUTPUT)/src/rgb_matrix_community_modules.inc: $(KEYMAP_JSON) $(DD_CONFIG_FILES) + @$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD) + $(eval CMD=$(QMK_BIN) generate-rgb-matrix-community-modules-inc -kb $(KEYBOARD) --quiet --output $(INTERMEDIATE_OUTPUT)/src/rgb_matrix_community_modules.inc $(KEYMAP_JSON)) + @$(BUILD_CMD) + SRC += $(INTERMEDIATE_OUTPUT)/src/community_modules.c -generated-files: $(INTERMEDIATE_OUTPUT)/src/community_modules.h $(INTERMEDIATE_OUTPUT)/src/community_modules.c $(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.c $(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.h - +generated-files: $(INTERMEDIATE_OUTPUT)/src/community_modules.h $(INTERMEDIATE_OUTPUT)/src/community_modules.c $(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.c $(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.h $(INTERMEDIATE_OUTPUT)/src/led_matrix_community_modules.inc $(INTERMEDIATE_OUTPUT)/src/rgb_matrix_community_modules.inc include $(BUILDDEFS_PATH)/converters.mk diff --git a/data/constants/module_hooks/1.1.1.hjson b/data/constants/module_hooks/1.1.1.hjson new file mode 100644 index 00000000000..49f5d0d5d0b --- /dev/null +++ b/data/constants/module_hooks/1.1.1.hjson @@ -0,0 +1,3 @@ +{ + // This version exists to signify addition of LED/RGB effect support. +} diff --git a/docs/features/community_modules.md b/docs/features/community_modules.md index 8dede47bd48..eff07c939a1 100644 --- a/docs/features/community_modules.md +++ b/docs/features/community_modules.md @@ -123,6 +123,14 @@ The source file may provide functions which allow access to information specifie Introspection is a relatively advanced topic within QMK, and existing patterns should be followed. If you need help please [open an issue](https://github.com/qmk/qmk_firmware/issues/new) or [chat with us on Discord](https://discord.gg/qmk). ::: +### `led_matrix_module.inc` + +This file defines LED matrix effects in the same form as used with `led_matrix_kb.inc` and `led_matrix_user.inc` (see [Custom LED Matrix Effects](led_matrix#custom-led-matrix-effects)). Effect mode names are prepended with `LED_MATRIX_COMMUNITY_MODULE_`. + +### `rgb_matrix_module.inc` + +This file defines RGB matrix effects in the same form as used with `rgb_matrix_kb.inc` and `rgb_matrix_user.inc` (see [Custom RGB Matrix Effects](rgb_matrix#custom-rgb-matrix-effects)). Effect mode names are prepended with `RGB_MATRIX_COMMUNITY_MODULE_`. + ### Compatible APIs Community Modules may provide specializations for the following APIs: diff --git a/keyboards/handwired/onekey/info.json b/keyboards/handwired/onekey/info.json index 7b6b7ddab89..d5f650f1bd4 100644 --- a/keyboards/handwired/onekey/info.json +++ b/keyboards/handwired/onekey/info.json @@ -26,5 +26,17 @@ {"x": 0, "y": 0, "matrix": [0, 0]} ] } + }, + "led_matrix": { + "driver": "snled27351", + "layout": [ + {"matrix": [0, 0], "x": 0, "y": 0, "flags": 1} + ] + }, + "rgb_matrix": { + "driver": "snled27351", + "layout": [ + {"matrix": [0, 0], "x": 0, "y": 0, "flags": 1} + ] } } diff --git a/keyboards/handwired/onekey/keymaps/cm_flow_led_matrix_effect/config.h b/keyboards/handwired/onekey/keymaps/cm_flow_led_matrix_effect/config.h new file mode 100644 index 00000000000..aed1e4ac6fa --- /dev/null +++ b/keyboards/handwired/onekey/keymaps/cm_flow_led_matrix_effect/config.h @@ -0,0 +1,16 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#pragma once + +#define SNLED27351_I2C_ADDRESS_1 SNLED27351_I2C_ADDRESS_GND diff --git a/keyboards/handwired/onekey/keymaps/cm_flow_led_matrix_effect/keymap.c b/keyboards/handwired/onekey/keymaps/cm_flow_led_matrix_effect/keymap.c new file mode 100644 index 00000000000..0bd835ff256 --- /dev/null +++ b/keyboards/handwired/onekey/keymaps/cm_flow_led_matrix_effect/keymap.c @@ -0,0 +1,27 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// This keymap serves as a test for modules/qmk/flow_led_matrix_effect. + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {LAYOUT_ortho_1x1(LM_TOGG)}; + +const snled27351_led_t PROGMEM g_snled27351_leds[LED_MATRIX_LED_COUNT] = { + {0, CB6_CA1}, +}; + +void keyboard_post_init_user(void) { + led_matrix_mode_noeeprom(LED_MATRIX_COMMUNITY_MODULE_FLOW); +} diff --git a/keyboards/handwired/onekey/keymaps/cm_flow_led_matrix_effect/keymap.json b/keyboards/handwired/onekey/keymaps/cm_flow_led_matrix_effect/keymap.json new file mode 100644 index 00000000000..0ff6bf5a4dc --- /dev/null +++ b/keyboards/handwired/onekey/keymaps/cm_flow_led_matrix_effect/keymap.json @@ -0,0 +1,3 @@ +{ + "modules": ["qmk/flow_led_matrix_effect"] +} diff --git a/keyboards/handwired/onekey/keymaps/cm_flow_rgb_matrix_effect/config.h b/keyboards/handwired/onekey/keymaps/cm_flow_rgb_matrix_effect/config.h new file mode 100644 index 00000000000..aed1e4ac6fa --- /dev/null +++ b/keyboards/handwired/onekey/keymaps/cm_flow_rgb_matrix_effect/config.h @@ -0,0 +1,16 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#pragma once + +#define SNLED27351_I2C_ADDRESS_1 SNLED27351_I2C_ADDRESS_GND diff --git a/keyboards/handwired/onekey/keymaps/cm_flow_rgb_matrix_effect/keymap.c b/keyboards/handwired/onekey/keymaps/cm_flow_rgb_matrix_effect/keymap.c new file mode 100644 index 00000000000..72ef2d3f80c --- /dev/null +++ b/keyboards/handwired/onekey/keymaps/cm_flow_rgb_matrix_effect/keymap.c @@ -0,0 +1,27 @@ +// Copyright 2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// This keymap serves as a test for modules/qmk/flow_rgb_matrix_effect. + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {LAYOUT_ortho_1x1(RM_TOGG)}; + +const snled27351_led_t PROGMEM g_snled27351_leds[LED_MATRIX_LED_COUNT] = { + {0, CB6_CA1}, +}; + +void keyboard_post_init_user(void) { + rgb_matrix_mode_noeeprom(RGB_MATRIX_COMMUNITY_MODULE_FLOW); +} diff --git a/keyboards/handwired/onekey/keymaps/cm_flow_rgb_matrix_effect/keymap.json b/keyboards/handwired/onekey/keymaps/cm_flow_rgb_matrix_effect/keymap.json new file mode 100644 index 00000000000..56d2342867d --- /dev/null +++ b/keyboards/handwired/onekey/keymaps/cm_flow_rgb_matrix_effect/keymap.json @@ -0,0 +1,3 @@ +{ + "modules": ["qmk/flow_rgb_matrix_effect"] +} diff --git a/lib/python/qmk/cli/generate/community_modules.py b/lib/python/qmk/cli/generate/community_modules.py index 61e24077d39..1f37b760ca0 100644 --- a/lib/python/qmk/cli/generate/community_modules.py +++ b/lib/python/qmk/cli/generate/community_modules.py @@ -278,33 +278,32 @@ def generate_community_modules_c(cli): dump_lines(cli.args.output, lines, cli.args.quiet, remove_repeated_newlines=True) +def _generate_include_per_module(cli, include_file_name): + """Generates C code to include "/include_file_name" for each module.""" + if cli.args.output and cli.args.output.name == '-': + cli.args.output = None + + lines = [GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE] + + for module in get_modules(cli.args.keyboard, cli.args.filename): + full_path = f'{find_module_path(module)}/{include_file_name}' + lines.append('') + lines.append(f'#if __has_include("{full_path}")') + lines.append(f'#include "{full_path}"') + lines.append(f'#endif // __has_include("{full_path}")') + + dump_lines(cli.args.output, lines, cli.args.quiet, remove_repeated_newlines=True) + + @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.argument('-kb', '--keyboard', arg_only=True, type=keyboard_folder, completer=keyboard_completer, help='Keyboard to generate community_modules.c for.') +@cli.argument('-kb', '--keyboard', arg_only=True, type=keyboard_folder, completer=keyboard_completer, help='Keyboard to generate community_modules_introspection.h for.') @cli.argument('filename', nargs='?', type=qmk.path.FileType('r'), arg_only=True, completer=FilesCompleter('.json'), help='Configurator JSON file') @cli.subcommand('Creates a community_modules_introspection.h from a keymap.json file.') def generate_community_modules_introspection_h(cli): """Creates a community_modules_introspection.h from a keymap.json file """ - if cli.args.output and cli.args.output.name == '-': - cli.args.output = None - - lines = [ - GPL2_HEADER_C_LIKE, - GENERATED_HEADER_C_LIKE, - '', - ] - - modules = get_modules(cli.args.keyboard, cli.args.filename) - if len(modules) > 0: - for module in modules: - module_path = find_module_path(module) - lines.append(f'#if __has_include("{module_path}/introspection.h")') - lines.append(f'#include "{module_path}/introspection.h"') - lines.append(f'#endif // __has_include("{module_path}/introspection.h")') - lines.append('') - - dump_lines(cli.args.output, lines, cli.args.quiet, remove_repeated_newlines=True) + _generate_include_per_module(cli, 'introspection.h') @cli.argument('-o', '--output', arg_only=True, type=qmk.path.normpath, help='File to write to') @@ -315,22 +314,26 @@ def generate_community_modules_introspection_h(cli): def generate_community_modules_introspection_c(cli): """Creates a community_modules_introspection.c from a keymap.json file """ - if cli.args.output and cli.args.output.name == '-': - cli.args.output = None + _generate_include_per_module(cli, 'introspection.c') - lines = [ - GPL2_HEADER_C_LIKE, - GENERATED_HEADER_C_LIKE, - '', - ] - modules = get_modules(cli.args.keyboard, cli.args.filename) - if len(modules) > 0: - for module in modules: - module_path = find_module_path(module) - lines.append(f'#if __has_include("{module_path}/introspection.c")') - lines.append(f'#include "{module_path}/introspection.c"') - lines.append(f'#endif // __has_include("{module_path}/introspection.c")') - lines.append('') +@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.argument('-kb', '--keyboard', arg_only=True, type=keyboard_folder, completer=keyboard_completer, help='Keyboard to generate led_matrix_community_modules.inc for.') +@cli.argument('filename', nargs='?', type=qmk.path.FileType('r'), arg_only=True, completer=FilesCompleter('.json'), help='Configurator JSON file') +@cli.subcommand('Creates an led_matrix_community_modules.inc from a keymap.json file.') +def generate_led_matrix_community_modules_inc(cli): + """Creates an led_matrix_community_modules.inc from a keymap.json file + """ + _generate_include_per_module(cli, 'led_matrix_module.inc') - dump_lines(cli.args.output, lines, cli.args.quiet, remove_repeated_newlines=True) + +@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.argument('-kb', '--keyboard', arg_only=True, type=keyboard_folder, completer=keyboard_completer, help='Keyboard to generate rgb_matrix_community_modules.inc for.') +@cli.argument('filename', nargs='?', type=qmk.path.FileType('r'), arg_only=True, completer=FilesCompleter('.json'), help='Configurator JSON file') +@cli.subcommand('Creates an rgb_matrix_community_modules.inc from a keymap.json file.') +def generate_rgb_matrix_community_modules_inc(cli): + """Creates an rgb_matrix_community_modules.inc from a keymap.json file + """ + _generate_include_per_module(cli, 'rgb_matrix_module.inc') diff --git a/modules/qmk/flow_led_matrix_effect/led_matrix_module.inc b/modules/qmk/flow_led_matrix_effect/led_matrix_module.inc new file mode 100644 index 00000000000..734e0f34945 --- /dev/null +++ b/modules/qmk/flow_led_matrix_effect/led_matrix_module.inc @@ -0,0 +1,58 @@ +// Copyright 2024-2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +LED_MATRIX_EFFECT(FLOW) + +#ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS + +// "Flow" animated effect. Draws moving wave patterns mimicking the appearance +// of flowing liquid. For interesting variety of patterns, space coordinates are +// slowly rotated and a function of several sine waves is evaluated. +static bool FLOW(effect_params_t* params) { + LED_MATRIX_USE_LIMITS(led_min, led_max); + + static uint16_t wrap_correction = 0; + static uint8_t last_high_byte = 0; + const uint8_t time_scale = 1 + led_matrix_eeconfig.speed / 8; + const uint8_t high_byte = (uint8_t)(g_led_timer >> 16); + if (last_high_byte != high_byte) { + last_high_byte = high_byte; + wrap_correction += ((uint16_t)time_scale) << 8; + } + const uint16_t time = scale16by8(g_led_timer, time_scale) + wrap_correction; + + // Compute rotation coefficients with 7 fractional bits. + const int8_t rot_c = cos8(time / 4) - 128; + const int8_t rot_s = sin8(time / 4) - 128; + const uint8_t omega = 32 + sin8(time) / 4; + + for (uint8_t i = led_min; i < led_max; ++i) { + LED_MATRIX_TEST_LED_FLAGS(); + const uint8_t x = g_led_config.point[i].x; + const uint8_t y = g_led_config.point[i].y; + + // Rotate (x, y) by the 2x2 rotation matrix described by rot_c, rot_s. + const uint8_t x1 = (uint8_t)((((int16_t)rot_c) * ((int16_t)x)) / 128) - (uint8_t)((((int16_t)rot_s) * ((int16_t)y)) / 128); + const uint8_t y1 = (uint8_t)((((int16_t)rot_s) * ((int16_t)x)) / 128) + (uint8_t)((((int16_t)rot_c) * ((int16_t)y)) / 128); + + uint8_t value = scale8(sin8(x1 - 2 * time), omega) + y1 + time / 4; + value = (value <= 127) ? value : (255 - value); + + led_matrix_set_value(i, scale8(led_matrix_eeconfig.val, value)); + } + + return led_matrix_check_finished_leds(led_max); +} + +#endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS diff --git a/modules/qmk/flow_led_matrix_effect/qmk_module.json b/modules/qmk/flow_led_matrix_effect/qmk_module.json new file mode 100644 index 00000000000..2d047cd0d08 --- /dev/null +++ b/modules/qmk/flow_led_matrix_effect/qmk_module.json @@ -0,0 +1,8 @@ +{ + "module_name": "Flow LED matrix effect", + "maintainer": "QMK Maintainers", + "license": "Apache-2.0", + "features": { + "led_matrix": true + } +} diff --git a/modules/qmk/flow_rgb_matrix_effect/qmk_module.json b/modules/qmk/flow_rgb_matrix_effect/qmk_module.json new file mode 100644 index 00000000000..3e42fe1ef46 --- /dev/null +++ b/modules/qmk/flow_rgb_matrix_effect/qmk_module.json @@ -0,0 +1,8 @@ +{ + "module_name": "Flow RGB matrix effect", + "maintainer": "QMK Maintainers", + "license": "Apache-2.0", + "features": { + "rgb_matrix": true + } +} diff --git a/modules/qmk/flow_rgb_matrix_effect/rgb_matrix_module.inc b/modules/qmk/flow_rgb_matrix_effect/rgb_matrix_module.inc new file mode 100644 index 00000000000..410838f7ec4 --- /dev/null +++ b/modules/qmk/flow_rgb_matrix_effect/rgb_matrix_module.inc @@ -0,0 +1,64 @@ +// Copyright 2024-2025 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +RGB_MATRIX_EFFECT(FLOW) + +#ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS + +// "Flow" animated effect. Draws moving wave patterns mimicking the appearance +// of flowing liquid. For interesting variety of patterns, space coordinates are +// slowly rotated and a function of several sine waves is evaluated. +static bool FLOW(effect_params_t* params) { + RGB_MATRIX_USE_LIMITS(led_min, led_max); + + static uint16_t wrap_correction = 0; + static uint8_t last_high_byte = 0; + const uint8_t time_scale = 1 + rgb_matrix_config.speed / 8; + const uint8_t high_byte = (uint8_t)(g_rgb_timer >> 16); + if (last_high_byte != high_byte) { + last_high_byte = high_byte; + wrap_correction += ((uint16_t)time_scale) << 8; + } + const uint16_t time = scale16by8(g_rgb_timer, time_scale) + wrap_correction; + + // Compute rotation coefficients with 7 fractional bits. + const int8_t rot_c = cos8(time / 4) - 128; + const int8_t rot_s = sin8(time / 4) - 128; + const uint8_t omega = 32 + sin8(time) / 4; + + for (uint8_t i = led_min; i < led_max; ++i) { + RGB_MATRIX_TEST_LED_FLAGS(); + const uint8_t x = g_led_config.point[i].x; + const uint8_t y = g_led_config.point[i].y; + + // Rotate (x, y) by the 2x2 rotation matrix described by rot_c, rot_s. + const uint8_t x1 = (uint8_t)((((int16_t)rot_c) * ((int16_t)x)) / 128) - (uint8_t)((((int16_t)rot_s) * ((int16_t)y)) / 128); + const uint8_t y1 = (uint8_t)((((int16_t)rot_s) * ((int16_t)x)) / 128) + (uint8_t)((((int16_t)rot_c) * ((int16_t)y)) / 128); + + uint8_t value = scale8(sin8(x1 - 2 * time), omega) + y1 + time / 4; + value = (value <= 127) ? value : (255 - value); + + hsv_t hsv = rgb_matrix_config.hsv; + hsv.h -= value / 4; + hsv.s = scale8(hsv.s, (value < 74) ? 255 : (549 - 4 * value)); + hsv.v = scale8(hsv.v, (value < 95) ? (64 + 2 * value) : 255); + + rgb_t rgb = rgb_matrix_hsv_to_rgb(hsv); + rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b); + } + + return rgb_matrix_check_finished_leds(led_max); +} + +#endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS diff --git a/quantum/led_matrix/led_matrix.c b/quantum/led_matrix/led_matrix.c index 00bc199ecf1..7a0e8a5ebbc 100644 --- a/quantum/led_matrix/led_matrix.c +++ b/quantum/led_matrix/led_matrix.c @@ -45,6 +45,9 @@ const led_point_t k_led_matrix_center = LED_MATRIX_CENTER; #define LED_MATRIX_CUSTOM_EFFECT_IMPLS #include "led_matrix_effects.inc" +#ifdef COMMUNITY_MODULES_ENABLE +# include "led_matrix_community_modules.inc" +#endif #ifdef LED_MATRIX_CUSTOM_KB # include "led_matrix_kb.inc" #endif @@ -282,6 +285,15 @@ static void led_task_render(uint8_t effect) { #include "led_matrix_effects.inc" #undef LED_MATRIX_EFFECT +#ifdef COMMUNITY_MODULES_ENABLE +# define LED_MATRIX_EFFECT(name, ...) \ + case LED_MATRIX_COMMUNITY_MODULE_##name: \ + rendering = name(&led_effect_params); \ + break; +# include "led_matrix_community_modules.inc" +# undef LED_MATRIX_EFFECT +#endif + #if defined(LED_MATRIX_CUSTOM_KB) || defined(LED_MATRIX_CUSTOM_USER) # define LED_MATRIX_EFFECT(name, ...) \ case LED_MATRIX_CUSTOM_##name: \ diff --git a/quantum/led_matrix/led_matrix.h b/quantum/led_matrix/led_matrix.h index 0006d487e9d..0dfe33ffab3 100644 --- a/quantum/led_matrix/led_matrix.h +++ b/quantum/led_matrix/led_matrix.h @@ -98,6 +98,12 @@ enum led_matrix_effects { #include "led_matrix_effects.inc" #undef LED_MATRIX_EFFECT +#ifdef COMMUNITY_MODULES_ENABLE +# define LED_MATRIX_EFFECT(name, ...) LED_MATRIX_COMMUNITY_MODULE_##name, +# include "led_matrix_community_modules.inc" +# undef LED_MATRIX_EFFECT +#endif + #if defined(LED_MATRIX_CUSTOM_KB) || defined(LED_MATRIX_CUSTOM_USER) # define LED_MATRIX_EFFECT(name, ...) LED_MATRIX_CUSTOM_##name, # ifdef LED_MATRIX_CUSTOM_KB diff --git a/quantum/rgb_matrix/rgb_matrix.c b/quantum/rgb_matrix/rgb_matrix.c index 94852e3520a..2679c483426 100644 --- a/quantum/rgb_matrix/rgb_matrix.c +++ b/quantum/rgb_matrix/rgb_matrix.c @@ -47,6 +47,9 @@ __attribute__((weak)) rgb_t rgb_matrix_hsv_to_rgb(hsv_t hsv) { #define RGB_MATRIX_CUSTOM_EFFECT_IMPLS #include "rgb_matrix_effects.inc" +#ifdef COMMUNITY_MODULES_ENABLE +# include "rgb_matrix_community_modules.inc" +#endif #ifdef RGB_MATRIX_CUSTOM_KB # include "rgb_matrix_kb.inc" #endif @@ -310,6 +313,15 @@ static void rgb_task_render(uint8_t effect) { #include "rgb_matrix_effects.inc" #undef RGB_MATRIX_EFFECT +#ifdef COMMUNITY_MODULES_ENABLE +# define RGB_MATRIX_EFFECT(name, ...) \ + case RGB_MATRIX_COMMUNITY_MODULE_##name: \ + rendering = name(&rgb_effect_params); \ + break; +# include "rgb_matrix_community_modules.inc" +# undef RGB_MATRIX_EFFECT +#endif + #if defined(RGB_MATRIX_CUSTOM_KB) || defined(RGB_MATRIX_CUSTOM_USER) # define RGB_MATRIX_EFFECT(name, ...) \ case RGB_MATRIX_CUSTOM_##name: \ diff --git a/quantum/rgb_matrix/rgb_matrix.h b/quantum/rgb_matrix/rgb_matrix.h index e00e3927c76..c6b302631ed 100644 --- a/quantum/rgb_matrix/rgb_matrix.h +++ b/quantum/rgb_matrix/rgb_matrix.h @@ -123,6 +123,12 @@ enum rgb_matrix_effects { #include "rgb_matrix_effects.inc" #undef RGB_MATRIX_EFFECT +#ifdef COMMUNITY_MODULES_ENABLE +# define RGB_MATRIX_EFFECT(name, ...) RGB_MATRIX_COMMUNITY_MODULE_##name, +# include "rgb_matrix_community_modules.inc" +# undef RGB_MATRIX_EFFECT +#endif + #if defined(RGB_MATRIX_CUSTOM_KB) || defined(RGB_MATRIX_CUSTOM_USER) # define RGB_MATRIX_EFFECT(name, ...) RGB_MATRIX_CUSTOM_##name, # ifdef RGB_MATRIX_CUSTOM_KB