From a0a707ac0e8c20d1095791773b5ab3ff370baa94 Mon Sep 17 00:00:00 2001 From: Adolfo Reyna Date: Tue, 18 Nov 2025 13:36:39 -0500 Subject: [PATCH] marquee" --- hello_usb.cpp | 49 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/hello_usb.cpp b/hello_usb.cpp index d2acac5..5dfd059 100644 --- a/hello_usb.cpp +++ b/hello_usb.cpp @@ -20,16 +20,40 @@ static SSD1306 *g_display = nullptr; // Holds last echoed line for display static char g_last_echo[128] = ""; +// Scrolling state for last echo (marquee) +static size_t g_last_echo_scroll_index = 0; +static uint64_t g_last_echo_last_scroll_ms = 0; +static const uint64_t SCROLL_INTERVAL_MS = 300; // milliseconds between scroll steps +static const size_t LAST_ECHO_VISIBLE_CHARS = 10; // visible chars for 12x16 font on 128px width // Refresh OLED with current input (line 0) and last echoed text (line 2) static void refresh_display(const char *current_input, const char *last_echo) { if (!g_display) return; g_display->clear(); - // Use next bigger font (12x16) to improve readability - // First line: current input - pico_ssd1306::drawText(g_display, font_12x16, current_input, 0, 0); - // Second line: last echoed text (start lower to avoid overlap) - pico_ssd1306::drawText(g_display, font_12x16, last_echo, 0, 20); + + // If current input is longer than 10 chars, use smaller font to fit more text + size_t input_len = current_input ? strlen(current_input) : 0; + const unsigned char *input_font = (input_len > 10) ? font_5x8 : font_12x16; + + // Draw current input using chosen font + pico_ssd1306::drawText(g_display, input_font, current_input, 0, 0); + + // Draw last echoed text using the larger font for readability + // If the last echo is longer than visible chars, create a scrolling window + size_t last_len = last_echo ? strlen(last_echo) : 0; + if (last_len > LAST_ECHO_VISIBLE_CHARS) { + char window[LAST_ECHO_VISIBLE_CHARS + 1]; + // copy up to visible chars starting at scroll index, wrapping as needed + for (size_t i = 0; i < LAST_ECHO_VISIBLE_CHARS; ++i) { + size_t src = (g_last_echo_scroll_index + i) % last_len; + window[i] = last_echo[src]; + } + window[LAST_ECHO_VISIBLE_CHARS] = '\0'; + pico_ssd1306::drawText(g_display, font_12x16, window, 0, 20); + } else { + pico_ssd1306::drawText(g_display, font_12x16, last_echo, 0, 20); + } + g_display->sendBuffer(); } @@ -58,6 +82,9 @@ void echo_and_reset(char* buffer, int* index_ptr) { g_last_echo[i] = (char)toupper(buffer[i]); } g_last_echo[i] = '\0'; + // reset scrolling state whenever last echo changes + g_last_echo_scroll_index = 0; + g_last_echo_last_scroll_ms = time_us_64() / 1000; } *index_ptr = 0; @@ -116,6 +143,18 @@ void run_echo_session() { last_char_time = time_us_64(); } + // Advance marquee for last echoed text if needed + size_t last_len = strlen(g_last_echo); + uint64_t now_ms = time_us_64() / 1000; + if (last_len > LAST_ECHO_VISIBLE_CHARS) { + if (now_ms - g_last_echo_last_scroll_ms >= SCROLL_INTERVAL_MS) { + g_last_echo_scroll_index = (g_last_echo_scroll_index + 1) % last_len; + g_last_echo_last_scroll_ms = now_ms; + // refresh display to show new window + refresh_display(input_buffer, g_last_echo); + } + } + sleep_us(100); }