aboutsummaryrefslogtreecommitdiff
path: root/visualizer.c
diff options
context:
space:
mode:
authorFred Sundvik <fsundvik@gmail.com>2016-03-13 17:54:45 +0200
committerFred Sundvik <fsundvik@gmail.com>2016-03-13 20:13:02 +0200
commitb93d07198a18063594a59dd193d0961622087868 (patch)
tree4978d505018cdd97cb8683511676bba0f097cf56 /visualizer.c
parent315edb48265e6baedd07f34c9e6e323d28814b4e (diff)
downloadqmk_firmware-b93d07198a18063594a59dd193d0961622087868.tar.gz
qmk_firmware-b93d07198a18063594a59dd193d0961622087868.zip
Suspend support for the visualizer
Diffstat (limited to 'visualizer.c')
-rw-r--r--visualizer.c114
1 files changed, 88 insertions, 26 deletions
diff --git a/visualizer.c b/visualizer.c
index ca7bcb776..5b0d560ed 100644
--- a/visualizer.c
+++ b/visualizer.c
@@ -52,10 +52,14 @@ static visualizer_keyboard_status_t current_status = {
52 .layer = 0xFFFFFFFF, 52 .layer = 0xFFFFFFFF,
53 .default_layer = 0xFFFFFFFF, 53 .default_layer = 0xFFFFFFFF,
54 .leds = 0xFFFFFFFF, 54 .leds = 0xFFFFFFFF,
55 .suspended = false,
55}; 56};
56 57
57static bool same_status(visualizer_keyboard_status_t* status1, visualizer_keyboard_status_t* status2) { 58static bool same_status(visualizer_keyboard_status_t* status1, visualizer_keyboard_status_t* status2) {
58 return memcmp(status1, status2, sizeof(visualizer_keyboard_status_t)) == 0; 59 return status1->layer == status2->layer &&
60 status1->default_layer == status2->default_layer &&
61 status1->leds == status2->leds &&
62 status1->suspended == status2->suspended;
59} 63}
60 64
61static event_source_t layer_changed_event; 65static event_source_t layer_changed_event;
@@ -104,6 +108,17 @@ void stop_keyframe_animation(keyframe_animation_t* animation) {
104 } 108 }
105} 109}
106 110
111void stop_all_keyframe_animations(void) {
112 for (int i=0;i<MAX_SIMULTANEOUS_ANIMATIONS;i++) {
113 if (animations[i]) {
114 animations[i]->current_frame = animations[i]->num_frames;
115 animations[i]->time_left_in_frame = 0;
116 animations[i]->need_update = true;
117 animations[i] = NULL;
118 }
119 }
120}
121
107static bool update_keyframe_animation(keyframe_animation_t* animation, visualizer_state_t* state, systime_t delta, systime_t* sleep_time) { 122static bool update_keyframe_animation(keyframe_animation_t* animation, visualizer_state_t* state, systime_t delta, systime_t* sleep_time) {
108 dprintf("Animation frame%d, left %d, delta %d\n", animation->current_frame, 123 dprintf("Animation frame%d, left %d, delta %d\n", animation->current_frame,
109 animation->time_left_in_frame, delta); 124 animation->time_left_in_frame, delta);
@@ -252,7 +267,19 @@ bool keyframe_display_layer_bitmap(keyframe_animation_t* animation, visualizer_s
252} 267}
253#endif // LCD_ENABLE 268#endif // LCD_ENABLE
254 269
255bool user_visualizer_inited(keyframe_animation_t* animation, visualizer_state_t* state) { 270bool keyframe_disable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state) {
271 (void)animation;
272 (void)state;
273 return false;
274}
275
276bool keyframe_enable_lcd_and_backlight(keyframe_animation_t* animation, visualizer_state_t* state) {
277 (void)animation;
278 (void)state;
279 return false;
280}
281
282bool enable_visualization(keyframe_animation_t* animation, visualizer_state_t* state) {
256 (void)animation; 283 (void)animation;
257 (void)state; 284 (void)state;
258 dprint("User visualizer inited\n"); 285 dprint("User visualizer inited\n");
@@ -268,13 +295,15 @@ static THD_FUNCTION(visualizerThread, arg) {
268 event_listener_t event_listener; 295 event_listener_t event_listener;
269 chEvtRegister(&layer_changed_event, &event_listener, 0); 296 chEvtRegister(&layer_changed_event, &event_listener, 0);
270 297
271 visualizer_state_t state = { 298 visualizer_keyboard_status_t initial_status = {
272 .status = { 299 .default_layer = 0xFFFFFFFF,
273 .default_layer = 0xFFFFFFFF, 300 .layer = 0xFFFFFFFF,
274 .layer = 0xFFFFFFFF, 301 .leds = 0xFFFFFFFF,
275 .leds = 0xFFFFFFFF, 302 .suspended = false,
276 }, 303 };
277 304
305 visualizer_state_t state = {
306 .status = initial_status,
278 .current_lcd_color = 0, 307 .current_lcd_color = 0,
279#ifdef LCD_ENABLE 308#ifdef LCD_ENABLE
280 .font_fixed5x8 = gdispOpenFont("fixed_5x8"), 309 .font_fixed5x8 = gdispOpenFont("fixed_5x8"),
@@ -301,17 +330,36 @@ static THD_FUNCTION(visualizerThread, arg) {
301 bool enabled = visualizer_enabled; 330 bool enabled = visualizer_enabled;
302 if (!same_status(&state.status, &current_status)) { 331 if (!same_status(&state.status, &current_status)) {
303 if (visualizer_enabled) { 332 if (visualizer_enabled) {
304 state.status = current_status; 333 if (current_status.suspended) {
305 update_user_visualizer_state(&state); 334 stop_all_keyframe_animations();
306 state.prev_lcd_color = state.current_lcd_color; 335 visualizer_enabled = false;
336 state.status = current_status;
337 user_visualizer_suspend(&state);
338 }
339 else {
340 state.status = current_status;
341 update_user_visualizer_state(&state);
342 state.prev_lcd_color = state.current_lcd_color;
343 }
307 } 344 }
308 } 345 }
346 if (!enabled && state.status.suspended && current_status.suspended == false) {
347 // Setting the status to the initial status will force an update
348 // when the visualizer is enabled again
349 state.status = initial_status;
350 state.status.suspended = false;
351 stop_all_keyframe_animations();
352 user_visualizer_resume(&state);
353 }
309 sleep_time = TIME_INFINITE; 354 sleep_time = TIME_INFINITE;
310 for (int i=0;i<MAX_SIMULTANEOUS_ANIMATIONS;i++) { 355 for (int i=0;i<MAX_SIMULTANEOUS_ANIMATIONS;i++) {
311 if (animations[i]) { 356 if (animations[i]) {
312 update_keyframe_animation(animations[i], &state, delta, &sleep_time); 357 update_keyframe_animation(animations[i], &state, delta, &sleep_time);
313 } 358 }
314 } 359 }
360 // The animation can enable the visualizer
361 // And we might need to update the state when that happens
362 // so don't sleep
315 if (enabled != visualizer_enabled) { 363 if (enabled != visualizer_enabled) {
316 sleep_time = 0; 364 sleep_time = 0;
317 } 365 }
@@ -354,7 +402,24 @@ void visualizer_init(void) {
354 LOWPRIO, visualizerThread, NULL); 402 LOWPRIO, visualizerThread, NULL);
355} 403}
356 404
357void visualizer_set_state(uint32_t default_state, uint32_t state, uint32_t leds) { 405void update_status(bool changed) {
406 if (changed) {
407 chEvtBroadcast(&layer_changed_event);
408 }
409#ifdef USE_SERIAL_LINK
410 static systime_t last_update = 0;
411 systime_t current_update = chVTGetSystemTimeX();
412 systime_t delta = current_update - last_update;
413 if (changed || delta > MS2ST(10)) {
414 last_update = current_update;
415 visualizer_keyboard_status_t* r = begin_write_current_status();
416 *r = current_status;
417 end_write_current_status();
418 }
419#endif
420}
421
422void visualizer_update(uint32_t default_state, uint32_t state, uint32_t leds) {
358 // Note that there's a small race condition here, the thread could read 423 // Note that there's a small race condition here, the thread could read
359 // a state where one of these are set but not the other. But this should 424 // a state where one of these are set but not the other. But this should
360 // not really matter as it will be fixed during the next loop step. 425 // not really matter as it will be fixed during the next loop step.
@@ -379,25 +444,22 @@ void visualizer_set_state(uint32_t default_state, uint32_t state, uint32_t leds)
379 .layer = state, 444 .layer = state,
380 .default_layer = default_state, 445 .default_layer = default_state,
381 .leds = leds, 446 .leds = leds,
447 .suspended = current_status.suspended,
382 }; 448 };
383 if (!same_status(&current_status, &new_status)) { 449 if (!same_status(&current_status, &new_status)) {
384 changed = true; 450 changed = true;
385 current_status = new_status; 451 current_status = new_status;
386 } 452 }
387 } 453 }
388 if (changed) { 454 update_status(changed);
389 chEvtBroadcast(&layer_changed_event); 455}
390 456
391 } 457void visualizer_suspend(void) {
392#ifdef USE_SERIAL_LINK 458 current_status.suspended = true;
393 static systime_t last_update = 0; 459 update_status(true);
394 systime_t current_update = chVTGetSystemTimeX(); 460}
395 systime_t delta = current_update - last_update; 461
396 if (changed || delta > MS2ST(10)) { 462void visualizer_resume(void) {
397 last_update = current_update; 463 current_status.suspended = false;
398 visualizer_keyboard_status_t* r = begin_write_current_status(); 464 update_status(true);
399 *r = current_status;
400 end_write_current_status();
401 }
402#endif
403} 465}