From a8100787069368181a24da8c330843f376f51de3 Mon Sep 17 00:00:00 2001 From: Victor Toni Date: Fri, 10 Sep 2021 19:02:59 +0200 Subject: [PATCH] Add RGB fade in when resuming after suspend --- .../gmmk/pro/iso/keymaps/vitoni/config.h | 2 + .../gmmk/pro/iso/keymaps/vitoni/keymap.c | 16 +- .../gmmk/pro/iso/keymaps/vitoni/readme.adoc | 22 +++ users/vitoni/readme.adoc | 16 ++ users/vitoni/rgb_matrix_effects.c | 158 ++++++++++++++++++ users/vitoni/rgb_matrix_effects.h | 90 ++++++++++ users/vitoni/rules.mk | 4 + users/vitoni/utils.c | 96 +++++++++++ users/vitoni/utils.h | 67 ++++++++ users/vitoni/vitoni.c | 71 ++++++++ users/vitoni/vitoni.h | 30 ++++ 11 files changed, 569 insertions(+), 3 deletions(-) create mode 100644 users/vitoni/readme.adoc create mode 100644 users/vitoni/rgb_matrix_effects.c create mode 100644 users/vitoni/rgb_matrix_effects.h create mode 100644 users/vitoni/rules.mk create mode 100644 users/vitoni/utils.c create mode 100644 users/vitoni/utils.h create mode 100644 users/vitoni/vitoni.c create mode 100644 users/vitoni/vitoni.h diff --git a/keyboards/gmmk/pro/iso/keymaps/vitoni/config.h b/keyboards/gmmk/pro/iso/keymaps/vitoni/config.h index 8e775851a41e..d34a239690fd 100644 --- a/keyboards/gmmk/pro/iso/keymaps/vitoni/config.h +++ b/keyboards/gmmk/pro/iso/keymaps/vitoni/config.h @@ -8,4 +8,6 @@ // number of milliseconds to wait until turning off RGB automatically #define RGB_DISABLE_TIMEOUT 300000 // 300 seconds / 5 min #define RGB_DISABLE_WHEN_USB_SUSPENDED + // fade in when we have been suspended + #define RGB_FADE_IN #endif diff --git a/keyboards/gmmk/pro/iso/keymaps/vitoni/keymap.c b/keyboards/gmmk/pro/iso/keymaps/vitoni/keymap.c index 80106987f19d..d5b64c153ab7 100644 --- a/keyboards/gmmk/pro/iso/keymaps/vitoni/keymap.c +++ b/keyboards/gmmk/pro/iso/keymaps/vitoni/keymap.c @@ -4,6 +4,8 @@ #include QMK_KEYBOARD_H +#include "vitoni.h" + enum layer_names { _BASE, _MOV, @@ -91,7 +93,7 @@ bool encoder_update_user(uint8_t index, bool clockwise) { * Set up default RGB color. */ void rgb_matrix_set_default_color(void) { - rgb_matrix_sethsv_noeeprom(HSV_CHARTREUSE); + rgb_matrix_sethsv_noeeprom_user(HSV_CHARTREUSE); } /* @@ -112,10 +114,10 @@ void keyboard_post_init_user(void) { layer_state_t layer_state_set_user(layer_state_t state) { switch (get_highest_layer(state)) { case _MOV: - rgb_matrix_sethsv_noeeprom(HSV_SPRINGGREEN); + rgb_matrix_sethsv_noeeprom_user(HSV_SPRINGGREEN); break; case _RGB: - rgb_matrix_sethsv_noeeprom(HSV_GREEN); + rgb_matrix_sethsv_noeeprom_user(HSV_GREEN); break; default: // for any other layer rgb_matrix_set_default_color(); @@ -124,7 +126,15 @@ layer_state_t layer_state_set_user(layer_state_t state) { return state; } +void matrix_scan_user(void) { + matrix_scan_user_rgb(); +} + bool process_record_user(uint16_t keycode, keyrecord_t *record) { + if (!process_record_user_rgb(keycode, record)) { + return false; + } + switch (keycode) { case RESET: // when activating RESET mode for flashing if (record->event.pressed) { diff --git a/keyboards/gmmk/pro/iso/keymaps/vitoni/readme.adoc b/keyboards/gmmk/pro/iso/keymaps/vitoni/readme.adoc index 941b05ac4234..0775888c7f6a 100644 --- a/keyboards/gmmk/pro/iso/keymaps/vitoni/readme.adoc +++ b/keyboards/gmmk/pro/iso/keymaps/vitoni/readme.adoc @@ -56,3 +56,25 @@ Revamped the stock FN layer to focus on RGB only. |=== No other changes have been made. + +== RGB light + +The code customizing RGB light usage is decribed here: + +* link:../../../../../../users/vitoni/readme.adoc[/users/vitoni/readme.adoc] + +When using `RGB_DISABLE_TIMEOUT` addtional options are available: + +* `RGB_FADE_IN` makes the RGB lights fade in instead of setting the value/brightness to 100% (implicitly due to HSV including the brightness) when resuming after RGB lights have been turned off. +Fade in occurs when the keyboard is initialized and when the RGB brightness has been changed (e.g. suspending, fade out, etc.). + +Parameters used to define the behavior are: +[%header] +|=== +|Key | Default | Description + +| RGB_MATRIX_MAXIMUM_BRIGHTNESS +| 200 (<= UNIT8_MAX) +| Maximum assumed value for brightness. +Used to calculate lead time for fade out before suspend timeout. +|=== diff --git a/users/vitoni/readme.adoc b/users/vitoni/readme.adoc new file mode 100644 index 000000000000..69ccfa9e682b --- /dev/null +++ b/users/vitoni/readme.adoc @@ -0,0 +1,16 @@ += User functions + +Functions are mostly related to changing the RGB lights depending on user interaction and when idling. + +== utils.h + +Common functions are declared in link:utils.h[]. These function are not directly RGB related but used to modify state and calculate values. + +== rgb_matrix_effects.h + +Functions in link:rgb_matrix_effects.h[] make use of common function in `utils.h` and are used to create to RGB matrix effects such as fading. + +== vitoni.h + +The functions declared in link:vitoni.h[] are used as entry points for usage of RGB effects. +One entry point is `matrix_scan` based for regular task while the other is `process_record` based for user activity tasks. diff --git a/users/vitoni/rgb_matrix_effects.c b/users/vitoni/rgb_matrix_effects.c new file mode 100644 index 000000000000..42e3f25a043c --- /dev/null +++ b/users/vitoni/rgb_matrix_effects.c @@ -0,0 +1,158 @@ +// Copyright 2021 Victor Toni (@vitoni) +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "rgb_matrix_effects.h" + +#include +#include + +#include "utils.h" + +/* + Offset used to start at the right point in th curve to avoid big jumps in brightness + 0 => 0% (signed) => 50% (unsigned) + 64 => 100% (signed) => 100% (unsigned) + 128 => 0% (signed) => 50% (unsigned) + 192 => -100% (signed) => 0% (unsigned) +*/ +enum PHASE { + PHASE_ZERO_RAISING + ,PHASE_HIGH + ,PHASE_ZERO_FALLING + ,PHASE_LOW +}; + +/** + * @brief Calculates the offset so that a specific time is aligned to a specific point in the sine curve. + * @param[in] time The time for which the offset shopuld be calculated. + * @param[in] phase Phase which should be reached with the offset + * @see PHASE + */ +uint8_t offset_for_time(const uint8_t time, const uint8_t phase) { + switch (phase) { + case PHASE_ZERO_RAISING: + return 0 - time; + case PHASE_HIGH: + return 64 - time; + case PHASE_ZERO_FALLING: + return 128 - time; + case PHASE_LOW: + return 192 - time; + default: + return 0; + } +} + +/** + * @brief Scales down `g_rgb_timer` so that it can be used for RGB effects. + * @return scaled down timer + * @see rgb_time_2_scale_w_factor() + */ +uint8_t rgb_time_2_scale(void) { + static const uint8_t factor = 1; + return rgb_time_2_scale_w_factor(factor); +} + +/* + * Used to slow down RGB speed. + */ +static const uint8_t rgb_speed_divisor = 8; + +/** + * @brief Scales down `g_rgb_timer` so that it can be used for RGB effects. + * @details Usually these calculations aredone internally by some RGB effects. + This method exposed to scaling so that all effects to have same timebase. If `rgb_matrix_config.speed` all effects are affected the same. + * @param[in] factor The factor can be used to speed up some operations in relation to others. + * @return scaled down timer taking into account the given factor + * @see g_rgb_timer + * @see rgb_matrix_config.speed + */ +uint8_t rgb_time_2_scale_w_factor(const uint8_t rgb_speed_factor) { + const uint8_t scaled_time = scale16by8(g_rgb_timer, rgb_matrix_config.speed * rgb_speed_factor / rgb_speed_divisor); + + return scaled_time; +} + +/** + * @brief Inverse function to calculate time required to execute `timer` steps. + * @details This method allows calculation of the time needed to execute N `timer`steps. + Usefull when using a scaled down time but requiring the time needed to perform these steps. + * @param[in] scaled_time scaled down timer to inverse to time + * @return time corresponding to scaled down time + * @see rgb_time_2_scale() + */ +uint16_t scale_2_rgb_time(const uint8_t scaled_time) { + const uint16_t time = scaled_time * rgb_speed_divisor * UINT8_MAX / rgb_matrix_config.speed; + + return time; +} + +bool fade_in_ranged(const uint8_t time, const uint8_t range_min, const uint8_t range_max) { + static const uint8_t max_delta = 1; + return scaled_sin_up(time, range_min, range_max, max_delta, &(rgb_matrix_config.hsv.v)); +} + +/** + * @brief Convenience method to eventually skip the value part when setting HSV. + * @details When setting HSV this includes the value/brightness. + As changing brightness might interfer with fading or breathing effects, + this method can skip the value part of HSV (depending on the preprocessor flag: RGB_FADE_IN). + * @param[in] hue Hue + * @param[in] sat Saturation + * @param[in] hue Value (brightness) + * @see rgb_matrix_sethsv_noeeprom() + */ +void rgb_matrix_sethsv_noeeprom_user(const uint16_t hue, const uint8_t sat, const uint8_t val) { +#if defined(RGB_FADE_IN) + rgb_matrix_config.hsv.h = hue; + rgb_matrix_config.hsv.s = sat; + // omitting setting the value to avoid interfering with effects +// rgb_matrix_config.hsv.v = val; +#else + rgb_matrix_sethsv_noeeprom(hue, sat, val); +#endif +} + +#if defined(RGB_FADE_IN) +/** + * @brief Calculates the time offset required by fade in. + * @details Using an arbitrary timer any point on the sine curve might be pointed to. + * The offest is calculated so that + * a) the point is at the lowest point in the curve and the curve is raising + * b) the point is near the current brightness (eg. fade in might be called while fading out and the lowest value has not yet been reached). + * @param[in] time Current time usually represented by (usually scaled) timer + * @return Offset required so that time matches the current brightness + */ +uint8_t calc_fade_in_offset(const uint8_t time) { + static const uint8_t max_steps = UINT8_MAX/2; + static const uint8_t range_min = 0; + static const uint8_t range_max = RGB_MATRIX_MAXIMUM_BRIGHTNESS; + + // start at the right point in the sine curve + uint8_t time_offset = offset_for_time(time, PHASE_LOW); + + // find the right offset to match the current brightness + for (int i = 1; i < max_steps; i++) { + const uint8_t value = scaled_sin(time + time_offset + 1, range_min, range_max); + if (in_range(value, range_min, range_max) && value < rgb_matrix_config.hsv.v) { + time_offset++; + } else { + break; + } + } + + return time_offset; +} + +/** + * @brief Increases value/brightness until reaching RGB_MATRIX_MAXIMUM_BRIGHTNESS based on given timer. + * @param[in] time A (usually scaled) timer + * @return Returns `true` if RGB_MATRIX_MAXIMUM_BRIGHTNESS has been reached, `false` otherwise. + */ +bool fade_in(const uint8_t time) { + static const uint8_t range_min = 0; + static const uint8_t range_max = RGB_MATRIX_MAXIMUM_BRIGHTNESS; + + return fade_in_ranged(time, range_min, range_max); +} +#endif diff --git a/users/vitoni/rgb_matrix_effects.h b/users/vitoni/rgb_matrix_effects.h new file mode 100644 index 000000000000..077614aab474 --- /dev/null +++ b/users/vitoni/rgb_matrix_effects.h @@ -0,0 +1,90 @@ +// Copyright 2021 Victor Toni (@vitoni) +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +/** + * States reflecting the state of the keyboard. + * Dependeing on these states various effects can set for the RGB matrix. + */ +enum states { + REGULAR //!< when in regular use +#if defined(RGB_FADE_IN) + ,FADE_IN //!< when starting initially or before going back to REGULAR +#endif + ,SUSPENDED //!< expecting to be suspended by RGB_DISABLE_TIMEOUT any time +}; + +/** + * @brief Scales down `g_rgb_timer` so that it can be used for RGB effects. + * @details Usually these calculations aredone internally by some RGB effects. + This method exposed to scaling so that all effects to have same timebase. If `rgb_matrix_config.speed` all effects are affected the same. + * @param[in] factor The factor can be used to speed up some operations in relation to others. + * @return scaled down timer taking into account the given factor + * @see g_rgb_timer + * @see rgb_matrix_config.speed + */ +uint8_t rgb_time_2_scale_w_factor(const uint8_t factor); + +/** + * @brief Scales down `g_rgb_timer` so that it can be used for RGB effects. + * @return scaled down timer + * @see rgb_time_2_scale_w_factor() + */ +uint8_t rgb_time_2_scale(void); + +/** + * @brief Inverse function to calculate time required to execute `timer` steps. + * @details This method allows calculation of the time needed to execute N `timer`steps. + Usefull when using a scaled down time but requiring the time needed to perform these steps. + * @param[in] scaled_time scaled down timer to inverse to time + * @return time corresponding to scaled down time + * @see rgb_time_2_scale() + */ +uint16_t scale_2_rgb_time(const uint8_t scaled_time); + +/** + * @brief Convenience method to eventually skip the value part when setting HSV. + * @details When setting HSV this includes the value/brightness. + As changing brightness might interfer with fading or breathing effects, + this method can skip the value part of HSV (depending on the preprocessor flag: RGB_FADE_IN). + * @param[in] hue Hue + * @param[in] sat Saturation + * @param[in] hue Value (brightness) + * @see rgb_matrix_sethsv_noeeprom() + */ +void rgb_matrix_sethsv_noeeprom_user(const uint16_t hue, const uint8_t sat, const uint8_t val); + +#if defined(RGB_FADE_IN) +# if defined(RGB_MATRIX_MAXIMUM_BRIGHTNESS) +# if (RGB_MATRIX_MAXIMUM_BRIGHTNESS) < 1 +# error "RGB_MATRIX_MAXIMUM_BRIGHTNESS must not be less than ONE" +# endif +# if UINT8_MAX < (RGB_MATRIX_MAXIMUM_BRIGHTNESS) +# error "RGB_MATRIX_MAXIMUM_BRIGHTNESS must not be larger than UINT8_MAX" +# endif +# else +# define RGB_MATRIX_MAXIMUM_BRIGHTNESS 200 +# endif + +/** + * @brief Calculates the time offset required by fade in. + * @details Using an arbitrary timer any point on the sine curve might be pointed to. + * The offset is calculated so that + * a) the point is at the lowest point in the curve and the curve is raising + * b) the point is near the current brightness (eg. fade in might be called while fading out and the lowest value has not yet been reached). + * @param[in] time Current time usually represented by a(usually scaled) timer + * @return Offset required so that time matches the current brightness + */ +uint8_t calc_fade_in_offset(const uint8_t time); + +/** + * @brief Increases value/brightness until reaching RGB_MATRIX_MAXIMUM_BRIGHTNESS based on given timer. + * @param[in] time A (usually scaled) timer + * @return Returns `true` if RGB_MATRIX_MAXIMUM_BRIGHTNESS has been reached, `false` otherwise. + */ +bool fade_in(const uint8_t time); +#endif diff --git a/users/vitoni/rules.mk b/users/vitoni/rules.mk new file mode 100644 index 000000000000..2f3b0d15e5da --- /dev/null +++ b/users/vitoni/rules.mk @@ -0,0 +1,4 @@ +SRC += \ + vitoni.c \ + utils.c \ + rgb_matrix_effects.c diff --git a/users/vitoni/utils.c b/users/vitoni/utils.c new file mode 100644 index 000000000000..0dbcfd5b4a1c --- /dev/null +++ b/users/vitoni/utils.c @@ -0,0 +1,96 @@ +// Copyright 2021 Victor Toni (@vitoni) +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "utils.h" + +#include + +/** +* @brief Changes `*value` to `new_value`. +* @param[in,out] value Pointer to variable to be changed. +* @param[in] new_value Value to be changed. +* @param[in,out] changed Flag indicating `*value` and `new_value` were different. +*/ +void update_value(uint8_t *value, const uint8_t new_value, bool *changed) { + if (new_value != (*value)) { + (*changed) = true; + (*value) = new_value; + } +} + +/** +* @brief Checks whether a value is in the given range. +* @param[in] value Value to be checked. +* @param[in] range_min Lower bound of range (inclusive). +* @param[in] range_max Upper bound of range (inclusive). +* @return `true` if (range_min <= value <= range_max), `false` otherwise +*/ +bool in_range(const uint8_t value, const uint8_t range_min, const uint8_t range_max) { + return range_min <= value && value <= range_max; +} + +/** +* @brief Calculates the sine value based on sin8() and scales it to the given range (unsigned). +* +* Table of values for unscaled sin8() eg. a theta of 0 results to 128 and a theta of 255 (240+15) results to 125. + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + +---------------------------------------------------------------- + 0: 128 131 134 137 140 143 146 149 152 155 158 161 164 167 170 173 + 16: 177 179 182 184 187 189 192 194 197 200 202 205 207 210 212 215 + 32: 218 219 221 223 224 226 228 229 231 233 234 236 238 239 241 243 + 48: 245 245 246 246 247 248 248 249 250 250 251 251 252 253 253 254 + 64: 255 254 253 253 252 251 251 250 250 249 248 248 247 246 246 245 + 80: 245 243 241 239 238 236 234 233 231 229 228 226 224 223 221 219 + 96: 218 215 212 210 207 205 202 200 197 194 192 189 187 184 182 179 + 112: 177 173 170 167 164 161 158 155 152 149 146 143 140 137 134 131 + 128: 128 125 122 119 116 113 110 107 104 101 98 95 92 89 86 83 + 144: 79 77 74 72 69 67 64 62 59 56 54 51 49 46 44 41 + 160: 38 37 35 33 32 30 28 27 25 23 22 20 18 17 15 13 + 176: 11 11 10 10 9 8 8 7 6 6 5 5 4 3 3 2 + 192: 1 2 3 3 4 5 5 6 6 7 8 8 9 10 10 11 + 208: 11 13 15 17 18 20 22 23 25 27 28 30 32 33 35 37 + 224: 38 41 44 46 49 51 54 56 59 62 64 67 69 72 74 77 + 240: 79 83 86 89 92 95 98 101 104 107 110 113 116 119 122 125 +* +* @param[in] theta Angle (a full circle mapped to 0-255) used as input for sine calculation. +* @param[in] range_min Lower bound of range (inclusive). +* @param[in] range_max Upper bound of range (inclusive). +* @return Calculated sine value mapped to the given range. +*/ +uint8_t scaled_sin(const uint8_t theta, const uint8_t range_min, const uint8_t range_max) { + const uint8_t range = range_max - range_min; + return scale8(sin8(theta), range) + range_min; +} + +/** +* @brief Increases the given value until reaching range_max. +* The increments occur following an upwards sine wave (scaled from range_min to range_max). +* @param[in] theta Angle (a full circle mapped to 0-255) used as input for sine calculation. +* @param[in] range_min Lower bound of range (inclusive). +* @param[in] range_max Upper bound of range (inclusive). +* @param[in] max_delta Maximum delta between value and range_max (due to values being integers and eventually not fully matching). +* @param[in,out] value Reference of variable to be increased +* @return `true` if value and range_max are within a delta of 3 (chosen by fair dice rolling), `false` otherwise +* @see scaled_sin() +*/ +bool scaled_sin_up(const uint8_t theta, const uint8_t range_min, const uint8_t range_max, const uint8_t max_delta, uint8_t *value) { + // ensure upper range bound + if (range_max <= (*value)) { + (*value) = range_max; + return true; + } + + const uint8_t new_value = scaled_sin(theta, range_min, range_max); + if (in_range(new_value, range_min, range_max) && (*value) < new_value) { + (*value) = new_value; + + return range_max == (*value); + } + + const uint8_t delta = range_max - (*value); + if (delta <= max_delta) { + (*value) = range_max; + } + + return delta <= max_delta; +} diff --git a/users/vitoni/utils.h b/users/vitoni/utils.h new file mode 100644 index 000000000000..8c2716c254f4 --- /dev/null +++ b/users/vitoni/utils.h @@ -0,0 +1,67 @@ +// Copyright 2021 Victor Toni (@vitoni) +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +/** +* @brief Changes `*value` to `new_value`. +* @param[in,out] value Pointer to variable to be changed. +* @param[in] new_value Value to be changed. +* @param[in,out] changed Flag indicating `*value` and `new_value` were different. +*/ +void update_value(uint8_t *value, const uint8_t new_value, bool *changed); + +/** +* @brief Checks whether a value is in the given range. +* @param[in] value Value to be checked. +* @param[in] range_min Lower bound of range (inclusive). +* @param[in] range_max Upper bound of range (inclusive). +* @return `true` if (range_min <= value <= range_max), `false` otherwise +*/ +bool in_range(const uint8_t value, const uint8_t range_min, const uint8_t range_max); + +/** +* @brief Calculates the sine value based on sin8() and scales it to the given range (unsigned). +* +* Table of values for unscaled sin8() eg. a theta of 0 results to 128 and a theta of 255 (240+15) results to 125. + 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + +---------------------------------------------------------------- + 0: 128 131 134 137 140 143 146 149 152 155 158 161 164 167 170 173 + 16: 177 179 182 184 187 189 192 194 197 200 202 205 207 210 212 215 + 32: 218 219 221 223 224 226 228 229 231 233 234 236 238 239 241 243 + 48: 245 245 246 246 247 248 248 249 250 250 251 251 252 253 253 254 + 64: 255 254 253 253 252 251 251 250 250 249 248 248 247 246 246 245 + 80: 245 243 241 239 238 236 234 233 231 229 228 226 224 223 221 219 + 96: 218 215 212 210 207 205 202 200 197 194 192 189 187 184 182 179 + 112: 177 173 170 167 164 161 158 155 152 149 146 143 140 137 134 131 + 128: 128 125 122 119 116 113 110 107 104 101 98 95 92 89 86 83 + 144: 79 77 74 72 69 67 64 62 59 56 54 51 49 46 44 41 + 160: 38 37 35 33 32 30 28 27 25 23 22 20 18 17 15 13 + 176: 11 11 10 10 9 8 8 7 6 6 5 5 4 3 3 2 + 192: 1 2 3 3 4 5 5 6 6 7 8 8 9 10 10 11 + 208: 11 13 15 17 18 20 22 23 25 27 28 30 32 33 35 37 + 224: 38 41 44 46 49 51 54 56 59 62 64 67 69 72 74 77 + 240: 79 83 86 89 92 95 98 101 104 107 110 113 116 119 122 125 +* +* @param[in] theta Angle (a full circle mapped to 0-255) used as input for sine calculation. +* @param[in] range_min Lower bound of range (inclusive). +* @param[in] range_max Upper bound of range (inclusive). +* @return Calculated sine value mapped to the given range. +*/ +uint8_t scaled_sin(const uint8_t theta, const uint8_t range_min, const uint8_t range_max); + +/** +* @brief Increases the given value until reaching range_max. +* The increments occur following an upwards sine wave (scaled from range_min to range_max). +* @param[in] theta Angle (a full circle mapped to 0-255) used as input for sine calculation. +* @param[in] range_min Lower bound of range (inclusive). +* @param[in] range_max Upper bound of range (inclusive). +* @param[in] max_delta Maximum delta between value and range_max (due to values being integers and eventually not fully matching). +* @param[in,out] value Reference of variable to be increased +* @return `true` if value and range_max are within a delta of 3 (chosen by fair dice rolling), `false` otherwise +* @see scaled_sin() +*/ +bool scaled_sin_up(const uint8_t thea, const uint8_t range_min, const uint8_t range_max, const uint8_t max_delta, uint8_t *value); diff --git a/users/vitoni/vitoni.c b/users/vitoni/vitoni.c new file mode 100644 index 000000000000..4f26039120a1 --- /dev/null +++ b/users/vitoni/vitoni.c @@ -0,0 +1,71 @@ +// Copyright 2021 Victor Toni (@vitoni) +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "vitoni.h" + +#include +#include + +#include "rgb_matrix_effects.h" +#include "utils.h" + +#if defined(RGB_FADE_IN) +static uint8_t state; + +// flag used to indicate that offset calculation is needed to adjust the timer, +// so that it matches the index used for sine calculation +static bool calc_offset; + +void matrix_scan_user_rgb(void) { + static uint8_t time_offset; + + const uint32_t inactivity_time = last_input_activity_elapsed(); + + // setting brightness to black as starting point for fade in + // for the time when returning from suspended state + if (RGB_DISABLE_TIMEOUT <= inactivity_time + 15) { + rgb_matrix_config.hsv.v = 0; + state = SUSPENDED; + } + + switch(state) { + case FADE_IN: + { + // since we want to be active, fade in should be faster than e.g. fading out + const uint8_t fade_in_time = rgb_time_2_scale_w_factor(4); + if (calc_offset) { + time_offset = calc_fade_in_offset(fade_in_time); + + // resetting flag for subsequent calls + calc_offset = false; + } + if (fade_in(fade_in_time + time_offset)) { + update_value(&state, REGULAR, &calc_offset); + } + } + break; + default: + break; + } +} + +bool process_record_user_rgb(const uint16_t keycode, const keyrecord_t *record) { + // if we are in a non regular state we might have faded out (eventually partially) + // so we restore brightness (to max as we don't keep track of manually changed brightness) + // if (REGULAR != state && FADE_IN != state) { + if (FADE_IN != state && REGULAR != state) { + update_value(&state, FADE_IN, &calc_offset); + } + + return true; // Process all other keycodes normally +} + +void suspend_wakeup_init_user(void) { + if (FADE_IN != state) { + // setting brightness to black as starting point for fade in + rgb_matrix_config.hsv.v = 0; + + update_value(&state, FADE_IN, &calc_offset); + } +} +#endif // defined(RGB_FADE_IN) diff --git a/users/vitoni/vitoni.h b/users/vitoni/vitoni.h new file mode 100644 index 000000000000..1f2603713570 --- /dev/null +++ b/users/vitoni/vitoni.h @@ -0,0 +1,30 @@ +// Copyright 2021 Victor Toni (@vitoni) +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include + +#include + +#include "rgb_matrix_effects.h" + +/** + * @brief Executes periodic tasks, eg. fading or checking for upcoming supend. + * @details Function declaration as weak as the implementation might "disappear" depending on the RGB settings used. + * The weak declaration avoids having to change `keymap.c`. + */ +__attribute__((weak)) +void matrix_scan_user_rgb(void); + +/** + * @brief Executes tasks based on user activity, eg. fading in. + * @details Function declaration as weak as the implementation might "disappear" depending on the RGB settings used. + * The weak declaration avoids having to change `keymap.c`. + * @param[in] keycode + * @param[in] record + * @return `false` if further processing should be stopped, `true` otherwise + */ +__attribute__((weak)) +bool process_record_user_rgb(const uint16_t keycode, const keyrecord_t *record);