2023-10-20 12:18:38 +00:00
|
|
|
#include <stdarg.h>
|
2018-11-03 13:30:49 +00:00
|
|
|
#include <stdint.h>
|
|
|
|
#include "hardware.h"
|
|
|
|
#include "memory.h"
|
2023-07-25 13:10:35 +00:00
|
|
|
#include "display.h"
|
2018-11-03 13:30:49 +00:00
|
|
|
|
|
|
|
#if defined(USE_UTFT)
|
2020-07-08 13:33:31 +00:00
|
|
|
#pragma message "UTFT configured"
|
2018-11-03 13:30:49 +00:00
|
|
|
#include <UTFT.h>
|
|
|
|
#include "TinyFont.h"
|
|
|
|
|
2019-03-03 14:38:47 +00:00
|
|
|
#if !defined(TFT_SER)
|
|
|
|
#define TFT_SER 0
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static UTFT utft(TFT_MODEL, TFT_RS, TFT_WR, TFT_CS, TFT_RST, TFT_SER);
|
2018-11-03 13:30:49 +00:00
|
|
|
|
|
|
|
#elif defined(USE_ESPI)
|
2021-02-27 13:32:49 +00:00
|
|
|
#pragma message "Configure TFT_eSPI in Makefile or <TFT_eSPI/User_Setup.h>"
|
2018-11-03 13:30:49 +00:00
|
|
|
#include <TFT_eSPI.h>
|
|
|
|
|
|
|
|
static TFT_eSPI espi;
|
2020-07-08 13:33:31 +00:00
|
|
|
|
2023-07-25 13:10:35 +00:00
|
|
|
#elif defined(USE_VGA)
|
|
|
|
#pragma message "FabGL VGA configured"
|
|
|
|
#include <fabgl.h>
|
|
|
|
|
|
|
|
static fabgl::VGAController vga;
|
|
|
|
static fabgl::Canvas canvas(&vga);
|
|
|
|
|
|
|
|
static const fabgl::RGB888 rgb(colour_t c) {
|
|
|
|
switch(c) {
|
|
|
|
case BLACK: return Color::Black;
|
2023-07-26 12:47:15 +00:00
|
|
|
case RED: return Color::Red;
|
2023-07-25 13:10:35 +00:00
|
|
|
case GREEN: return Color::Green;
|
|
|
|
case YELLOW: return Color::Yellow;
|
|
|
|
case BLUE: return Color::Blue;
|
|
|
|
case MAGENTA: return Color::Magenta;
|
|
|
|
case CYAN: return Color::Cyan;
|
2023-07-26 12:47:15 +00:00
|
|
|
case WHITE: return Color::White;
|
2023-07-25 13:10:35 +00:00
|
|
|
}
|
2023-07-26 12:47:15 +00:00
|
|
|
return Color::BrightWhite;
|
2023-07-25 13:10:35 +00:00
|
|
|
}
|
|
|
|
|
2020-07-08 13:33:31 +00:00
|
|
|
#else
|
|
|
|
#pragma error "Display not configured!"
|
2018-11-03 13:30:49 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
static inline void setColor(colour_t c) {
|
|
|
|
#if defined(USE_UTFT)
|
|
|
|
utft.setColor(c);
|
|
|
|
#elif defined(USE_ESPI)
|
|
|
|
espi.setTextColor(c);
|
2023-07-25 13:10:35 +00:00
|
|
|
#elif defined(USE_VGA)
|
|
|
|
canvas.setPenColor(rgb(c));
|
2018-11-03 13:30:49 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2023-07-26 14:32:11 +00:00
|
|
|
void Display::begin(colour_t bg, colour_t fg, orientation_t orient, unsigned dispx, unsigned dispy) {
|
|
|
|
begin(bg, fg, orient);
|
|
|
|
_xoff = (_dx - dispx) / 2;
|
|
|
|
_yoff = (_dy - dispy) / 2;
|
|
|
|
_dx -= _xoff;
|
|
|
|
_dy -= _yoff;
|
2023-08-30 13:01:30 +00:00
|
|
|
|
2023-11-18 11:03:47 +00:00
|
|
|
DBG(printf("xoff %d yoff %d dx %d dy %d", _xoff, _yoff, _dx, _dy));
|
|
|
|
DBG(println());
|
2023-07-26 14:32:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Display::begin(colour_t bg, colour_t fg, orientation_t orient) {
|
2018-11-03 13:30:49 +00:00
|
|
|
_bg = bg;
|
|
|
|
_fg = fg;
|
2023-07-26 14:32:11 +00:00
|
|
|
_xoff = _yoff = 0;
|
2018-11-03 13:30:49 +00:00
|
|
|
|
|
|
|
#if defined(USE_UTFT)
|
|
|
|
utft.InitLCD(orient);
|
|
|
|
_dx = utft.getDisplayXSize();
|
|
|
|
_dy = utft.getDisplayYSize();
|
|
|
|
|
|
|
|
utft.setFont((uint8_t *)TinyFont);
|
|
|
|
_cx = utft.getFontXsize();
|
|
|
|
_cy = utft.getFontYsize();
|
2020-07-08 13:33:31 +00:00
|
|
|
|
2018-11-03 13:30:49 +00:00
|
|
|
#elif defined(USE_ESPI)
|
|
|
|
espi.init();
|
|
|
|
espi.setRotation(orient);
|
|
|
|
_dx = espi.width();
|
|
|
|
_dy = espi.height();
|
|
|
|
_cy = espi.fontHeight();
|
2018-11-12 22:18:44 +00:00
|
|
|
_cx = 6; // FIXME
|
2023-07-25 13:10:35 +00:00
|
|
|
|
|
|
|
#elif defined(USE_VGA)
|
|
|
|
static bool init;
|
|
|
|
|
|
|
|
if (init)
|
|
|
|
vga.end();
|
|
|
|
init = true;
|
|
|
|
vga.begin();
|
2023-08-30 08:59:31 +00:00
|
|
|
vga.setResolution(VGA_RESOLUTION);
|
2023-07-25 13:10:35 +00:00
|
|
|
|
|
|
|
canvas.setBrushColor(rgb(_bg));
|
|
|
|
canvas.clear();
|
|
|
|
canvas.setGlyphOptions(GlyphOptions().FillBackground(true));
|
|
|
|
canvas.selectFont(&fabgl::FONT_5x7);
|
|
|
|
_cy = canvas.getFontInfo()->height;
|
|
|
|
_cx = canvas.getFontInfo()->width;
|
|
|
|
_dx = canvas.getWidth();
|
|
|
|
_dy = canvas.getHeight();
|
2023-08-30 13:01:30 +00:00
|
|
|
|
2023-11-18 11:03:47 +00:00
|
|
|
DBG(printf("w %d h %d", _dx, _dy));
|
|
|
|
DBG(println());
|
2018-11-03 13:30:49 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
setColor(fg);
|
|
|
|
_oxs = _dx;
|
|
|
|
}
|
|
|
|
|
2023-07-25 13:10:35 +00:00
|
|
|
void Display::clear() {
|
2018-11-03 13:30:49 +00:00
|
|
|
#if defined(USE_UTFT)
|
|
|
|
utft.fillScr(_bg);
|
|
|
|
#elif defined(USE_ESPI)
|
|
|
|
espi.fillScreen(_bg);
|
2023-07-25 13:10:35 +00:00
|
|
|
#elif defined(USE_VGA)
|
|
|
|
canvas.clear();
|
2018-11-03 13:30:49 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2023-07-25 13:10:35 +00:00
|
|
|
void Display::status(const char *s) {
|
2018-11-03 13:30:49 +00:00
|
|
|
setColor(_fg);
|
|
|
|
|
|
|
|
#if defined(USE_UTFT)
|
|
|
|
unsigned y = _dy - _cy, n = strlen(s), xs = _dx - n*_cx;
|
|
|
|
for (unsigned x = _oxs; x < xs; x += _cx)
|
|
|
|
utft.print(" ", x, y);
|
|
|
|
utft.print(s, xs, y);
|
|
|
|
_oxs = xs;
|
|
|
|
#elif defined(USE_ESPI)
|
2018-11-10 13:34:36 +00:00
|
|
|
espi.fillRect(_dx - _oxs, _dy - _cy, _oxs, _cy, _bg);
|
2018-11-03 13:30:49 +00:00
|
|
|
_oxs = espi.textWidth(s);
|
2018-11-10 13:34:36 +00:00
|
|
|
espi.setTextDatum(BR_DATUM);
|
|
|
|
espi.drawString(s, _dx, _dy);
|
2023-07-25 13:10:35 +00:00
|
|
|
#elif defined(USE_VGA)
|
|
|
|
canvas.fillRectangle(_dx - _oxs, _dy - _cy, _dx, _dy);
|
|
|
|
_oxs = canvas.textExtent(s) + _cx;
|
|
|
|
canvas.drawText(_dx - _oxs, _dy - _cy, s);
|
2018-11-03 13:30:49 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2023-10-20 12:18:38 +00:00
|
|
|
void Display::statusf(const char *fmt, ...) {
|
|
|
|
va_list args;
|
|
|
|
char buf[80];
|
|
|
|
va_start(args, fmt);
|
|
|
|
vsnprintf(buf, sizeof(buf), fmt, args);
|
|
|
|
va_end(args);
|
|
|
|
status(buf);
|
|
|
|
}
|
|
|
|
|
2023-07-25 13:10:35 +00:00
|
|
|
void Display::drawPixel(unsigned x, unsigned y, colour_t col) {
|
2023-07-26 14:32:11 +00:00
|
|
|
x += _xoff;
|
|
|
|
y += _yoff;
|
2018-11-03 13:30:49 +00:00
|
|
|
#if defined(USE_UTFT)
|
|
|
|
utft.setColor(col);
|
|
|
|
utft.drawPixel(x, y);
|
|
|
|
#elif defined(USE_ESPI)
|
2018-11-10 13:34:36 +00:00
|
|
|
espi.drawPixel(x, y, col);
|
2023-07-25 13:10:35 +00:00
|
|
|
#elif defined(USE_VGA)
|
|
|
|
canvas.setPixel(x, y, rgb(col));
|
2018-11-03 13:30:49 +00:00
|
|
|
#endif
|
|
|
|
}
|
2018-11-12 07:46:21 +00:00
|
|
|
|
2023-11-18 11:03:47 +00:00
|
|
|
void Display::drawLine(unsigned x1, unsigned y1, unsigned x2, unsigned y2, colour_t col) {
|
|
|
|
x1 += _xoff;
|
|
|
|
y1 += _yoff;
|
|
|
|
x2 += _xoff;
|
|
|
|
y2 += _yoff;
|
|
|
|
#if defined(USE_UTFT)
|
|
|
|
utft.setColor(col);
|
|
|
|
utft.drawLine(x1, y1, x2, y2);
|
|
|
|
#elif defined(USE_ESPI)
|
|
|
|
espi.drawLine(x1, y1, x2, y2, col);
|
|
|
|
#elif defined(USE_VGA)
|
|
|
|
canvas.drawLine(x1, y1, x2, y2, rgb(col));
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void Display::drawCircle(unsigned x, unsigned y, unsigned r, colour_t col) {
|
|
|
|
x += _xoff;
|
|
|
|
y += _yoff;
|
|
|
|
#if defined(USE_UTFT)
|
|
|
|
utft.setColor(col);
|
|
|
|
utft.drawCircle(x, y, r);
|
|
|
|
#elif defined(USE_ESPI)
|
|
|
|
espi.drawCircle(x, y, r, col);
|
|
|
|
#elif defined(USE_VGA)
|
|
|
|
canvas.setBrushColor(col);
|
|
|
|
canvas.fillEllipse(x, y, r, r);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void Display::fillCircle(unsigned x, unsigned y, unsigned r, colour_t col) {
|
|
|
|
x += _xoff;
|
|
|
|
y += _yoff;
|
|
|
|
#if defined(USE_UTFT)
|
|
|
|
utft.setColor(col);
|
|
|
|
utft.fillCircle(x, y, r);
|
|
|
|
#elif defined(USE_ESPI)
|
|
|
|
espi.fillCircle(x, y, r, col);
|
|
|
|
#elif defined(USE_VGA)
|
|
|
|
canvas.setPenColor(col);
|
|
|
|
canvas.drawEllipse(x, y, r, r);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void Display::drawRectangle(unsigned x, unsigned y, unsigned w, unsigned h, colour_t col) {
|
|
|
|
x += _xoff;
|
|
|
|
y += _yoff;
|
|
|
|
#if defined(USE_UTFT)
|
|
|
|
utft.setColor(col);
|
|
|
|
utft.drawRect(x, y, x+w, y+h);
|
|
|
|
#elif defined(USE_ESPI)
|
|
|
|
espi.drawRect(x, y, w, h, col);
|
|
|
|
#elif defined(USE_VGA)
|
|
|
|
canvas.setBrushColor(col);
|
|
|
|
canvas.fillRectangle(x, y, x+w, y+h);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void Display::fillRectangle(unsigned x, unsigned y, unsigned w, unsigned h, colour_t col) {
|
|
|
|
x += _xoff;
|
|
|
|
y += _yoff;
|
|
|
|
#if defined(USE_UTFT)
|
|
|
|
utft.setColor(col);
|
|
|
|
utft.fillRect(x, y, x+w, y+h);
|
|
|
|
#elif defined(USE_ESPI)
|
|
|
|
espi.fillRect(x, y, w, h, col);
|
|
|
|
#elif defined(USE_VGA)
|
|
|
|
canvas.setPenColor(col);
|
|
|
|
canvas.drawRectangle(x, y, x+w, y+h);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void Display::drawString(const char *s, unsigned x, unsigned y, colour_t col) {
|
2023-07-26 14:32:11 +00:00
|
|
|
x += _xoff;
|
|
|
|
y += _yoff;
|
2018-11-12 07:46:21 +00:00
|
|
|
#if defined(USE_UTFT)
|
2023-11-18 11:03:47 +00:00
|
|
|
utft.setColor(col);
|
2018-11-12 07:46:21 +00:00
|
|
|
utft.print(s, x, y);
|
|
|
|
#elif defined(USE_ESPI)
|
2018-11-12 22:18:44 +00:00
|
|
|
espi.setTextDatum(TL_DATUM);
|
2023-11-18 11:03:47 +00:00
|
|
|
/*
|
2018-11-12 22:18:44 +00:00
|
|
|
unsigned w = espi.textWidth(s);
|
|
|
|
espi.fillRect(x, y, w, _cy, _bg);
|
2018-11-12 07:46:21 +00:00
|
|
|
espi.drawString(s, x, y);
|
2023-11-18 11:03:47 +00:00
|
|
|
*/
|
|
|
|
espi.setTextColor(col, _bg, true);
|
|
|
|
espi.drawString(s, x, y);
|
2023-07-25 13:10:35 +00:00
|
|
|
#elif defined(USE_VGA)
|
2023-11-18 11:03:47 +00:00
|
|
|
canvas.setPenColor(col);
|
2023-07-25 13:10:35 +00:00
|
|
|
canvas.drawText(x, y, s);
|
2018-11-12 07:46:21 +00:00
|
|
|
#endif
|
|
|
|
}
|