summaryrefslogtreecommitdiffstats
path: root/src/device/screen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/device/screen.cpp')
-rw-r--r--src/device/screen.cpp121
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;
+ }
+ }
+ }
}