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.cpp83
1 files changed, 83 insertions, 0 deletions
diff --git a/src/device/screen.cpp b/src/device/screen.cpp
new file mode 100644
index 0000000..2857161
--- /dev/null
+++ b/src/device/screen.cpp
@@ -0,0 +1,83 @@
+#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);
+
+/* Effectively const. For type safety reasons. */
+static char NOTHING[] = {'\0'};
+
+void display_status_init(OLEDDisplay *screen, struct display_status *status, char *msg)
+{
+ status->delta = 2; /* Currently default */
+ status->screen = screen;
+ init_msg(msg, strlen(msg));
+ status->message = msg;
+ status->line_cursor = 0;
+ status->last_scroll_time = time(NULL);
+ update_lines(status);
+}
+
+/**
+ * Turns all whitespace into literal spaces to save screen real-estate and
+ * possible misinterpretation.
+ */
+void init_msg(char *msg, size_t size)
+{
+ size_t i;
+
+ for (i = 0; i < size; i++) {
+ switch (msg[i]) {
+ case '\n':
+ case '\t':
+ case '\r':
+ msg[i] = ' ';
+ break;
+ case '\0':
+ goto end;
+ default:
+ break;
+ }
+ }
+end:
+ return;
+}
+
+int display_update_scroll(struct display_status *status)
+{
+ time_t crr_time = time(NULL);
+ /* 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 == NOTHING && status->second_line == NOTHING) {
+ return END_OF_MESSAGE;
+ } else {
+ return 0;
+ }
+}
+
+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);
+}
+
+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
+ : NOTHING;
+ status->second_line = (status->line_cursor * SCREEN_MAX_CHARS < status->message_len)
+ ? status->message + (status->line_cursor + 1) * SCREEN_MAX_CHARS
+ : NOTHING;
+}