Skip to content

Commit

Permalink
Adjust oled gen to fix flashing on timeout (qmk#18747)
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
snowe2010 authored Oct 19, 2022
1 parent 89dbc18 commit 0b8fbff
Showing 1 changed file with 62 additions and 61 deletions.
123 changes: 62 additions & 61 deletions users/snowe/ocean_dream.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -494,60 +494,61 @@ static void animate_shooting_stars(void) {
end_extra_stars(number_of_shooting_stars);
}
}
#endif // endregion
#endif // endregion

/**
* Main rendering function
*
* 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();
Expand Down

0 comments on commit 0b8fbff

Please sign in to comment.