321 lines
7.0 KiB
C++
321 lines
7.0 KiB
C++
#include "Scroller.h"
|
|
#include <SimpleMap.h>
|
|
//#define DEBUG
|
|
|
|
eDict_t Escapes[] = {
|
|
{"\u001b[30m","black",eDict_t::COLOR, CRGB::Black },
|
|
{"\u001b[31m","red",eDict_t::COLOR, CRGB::Red },
|
|
{"\u001b[32m","green",eDict_t::COLOR, CRGB::Green },
|
|
{"\u001b[33m","yellow",eDict_t::COLOR, CRGB::Yellow },
|
|
{"\u001b[34m","blue",eDict_t::COLOR, CRGB::Blue },
|
|
{"\u001b[35m","magenta",eDict_t::COLOR, CRGB::Magenta },
|
|
{"\u001b[36m","cyan",eDict_t::COLOR, CRGB::Cyan },
|
|
{"\u001b[37m","white",eDict_t::COLOR, CRGB::White },
|
|
{"\u001b[40m","black",eDict_t::BCOLOR, CRGB::Black },
|
|
{"\u001b[41m","red",eDict_t::BCOLOR, CRGB::Red },
|
|
{"\u001b[42m","green",eDict_t::BCOLOR, CRGB::Green },
|
|
{"\u001b[43m","yellow",eDict_t::BCOLOR, CRGB::Yellow },
|
|
{"\u001b[44m","blue",eDict_t::BCOLOR, CRGB::Blue },
|
|
{"\u001b[45m","magenta",eDict_t::BCOLOR, CRGB::Magenta },
|
|
{"\u001b[46m","cyan",eDict_t::BCOLOR, CRGB::Cyan },
|
|
{"\u001b[47m","white",eDict_t::BCOLOR, CRGB::White },
|
|
|
|
{"\u001b[0m","reset",eDict_t::CONTROL, RESET_ALL},
|
|
{"\u001b[1m","bold",eDict_t::CONTROL, BOLD},
|
|
{"\u001b[4m","underline",eDict_t::CONTROL, UNDERLINE},
|
|
{"\u001b[7m","reversed",eDict_t::CONTROL, REVERSED},
|
|
{"\u001b[2J","clear",eDict_t::CONTROL, CLEAR_ALL},
|
|
{"\u001b[97;%dm","loops",eDict_t::CONTOL_WITH_PARAM, LOOPS},
|
|
{"\u001b[98;%dm","speed",eDict_t::CONTOL_WITH_PARAM, SPEED},
|
|
{"\u001b[99;%dm","timeout",eDict_t::CONTOL_WITH_PARAM, TIMEOUT},
|
|
};
|
|
|
|
SimpleMap<String, eDict_t*>* escMap;
|
|
|
|
Scroller::Scroller()
|
|
{
|
|
_act_setting = _setting;
|
|
}
|
|
|
|
void Scroller::init()
|
|
{
|
|
Serial.println("INIT ESCAPES");
|
|
escMap = new SimpleMap<String, eDict_t*>([](String &a, String &b) -> int {
|
|
if (a == b) return 0; // a and b are equal
|
|
else if (a > b) return 1; // a is bigger than b
|
|
else return -1; // a is smaller than b
|
|
});
|
|
for (int i=0; i< (sizeof(Escapes)/sizeof(Escapes[0])) ; i++) {
|
|
String s = String(Escapes[i].code);
|
|
String escape;
|
|
|
|
escape = String(s);
|
|
if (Escapes[i].tt == eDict_t::CONTOL_WITH_PARAM) {
|
|
int n = s.indexOf('%');
|
|
if (n !=-1)
|
|
escape = String(s.substring(0,n));
|
|
}
|
|
|
|
Serial.printf("%s = %s\n",escape,Escapes[i].name);
|
|
escMap->put(escape,&Escapes[i]);
|
|
|
|
}
|
|
DumpSetting(_act_setting);
|
|
}
|
|
|
|
bool Scroller::decodeEscape2Setting(String es)
|
|
{
|
|
String s;
|
|
eDict_t *e;
|
|
int p = es.indexOf(';');
|
|
|
|
if (p != -1) {
|
|
s = es.substring(0,p+1);
|
|
} else {
|
|
s = es;
|
|
}
|
|
|
|
//Serial.printf("ESC GET = %s\n",s);
|
|
e = escMap->get(s);
|
|
if (!e) return false;
|
|
|
|
if (e->tt == eDict_t::CONTROL) {
|
|
switch (e->control) {
|
|
case CLEAR_ALL:
|
|
DeleteLines();
|
|
case RESET_ALL:
|
|
_act_setting = _setting;
|
|
break;
|
|
case BOLD:
|
|
_act_setting.bold = true;
|
|
break;
|
|
case UNDERLINE:
|
|
_act_setting.underline = true;
|
|
break;
|
|
case REVERSED:
|
|
_act_setting.reversed = true;
|
|
break;
|
|
}
|
|
}
|
|
if (e->tt == eDict_t::CONTOL_WITH_PARAM)
|
|
{
|
|
int param;
|
|
sscanf(es.c_str(),e->code,¶m);
|
|
switch (e->control) {
|
|
case SPEED:
|
|
_act_setting.speed = param;
|
|
break;
|
|
case TIMEOUT:
|
|
_act_setting.timeout = param;
|
|
break;
|
|
case LOOPS:
|
|
_act_setting.loops = param;
|
|
break;
|
|
}
|
|
}
|
|
if (e->tt == eDict_t::COLOR) _act_setting.color = e->color;
|
|
if (e->tt == eDict_t::BCOLOR) _act_setting.bcolor = e->color;
|
|
#ifdef DEBUG
|
|
DumpSetting(_act_setting);
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
void Scroller::DumpSetting(Setting & s)
|
|
{
|
|
Serial.printf("[COLOR=%x Brightness=%d Speed=%d Timeout=%d]\n",s.color,s.brightness,s.speed,s.timeout);
|
|
}
|
|
|
|
void Scroller::SetMatrix(FastLED_NeoMatrix *matrix)
|
|
{
|
|
_matrix = matrix;
|
|
}
|
|
|
|
int Scroller::GetNumberOfLines()
|
|
{
|
|
return _nlines;
|
|
}
|
|
|
|
int Scroller::AddLine(String line)
|
|
{
|
|
_Lines[_nlines] = line;
|
|
return _nlines++;
|
|
}
|
|
|
|
int Scroller::AddLines(String* lines,int nlines)
|
|
{
|
|
for (int i=0; i < nlines; i++) {
|
|
_Lines[i] = lines[i];
|
|
}
|
|
_nlines = nlines;
|
|
|
|
return _nlines;
|
|
}
|
|
|
|
bool Scroller::ReplaceLine(int number,String line)
|
|
{
|
|
_Lines[number] = line;
|
|
return true;
|
|
}
|
|
|
|
void Scroller::DeleteLines()
|
|
{
|
|
_nlines = 0;
|
|
_lp = 0;
|
|
}
|
|
|
|
void Scroller::Show(int _x,int _y,String line)
|
|
{
|
|
_matrix->fillScreen(0);
|
|
_matrix->setCursor(_x, _y);
|
|
|
|
for (int l=0;l < line.length();l++) {
|
|
if (line.charAt(l) == '\u001b') {
|
|
int ee;
|
|
for (ee = l+2; (line.charAt(ee) >= '0' && line.charAt(ee) <= '9') || line.charAt(ee) == ';'; ee++ )
|
|
;
|
|
decodeEscape2Setting(line.substring(l,ee+1));
|
|
l = ee;
|
|
continue;
|
|
}
|
|
_matrix->setTextColor(Framebuffer_GFX::Color24to16(_act_setting.color));
|
|
_matrix->setBrightness(_act_setting.brightness);
|
|
if (l != line.length()) {
|
|
#ifdef DEBUG
|
|
Serial.print(line.charAt(l));
|
|
#endif
|
|
_matrix->print(line.charAt(l));
|
|
}
|
|
|
|
}
|
|
#ifdef DEBUG
|
|
Serial.print("\n");
|
|
#endif
|
|
_matrix->show();
|
|
}
|
|
|
|
String Scroller::LineUnescaped(String line)
|
|
{
|
|
String rawLine = "";
|
|
for (int l=0;l < line.length();l++) {
|
|
if (line.charAt(l) == '\u001b') {
|
|
int ee;
|
|
for (ee = l+2; (line.charAt(ee) >= '0' && line.charAt(ee) <= '9') || line.charAt(ee) == ';'; ee++ )
|
|
;
|
|
l = ee;
|
|
continue;
|
|
}
|
|
if (l != line.length()) {
|
|
rawLine.concat(line.charAt(l));
|
|
}
|
|
}
|
|
return rawLine;
|
|
}
|
|
|
|
int Scroller::Scroll()
|
|
{
|
|
int mx = 32;
|
|
String line;
|
|
|
|
line = _Lines[_lp];
|
|
int ll = LineUnescaped(line).length();
|
|
if (ll * 6 > mx)
|
|
{
|
|
if (_x < ll * 6 - mx)
|
|
{
|
|
Show(-_x,_y,line);
|
|
if (_x++ == 0) {
|
|
return _act_setting.timeout/SCROLLER_TICK_TIME;
|
|
}
|
|
else {
|
|
return _act_setting.speed/SCROLLER_TICK_TIME;
|
|
}
|
|
}
|
|
_lp++;
|
|
_x = 0;
|
|
return _act_setting.timeout/SCROLLER_TICK_TIME;
|
|
}
|
|
else
|
|
{
|
|
Show(_x,_y,line);
|
|
_lp++;
|
|
return _act_setting.timeout/SCROLLER_TICK_TIME;
|
|
}
|
|
}
|
|
|
|
void Scroller::PrintSerialLines()
|
|
{
|
|
for (int i=0; i < _nlines; i++)
|
|
{
|
|
Serial.println(_Lines[i]);
|
|
}
|
|
}
|
|
|
|
bool Scroller::TurnOn()
|
|
{
|
|
Serial.println("Turn on Scroller");
|
|
_off = false;
|
|
_lp = 0;
|
|
_x = 0;
|
|
_y = 0;
|
|
_nscrolled = 0;
|
|
_delayTicks = 0;
|
|
|
|
return true;
|
|
}
|
|
|
|
void Scroller::TurnOff()
|
|
{
|
|
Serial.println("TURN OFF");
|
|
_matrix->fillScreen(0);
|
|
_matrix->print("");
|
|
_matrix->show();
|
|
_off = true;
|
|
}
|
|
|
|
void Scroller::loop(ulong tick)
|
|
{
|
|
if (_off) return;
|
|
|
|
int delta = tick - _tick;
|
|
|
|
if (_lp == _nlines) {
|
|
_lp =0;
|
|
_nscrolled++;
|
|
_delayTicks = 50;
|
|
}
|
|
|
|
if (TimesScrolled() == _act_setting.loops) {
|
|
Serial.println("MAX LOOP");
|
|
TurnOff();
|
|
return;
|
|
}
|
|
|
|
if (_delayTicks - delta <= 0) _delayTicks = Scroll();
|
|
else _delayTicks -= delta;
|
|
|
|
|
|
if (_delayTicks < 0) _delayTicks = 0;
|
|
|
|
_tick = tick;
|
|
}
|
|
|
|
int Scroller::TimesScrolled()
|
|
{
|
|
return _nscrolled;
|
|
}
|
|
|
|
void Scroller::SetParameters(int line,uint8_t color,uint8_t brightness,int timeout_off,int timeout_on,int speed)
|
|
{
|
|
_act_setting.color = color;
|
|
_act_setting.brightness = brightness;
|
|
_act_setting.timeout = timeout_on;
|
|
_act_setting.timeout = timeout_off;
|
|
_act_setting.speed = speed;
|
|
}
|
|
|
|
Scroller::~Scroller()
|
|
{
|
|
}
|
|
|