Skip to content

Commit 72ec74e

Browse files
committed
Implement proper scrolling
1 parent 105c675 commit 72ec74e

File tree

1 file changed

+61
-12
lines changed

1 file changed

+61
-12
lines changed

OLEDDisplay.cpp

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -507,30 +507,44 @@ void OLEDDisplay::clear(void) {
507507
}
508508

509509
void OLEDDisplay::drawLogBuffer(uint16_t xMove, uint16_t yMove) {
510-
setTextAlignment(TEXT_ALIGN_LEFT);
511510
uint16_t lineHeight = pgm_read_byte(fontData + HEIGHT_POS);
512-
uint16_t length = 0;
513-
uint16_t line = 0;
514-
uint16_t lastPos = 0;
511+
// Always align left
512+
setTextAlignment(TEXT_ALIGN_LEFT);
513+
514+
// State values
515+
uint16_t length = 0;
516+
uint16_t line = 0;
517+
uint16_t lastPos = 0;
518+
515519
for (uint16_t i=0;i<this->logBufferFilled;i++){
520+
// Everytime we have a \n print
516521
if (this->logBuffer[i] == 10) {
522+
length++;
523+
// Draw string on line `line` from lastPos to length
524+
// Passing 0 as the lenght because we are in TEXT_ALIGN_LEFT
517525
drawStringInternal(xMove, yMove + (line++) * lineHeight, &this->logBuffer[lastPos], length, 0);
526+
// Remember last pos
518527
lastPos = i;
528+
// Reset length
519529
length = 0;
520530
} else {
531+
// Count chars until next linebreak
521532
length++;
522533
}
523534
}
524-
drawStringInternal(xMove, yMove + (line++) * lineHeight, &this->logBuffer[lastPos], length, 0);
535+
// Draw the remaining string
536+
if (length > 0) {
537+
drawStringInternal(xMove, yMove + line * lineHeight, &this->logBuffer[lastPos], length, 0);
538+
}
525539
}
526540

527541
bool OLEDDisplay::setLogBuffer(uint16_t lines, uint16_t chars){
528542
if (logBuffer != NULL) free(logBuffer);
529543
uint16_t size = lines * chars;
530544
if (size > 0) {
531-
this->logBufferMaxLines = lines;
532-
this->logBufferLine = 0;
533-
this->logBufferSize = size;
545+
this->logBufferLine = 0; // Lines printed
546+
this->logBufferMaxLines = lines; // Lines max printable
547+
this->logBufferSize = size; // Total number of characters the buffer can hold
534548
this->logBuffer = (char *) malloc(size * sizeof(uint8_t));
535549
if(!this->logBuffer) {
536550
DEBUG_OLEDDISPLAY("[OLEDDISPLAY][setLogBuffer] Not enough memory to create log buffer\n");
@@ -542,24 +556,59 @@ bool OLEDDisplay::setLogBuffer(uint16_t lines, uint16_t chars){
542556

543557
size_t OLEDDisplay::write(uint8_t c) {
544558
if (this->logBufferSize > 0) {
545-
if (this->logBufferFilled < this->logBufferSize && this->logBufferLine < this->logBufferMaxLines) {
559+
// Don't waste space on \r\n line endings, dropping \r
560+
if (c == 13) return 1;
561+
562+
bool maxLineNotReached = this->logBufferLine < this->logBufferMaxLines;
563+
bool bufferNotFull = this->logBufferFilled < this->logBufferSize;
564+
565+
// Can we write to the buffer?
566+
if (bufferNotFull && maxLineNotReached) {
546567
this->logBuffer[logBufferFilled] = utf8ascii(c);
547568
this->logBufferFilled++;
569+
// Keep track of lines written
548570
if (c == 10) this->logBufferLine++;
549571
} else {
550-
if (this->logBufferLine <= this->logBufferMaxLines) this->logBufferLine = 0;
551-
this->logBufferFilled = 0;
572+
// Max line number is reached
573+
if (!maxLineNotReached) this->logBufferLine--;
574+
575+
// Find the end of the first line
576+
uint16_t firstLineEnd = 0;
577+
for (uint16_t i=0;i<this->logBufferFilled;i++) {
578+
if (this->logBuffer[i] == 10){
579+
// Include last char too
580+
firstLineEnd = i + 1;
581+
break;
582+
}
583+
}
584+
// If there was a line ending
585+
if (firstLineEnd > 0) {
586+
// Calculate the new logBufferFilled value
587+
this->logBufferFilled = logBufferFilled - firstLineEnd;
588+
// Now we move the lines infront of the buffer
589+
memcpy(this->logBuffer, &this->logBuffer[firstLineEnd], logBufferFilled);
590+
} else {
591+
// Let's reuse the buffer if it was full
592+
if (!bufferNotFull) {
593+
this->logBufferFilled = 0;
594+
}// else {
595+
// Nothing to do here
596+
//}
597+
}
552598
write(c);
553599
}
554600
}
555-
601+
// We are always writing all uint8_t to the buffer
602+
return 1;
556603
}
557604

558605
size_t OLEDDisplay::write(const char* str) {
606+
if (str == NULL) return 0;
559607
size_t length = strlen(str);
560608
for (size_t i = 0; i < length; i++) {
561609
write(str[i]);
562610
}
611+
return length;
563612
}
564613

565614
// Private functions

0 commit comments

Comments
 (0)