diff options
19 files changed, 339 insertions, 38 deletions
diff --git a/builddefs/build_keyboard.mk b/builddefs/build_keyboard.mk index 514191b17d..c2c47c00fb 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 | |||
| 274 | $(eval CMD=$(QMK_BIN) generate-community-modules-introspection-h -kb $(KEYBOARD) --quiet --output $(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.h $(KEYMAP_JSON)) | 274 | $(eval CMD=$(QMK_BIN) generate-community-modules-introspection-h -kb $(KEYBOARD) --quiet --output $(INTERMEDIATE_OUTPUT)/src/community_modules_introspection.h $(KEYMAP_JSON)) |
| 275 | @$(BUILD_CMD) | 275 | @$(BUILD_CMD) |
| 276 | 276 | ||
| 277 | SRC += $(INTERMEDIATE_OUTPUT)/src/community_modules.c | 277 | $(INTERMEDIATE_OUTPUT)/src/led_matrix_community_modules.inc: $(KEYMAP_JSON) $(DD_CONFIG_FILES) |
| 278 | @$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD) | ||
| 279 | $(eval CMD=$(QMK_BIN) generate-led-matrix-community-modules-inc -kb $(KEYBOARD) --quiet --output $(INTERMEDIATE_OUTPUT)/src/led_matrix_community_modules.inc $(KEYMAP_JSON)) | ||
| 280 | @$(BUILD_CMD) | ||
| 278 | 281 | ||
| 279 | 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 | 282 | $(INTERMEDIATE_OUTPUT)/src/rgb_matrix_community_modules.inc: $(KEYMAP_JSON) $(DD_CONFIG_FILES) |
| 283 | @$(SILENT) || printf "$(MSG_GENERATING) $@" | $(AWK_CMD) | ||
| 284 | $(eval CMD=$(QMK_BIN) generate-rgb-matrix-community-modules-inc -kb $(KEYBOARD) --quiet --output $(INTERMEDIATE_OUTPUT)/src/rgb_matrix_community_modules.inc $(KEYMAP_JSON)) | ||
| 285 | @$(BUILD_CMD) | ||
| 286 | |||
| 287 | SRC += $(INTERMEDIATE_OUTPUT)/src/community_modules.c | ||
| 280 | 288 | ||
| 289 | 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 | ||
| 281 | 290 | ||
| 282 | include $(BUILDDEFS_PATH)/converters.mk | 291 | include $(BUILDDEFS_PATH)/converters.mk |
| 283 | 292 | ||
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 0000000000..49f5d0d5d0 --- /dev/null +++ b/data/constants/module_hooks/1.1.1.hjson | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | { | ||
| 2 | // This version exists to signify addition of LED/RGB effect support. | ||
| 3 | } | ||
diff --git a/docs/features/community_modules.md b/docs/features/community_modules.md index 8dede47bd4..eff07c939a 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 | |||
| 123 | 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). | 123 | 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). |
| 124 | ::: | 124 | ::: |
| 125 | 125 | ||
| 126 | ### `led_matrix_module.inc` | ||
| 127 | |||
| 128 | 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_`. | ||
| 129 | |||
| 130 | ### `rgb_matrix_module.inc` | ||
| 131 | |||
| 132 | 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_`. | ||
| 133 | |||
| 126 | ### Compatible APIs | 134 | ### Compatible APIs |
| 127 | 135 | ||
| 128 | Community Modules may provide specializations for the following APIs: | 136 | Community Modules may provide specializations for the following APIs: |
diff --git a/keyboards/handwired/onekey/info.json b/keyboards/handwired/onekey/info.json index 7b6b7ddab8..d5f650f1bd 100644 --- a/keyboards/handwired/onekey/info.json +++ b/keyboards/handwired/onekey/info.json | |||
| @@ -26,5 +26,17 @@ | |||
| 26 | {"x": 0, "y": 0, "matrix": [0, 0]} | 26 | {"x": 0, "y": 0, "matrix": [0, 0]} |
| 27 | ] | 27 | ] |
| 28 | } | 28 | } |
| 29 | }, | ||
| 30 | "led_matrix": { | ||
| 31 | "driver": "snled27351", | ||
| 32 | "layout": [ | ||
| 33 | {"matrix": [0, 0], "x": 0, "y": 0, "flags": 1} | ||
| 34 | ] | ||
| 35 | }, | ||
| 36 | "rgb_matrix": { | ||
| 37 | "driver": "snled27351", | ||
| 38 | "layout": [ | ||
| 39 | {"matrix": [0, 0], "x": 0, "y": 0, "flags": 1} | ||
| 40 | ] | ||
| 29 | } | 41 | } |
| 30 | } | 42 | } |
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 0000000000..aed1e4ac6f --- /dev/null +++ b/keyboards/handwired/onekey/keymaps/cm_flow_led_matrix_effect/config.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | // Copyright 2025 Google LLC | ||
| 2 | // | ||
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | // you may not use this file except in compliance with the License. | ||
| 5 | // You may obtain a copy of the License at | ||
| 6 | // | ||
| 7 | // https://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | // | ||
| 9 | // Unless required by applicable law or agreed to in writing, software | ||
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | // See the License for the specific language governing permissions and | ||
| 13 | // limitations under the License. | ||
| 14 | #pragma once | ||
| 15 | |||
| 16 | #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 0000000000..0bd835ff25 --- /dev/null +++ b/keyboards/handwired/onekey/keymaps/cm_flow_led_matrix_effect/keymap.c | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | // Copyright 2025 Google LLC | ||
| 2 | // | ||
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | // you may not use this file except in compliance with the License. | ||
| 5 | // You may obtain a copy of the License at | ||
| 6 | // | ||
| 7 | // https://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | // | ||
| 9 | // Unless required by applicable law or agreed to in writing, software | ||
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | // See the License for the specific language governing permissions and | ||
| 13 | // limitations under the License. | ||
| 14 | // | ||
| 15 | // This keymap serves as a test for modules/qmk/flow_led_matrix_effect. | ||
| 16 | |||
| 17 | #include QMK_KEYBOARD_H | ||
| 18 | |||
| 19 | const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {LAYOUT_ortho_1x1(LM_TOGG)}; | ||
| 20 | |||
| 21 | const snled27351_led_t PROGMEM g_snled27351_leds[LED_MATRIX_LED_COUNT] = { | ||
| 22 | {0, CB6_CA1}, | ||
| 23 | }; | ||
| 24 | |||
| 25 | void keyboard_post_init_user(void) { | ||
| 26 | led_matrix_mode_noeeprom(LED_MATRIX_COMMUNITY_MODULE_FLOW); | ||
| 27 | } | ||
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 0000000000..0ff6bf5a4d --- /dev/null +++ b/keyboards/handwired/onekey/keymaps/cm_flow_led_matrix_effect/keymap.json | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | { | ||
| 2 | "modules": ["qmk/flow_led_matrix_effect"] | ||
| 3 | } | ||
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 0000000000..aed1e4ac6f --- /dev/null +++ b/keyboards/handwired/onekey/keymaps/cm_flow_rgb_matrix_effect/config.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | // Copyright 2025 Google LLC | ||
| 2 | // | ||
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | // you may not use this file except in compliance with the License. | ||
| 5 | // You may obtain a copy of the License at | ||
| 6 | // | ||
| 7 | // https://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | // | ||
| 9 | // Unless required by applicable law or agreed to in writing, software | ||
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | // See the License for the specific language governing permissions and | ||
| 13 | // limitations under the License. | ||
| 14 | #pragma once | ||
| 15 | |||
| 16 | #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 0000000000..72ef2d3f80 --- /dev/null +++ b/keyboards/handwired/onekey/keymaps/cm_flow_rgb_matrix_effect/keymap.c | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | // Copyright 2025 Google LLC | ||
| 2 | // | ||
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | // you may not use this file except in compliance with the License. | ||
| 5 | // You may obtain a copy of the License at | ||
| 6 | // | ||
| 7 | // https://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | // | ||
| 9 | // Unless required by applicable law or agreed to in writing, software | ||
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | // See the License for the specific language governing permissions and | ||
| 13 | // limitations under the License. | ||
| 14 | // | ||
| 15 | // This keymap serves as a test for modules/qmk/flow_rgb_matrix_effect. | ||
| 16 | |||
| 17 | #include QMK_KEYBOARD_H | ||
| 18 | |||
| 19 | const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {LAYOUT_ortho_1x1(RM_TOGG)}; | ||
| 20 | |||
| 21 | const snled27351_led_t PROGMEM g_snled27351_leds[LED_MATRIX_LED_COUNT] = { | ||
| 22 | {0, CB6_CA1}, | ||
| 23 | }; | ||
| 24 | |||
| 25 | void keyboard_post_init_user(void) { | ||
| 26 | rgb_matrix_mode_noeeprom(RGB_MATRIX_COMMUNITY_MODULE_FLOW); | ||
| 27 | } | ||
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 0000000000..56d2342867 --- /dev/null +++ b/keyboards/handwired/onekey/keymaps/cm_flow_rgb_matrix_effect/keymap.json | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | { | ||
| 2 | "modules": ["qmk/flow_rgb_matrix_effect"] | ||
| 3 | } | ||
diff --git a/lib/python/qmk/cli/generate/community_modules.py b/lib/python/qmk/cli/generate/community_modules.py index 61e24077d3..1f37b760ca 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): | |||
| 278 | dump_lines(cli.args.output, lines, cli.args.quiet, remove_repeated_newlines=True) | 278 | dump_lines(cli.args.output, lines, cli.args.quiet, remove_repeated_newlines=True) |
| 279 | 279 | ||
| 280 | 280 | ||
| 281 | def _generate_include_per_module(cli, include_file_name): | ||
| 282 | """Generates C code to include "<module_path>/include_file_name" for each module.""" | ||
| 283 | if cli.args.output and cli.args.output.name == '-': | ||
| 284 | cli.args.output = None | ||
| 285 | |||
| 286 | lines = [GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE] | ||
| 287 | |||
| 288 | for module in get_modules(cli.args.keyboard, cli.args.filename): | ||
| 289 | full_path = f'{find_module_path(module)}/{include_file_name}' | ||
| 290 | lines.append('') | ||
| 291 | lines.append(f'#if __has_include("{full_path}")') | ||
| 292 | lines.append(f'#include "{full_path}"') | ||
| 293 | lines.append(f'#endif // __has_include("{full_path}")') | ||
| 294 | |||
| 295 | dump_lines(cli.args.output, lines, cli.args.quiet, remove_repeated_newlines=True) | ||
| 296 | |||
| 297 | |||
| 281 | @cli.argument('-o', '--output', arg_only=True, type=qmk.path.normpath, help='File to write to') | 298 | @cli.argument('-o', '--output', arg_only=True, type=qmk.path.normpath, help='File to write to') |
| 282 | @cli.argument('-q', '--quiet', arg_only=True, action='store_true', help="Quiet mode, only output error messages") | 299 | @cli.argument('-q', '--quiet', arg_only=True, action='store_true', help="Quiet mode, only output error messages") |
| 283 | @cli.argument('-kb', '--keyboard', arg_only=True, type=keyboard_folder, completer=keyboard_completer, help='Keyboard to generate community_modules.c for.') | 300 | @cli.argument('-kb', '--keyboard', arg_only=True, type=keyboard_folder, completer=keyboard_completer, help='Keyboard to generate community_modules_introspection.h for.') |
| 284 | @cli.argument('filename', nargs='?', type=qmk.path.FileType('r'), arg_only=True, completer=FilesCompleter('.json'), help='Configurator JSON file') | 301 | @cli.argument('filename', nargs='?', type=qmk.path.FileType('r'), arg_only=True, completer=FilesCompleter('.json'), help='Configurator JSON file') |
| 285 | @cli.subcommand('Creates a community_modules_introspection.h from a keymap.json file.') | 302 | @cli.subcommand('Creates a community_modules_introspection.h from a keymap.json file.') |
| 286 | def generate_community_modules_introspection_h(cli): | 303 | def generate_community_modules_introspection_h(cli): |
| 287 | """Creates a community_modules_introspection.h from a keymap.json file | 304 | """Creates a community_modules_introspection.h from a keymap.json file |
| 288 | """ | 305 | """ |
| 289 | if cli.args.output and cli.args.output.name == '-': | 306 | _generate_include_per_module(cli, 'introspection.h') |
| 290 | cli.args.output = None | ||
| 291 | |||
| 292 | lines = [ | ||
| 293 | GPL2_HEADER_C_LIKE, | ||
| 294 | GENERATED_HEADER_C_LIKE, | ||
| 295 | '', | ||
| 296 | ] | ||
| 297 | |||
| 298 | modules = get_modules(cli.args.keyboard, cli.args.filename) | ||
| 299 | if len(modules) > 0: | ||
| 300 | for module in modules: | ||
| 301 | module_path = find_module_path(module) | ||
| 302 | lines.append(f'#if __has_include("{module_path}/introspection.h")') | ||
| 303 | lines.append(f'#include "{module_path}/introspection.h"') | ||
| 304 | lines.append(f'#endif // __has_include("{module_path}/introspection.h")') | ||
| 305 | lines.append('') | ||
| 306 | |||
| 307 | dump_lines(cli.args.output, lines, cli.args.quiet, remove_repeated_newlines=True) | ||
| 308 | 307 | ||
| 309 | 308 | ||
| 310 | @cli.argument('-o', '--output', arg_only=True, type=qmk.path.normpath, help='File to write to') | 309 | @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): | |||
| 315 | def generate_community_modules_introspection_c(cli): | 314 | def generate_community_modules_introspection_c(cli): |
| 316 | """Creates a community_modules_introspection.c from a keymap.json file | 315 | """Creates a community_modules_introspection.c from a keymap.json file |
| 317 | """ | 316 | """ |
| 318 | if cli.args.output and cli.args.output.name == '-': | 317 | _generate_include_per_module(cli, 'introspection.c') |
| 319 | cli.args.output = None | ||
| 320 | 318 | ||
| 321 | lines = [ | ||
| 322 | GPL2_HEADER_C_LIKE, | ||
| 323 | GENERATED_HEADER_C_LIKE, | ||
| 324 | '', | ||
| 325 | ] | ||
| 326 | 319 | ||
| 327 | modules = get_modules(cli.args.keyboard, cli.args.filename) | 320 | @cli.argument('-o', '--output', arg_only=True, type=qmk.path.normpath, help='File to write to') |
| 328 | if len(modules) > 0: | 321 | @cli.argument('-q', '--quiet', arg_only=True, action='store_true', help="Quiet mode, only output error messages") |
| 329 | for module in modules: | 322 | @cli.argument('-kb', '--keyboard', arg_only=True, type=keyboard_folder, completer=keyboard_completer, help='Keyboard to generate led_matrix_community_modules.inc for.') |
| 330 | module_path = find_module_path(module) | 323 | @cli.argument('filename', nargs='?', type=qmk.path.FileType('r'), arg_only=True, completer=FilesCompleter('.json'), help='Configurator JSON file') |
| 331 | lines.append(f'#if __has_include("{module_path}/introspection.c")') | 324 | @cli.subcommand('Creates an led_matrix_community_modules.inc from a keymap.json file.') |
| 332 | lines.append(f'#include "{module_path}/introspection.c"') | 325 | def generate_led_matrix_community_modules_inc(cli): |
| 333 | lines.append(f'#endif // __has_include("{module_path}/introspection.c")') | 326 | """Creates an led_matrix_community_modules.inc from a keymap.json file |
| 334 | lines.append('') | 327 | """ |
| 328 | _generate_include_per_module(cli, 'led_matrix_module.inc') | ||
| 335 | 329 | ||
| 336 | dump_lines(cli.args.output, lines, cli.args.quiet, remove_repeated_newlines=True) | 330 | |
| 331 | @cli.argument('-o', '--output', arg_only=True, type=qmk.path.normpath, help='File to write to') | ||
| 332 | @cli.argument('-q', '--quiet', arg_only=True, action='store_true', help="Quiet mode, only output error messages") | ||
| 333 | @cli.argument('-kb', '--keyboard', arg_only=True, type=keyboard_folder, completer=keyboard_completer, help='Keyboard to generate rgb_matrix_community_modules.inc for.') | ||
| 334 | @cli.argument('filename', nargs='?', type=qmk.path.FileType('r'), arg_only=True, completer=FilesCompleter('.json'), help='Configurator JSON file') | ||
| 335 | @cli.subcommand('Creates an rgb_matrix_community_modules.inc from a keymap.json file.') | ||
| 336 | def generate_rgb_matrix_community_modules_inc(cli): | ||
| 337 | """Creates an rgb_matrix_community_modules.inc from a keymap.json file | ||
| 338 | """ | ||
| 339 | _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 0000000000..734e0f3494 --- /dev/null +++ b/modules/qmk/flow_led_matrix_effect/led_matrix_module.inc | |||
| @@ -0,0 +1,58 @@ | |||
| 1 | // Copyright 2024-2025 Google LLC | ||
| 2 | // | ||
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | // you may not use this file except in compliance with the License. | ||
| 5 | // You may obtain a copy of the License at | ||
| 6 | // | ||
| 7 | // https://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | // | ||
| 9 | // Unless required by applicable law or agreed to in writing, software | ||
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | // See the License for the specific language governing permissions and | ||
| 13 | // limitations under the License. | ||
| 14 | |||
| 15 | LED_MATRIX_EFFECT(FLOW) | ||
| 16 | |||
| 17 | #ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS | ||
| 18 | |||
| 19 | // "Flow" animated effect. Draws moving wave patterns mimicking the appearance | ||
| 20 | // of flowing liquid. For interesting variety of patterns, space coordinates are | ||
| 21 | // slowly rotated and a function of several sine waves is evaluated. | ||
| 22 | static bool FLOW(effect_params_t* params) { | ||
| 23 | LED_MATRIX_USE_LIMITS(led_min, led_max); | ||
| 24 | |||
| 25 | static uint16_t wrap_correction = 0; | ||
| 26 | static uint8_t last_high_byte = 0; | ||
| 27 | const uint8_t time_scale = 1 + led_matrix_eeconfig.speed / 8; | ||
| 28 | const uint8_t high_byte = (uint8_t)(g_led_timer >> 16); | ||
| 29 | if (last_high_byte != high_byte) { | ||
| 30 | last_high_byte = high_byte; | ||
| 31 | wrap_correction += ((uint16_t)time_scale) << 8; | ||
| 32 | } | ||
| 33 | const uint16_t time = scale16by8(g_led_timer, time_scale) + wrap_correction; | ||
| 34 | |||
| 35 | // Compute rotation coefficients with 7 fractional bits. | ||
| 36 | const int8_t rot_c = cos8(time / 4) - 128; | ||
| 37 | const int8_t rot_s = sin8(time / 4) - 128; | ||
| 38 | const uint8_t omega = 32 + sin8(time) / 4; | ||
| 39 | |||
| 40 | for (uint8_t i = led_min; i < led_max; ++i) { | ||
| 41 | LED_MATRIX_TEST_LED_FLAGS(); | ||
| 42 | const uint8_t x = g_led_config.point[i].x; | ||
| 43 | const uint8_t y = g_led_config.point[i].y; | ||
| 44 | |||
| 45 | // Rotate (x, y) by the 2x2 rotation matrix described by rot_c, rot_s. | ||
| 46 | const uint8_t x1 = (uint8_t)((((int16_t)rot_c) * ((int16_t)x)) / 128) - (uint8_t)((((int16_t)rot_s) * ((int16_t)y)) / 128); | ||
| 47 | const uint8_t y1 = (uint8_t)((((int16_t)rot_s) * ((int16_t)x)) / 128) + (uint8_t)((((int16_t)rot_c) * ((int16_t)y)) / 128); | ||
| 48 | |||
| 49 | uint8_t value = scale8(sin8(x1 - 2 * time), omega) + y1 + time / 4; | ||
| 50 | value = (value <= 127) ? value : (255 - value); | ||
| 51 | |||
| 52 | led_matrix_set_value(i, scale8(led_matrix_eeconfig.val, value)); | ||
| 53 | } | ||
| 54 | |||
| 55 | return led_matrix_check_finished_leds(led_max); | ||
| 56 | } | ||
| 57 | |||
| 58 | #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 0000000000..2d047cd0d0 --- /dev/null +++ b/modules/qmk/flow_led_matrix_effect/qmk_module.json | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | { | ||
| 2 | "module_name": "Flow LED matrix effect", | ||
| 3 | "maintainer": "QMK Maintainers", | ||
| 4 | "license": "Apache-2.0", | ||
| 5 | "features": { | ||
| 6 | "led_matrix": true | ||
| 7 | } | ||
| 8 | } | ||
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 0000000000..3e42fe1ef4 --- /dev/null +++ b/modules/qmk/flow_rgb_matrix_effect/qmk_module.json | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | { | ||
| 2 | "module_name": "Flow RGB matrix effect", | ||
| 3 | "maintainer": "QMK Maintainers", | ||
| 4 | "license": "Apache-2.0", | ||
| 5 | "features": { | ||
| 6 | "rgb_matrix": true | ||
| 7 | } | ||
| 8 | } | ||
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 0000000000..410838f7ec --- /dev/null +++ b/modules/qmk/flow_rgb_matrix_effect/rgb_matrix_module.inc | |||
| @@ -0,0 +1,64 @@ | |||
| 1 | // Copyright 2024-2025 Google LLC | ||
| 2 | // | ||
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 4 | // you may not use this file except in compliance with the License. | ||
| 5 | // You may obtain a copy of the License at | ||
| 6 | // | ||
| 7 | // https://www.apache.org/licenses/LICENSE-2.0 | ||
| 8 | // | ||
| 9 | // Unless required by applicable law or agreed to in writing, software | ||
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, | ||
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 12 | // See the License for the specific language governing permissions and | ||
| 13 | // limitations under the License. | ||
| 14 | |||
| 15 | RGB_MATRIX_EFFECT(FLOW) | ||
| 16 | |||
| 17 | #ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS | ||
| 18 | |||
| 19 | // "Flow" animated effect. Draws moving wave patterns mimicking the appearance | ||
| 20 | // of flowing liquid. For interesting variety of patterns, space coordinates are | ||
| 21 | // slowly rotated and a function of several sine waves is evaluated. | ||
| 22 | static bool FLOW(effect_params_t* params) { | ||
| 23 | RGB_MATRIX_USE_LIMITS(led_min, led_max); | ||
| 24 | |||
| 25 | static uint16_t wrap_correction = 0; | ||
| 26 | static uint8_t last_high_byte = 0; | ||
| 27 | const uint8_t time_scale = 1 + rgb_matrix_config.speed / 8; | ||
| 28 | const uint8_t high_byte = (uint8_t)(g_rgb_timer >> 16); | ||
| 29 | if (last_high_byte != high_byte) { | ||
| 30 | last_high_byte = high_byte; | ||
| 31 | wrap_correction += ((uint16_t)time_scale) << 8; | ||
| 32 | } | ||
| 33 | const uint16_t time = scale16by8(g_rgb_timer, time_scale) + wrap_correction; | ||
| 34 | |||
| 35 | // Compute rotation coefficients with 7 fractional bits. | ||
| 36 | const int8_t rot_c = cos8(time / 4) - 128; | ||
| 37 | const int8_t rot_s = sin8(time / 4) - 128; | ||
| 38 | const uint8_t omega = 32 + sin8(time) / 4; | ||
| 39 | |||
| 40 | for (uint8_t i = led_min; i < led_max; ++i) { | ||
| 41 | RGB_MATRIX_TEST_LED_FLAGS(); | ||
| 42 | const uint8_t x = g_led_config.point[i].x; | ||
| 43 | const uint8_t y = g_led_config.point[i].y; | ||
| 44 | |||
| 45 | // Rotate (x, y) by the 2x2 rotation matrix described by rot_c, rot_s. | ||
| 46 | const uint8_t x1 = (uint8_t)((((int16_t)rot_c) * ((int16_t)x)) / 128) - (uint8_t)((((int16_t)rot_s) * ((int16_t)y)) / 128); | ||
| 47 | const uint8_t y1 = (uint8_t)((((int16_t)rot_s) * ((int16_t)x)) / 128) + (uint8_t)((((int16_t)rot_c) * ((int16_t)y)) / 128); | ||
| 48 | |||
| 49 | uint8_t value = scale8(sin8(x1 - 2 * time), omega) + y1 + time / 4; | ||
| 50 | value = (value <= 127) ? value : (255 - value); | ||
| 51 | |||
| 52 | hsv_t hsv = rgb_matrix_config.hsv; | ||
| 53 | hsv.h -= value / 4; | ||
| 54 | hsv.s = scale8(hsv.s, (value < 74) ? 255 : (549 - 4 * value)); | ||
| 55 | hsv.v = scale8(hsv.v, (value < 95) ? (64 + 2 * value) : 255); | ||
| 56 | |||
| 57 | rgb_t rgb = rgb_matrix_hsv_to_rgb(hsv); | ||
| 58 | rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b); | ||
| 59 | } | ||
| 60 | |||
| 61 | return rgb_matrix_check_finished_leds(led_max); | ||
| 62 | } | ||
| 63 | |||
| 64 | #endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS | ||
diff --git a/quantum/led_matrix/led_matrix.c b/quantum/led_matrix/led_matrix.c index 00bc199ecf..7a0e8a5ebb 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; | |||
| 45 | #define LED_MATRIX_CUSTOM_EFFECT_IMPLS | 45 | #define LED_MATRIX_CUSTOM_EFFECT_IMPLS |
| 46 | 46 | ||
| 47 | #include "led_matrix_effects.inc" | 47 | #include "led_matrix_effects.inc" |
| 48 | #ifdef COMMUNITY_MODULES_ENABLE | ||
| 49 | # include "led_matrix_community_modules.inc" | ||
| 50 | #endif | ||
| 48 | #ifdef LED_MATRIX_CUSTOM_KB | 51 | #ifdef LED_MATRIX_CUSTOM_KB |
| 49 | # include "led_matrix_kb.inc" | 52 | # include "led_matrix_kb.inc" |
| 50 | #endif | 53 | #endif |
| @@ -282,6 +285,15 @@ static void led_task_render(uint8_t effect) { | |||
| 282 | #include "led_matrix_effects.inc" | 285 | #include "led_matrix_effects.inc" |
| 283 | #undef LED_MATRIX_EFFECT | 286 | #undef LED_MATRIX_EFFECT |
| 284 | 287 | ||
| 288 | #ifdef COMMUNITY_MODULES_ENABLE | ||
| 289 | # define LED_MATRIX_EFFECT(name, ...) \ | ||
| 290 | case LED_MATRIX_COMMUNITY_MODULE_##name: \ | ||
| 291 | rendering = name(&led_effect_params); \ | ||
| 292 | break; | ||
| 293 | # include "led_matrix_community_modules.inc" | ||
| 294 | # undef LED_MATRIX_EFFECT | ||
| 295 | #endif | ||
| 296 | |||
| 285 | #if defined(LED_MATRIX_CUSTOM_KB) || defined(LED_MATRIX_CUSTOM_USER) | 297 | #if defined(LED_MATRIX_CUSTOM_KB) || defined(LED_MATRIX_CUSTOM_USER) |
| 286 | # define LED_MATRIX_EFFECT(name, ...) \ | 298 | # define LED_MATRIX_EFFECT(name, ...) \ |
| 287 | case LED_MATRIX_CUSTOM_##name: \ | 299 | case LED_MATRIX_CUSTOM_##name: \ |
diff --git a/quantum/led_matrix/led_matrix.h b/quantum/led_matrix/led_matrix.h index 0006d487e9..0dfe33ffab 100644 --- a/quantum/led_matrix/led_matrix.h +++ b/quantum/led_matrix/led_matrix.h | |||
| @@ -98,6 +98,12 @@ enum led_matrix_effects { | |||
| 98 | #include "led_matrix_effects.inc" | 98 | #include "led_matrix_effects.inc" |
| 99 | #undef LED_MATRIX_EFFECT | 99 | #undef LED_MATRIX_EFFECT |
| 100 | 100 | ||
| 101 | #ifdef COMMUNITY_MODULES_ENABLE | ||
| 102 | # define LED_MATRIX_EFFECT(name, ...) LED_MATRIX_COMMUNITY_MODULE_##name, | ||
| 103 | # include "led_matrix_community_modules.inc" | ||
| 104 | # undef LED_MATRIX_EFFECT | ||
| 105 | #endif | ||
| 106 | |||
| 101 | #if defined(LED_MATRIX_CUSTOM_KB) || defined(LED_MATRIX_CUSTOM_USER) | 107 | #if defined(LED_MATRIX_CUSTOM_KB) || defined(LED_MATRIX_CUSTOM_USER) |
| 102 | # define LED_MATRIX_EFFECT(name, ...) LED_MATRIX_CUSTOM_##name, | 108 | # define LED_MATRIX_EFFECT(name, ...) LED_MATRIX_CUSTOM_##name, |
| 103 | # ifdef LED_MATRIX_CUSTOM_KB | 109 | # ifdef LED_MATRIX_CUSTOM_KB |
diff --git a/quantum/rgb_matrix/rgb_matrix.c b/quantum/rgb_matrix/rgb_matrix.c index 94852e3520..2679c48342 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) { | |||
| 47 | #define RGB_MATRIX_CUSTOM_EFFECT_IMPLS | 47 | #define RGB_MATRIX_CUSTOM_EFFECT_IMPLS |
| 48 | 48 | ||
| 49 | #include "rgb_matrix_effects.inc" | 49 | #include "rgb_matrix_effects.inc" |
| 50 | #ifdef COMMUNITY_MODULES_ENABLE | ||
| 51 | # include "rgb_matrix_community_modules.inc" | ||
| 52 | #endif | ||
| 50 | #ifdef RGB_MATRIX_CUSTOM_KB | 53 | #ifdef RGB_MATRIX_CUSTOM_KB |
| 51 | # include "rgb_matrix_kb.inc" | 54 | # include "rgb_matrix_kb.inc" |
| 52 | #endif | 55 | #endif |
| @@ -310,6 +313,15 @@ static void rgb_task_render(uint8_t effect) { | |||
| 310 | #include "rgb_matrix_effects.inc" | 313 | #include "rgb_matrix_effects.inc" |
| 311 | #undef RGB_MATRIX_EFFECT | 314 | #undef RGB_MATRIX_EFFECT |
| 312 | 315 | ||
| 316 | #ifdef COMMUNITY_MODULES_ENABLE | ||
| 317 | # define RGB_MATRIX_EFFECT(name, ...) \ | ||
| 318 | case RGB_MATRIX_COMMUNITY_MODULE_##name: \ | ||
| 319 | rendering = name(&rgb_effect_params); \ | ||
| 320 | break; | ||
| 321 | # include "rgb_matrix_community_modules.inc" | ||
| 322 | # undef RGB_MATRIX_EFFECT | ||
| 323 | #endif | ||
| 324 | |||
| 313 | #if defined(RGB_MATRIX_CUSTOM_KB) || defined(RGB_MATRIX_CUSTOM_USER) | 325 | #if defined(RGB_MATRIX_CUSTOM_KB) || defined(RGB_MATRIX_CUSTOM_USER) |
| 314 | # define RGB_MATRIX_EFFECT(name, ...) \ | 326 | # define RGB_MATRIX_EFFECT(name, ...) \ |
| 315 | case RGB_MATRIX_CUSTOM_##name: \ | 327 | case RGB_MATRIX_CUSTOM_##name: \ |
diff --git a/quantum/rgb_matrix/rgb_matrix.h b/quantum/rgb_matrix/rgb_matrix.h index e00e3927c7..c6b302631e 100644 --- a/quantum/rgb_matrix/rgb_matrix.h +++ b/quantum/rgb_matrix/rgb_matrix.h | |||
| @@ -123,6 +123,12 @@ enum rgb_matrix_effects { | |||
| 123 | #include "rgb_matrix_effects.inc" | 123 | #include "rgb_matrix_effects.inc" |
| 124 | #undef RGB_MATRIX_EFFECT | 124 | #undef RGB_MATRIX_EFFECT |
| 125 | 125 | ||
| 126 | #ifdef COMMUNITY_MODULES_ENABLE | ||
| 127 | # define RGB_MATRIX_EFFECT(name, ...) RGB_MATRIX_COMMUNITY_MODULE_##name, | ||
| 128 | # include "rgb_matrix_community_modules.inc" | ||
| 129 | # undef RGB_MATRIX_EFFECT | ||
| 130 | #endif | ||
| 131 | |||
| 126 | #if defined(RGB_MATRIX_CUSTOM_KB) || defined(RGB_MATRIX_CUSTOM_USER) | 132 | #if defined(RGB_MATRIX_CUSTOM_KB) || defined(RGB_MATRIX_CUSTOM_USER) |
| 127 | # define RGB_MATRIX_EFFECT(name, ...) RGB_MATRIX_CUSTOM_##name, | 133 | # define RGB_MATRIX_EFFECT(name, ...) RGB_MATRIX_CUSTOM_##name, |
| 128 | # ifdef RGB_MATRIX_CUSTOM_KB | 134 | # ifdef RGB_MATRIX_CUSTOM_KB |
