#include #include #include #include #include "screen.h" static void draw_lines(OLEDDisplay *screen, struct display_status *status); static void update_lines(struct display_status *status); static void sanitize_msg(char *msg); void display_status_init(OLEDDisplay *screen, struct display_status *status, char *msg, size_t size, unsigned long int period) { status->period = period; status->screen = screen; size = MESSAGE_MAX < size ? MESSAGE_MAX : size; memset(status->message, 0, size + 1); memcpy(status->message, msg, size); status->msg_len = size; sanitize_msg(status->message); status->cursor = status->message; status->remaining = status->msg_len; update_lines(status); draw_lines(status->screen, status); status->last_scroll_time = millis(); } int display_update_scroll(struct display_status *status) { unsigned long crr_time; int ret = END_OF_MESSAGE; if (status->remaining) { crr_time = millis(); /* Only scroll lines once a period, because --- duh! */ if ((crr_time - status->last_scroll_time) > status->period) { status->last_scroll_time = crr_time; update_lines(status); draw_lines(status->screen, status); } ret = 0; } return ret; } /** * Turns all whitespace and special characters into literal spaces to save * screen real-estate and possible misinterpretation. */ static void sanitize_msg(char *msg) { do { switch (*msg) { case '\f': case '\n': case '\r': case '\t': case '\v': *msg = ' '; break; default: if (*msg < 0x20 || *msg > 0x7f) { *msg = '?'; } break; } } while (*(++msg)); end: return; } static void draw_lines(OLEDDisplay *screen, struct display_status *status) { size_t i; screen->clear(); for (i = 0; i < SCREEN_LINE_COUNT; ++i) { screen->drawString(0, i * FONT_HEIGHT, status->lines[i]); } screen->display(); } static void update_lines(struct display_status *status) { size_t i; if (status->remaining) { memset(status->lines, 0, sizeof(status->lines)); for (i = 0; i < SCREEN_LINE_COUNT; ++i) { if (status->remaining > SCREEN_LINE_CHARS) { memcpy(status->lines[i], status->cursor, SCREEN_LINE_CHARS); status->cursor += SCREEN_LINE_CHARS; status->remaining -= SCREEN_LINE_CHARS; } else if (status->remaining) { memcpy(status->lines[i], status->cursor, status->remaining); status->cursor += status->remaining; status->remaining = 0; } } } }