diff options
Diffstat (limited to 'src/device/screen.cpp')
-rw-r--r-- | src/device/screen.cpp | 121 |
1 files changed, 71 insertions, 50 deletions
diff --git a/src/device/screen.cpp b/src/device/screen.cpp index cf1428a..bc25d65 100644 --- a/src/device/screen.cpp +++ b/src/device/screen.cpp @@ -1,83 +1,104 @@ -#include <time.h> #include <stdlib.h> #include <string.h> #include <OLEDDisplay.h> #include <Wire.h> #include "screen.h" -void draw_lines(OLEDDisplay *screen, struct display_status *status); -void update_lines(struct display_status *status); -void init_msg(char *msg, size_t size); +static void draw_lines(OLEDDisplay *screen, struct display_status *status); +static void update_lines(struct display_status *status); +static void sanitize_msg(char *msg); -static char empty_string[] = ""; - -void display_status_init(OLEDDisplay *screen, struct display_status *status, char *msg) +void display_status_init(OLEDDisplay *screen, struct display_status *status, char *msg, size_t size, unsigned long int period) { - status->delta = 2000; /* Currently default */ + status->period = period; status->screen = screen; - init_msg(msg, strlen(msg)); - status->message = msg; - status->line_cursor = 0; - status->last_scroll_time = time(NULL); + 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 into literal spaces to save screen real-estate and - * possible misinterpretation. + * Turns all whitespace and special characters into literal spaces to save + * screen real-estate and possible misinterpretation. */ -void init_msg(char *msg, size_t size) +static void sanitize_msg(char *msg) { - size_t i; - - for (i = 0; i < size; i++) { - switch (msg[i]) { + do { + switch (*msg) { + case '\f': case '\n': - case '\t': case '\r': - msg[i] = ' '; + case '\t': + case '\v': + *msg = ' '; break; - case '\0': - goto end; default: + if (*msg < 0x20 || *msg > 0x7f) { + *msg = '?'; + } break; } - } + } while (*(++msg)); end: return; } -int display_update_scroll(struct display_status *status) +static void draw_lines(OLEDDisplay *screen, struct display_status *status) { - unsigned long crr_time = millis(); - /* Only scroll lines once a delta, because --- duh! */ - if (status->last_scroll_time - crr_time > status->delta) { - status->last_scroll_time += status->delta; - status->line_cursor++; - update_lines(status); - draw_lines(status->screen, status); - } - if (!(*status->first_line) && !(*(status->second_line))) { - return END_OF_MESSAGE; - } else { - return 0; + size_t i; + screen->clear(); + + for (i = 0; i < SCREEN_LINE_COUNT; ++i) { + screen->drawString(0, i * FONT_HEIGHT, status->lines[i]); } -} -void draw_lines(OLEDDisplay *screen, struct display_status *status) -{ - screen->clear(); - screen->drawString(0, 0, status->first_line); - screen->drawString(0, SCREEN_HEIGHT / 2, status->second_line); screen->display(); } -void update_lines(struct display_status *status) +static void update_lines(struct display_status *status) { - status->first_line = (status->line_cursor * SCREEN_MAX_CHARS < status->message_len) - ? status->message + status->line_cursor * SCREEN_MAX_CHARS - : empty_string; - status->second_line = (status->line_cursor * SCREEN_MAX_CHARS < status->message_len) - ? status->message + (status->line_cursor + 1) * SCREEN_MAX_CHARS - : empty_string; + 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; + } + } + } } |