Test VGA output at predefined resolutions or custom resolution by specifying linux-like modelines
const char * PresetResolutions[] = {
VGA_320x200_60HzD,
};
int currentResolution = 24;
int moveX = 0;
int moveY = 0;
int shrinkX = 0;
int shrinkY = 0;
void printHelp()
{
Serial.printf("Modeline studio\n");
Serial.printf("Chip Revision: %d Chip Frequency: %d MHz\n\n", ESP.getChipRevision(), ESP.getCpuFreqMHz());
Serial.printf("%s\n", VGAController.getResolutionTimings()->label);
Serial.printf("\nScreen move:\n");
Serial.printf(" w = Move Up z = Move Down a = Move Left s = Move Right\n");
Serial.printf("Screen shrink:\n");
Serial.printf(" n = Dec Horiz N = Inc Horiz m = Dec Vert M = Inc Vert\n");
Serial.printf("Resolutions:\n");
Serial.printf(" + = Next resolution - = Prev resolution x = Restore modeline\n");
Serial.printf("Modeline change:\n");
Serial.printf(" Just insert a modline. Example: \"640x350@70Hz\" 25.175 640 656 752 800 350 366 462 510 -HSync -VSync\n");
Serial.printf(" e = Decrease horiz. Front Porch E = Increase horiz. Front Porch\n");
Serial.printf(" r = Decrease horiz. Sync Pulse R = Increase horiz. Sync Pulse\n");
Serial.printf(" t = Decrease horiz. Bach Porch T = Increase horiz. Back Porch\n");
Serial.printf(" y = Decrease vert. Front Porch Y = Increase vert. Front Porch\n");
Serial.printf(" u = Decrease vert. Sync Pulse U = Increase vert. Sync Pulse\n");
Serial.printf(" i = Decrease vert. Bach Porch I = Increase vert. Back Porch\n");
Serial.printf(" o = Decrease frequency by 5KHz O = Increase frequency by 5KHz\n");
Serial.printf(" . = Change horiz. signals order\n");
Serial.printf("Various:\n");
Serial.printf(" h = Print This help\n\n");
}
void printInfo()
{
auto t = VGAController.getResolutionTimings();
Serial.printf("Modeline \"%s\" %2.8g %d %d %d %d %d %d %d %d %cHSync %cVSync %s %s\n",
t->label,
t->frequency / 1000000.0,
t->HVisibleArea,
t->HVisibleArea + t->HFrontPorch,
t->HVisibleArea + t->HFrontPorch + t->HSyncPulse,
t->HVisibleArea + t->HFrontPorch + t->HSyncPulse + t->HBackPorch,
t->VVisibleArea,
t->VVisibleArea + t->VFrontPorch,
t->VVisibleArea + t->VFrontPorch + t->VSyncPulse,
t->VVisibleArea + t->VFrontPorch + t->VSyncPulse + t->VBackPorch,
t->HSyncLogic, t->VSyncLogic,
t->scanCount == 2 ? "DoubleScan" : "",
if (moveX || moveY)
Serial.printf("moveScreen(%d, %d)\n", moveX, moveY);
if (shrinkX || shrinkY)
Serial.printf("shrinkScreen(%d, %d)\n", shrinkX, shrinkY);
Serial.printf("Free memory (total, min, largest): %d, %d, %d\n\n", heap_caps_get_free_size(MALLOC_CAP_32BIT),
heap_caps_get_minimum_free_size(MALLOC_CAP_32BIT),
heap_caps_get_largest_free_block(MALLOC_CAP_32BIT));
}
void updateScreen()
{
Canvas cv(&VGAController);
cv.clear();
cv.fillRectangle(0, 0, cv.getWidth() - 1, cv.getHeight() - 1);
cv.drawRectangle(0, 0, cv.getWidth() - 1, cv.getHeight() - 1);
cv.selectFont(&fabgl::FONT_8x8);
cv.drawText(40, 20, VGAController.getResolutionTimings()->label);
cv.setGlyphOptions(GlyphOptions());
cv.drawTextFmt(40, 60, "Viewport Size : %d x %d", cv.getWidth(), cv.getHeight());
cv.drawText(40, 80, "Commands (More on UART):");
cv.drawText(40, 100, " w = Move Up z = Move Down");
cv.drawText(40, 120, " a = Move Left s = Move Right");
cv.drawText(40, 140, " + = Next Resolution");
cv.drawRectangle(35, 15, 310, 155);
}
void setup()
{
Serial.begin(115200);
delay(500);
VGAController.begin();
VGAController.
setResolution(PresetResolutions[currentResolution]);
updateScreen();
printHelp();
printInfo();
}
void loop()
{
if (Serial.available() > 0) {
char c = Serial.read();
switch (c) {
case 'h':
printHelp();
break;
case 'w':
--moveY;
VGAController.moveScreen(0, -1);
printInfo();
break;
case 'z':
++moveY;
VGAController.moveScreen(0, +1);
printInfo();
break;
case 'a':
--moveX;
VGAController.moveScreen(-1, 0);
printInfo();
break;
case 's':
++moveX;
VGAController.moveScreen(+1, 0);
printInfo();
break;
case 'x':
moveX = moveY = shrinkX = shrinkY = 0;
VGAController.setResolution(PresetResolutions[currentResolution]);
updateScreen();
printInfo();
break;
case '+':
case '-':
moveX = moveY = shrinkX = shrinkY = 0;
currentResolution = (c == '+' ? currentResolution + 1 : currentResolution - 1);
if (currentResolution == sizeof(PresetResolutions) / sizeof(const char *))
currentResolution = 0;
if (currentResolution < 0)
currentResolution = sizeof(PresetResolutions) / sizeof(const char *) - 1;
VGAController.setResolution(PresetResolutions[currentResolution]);
updateScreen();
printInfo();
break;
case '"':
moveX = moveY = shrinkX = shrinkY = 0;
VGAController.setResolution( (String("\"") + Serial.readStringUntil('\n')).c_str() );
updateScreen();
printInfo();
break;
case 'e':
case 'E':
t = *VGAController.getResolutionTimings();
VGAController.setResolution(t);
updateScreen();
printInfo();
break;
case 'r':
case 'R':
t = *VGAController.getResolutionTimings();
VGAController.setResolution(t);
updateScreen();
printInfo();
break;
case 't':
case 'T':
t = *VGAController.getResolutionTimings();
VGAController.setResolution(t);
updateScreen();
printInfo();
break;
case 'y':
case 'Y':
t = *VGAController.getResolutionTimings();
VGAController.setResolution(t);
updateScreen();
printInfo();
break;
case 'u':
case 'U':
t = *VGAController.getResolutionTimings();
VGAController.setResolution(t);
updateScreen();
printInfo();
break;
case 'i':
case 'I':
t = *VGAController.getResolutionTimings();
VGAController.setResolution(t);
updateScreen();
printInfo();
break;
case 'o':
case 'O':
t = *VGAController.getResolutionTimings();
VGAController.setResolution(t);
updateScreen();
printInfo();
break;
case '.':
t = *VGAController.getResolutionTimings();
break;
break;
break;
break;
}
VGAController.setResolution(t);
updateScreen();
printInfo();
break;
case 'n':
++shrinkX;
VGAController.shrinkScreen(+1, 0);
updateScreen();
printInfo();
break;
case 'N':
--shrinkX;
VGAController.shrinkScreen(-1, 0);
updateScreen();
printInfo();
break;
case 'm':
++shrinkY;
VGAController.shrinkScreen(0, +1);
updateScreen();
printInfo();
break;
case 'M':
--shrinkY;
VGAController.shrinkScreen(0, -1);
updateScreen();
printInfo();
break;
}
}
}
int getScreenHeight()
Determines the screen height in pixels.
int getViewPortHeight()
Determines vertical size of the viewport.
int getViewPortWidth()
Determines horizontal size of the viewport.
int getScreenWidth()
Determines the screen width in pixels.
Represents the VGA 2 colors bitmapped controller.
GlyphOptions & DoubleWidth(uint8_t value)
Helper method to set or reset doubleWidth.
GlyphOptions & FillBackground(bool value)
Helper method to set or reset fillBackground.
This file is the all in one include file. Application can just include this file to use FabGL library...
#define VGA_640x480_60HzAlt1
#define SVGA_800x600_56Hz
#define SVGA_800x300_60Hz
#define SVGA_800x600_60Hz
#define VESA_640x350_85Hz
#define SVGA_1024x768_60Hz
#define SVGA_960x540_60Hz
#define VGA_720x348_50HzD
#define SVGA_1280x768_50Hz
#define SVGA_1280x720_60Hz
#define VGA_640x200_60HzD
#define VESA_768x576_60Hz
#define QVGA_320x240_60Hz
#define VESA_720x400_85Hz
#define SVGA_1280x600_60Hz
#define VGA_640x480_60HzD
#define VESA_640x480_75Hz
#define VGA_640x350_70HzAlt1
#define SVGA_1280x720_60HzAlt1
#define SVGA_1024x768_75Hz
#define SVGA_1024x768_70Hz
VGAScanStart HStartingBlock
Specifies the VGA timings. This is a modeline decoded.