aboutsummaryrefslogtreecommitdiff
path: root/quantum
diff options
context:
space:
mode:
Diffstat (limited to 'quantum')
-rw-r--r--quantum/audio/audio.c5
-rw-r--r--quantum/debounce/tests/rules.mk1
-rw-r--r--quantum/dynamic_keymap.c66
-rw-r--r--quantum/keymap_extras/keymap_eurkey.h166
-rw-r--r--quantum/keymap_extras/keymap_farsi.h2
-rw-r--r--quantum/leader.c7
-rw-r--r--quantum/leader.h9
-rw-r--r--quantum/os_detection/tests/rules.mk1
-rw-r--r--quantum/painter/qgf.c8
-rw-r--r--quantum/painter/qp_draw_image.c6
-rw-r--r--quantum/rgb_matrix/animations/hue_breathing_anim.h22
-rw-r--r--quantum/rgb_matrix/animations/raindrops_anim.h29
-rw-r--r--quantum/rgb_matrix/animations/starlight_anim.h29
-rw-r--r--quantum/rgb_matrix/animations/starlight_dual_hue_anim.h31
-rw-r--r--quantum/rgb_matrix/animations/starlight_dual_sat_anim.h31
-rw-r--r--quantum/send_string/send_string.c88
-rw-r--r--quantum/send_string/send_string.h8
-rw-r--r--quantum/sequencer/tests/rules.mk1
18 files changed, 338 insertions, 172 deletions
diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c
index b2611c5f09..2cc3c2d661 100644
--- a/quantum/audio/audio.c
+++ b/quantum/audio/audio.c
@@ -258,11 +258,10 @@ void audio_stop_tone(float pitch) {
for (int i = AUDIO_TONE_STACKSIZE - 1; i >= 0; i--) {
found = (tones[i].pitch == pitch);
if (found) {
- tones[i] = (musical_tone_t){.time_started = 0, .pitch = -1.0f, .duration = 0};
for (int j = i; (j < AUDIO_TONE_STACKSIZE - 1); j++) {
- tones[j] = tones[j + 1];
- tones[j + 1] = (musical_tone_t){.time_started = 0, .pitch = -1.0f, .duration = 0};
+ tones[j] = tones[j + 1];
}
+ tones[AUDIO_TONE_STACKSIZE - 1] = (musical_tone_t){.time_started = 0, .pitch = -1.0f, .duration = 0};
break;
}
}
diff --git a/quantum/debounce/tests/rules.mk b/quantum/debounce/tests/rules.mk
index bbc362d4c7..d38b1cd342 100644
--- a/quantum/debounce/tests/rules.mk
+++ b/quantum/debounce/tests/rules.mk
@@ -16,6 +16,7 @@
DEBOUNCE_COMMON_DEFS := -DMATRIX_ROWS=4 -DMATRIX_COLS=10 -DDEBOUNCE=5
DEBOUNCE_COMMON_SRC := $(QUANTUM_PATH)/debounce/tests/debounce_test_common.cpp \
+ $(PLATFORM_PATH)/timer.c \
$(PLATFORM_PATH)/$(PLATFORM_KEY)/timer.c
debounce_none_DEFS := $(DEBOUNCE_COMMON_DEFS)
diff --git a/quantum/dynamic_keymap.c b/quantum/dynamic_keymap.c
index 3c22bbd445..beb7f9d18f 100644
--- a/quantum/dynamic_keymap.c
+++ b/quantum/dynamic_keymap.c
@@ -245,6 +245,17 @@ void dynamic_keymap_macro_set_buffer(uint16_t offset, uint16_t size, uint8_t *da
}
}
+typedef struct send_string_eeprom_state_t {
+ const uint8_t *ptr;
+} send_string_eeprom_state_t;
+
+char send_string_get_next_eeprom(void *arg) {
+ send_string_eeprom_state_t *state = (send_string_eeprom_state_t *)arg;
+ char ret = eeprom_read_byte(state->ptr);
+ state->ptr++;
+ return ret;
+}
+
void dynamic_keymap_macro_reset(void) {
void *p = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR);
void *end = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE);
@@ -284,57 +295,6 @@ void dynamic_keymap_macro_send(uint8_t id) {
++p;
}
- // Send the macro string by making a temporary string.
- char data[8] = {0};
- // We already checked there was a null at the end of
- // the buffer, so this cannot go past the end
- while (1) {
- data[0] = eeprom_read_byte(p++);
- data[1] = 0;
- // Stop at the null terminator of this macro string
- if (data[0] == 0) {
- break;
- }
- if (data[0] == SS_QMK_PREFIX) {
- // Get the code
- data[1] = eeprom_read_byte(p++);
- // Unexpected null, abort.
- if (data[1] == 0) {
- return;
- }
- if (data[1] == SS_TAP_CODE || data[1] == SS_DOWN_CODE || data[1] == SS_UP_CODE) {
- // Get the keycode
- data[2] = eeprom_read_byte(p++);
- // Unexpected null, abort.
- if (data[2] == 0) {
- return;
- }
- // Null terminate
- data[3] = 0;
- } else if (data[1] == SS_DELAY_CODE) {
- // Get the number and '|'
- // At most this is 4 digits plus '|'
- uint8_t i = 2;
- while (1) {
- data[i] = eeprom_read_byte(p++);
- // Unexpected null, abort
- if (data[i] == 0) {
- return;
- }
- // Found '|', send it
- if (data[i] == '|') {
- data[i + 1] = 0;
- break;
- }
- // If haven't found '|' by i==6 then
- // number too big, abort
- if (i == 6) {
- return;
- }
- ++i;
- }
- }
- }
- send_string_with_delay(data, DYNAMIC_KEYMAP_MACRO_DELAY);
- }
+ send_string_eeprom_state_t state = {p};
+ send_string_with_delay_impl(send_string_get_next_eeprom, &state, DYNAMIC_KEYMAP_MACRO_DELAY);
}
diff --git a/quantum/keymap_extras/keymap_eurkey.h b/quantum/keymap_extras/keymap_eurkey.h
new file mode 100644
index 0000000000..20f7f58683
--- /dev/null
+++ b/quantum/keymap_extras/keymap_eurkey.h
@@ -0,0 +1,166 @@
+// Copyright 2025 QMK
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/*******************************************************************************
+ 88888888888 888 d8b .d888 d8b 888 d8b
+ 888 888 Y8P d88P" Y8P 888 Y8P
+ 888 888 888 888
+ 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b
+ 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K
+ 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b.
+ 888 888 888 888 X88 888 888 888 Y8b. 888 X88
+ 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P'
+ 888 888
+ 888 888
+ 888 888
+ .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888
+ d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888
+ 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888
+ Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888
+ "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888
+ 888
+ Y8b d88P
+ "Y88P"
+*******************************************************************************/
+
+#pragma once
+#include "keycodes.h"
+// clang-format off
+
+// Aliases
+#define EU_GRV KC_GRV // `
+#define EU_1 KC_1 // 1
+#define EU_2 KC_2 // 2
+#define EU_3 KC_3 // 3
+#define EU_4 KC_4 // 4
+#define EU_5 KC_5 // 5
+#define EU_6 KC_6 // 6
+#define EU_7 KC_7 // 7
+#define EU_8 KC_8 // 8
+#define EU_9 KC_9 // 9
+#define EU_0 KC_0 // 0
+#define EU_MINS KC_MINS // -
+#define EU_EQL KC_EQL // =
+#define EU_Q KC_Q // Q
+#define EU_W KC_W // W
+#define EU_E KC_E // E
+#define EU_R KC_R // R
+#define EU_T KC_T // T
+#define EU_Y KC_Y // Y
+#define EU_U KC_U // U
+#define EU_I KC_I // I
+#define EU_O KC_O // O
+#define EU_P KC_P // P
+#define EU_LBRC KC_LBRC // [
+#define EU_RBRC KC_RBRC // ]
+#define EU_BSLS KC_BSLS // (backslash)
+#define EU_A KC_A // A
+#define EU_S KC_S // S
+#define EU_D KC_D // D
+#define EU_F KC_F // F
+#define EU_G KC_G // G
+#define EU_H KC_H // H
+#define EU_J KC_J // J
+#define EU_K KC_K // K
+#define EU_L KC_L // L
+#define EU_SCLN KC_SCLN // ;
+#define EU_QUOT KC_QUOT // '
+#define EU_Z KC_Z // Z
+#define EU_X KC_X // X
+#define EU_C KC_C // C
+#define EU_V KC_V // V
+#define EU_B KC_B // B
+#define EU_N KC_N // N
+#define EU_M KC_M // M
+#define EU_COMM KC_COMM // ,
+#define EU_DOT KC_DOT // .
+#define EU_SLSH KC_SLSH // /
+#define EU_TILD S(EU_GRV) // ~
+#define EU_EXLM S(EU_1) // !
+#define EU_AT S(EU_2) // @
+#define EU_HASH S(EU_3) // #
+#define EU_DLR S(EU_4) // $
+#define EU_PERC S(EU_5) // %
+#define EU_CIRC S(EU_6) // ^
+#define EU_AMPR S(EU_7) // &
+#define EU_ASTR S(EU_8) // *
+#define EU_LPRN S(EU_9) // (
+#define EU_RPRN S(EU_0) // )
+#define EU_UNDS S(EU_MINS) // _
+#define EU_PLUS S(EU_EQL) // +
+#define EU_LCBR S(EU_LBRC) // {
+#define EU_RCBR S(EU_RBRC) // }
+#define EU_PIPE S(EU_BSLS) // |
+#define EU_COLN S(EU_SCLN) // :
+#define EU_DQUO S(EU_QUOT) // "
+#define EU_LABK S(EU_COMM) // <
+#define EU_RABK S(EU_DOT) // >
+#define EU_QUES S(EU_SLSH) // ?
+#define EU_DGRV ALGR(EU_GRV) // ` (dead)
+#define EU_IEXL ALGR(EU_1) // ¡
+#define EU_FORD ALGR(EU_2) // ª
+#define EU_MORD ALGR(EU_3) // º
+#define EU_PND ALGR(EU_4) // £
+#define EU_EURO ALGR(EU_5) // €
+#define EU_DCIR ALGR(EU_6) // ^ (dead)
+#define EU_RNGA ALGR(EU_7) // ˚ (dead)
+#define EU_DLQU ALGR(EU_8) // „
+#define EU_LDQU ALGR(EU_9) // “
+#define EU_RDQU ALGR(EU_0) // ”
+#define EU_NDSH ALGR(EU_MINS) // –
+#define EU_MUL ALGR(EU_EQL) // ×
+#define EU_AE ALGR(EU_Q) // æ
+#define EU_ARNG ALGR(EU_W) // Å
+#define EU_EDIA ALGR(EU_E) // Ë
+#define EU_YACU ALGR(EU_R) // Ý
+#define EU_THRN ALGR(EU_T) // Þ
+#define EU_YDIA ALGR(EU_Y) // Ÿ
+#define EU_UDIA ALGR(EU_U) // Ü
+#define EU_IDIA ALGR(EU_I) // Ï
+#define EU_ODIA ALGR(EU_O) // Ö
+#define EU_OE ALGR(EU_P) // Œ
+#define EU_LDAQ ALGR(EU_LBRC) // «
+#define EU_RDAQ ALGR(EU_RBRC) // »
+#define EU_NOT ALGR(EU_BSLS) // ¬
+#define EU_ADIA ALGR(EU_A) // Ä
+#define EU_SS ALGR(EU_S) // ß
+#define EU_ETH ALGR(EU_D) // Ð
+#define EU_EGRV ALGR(EU_F) // È
+#define EU_EACU ALGR(EU_G) // É
+#define EU_UGRV ALGR(EU_H) // Ù
+#define EU_UACU ALGR(EU_J) // Ú
+#define EU_IJ ALGR(EU_K) // IJ
+#define EU_OSTR ALGR(EU_L) // Ø
+#define EU_DEG ALGR(EU_SCLN) // °
+#define EU_ACUT ALGR(EU_QUOT) // ´ (dead)
+#define EU_AGRV ALGR(EU_Z) // À
+#define EU_AACU ALGR(EU_X) // Á
+#define EU_CCED ALGR(EU_C) // Ç
+#define EU_IGRV ALGR(EU_V) // Ì
+#define EU_IACU ALGR(EU_B) // Í
+#define EU_NTIL ALGR(EU_N) // Ñ
+#define EU_DGRK ALGR(EU_M) // μ (dead Greek key)
+#define EU_OGRV ALGR(EU_COMM) // Ò
+#define EU_OACU ALGR(EU_DOT) // Ó
+#define EU_IQUE ALGR(EU_SLSH) // ¿
+#define EU_DTIL ALGR(EU_TILD) // ~ (dead)
+#define EU_SUP1 S(ALGR(EU_1)) // ¹
+#define EU_SUP2 S(ALGR(EU_2)) // ²
+#define EU_SUP3 S(ALGR(EU_3)) // ³
+#define EU_YEN ALGR(EU_DLR) // ¥
+#define EU_CENT S(EU_EURO) // ¢
+#define EU_CARN S(EU_DCIR) // ˇ (dead)
+#define EU_MACR S(ALGR(EU_7)) // ¯ (dead)
+#define EU_SLQU S(EU_DLQU) // ‚
+#define EU_LSQU S(EU_LDQU) // ‘
+#define EU_RSQU S(EU_RDQU) // ’
+#define EU_MDSH S(EU_NDSH) // —
+#define EU_DIV S(EU_MUL) // ÷
+#define EU_LSAQ S(EU_LDAQ) // ‹
+#define EU_RSAQ S(EU_RDAQ) // ›
+#define EU_BRKP S(ALGR(EU_BSLS)) // ¦
+#define EU_SECT S(ALGR(EU_S)) // §
+#define EU_MDDT S(ALGR(EU_SCLN)) // ·
+#define EU_DIAE ALGR(EU_DQUO) // ¨ (dead)
+#define EU_ELLP ALGR(EU_QUES) // …
+
diff --git a/quantum/keymap_extras/keymap_farsi.h b/quantum/keymap_extras/keymap_farsi.h
index 8e16188a8f..4f34b08d92 100644
--- a/quantum/keymap_extras/keymap_farsi.h
+++ b/quantum/keymap_extras/keymap_farsi.h
@@ -150,7 +150,7 @@
#define FA_DQT ALGR(FA_GAF) // "
#define FA_MINA ALGR(FA_BSLS) // -
#define FA_PIPE ALGR(FA_ZA) // |
-#define FA_SUBA ALGR(FA_RA) // ٖ
+#define FA_SUBA ALGR(FA_RE) // ٖ
#define FA_HMZB ALGR(FA_DAL) // ء
#define FA_ELLP ALGR(FA_PE) // …
#define FA_COMM ALGR(FA_WAW) // ,
diff --git a/quantum/leader.c b/quantum/leader.c
index 272609ad0c..23e5e8cd6d 100644
--- a/quantum/leader.c
+++ b/quantum/leader.c
@@ -21,6 +21,10 @@ __attribute__((weak)) void leader_start_user(void) {}
__attribute__((weak)) void leader_end_user(void) {}
+__attribute__((weak)) bool leader_add_user(uint16_t keycode) {
+ return false;
+}
+
void leader_start(void) {
if (leading) {
return;
@@ -61,6 +65,9 @@ bool leader_sequence_add(uint16_t keycode) {
leader_sequence[leader_sequence_size] = keycode;
leader_sequence_size++;
+ if (leader_add_user(keycode)) {
+ leader_end();
+ }
return true;
}
diff --git a/quantum/leader.h b/quantum/leader.h
index 3177fcd196..fba6b287ba 100644
--- a/quantum/leader.h
+++ b/quantum/leader.h
@@ -22,6 +22,15 @@ void leader_start_user(void);
void leader_end_user(void);
/**
+ * \brief User callback, invoked when a keycode is added to the leader sequence.
+ *
+ * \param keycode The keycode added to the leader sequence.
+ *
+ * \return `true` to finish the key sequence, `false` to continue.
+ */
+bool leader_add_user(uint16_t keycode);
+
+/**
* Begin the leader sequence, resetting the buffer and timer.
*/
void leader_start(void);
diff --git a/quantum/os_detection/tests/rules.mk b/quantum/os_detection/tests/rules.mk
index 1b69b71ba9..2f31f5e391 100644
--- a/quantum/os_detection/tests/rules.mk
+++ b/quantum/os_detection/tests/rules.mk
@@ -4,4 +4,5 @@ os_detection_DEFS += -DOS_DETECTION_DEBOUNCE=50
os_detection_SRC := \
$(QUANTUM_PATH)/os_detection/tests/os_detection.cpp \
$(QUANTUM_PATH)/os_detection.c \
+ $(PLATFORM_PATH)/timer.c \
$(PLATFORM_PATH)/$(PLATFORM_KEY)/timer.c
diff --git a/quantum/painter/qgf.c b/quantum/painter/qgf.c
index bc2df94933..07c3f80314 100644
--- a/quantum/painter/qgf.c
+++ b/quantum/painter/qgf.c
@@ -255,10 +255,10 @@ bool qgf_validate_stream(qp_stream_t *stream) {
// Read and validate all the frames (automatically validates the frame offset descriptor in the process)
for (uint16_t i = 0; i < frame_count; ++i) {
// Validate the frame descriptor block
- uint8_t bpp;
- bool has_palette;
- bool is_panel_native;
- bool has_delta;
+ uint8_t bpp = 0;
+ bool has_palette = false;
+ bool is_panel_native = false;
+ bool has_delta = false;
if (!qgf_validate_frame_descriptor(stream, i, &bpp, &has_palette, &is_panel_native, &has_delta)) {
return false;
}
diff --git a/quantum/painter/qp_draw_image.c b/quantum/painter/qp_draw_image.c
index 18fa38cb19..a225039af4 100644
--- a/quantum/painter/qp_draw_image.c
+++ b/quantum/painter/qp_draw_image.c
@@ -318,9 +318,9 @@ static deferred_token qp_render_animation_state(animation_state_t *state, uint16
}
static uint32_t animation_callback(uint32_t trigger_time, void *cb_arg) {
- animation_state_t *state = (animation_state_t *)cb_arg;
- uint16_t delay_ms;
- bool ret = qp_render_animation_state(state, &delay_ms);
+ animation_state_t *state = (animation_state_t *)cb_arg;
+ uint16_t delay_ms = 0;
+ bool ret = qp_render_animation_state(state, &delay_ms);
if (!ret) {
// Setting the device to NULL clears the animation slot
state->device = NULL;
diff --git a/quantum/rgb_matrix/animations/hue_breathing_anim.h b/quantum/rgb_matrix/animations/hue_breathing_anim.h
index 5316e92dbd..60d7426cfc 100644
--- a/quantum/rgb_matrix/animations/hue_breathing_anim.h
+++ b/quantum/rgb_matrix/animations/hue_breathing_anim.h
@@ -2,21 +2,17 @@
RGB_MATRIX_EFFECT(HUE_BREATHING)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-// Change huedelta to adjust range of hue change. 0-255.
// Hue Breathing - All LED's light up
+hsv_t HUE_BREATHING_math(hsv_t hsv, uint8_t i, uint8_t time) {
+ // Adjust delta between 0-255 to change hue range
+ uint8_t delta = 12;
+ hsv.h = hsv.h + scale8(abs8(sin8(time / 2) - 128) * 2, delta);
+ return hsv;
+}
+
bool HUE_BREATHING(effect_params_t* params) {
- RGB_MATRIX_USE_LIMITS(led_min, led_max);
- uint8_t huedelta = 12;
- hsv_t hsv = rgb_matrix_config.hsv;
- uint16_t time = scale16by8(g_rgb_timer, rgb_matrix_config.speed / 8);
- hsv.h = hsv.h + scale8(abs8(sin8(time) - 128) * 2, huedelta);
- rgb_t rgb = hsv_to_rgb(hsv);
- for (uint8_t i = led_min; i < led_max; i++) {
- RGB_MATRIX_TEST_LED_FLAGS();
- rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
- }
- return rgb_matrix_check_finished_leds(led_max);
+ return effect_runner_i(params, &HUE_BREATHING_math);
}
# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-#endif // DISABLE_RGB_HUE_BREATHING
+#endif // ENABLE_RGB_MATRIX_HUE_BREATHING
diff --git a/quantum/rgb_matrix/animations/raindrops_anim.h b/quantum/rgb_matrix/animations/raindrops_anim.h
index a682156da2..d4f79adb56 100644
--- a/quantum/rgb_matrix/animations/raindrops_anim.h
+++ b/quantum/rgb_matrix/animations/raindrops_anim.h
@@ -2,35 +2,42 @@
RGB_MATRIX_EFFECT(RAINDROPS)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-static void raindrops_set_color(int i, effect_params_t* params) {
+static void raindrops_set_color(uint8_t i, effect_params_t* params) {
if (!HAS_ANY_FLAGS(g_led_config.flags[i], params->flags)) return;
- hsv_t hsv = {0, rgb_matrix_config.hsv.s, rgb_matrix_config.hsv.v};
+ hsv_t hsv = rgb_matrix_config.hsv;
// Take the shortest path between hues
- int16_t deltaH = ((rgb_matrix_config.hsv.h + 180) % 360 - rgb_matrix_config.hsv.h) / 4;
+ int16_t deltaH = ((hsv.h + 180) % 360 - hsv.h) / 4;
if (deltaH > 127) {
deltaH -= 256;
} else if (deltaH < -127) {
deltaH += 256;
}
- hsv.h = rgb_matrix_config.hsv.h + (deltaH * (random8() & 0x03));
+ hsv.h += (deltaH * random8_max(3));
rgb_t rgb = rgb_matrix_hsv_to_rgb(hsv);
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
bool RAINDROPS(effect_params_t* params) {
+ static uint16_t index = RGB_MATRIX_LED_COUNT + 1;
+
+ // Periodic trigger for LED change
+ if ((params->iter == 0) && (scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed, 16)) % 10 == 0)) {
+ index = random8_max(RGB_MATRIX_LED_COUNT);
+ }
+
RGB_MATRIX_USE_LIMITS(led_min, led_max);
- if (!params->init) {
- // Change one LED every tick, make sure speed is not 0
- if (scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed, 16)) % 10 == 0) {
- raindrops_set_color(random8_max(RGB_MATRIX_LED_COUNT), params);
- }
- } else {
- for (int i = led_min; i < led_max; i++) {
+ if (params->init) {
+ for (uint8_t i = led_min; i < led_max; i++) {
raindrops_set_color(i, params);
}
}
+ // Change LED once and set index out of range till next trigger
+ else if (led_min <= index && index < led_max) {
+ raindrops_set_color(index, params);
+ index = RGB_MATRIX_LED_COUNT + 1;
+ }
return rgb_matrix_check_finished_leds(led_max);
}
diff --git a/quantum/rgb_matrix/animations/starlight_anim.h b/quantum/rgb_matrix/animations/starlight_anim.h
index 742e843b57..c4f943c5ce 100644
--- a/quantum/rgb_matrix/animations/starlight_anim.h
+++ b/quantum/rgb_matrix/animations/starlight_anim.h
@@ -2,7 +2,9 @@
RGB_MATRIX_EFFECT(STARLIGHT)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-void set_starlight_color(uint8_t i, effect_params_t* params) {
+static void set_starlight_color(uint8_t i, effect_params_t* params) {
+ if (!HAS_ANY_FLAGS(g_led_config.flags[i], params->flags)) return;
+
uint16_t time = scale16by8(g_rgb_timer, rgb_matrix_config.speed / 8);
hsv_t hsv = rgb_matrix_config.hsv;
hsv.v = scale8(abs8(sin8(time) - 128) * 2, hsv.v);
@@ -11,21 +13,26 @@ void set_starlight_color(uint8_t i, effect_params_t* params) {
}
bool STARLIGHT(effect_params_t* params) {
- if (!params->init) {
- if (scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed, 5)) % 5 == 0) {
- uint8_t rand_led = random8_max(RGB_MATRIX_LED_COUNT);
- set_starlight_color(rand_led, params);
- }
- return false;
+ static uint16_t index = RGB_MATRIX_LED_COUNT + 1;
+
+ // Periodic trigger for LED change
+ if ((params->iter == 0) && (scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed, 5)) % 5 == 0)) {
+ index = random8_max(RGB_MATRIX_LED_COUNT);
}
RGB_MATRIX_USE_LIMITS(led_min, led_max);
- for (uint8_t i = led_min; i < led_max; i++) {
- RGB_MATRIX_TEST_LED_FLAGS();
- set_starlight_color(i, params);
+ if (params->init) {
+ for (uint8_t i = led_min; i < led_max; i++) {
+ set_starlight_color(i, params);
+ }
+ }
+ // Change LED once and set index out of range till next trigger
+ else if (led_min <= index && index < led_max) {
+ set_starlight_color(index, params);
+ index = RGB_MATRIX_LED_COUNT + 1;
}
return rgb_matrix_check_finished_leds(led_max);
}
# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-#endif // ENABLE_RGB_MATRIX_STARLIGHT \ No newline at end of file
+#endif // ENABLE_RGB_MATRIX_STARLIGHT
diff --git a/quantum/rgb_matrix/animations/starlight_dual_hue_anim.h b/quantum/rgb_matrix/animations/starlight_dual_hue_anim.h
index 50ce5d6ab4..276b8c3fdf 100644
--- a/quantum/rgb_matrix/animations/starlight_dual_hue_anim.h
+++ b/quantum/rgb_matrix/animations/starlight_dual_hue_anim.h
@@ -2,31 +2,38 @@
RGB_MATRIX_EFFECT(STARLIGHT_DUAL_HUE)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-void set_starlight_dual_hue_color(uint8_t i, effect_params_t* params) {
+static void set_starlight_dual_hue_color(uint8_t i, effect_params_t* params) {
+ if (!HAS_ANY_FLAGS(g_led_config.flags[i], params->flags)) return;
+
uint16_t time = scale16by8(g_rgb_timer, rgb_matrix_config.speed / 8);
hsv_t hsv = rgb_matrix_config.hsv;
hsv.v = scale8(abs8(sin8(time) - 128) * 2, hsv.v);
- hsv.h = hsv.h + random8_max((30 + 1 - -30) + -30);
+ hsv.h = hsv.h + random8_max(31);
rgb_t rgb = rgb_matrix_hsv_to_rgb(hsv);
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
bool STARLIGHT_DUAL_HUE(effect_params_t* params) {
- if (!params->init) {
- if (scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed, 5)) % 5 == 0) {
- uint8_t rand_led = random8_max(RGB_MATRIX_LED_COUNT);
- set_starlight_dual_hue_color(rand_led, params);
- }
- return false;
+ static uint16_t index = RGB_MATRIX_LED_COUNT + 1;
+
+ // Periodic trigger for LED change
+ if ((params->iter == 0) && (scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed, 5)) % 5 == 0)) {
+ index = random8_max(RGB_MATRIX_LED_COUNT);
}
RGB_MATRIX_USE_LIMITS(led_min, led_max);
- for (uint8_t i = led_min; i < led_max; i++) {
- RGB_MATRIX_TEST_LED_FLAGS();
- set_starlight_dual_hue_color(i, params);
+ if (params->init) {
+ for (uint8_t i = led_min; i < led_max; i++) {
+ set_starlight_dual_hue_color(i, params);
+ }
+ }
+ // Change LED once and set index out of range till next trigger
+ else if (led_min <= index && index < led_max) {
+ set_starlight_dual_hue_color(index, params);
+ index = RGB_MATRIX_LED_COUNT + 1;
}
return rgb_matrix_check_finished_leds(led_max);
}
# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-#endif // ENABLE_RGB_MATRIX_STARLIGHT_DUAL_HUE \ No newline at end of file
+#endif // ENABLE_RGB_MATRIX_STARLIGHT_DUAL_HUE
diff --git a/quantum/rgb_matrix/animations/starlight_dual_sat_anim.h b/quantum/rgb_matrix/animations/starlight_dual_sat_anim.h
index 6def4eea09..e063658982 100644
--- a/quantum/rgb_matrix/animations/starlight_dual_sat_anim.h
+++ b/quantum/rgb_matrix/animations/starlight_dual_sat_anim.h
@@ -2,31 +2,38 @@
RGB_MATRIX_EFFECT(STARLIGHT_DUAL_SAT)
# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-void set_starlight_dual_sat_color(uint8_t i, effect_params_t* params) {
+static void set_starlight_dual_sat_color(uint8_t i, effect_params_t* params) {
+ if (!HAS_ANY_FLAGS(g_led_config.flags[i], params->flags)) return;
+
uint16_t time = scale16by8(g_rgb_timer, rgb_matrix_config.speed / 8);
hsv_t hsv = rgb_matrix_config.hsv;
hsv.v = scale8(abs8(sin8(time) - 128) * 2, hsv.v);
- hsv.s = hsv.s + random8_max((30 + 1 - -30) + -30);
+ hsv.s = hsv.s + random8_max(31);
rgb_t rgb = rgb_matrix_hsv_to_rgb(hsv);
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
bool STARLIGHT_DUAL_SAT(effect_params_t* params) {
- if (!params->init) {
- if (scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed, 5)) % 5 == 0) {
- uint8_t rand_led = random8_max(RGB_MATRIX_LED_COUNT);
- set_starlight_dual_sat_color(rand_led, params);
- }
- return false;
+ static uint16_t index = RGB_MATRIX_LED_COUNT + 1;
+
+ // Periodic trigger for LED change
+ if ((params->iter == 0) && (scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed, 5)) % 5 == 0)) {
+ index = random8_max(RGB_MATRIX_LED_COUNT);
}
RGB_MATRIX_USE_LIMITS(led_min, led_max);
- for (uint8_t i = led_min; i < led_max; i++) {
- RGB_MATRIX_TEST_LED_FLAGS();
- set_starlight_dual_sat_color(i, params);
+ if (params->init) {
+ for (uint8_t i = led_min; i < led_max; i++) {
+ set_starlight_dual_sat_color(i, params);
+ }
+ }
+ // Change LED once and set index out of range till next trigger
+ else if (led_min <= index && index < led_max) {
+ set_starlight_dual_sat_color(index, params);
+ index = RGB_MATRIX_LED_COUNT + 1;
}
return rgb_matrix_check_finished_leds(led_max);
}
# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
-#endif // ENABLE_RGB_MATRIX_STARLIGHT_DUAL_SAT \ No newline at end of file
+#endif // ENABLE_RGB_MATRIX_STARLIGHT_DUAL_SAT
diff --git a/quantum/send_string/send_string.c b/quantum/send_string/send_string.c
index 44c5ec5ab9..602f24dabe 100644
--- a/quantum/send_string/send_string.c
+++ b/quantum/send_string/send_string.c
@@ -150,48 +150,65 @@ void send_string(const char *string) {
send_string_with_delay(string, TAP_CODE_DELAY);
}
-void send_string_with_delay(const char *string, uint8_t interval) {
+void send_string_with_delay_impl(char (*getter)(void *), void *arg, uint8_t interval) {
while (1) {
- char ascii_code = *string;
+ char ascii_code = getter(arg);
if (!ascii_code) break;
if (ascii_code == SS_QMK_PREFIX) {
- ascii_code = *(++string);
+ ascii_code = getter(arg);
if (ascii_code == SS_TAP_CODE) {
// tap
- uint8_t keycode = *(++string);
+ uint8_t keycode = getter(arg);
tap_code(keycode);
} else if (ascii_code == SS_DOWN_CODE) {
// down
- uint8_t keycode = *(++string);
+ uint8_t keycode = getter(arg);
register_code(keycode);
} else if (ascii_code == SS_UP_CODE) {
// up
- uint8_t keycode = *(++string);
+ uint8_t keycode = getter(arg);
unregister_code(keycode);
} else if (ascii_code == SS_DELAY_CODE) {
// delay
- int ms = 0;
- uint8_t keycode = *(++string);
+ int ms = 0;
+ ascii_code = getter(arg);
- while (isdigit(keycode)) {
+ while (isdigit(ascii_code)) {
ms *= 10;
- ms += keycode - '0';
- keycode = *(++string);
+ ms += ascii_code - '0';
+ ascii_code = getter(arg);
}
wait_ms(ms);
}
wait_ms(interval);
+
+ // if we had a delay that terminated with a null, we're done
+ if (ascii_code == 0) break;
} else {
send_char_with_delay(ascii_code, interval);
}
-
- ++string;
}
}
+typedef struct send_string_memory_state_t {
+ const char *string;
+} send_string_memory_state_t;
+
+char send_string_get_next_ram(void *arg) {
+ send_string_memory_state_t *state = (send_string_memory_state_t *)arg;
+ char ret = *state->string;
+ state->string++;
+ return ret;
+}
+
+void send_string_with_delay(const char *string, uint8_t interval) {
+ send_string_memory_state_t state = {string};
+ send_string_with_delay_impl(send_string_get_next_ram, &state, interval);
+}
+
void send_char(char ascii_code) {
send_char_with_delay(ascii_code, TAP_CODE_DELAY);
}
@@ -297,42 +314,15 @@ void send_string_P(const char *string) {
send_string_with_delay_P(string, TAP_CODE_DELAY);
}
-void send_string_with_delay_P(const char *string, uint8_t interval) {
- while (1) {
- char ascii_code = pgm_read_byte(string);
- if (!ascii_code) break;
- if (ascii_code == SS_QMK_PREFIX) {
- ascii_code = pgm_read_byte(++string);
-
- if (ascii_code == SS_TAP_CODE) {
- // tap
- uint8_t keycode = pgm_read_byte(++string);
- tap_code(keycode);
- } else if (ascii_code == SS_DOWN_CODE) {
- // down
- uint8_t keycode = pgm_read_byte(++string);
- register_code(keycode);
- } else if (ascii_code == SS_UP_CODE) {
- // up
- uint8_t keycode = pgm_read_byte(++string);
- unregister_code(keycode);
- } else if (ascii_code == SS_DELAY_CODE) {
- // delay
- int ms = 0;
- uint8_t keycode = pgm_read_byte(++string);
-
- while (isdigit(keycode)) {
- ms *= 10;
- ms += keycode - '0';
- keycode = pgm_read_byte(++string);
- }
- wait_ms(ms);
- }
- } else {
- send_char_with_delay(ascii_code, interval);
- }
+char send_string_get_next_progmem(void *arg) {
+ send_string_memory_state_t *state = (send_string_memory_state_t *)arg;
+ char ret = pgm_read_byte(state->string);
+ state->string++;
+ return ret;
+}
- ++string;
- }
+void send_string_with_delay_P(const char *string, uint8_t interval) {
+ send_string_memory_state_t state = {string};
+ send_string_with_delay_impl(send_string_get_next_progmem, &state, interval);
}
#endif
diff --git a/quantum/send_string/send_string.h b/quantum/send_string/send_string.h
index f727ec507d..4f91252075 100644
--- a/quantum/send_string/send_string.h
+++ b/quantum/send_string/send_string.h
@@ -161,4 +161,12 @@ void send_string_with_delay_P(const char *string, uint8_t interval);
*/
#define SEND_STRING_DELAY(string, interval) send_string_with_delay_P(PSTR(string), interval)
+/**
+ * \brief Actual implementation function that iterates and sends the string returned by the getter function.
+ *
+ * The getter assumes that the next byte is available to be read, and returns it. `arg` is passed in and can be whatever
+ * makes most sense for the getter -- each invocation of `getter` must advance its position in the source.
+ */
+void send_string_with_delay_impl(char (*getter)(void *), void *arg, uint8_t interval);
+
/** \} */
diff --git a/quantum/sequencer/tests/rules.mk b/quantum/sequencer/tests/rules.mk
index 611459e060..74b680ae31 100644
--- a/quantum/sequencer/tests/rules.mk
+++ b/quantum/sequencer/tests/rules.mk
@@ -8,4 +8,5 @@ sequencer_SRC := \
$(QUANTUM_PATH)/sequencer/tests/midi_mock.c \
$(QUANTUM_PATH)/sequencer/tests/sequencer_tests.cpp \
$(QUANTUM_PATH)/sequencer/sequencer.c \
+ $(PLATFORM_PATH)/timer.c \
$(PLATFORM_PATH)/$(PLATFORM_KEY)/timer.c