FabGL
ESP32 Display Controller and Graphics Library
VGA/SimpleTerminalOut/SimpleTerminalOut.ino

Simple terminal - output only

/*
Created by Fabrizio Di Vittorio (fdivitto2013@gmail.com) - <http://www.fabgl.com>
Copyright (c) 2019-2022 Fabrizio Di Vittorio.
All rights reserved.
* Please contact fdivitto2013@gmail.com if you need a commercial license.
* This library and related software is available under GPL v3.
FabGL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
FabGL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FabGL. If not, see <http://www.gnu.org/licenses/>.
*/
#include "fabgl.h"
#include "devdrivers/cvbsgenerator.h"
#include "vtanimations.h"
fabgl::CVBS16Controller DisplayController;
fabgl::Terminal Terminal;
using fabgl::CVBSGenerator;
void setup()
{
Serial.begin(115200); delay(500); Serial.write("\n\n\n"); // DEBUG ONLY
DisplayController.begin();
DisplayController.setHorizontalRate(2);
DisplayController.setMonochrome(false);
//DisplayController.setResolution("I-PAL-B");
DisplayController.setResolution("P-PAL-B");
//DisplayController.setResolution("I-NTSC-M");
//DisplayController.setResolution("P-NTSC-M");
//while (1) printf("frame=%d field=%d frameLine=%d interFrameLine=%d pictureLine=%d scPhaseSam=%d\n", CVBSGenerator::frame(), CVBSGenerator::field(), CVBSGenerator::frameLine(), CVBSGenerator::interFrameLine(), CVBSGenerator::pictureLine(), CVBSGenerator::subCarrierPhase());
Terminal.begin(&DisplayController);
//Terminal.setLogStream(Serial); // DEBUG ONLY
//Terminal.enableCursor(true);
}
void slowPrintf(const char * format, ...)
{
va_list ap;
va_start(ap, format);
int size = vsnprintf(nullptr, 0, format, ap) + 1;
if (size > 0) {
va_end(ap);
va_start(ap, format);
char buf[size + 1];
vsnprintf(buf, size, format, ap);
for (int i = 0; i < size; ++i) {
Terminal.write(buf[i]);
//Serial.write(buf[i]);
delay(25);
}
}
va_end(ap);
}
void demo1()
{
//Terminal.loadFont(&fabgl::FONT_10x20);
Terminal.loadFont(&fabgl::FONT_8x8);
Terminal.clear();
Terminal.enableCursor(false);
//*/
for (int i = 1; i < Terminal.getColumns(); ++i)
Terminal.write("M");
Terminal.write("X\r\n");
for (int i = 2; i < Terminal.getRows(); ++i)
Terminal.printf("%d\r\n", i);
Terminal.printf("%d", Terminal.getRows());
Terminal.flush(); delay(500);
//*/
Canvas cv(&DisplayController);
// linee rosse
cv.setPenColor(255, 0, 0);
cv.drawLine(0, 0, cv.getWidth() - 1, cv.getHeight() - 1);
cv.drawLine(0, cv.getHeight() - 1, cv.getWidth() - 1, 0);
cv.drawLine(cv.getWidth() / 2, 0, cv.getWidth() / 2, cv.getHeight() - 1);
cv.drawLine(0, cv.getHeight() / 2, cv.getWidth() - 1, cv.getHeight() / 2);
//*/
cv.setBrushColor(Color::BrightRed);
cv.fillRectangle(cv.getWidth()/2-80, cv.getHeight()/2-80, cv.getWidth()/2+80, cv.getHeight()/2+80);
cv.setBrushColor(Color::BrightGreen);
cv.fillRectangle(cv.getWidth()/2-60, cv.getHeight()/2-60, cv.getWidth()/2+60, cv.getHeight()/2+60);
cv.setBrushColor(Color::BrightBlue);
cv.fillRectangle(cv.getWidth()/2-40, cv.getHeight()/2-40, cv.getWidth()/2+40, cv.getHeight()/2+40);
cv.setBrushColor(Color::BrightYellow);
cv.fillRectangle(50, cv.getHeight()/2 - 20, 100, cv.getHeight()/2 + 20);
cv.setBrushColor(Color::White);
cv.fillRectangle(cv.getWidth() - 50, cv.getHeight()/2 - 20, cv.getWidth() - 100, cv.getHeight()/2 + 20);
//*/
/*
// tre bande orizzontali
int w = cv.getWidth();
int h = cv.getHeight() / 3;
cv.setBrushColor(Color::BrightRed);
cv.fillRectangle(0, 0, w, h);
cv.setBrushColor(Color::BrightGreen);
cv.fillRectangle(0, h, w, h + h);
cv.setBrushColor(Color::BrightBlue);
cv.fillRectangle(0, h + h, w, h + h + h);
//*/
/*
// tutto rosso
int w = cv.getWidth();
int h = cv.getHeight();
cv.setBrushColor(Color::BrightRed);
cv.fillRectangle(0, 0, w, h);
//*/
//cv.setBrushColor(Color::BrightBlue);
//cv.fillRectangle(0, 0, cv.getWidth(), cv.getHeight());
while (1) {
delay(10);
//while (1) printf("frame=%d field=%d frameLine=%d interFrameLine=%d pictureLine=%d scPhaseSam=%d\n", CVBSGenerator::frame(), CVBSGenerator::field(), CVBSGenerator::frameLine(), CVBSGenerator::interFrameLine(), CVBSGenerator::pictureLine(), CVBSGenerator::subCarrierPhase());
}
//*/
Terminal.write("\e[40;92m"); // background: black, foreground: green
Terminal.write("\e[2J"); // clear screen
Terminal.write("\e[1;1H"); // move cursor to 1,1
slowPrintf("* * * * W E L C O M E T O F a b G L * * * *\r\n");
slowPrintf("2019-2022 by Fabrizio Di Vittorio - www.fabgl.com\r\n");
slowPrintf("=================================================\r\n\n");
slowPrintf("A Display Controller, PS2 Mouse and Keyboard Controller, Graphics Library, Audio Engine, Game Engine and ANSI/VT Terminal for the ESP32\r\n\n");
slowPrintf("Current settings\r\n");
slowPrintf("Screen Size : %d x %d\r\n", DisplayController.getScreenWidth(), DisplayController.getScreenHeight());
slowPrintf("Viewport Size : %d x %d\r\n", DisplayController.getViewPortWidth(), DisplayController.getViewPortHeight());
slowPrintf("Terminal Size : %d x %d\r\n", Terminal.getColumns(), Terminal.getRows());
slowPrintf("Free Memory : %d bytes\r\n\n", heap_caps_get_free_size(MALLOC_CAP_32BIT));
}
void demo2()
{
Terminal.write("\e[40;32m"); // background: black, foreground: green
slowPrintf("8 or 64 colors supported\r\n");
slowPrintf("ANSI colors:\r\n");
// foregrounds
Terminal.write("\e[31mRED\t"); delay(500);
Terminal.write("\e[32mGREEN\t"); delay(500);
Terminal.write("\e[33mYELLOW\t"); delay(500);
Terminal.write("\e[34mBLUE\t"); delay(500);
Terminal.write("\e[35mMAGENTA\t"); delay(500);
Terminal.write("\e[36mCYAN\t"); delay(500);
Terminal.write("\e[37mWHITE\r\n"); delay(500);
Terminal.write("\e[90mHBLACK\t"); delay(500);
Terminal.write("\e[91mHRED\t"); delay(500);
Terminal.write("\e[92mHGREEN\t"); delay(500);
Terminal.write("\e[93mHYELLOW\t"); delay(500);
Terminal.write("\e[94mHBLUE\t"); delay(500);
Terminal.write("\e[95mHMAGENTA\t"); delay(500);
Terminal.write("\e[96mHCYAN\t"); delay(500);
Terminal.write("\e[97mHWHITE\r\n"); delay(500);
// backgrounds
Terminal.write("\e[40mBLACK\t"); delay(500);
Terminal.write("\e[41mRED\e[40m\t"); delay(500);
Terminal.write("\e[42mGREEN\e[40m\t"); delay(500);
Terminal.write("\e[43mYELLOW\e[40m\t"); delay(500);
Terminal.write("\e[44mBLUE\e[40m\t"); delay(500);
Terminal.write("\e[45mMAGENTA\e[40m\t"); delay(500);
Terminal.write("\e[46mCYAN\e[40m\t"); delay(500);
Terminal.write("\e[47mWHITE\e[40m\r\n"); delay(500);
Terminal.write("\e[100mHBLACK\e[40m\t"); delay(500);
Terminal.write("\e[101mHRED\e[40m\t"); delay(500);
Terminal.write("\e[102mHGREEN\e[40m\t"); delay(500);
Terminal.write("\e[103mHYELLOW\e[40m\t"); delay(500);
Terminal.write("\e[104mHBLUE\e[40m\t"); delay(500);
Terminal.write("\e[105mHMAGENTA\e[40m\t"); delay(500);
Terminal.write("\e[106mHCYAN\e[40m\r\n"); delay(500);
}
void demo3()
{
Terminal.write("\e[40;32m"); // background: black, foreground: green
slowPrintf("\nSupported styles:\r\n");
slowPrintf("\e[0mNormal\r\n");
slowPrintf("\e[1mBold\e[0m\r\n");
slowPrintf("\e[3mItalic\e[0m\r\n");
slowPrintf("\e[4mUnderlined\e[0m\r\n");
slowPrintf("\e[5mBlink\e[0m\r\n");
slowPrintf("\e[7mInverse\e[0m\r\n");
slowPrintf("\e[1;3mBoldItalic\e[0m\r\n");
slowPrintf("\e[1;3;4mBoldItalicUnderlined\e[0m\r\n");
slowPrintf("\e[1;3;4;5mBoldItalicUnderlinedBlinking\e[0m\r\n");
slowPrintf("\e[1;3;4;5;7mBoldItalicUnderlinedBlinkingInverse\e[0m\r\n");
slowPrintf("\e#6Double Width Line\r\n");
slowPrintf("\e#6\e#3Double Height Line\r\n"); // top half
slowPrintf("\e#6\e#4Double Height Line\r\n"); // bottom half
}
void demo4()
{
Canvas cv(&DisplayController);
Terminal.write("\e[40;32m"); // background: black, foreground: green
slowPrintf("\nMixed text and graphics:\r\n");
slowPrintf("Points...\r\n");
for (int i = 0; i < 500; ++i) {
cv.setPenColor(random(256), random(256), random(256));
cv.setPixel(random(cv.getWidth()), random(cv.getHeight()));
delay(15);
}
delay(500);
slowPrintf("\e[40;32mLines...\r\n");
for (int i = 0; i < 50; ++i) {
cv.setPenColor(random(256), random(256), random(256));
cv.drawLine(random(cv.getWidth()), random(cv.getHeight()), random(cv.getWidth()), random(cv.getHeight()));
delay(50);
}
delay(500);
slowPrintf("\e[40;32mRectangles...\r\n");
for (int i = 0; i < 50; ++i) {
cv.setPenColor(random(256), random(256), random(256));
cv.drawRectangle(random(cv.getWidth()), random(cv.getHeight()), random(cv.getWidth()), random(cv.getHeight()));
delay(50);
}
delay(500);
slowPrintf("\e[40;32mEllipses...\r\n");
for (int i = 0; i < 50; ++i) {
cv.setPenColor(random(256), random(256), random(256));
cv.drawEllipse(random(cv.getWidth()), random(cv.getHeight()), random(cv.getWidth()), random(cv.getHeight()));
delay(50);
}
for (int i = 0; i < 30; ++i) {
Terminal.write("\e[40;32mScrolling...\r\n");
delay(250);
}
cv.clear();
}
void demo5()
{
Terminal.write("\e[40;93m"); // background: black, foreground: yellow
Terminal.write("\e[2J"); // clear screen
slowPrintf("\e[10;56HFast Rendering");
slowPrintf("\e[12;50HThis is a VT/ANSI animation");
Terminal.write("\e[20h"); // automatic new line on
Terminal.write("\e[92m"); // light-green
Terminal.enableCursor(false);
for (int j = 0; j < 4; ++j) {
for (int i = 0; i < sizeof(vt_animation); ++i) {
Terminal.write(vt_animation[i]);
if (vt_animation[i] == 0x1B && vt_animation[i + 1] == 0x5B && vt_animation[i + 2] == 0x48)
delay(120); // pause 100ms every frame
}
}
Terminal.enableCursor(true);
Terminal.write("\e[20l"); // automatic new line off
}
void demo6()
{
Terminal.write("\e[40;32m"); // background: black, foreground: green
slowPrintf("\nColored Attributes with styles:\r\n");
slowPrintf("\e[0mNormal\r\n");
slowPrintf("\e[1mBold\e[0m\r\n");
slowPrintf("\e[3mItalic\e[0m\r\n");
slowPrintf("\e[4mUnderlined\e[0m\r\n");
delay(1000);
slowPrintf("\nColored Attributes without styles:\r\n");
slowPrintf("\e[0mNormal\r\n");
slowPrintf("\e[1mBold\e[0m\r\n");
slowPrintf("\e[3mItalic\e[0m\r\n");
slowPrintf("\e[4mUnderlined\e[0m\r\n");
}
void loop()
{
delay(1000);
demo1();
delay(4000);
demo2();
delay(4000);
demo3();
delay(4000);
demo4();
delay(4000);
demo5();
delay(4000);
demo6();
delay(4000);
}
int getRows()
Returns the number of lines.
Definition: terminal.h:1215
void clear(bool moveCursor=true)
Clears the screen.
Definition: terminal.cpp:1001
int getColumns()
Returns the number of columns.
Definition: terminal.h:1208
void loadFont(FontInfo const *font)
Sets the font to use.
Definition: terminal.cpp:797
size_t write(const uint8_t *buffer, size_t size)
Sends specified number of codes to the display.
Definition: terminal.cpp:1950
void enableCursor(bool value)
Enables or disables cursor.
Definition: terminal.cpp:1106
void setColorForAttribute(CharStyle attribute, Color color, bool maintainStyle)
Selects a color for the specified attribute.
Definition: terminal.cpp:968
bool begin(BaseDisplayController *displayController, int maxColumns=-1, int maxRows=-1, Keyboard *keyboard=nullptr)
Initializes the terminal.
Definition: terminal.cpp:323
void flush(bool waitVSync)
Waits for all codes sent to the display has been processed.
Definition: terminal.cpp:878
void setForegroundColor(Color color, bool setAsDefault=true)
Sets the foreground color.
Definition: terminal.cpp:931
An ANSI-VT100 compatible display terminal.
Definition: terminal.h:953
GlyphOptions & Underline(bool value)
Helper method to set or reset underlined.
GlyphOptions & Italic(bool value)
Helper method to set or reset italic.
GlyphOptions & Bold(bool value)
Helper method to set or reset bold.
This file is the all in one include file. Application can just include this file to use FabGL library...