~ruther/qmk_firmware

0b8fbff1cbb510e922a6c3a23793b7d0ddf9e3b9 — Tyler Thrailkill 2 years ago 89dbc18
Adjust oled gen to fix flashing on timeout (#18747)

Fixes an issue in Ocean Dream that causes flashing after the oled screen
times out and turns off.

This occurs because writing to an OLED screen turns it on as well and we
are both writing then immediately turning the screen off, but only if
the timeout has occurred (no WPM, 30 seconds has passed).
1 files changed, 62 insertions(+), 61 deletions(-)

M users/snowe/ocean_dream.c
M users/snowe/ocean_dream.c => users/snowe/ocean_dream.c +62 -61
@@ 20,13 20,13 @@
#include "print.h"

// Calculated Parameters
#define TWINKLE_PROBABILITY_MODULATOR 100 / TWINKLE_PROBABILITY                             // CALCULATED: Don't Touch
#define TOTAL_STARS STARS_PER_LINE *NUMBER_OF_STAR_LINES                                    // CALCULATED: Don't Touch
#define OCEAN_ANIMATION_MODULATOR NUMBER_OF_FRAMES / OCEAN_ANIMATION_SPEED                  // CALCULATED: Don't Touch
#define SHOOTING_STAR_ANIMATION_MODULATOR NUMBER_OF_FRAMES / SHOOTING_STAR_ANIMATION_SPEED  // CALCULATED: Don't Touch
#define STAR_ANIMATION_MODULATOR NUMBER_OF_FRAMES / STAR_ANIMATION_SPEED                    // CALCULATED: Don't Touch
#define TWINKLE_PROBABILITY_MODULATOR 100 / TWINKLE_PROBABILITY                            // CALCULATED: Don't Touch
#define TOTAL_STARS STARS_PER_LINE *NUMBER_OF_STAR_LINES                                   // CALCULATED: Don't Touch
#define OCEAN_ANIMATION_MODULATOR NUMBER_OF_FRAMES / OCEAN_ANIMATION_SPEED                 // CALCULATED: Don't Touch
#define SHOOTING_STAR_ANIMATION_MODULATOR NUMBER_OF_FRAMES / SHOOTING_STAR_ANIMATION_SPEED // CALCULATED: Don't Touch
#define STAR_ANIMATION_MODULATOR NUMBER_OF_FRAMES / STAR_ANIMATION_SPEED                   // CALCULATED: Don't Touch

uint8_t    animation_counter       = 0;  // global animation counter.
uint8_t    animation_counter       = 0; // global animation counter.
bool       is_calm                 = false;
uint32_t   starry_night_anim_timer = 0;
uint32_t   starry_night_anim_sleep = 0;


@@ 52,10 52,10 @@ static uint8_t decrement_counter(uint8_t counter, uint8_t max) {
}
#endif

#ifdef ENABLE_MOON  // region
#ifdef ENABLE_MOON // region
#    ifndef STATIC_MOON
uint8_t  moon_animation_frame   = 0;  // keeps track of current moon frame
uint16_t moon_animation_counter = 0;  // counts how many frames to wait before animating moon to next frame
uint8_t  moon_animation_frame   = 0; // keeps track of current moon frame
uint16_t moon_animation_counter = 0; // counts how many frames to wait before animating moon to next frame
#    endif

#    ifdef STATIC_MOON


@@ 99,9 99,9 @@ static void draw_moon(void) {
    }
#    endif
}
#endif  // endregion
#endif // endregion

#ifdef ENABLE_WAVE  // region
#ifdef ENABLE_WAVE // region
uint8_t starry_night_wave_frame_width_counter = 31;
uint8_t rough_waves_frame_counter             = 0;



@@ 193,8 193,8 @@ static const char PROGMEM ocean_bottom[8][32] = {
// clang-format on

static void animate_waves(void) {
    starry_night_wave_frame_width_counter = decrement_counter(starry_night_wave_frame_width_counter, WIDTH - 1);  // only 3 frames for last wave type
    rough_waves_frame_counter             = increment_counter(rough_waves_frame_counter, 3);                      // only 3 frames for last wave type
    starry_night_wave_frame_width_counter = decrement_counter(starry_night_wave_frame_width_counter, WIDTH - 1); // only 3 frames for last wave type
    rough_waves_frame_counter             = increment_counter(rough_waves_frame_counter, 3);                     // only 3 frames for last wave type

    void draw_ocean(uint8_t frame, uint16_t offset, uint8_t byte_index) {
        oled_write_raw_byte(pgm_read_byte(ocean_top[frame] + byte_index), offset);


@@ 218,9 218,9 @@ static void animate_waves(void) {
        }
    }
}
#endif  // endregion
#endif // endregion

#ifdef ENABLE_ISLAND  // region
#ifdef ENABLE_ISLAND // region
uint8_t island_frame_1 = 0;

// clang-format off


@@ 276,17 276,17 @@ static void animate_island(void) {
        draw_island_parts(island_frame_1 + 4);
    }
}
#endif  // endregion
#endif // endregion

#ifdef ENABLE_STARS  // region
bool stars_setup = false;  // only setup stars once, then we just twinkle them
#ifdef ENABLE_STARS       // region
bool stars_setup = false; // only setup stars once, then we just twinkle them
struct Coordinate {
    int  x;
    int  y;
    bool exists;
};

struct Coordinate stars[TOTAL_STARS];  // tracks all stars/coordinates
struct Coordinate stars[TOTAL_STARS]; // tracks all stars/coordinates

/**
 * Setup all the initial stars on the screen


@@ 334,18 334,18 @@ static void twinkle_stars(void) {
                continue;
            }
            if (rand() % TWINKLE_PROBABILITY_MODULATOR == 0) {
                oled_write_pixel(star.x, star.y, false);  // black out pixel
                oled_write_pixel(star.x, star.y, false); // black out pixel

                // don't allow stars to leave their own region
                if (star.x == (column_group * 8)) {                     // star is the farthest left it can go in its region
                    star.x++;                                           // move it right immediately
                } else if (star.x == (((column_group + 1) * 8) - 1)) {  // star is farthest right it can go in its region
                    star.x--;                                           // move it left immediately
                if (star.x == (column_group * 8)) {                    // star is the farthest left it can go in its region
                    star.x++;                                          // move it right immediately
                } else if (star.x == (((column_group + 1) * 8) - 1)) { // star is farthest right it can go in its region
                    star.x--;                                          // move it left immediately
                }
                if (star.y == (line * 8)) {                     // star is the farthest up it can go in its region
                    star.y++;                                   // move it down immediately
                } else if (star.y == (((line + 1) * 8) - 1)) {  // star is farthest down it can go in its region
                    star.y--;                                   // move it up immediately
                if (star.y == (line * 8)) {                    // star is the farthest up it can go in its region
                    star.y++;                                  // move it down immediately
                } else if (star.y == (((line + 1) * 8) - 1)) { // star is farthest down it can go in its region
                    star.y--;                                  // move it up immediately
                }

                // now decide direction


@@ 389,10 389,10 @@ static void animate_stars(void) {
        twinkle_stars();
    }
}
#endif  // endregion
#endif // endregion

#ifdef ENABLE_SHOOTING_STARS  // region
bool shooting_stars_setup = false;  // only setup shooting stars array once with defaults
#ifdef ENABLE_SHOOTING_STARS       // region
bool shooting_stars_setup = false; // only setup shooting stars array once with defaults

struct ShootingStar {
    int  x_1;


@@ 404,11 404,11 @@ struct ShootingStar {
    int  delay;
};

struct ShootingStar shooting_stars[MAX_NUMBER_OF_SHOOTING_STARS];  // tracks all the shooting stars
struct ShootingStar shooting_stars[MAX_NUMBER_OF_SHOOTING_STARS]; // tracks all the shooting stars

static void setup_shooting_star(struct ShootingStar *shooting_star) {
    int column_to_start = rand() % (WIDTH / 2);
    int row_to_start    = rand() % (HEIGHT - 48);  // shooting_stars travel diagonally 1 down, 1 across. So the lowest a shooting_star can start and not 'hit' the ocean is 32 above the ocean.
    int row_to_start    = rand() % (HEIGHT - 48); // shooting_stars travel diagonally 1 down, 1 across. So the lowest a shooting_star can start and not 'hit' the ocean is 32 above the ocean.

    shooting_star->x_1     = column_to_start;
    shooting_star->y_1     = row_to_start;


@@ 494,7 494,7 @@ static void animate_shooting_stars(void) {
        end_extra_stars(number_of_shooting_stars);
    }
}
#endif  // endregion
#endif // endregion

/**
 * Main rendering function


@@ 502,52 502,53 @@ static void animate_shooting_stars(void) {
 * Calls all different animations at different rates
 */
void render_stars(void) {
    //    // animation timer
    if (timer_elapsed32(starry_night_anim_timer) > STARRY_NIGHT_ANIM_FRAME_DURATION) {
        starry_night_anim_timer = timer_read32();
        current_wpm             = get_current_wpm();
    current_wpm             = get_current_wpm();

    void render_stars_anim(void) {
#ifdef ENABLE_ISLAND
        animate_island();
            animate_island();
#endif

#ifdef ENABLE_SHOOTING_STARS
        if (animation_counter % SHOOTING_STAR_ANIMATION_MODULATOR == 0) {
            animate_shooting_stars();
        }
            if (animation_counter % SHOOTING_STAR_ANIMATION_MODULATOR == 0) {
                animate_shooting_stars();
            }
#endif

#ifdef ENABLE_STARS
        // TODO offsetting the star animation from the wave animation would look better,
        // but if I do that, then the stars appear in the water because
        // the ocean animation has to wait a bunch of frames to overwrite it.
        // Possible solutions:
        // 1. Only draw stars to the top of the island/ocean.
        // 2. Draw ocean every frame, only move ocean on frames matching modulus
        // Problems:
        // 1. What if someone wants to move the island up a bit, or they want to have the stars reflect in the water?
        // 2. More cpu intensive. And I'm already running out of cpu as it is...
        if (animation_counter % STAR_ANIMATION_MODULATOR == 0) {
            animate_stars();
        }
            // TODO offsetting the star animation from the wave animation would look better,
            // but if I do that, then the stars appear in the water because
            // the ocean animation has to wait a bunch of frames to overwrite it.
            // Possible solutions:
            // 1. Only draw stars to the top of the island/ocean.
            // 2. Draw ocean every frame, only move ocean on frames matching modulus
            // Problems:
            // 1. What if someone wants to move the island up a bit, or they want to have the stars reflect in the water?
            // 2. More cpu intensive. And I'm already running out of cpu as it is...
            if (animation_counter % STAR_ANIMATION_MODULATOR == 0) {
                animate_stars();
            }
#endif

#ifdef ENABLE_WAVE
        if (animation_counter % OCEAN_ANIMATION_MODULATOR == 0) {
            animate_waves();
        }
            if (animation_counter % OCEAN_ANIMATION_MODULATOR == 0) {
                animate_waves();
            }
#endif

#ifdef ENABLE_MOON
        draw_moon();
            draw_moon();
#endif

        animation_counter = increment_counter(animation_counter, NUMBER_OF_FRAMES);
            animation_counter = increment_counter(animation_counter, NUMBER_OF_FRAMES);
    }

    // this fixes the screen on and off bug
    if (current_wpm > 0) {

    // Turn screen on/off based on typing and timeout
    if (current_wpm > 0 && timer_elapsed32(starry_night_anim_timer) > STARRY_NIGHT_ANIM_FRAME_DURATION) {
        starry_night_anim_timer = timer_read32();
        oled_on();
        render_stars_anim();
        starry_night_anim_sleep = timer_read32();
    } else if (timer_elapsed32(starry_night_anim_sleep) > OLED_TIMEOUT) {
        oled_off();