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(" ! = Insert modline. Example: !\"640x350@70Hz\" 25.175 640 656 752 800 350 366 462 510 -HSync -VSync\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("Viewport size : %d x %d\n", VGAController.getViewPortWidth(), VGAController.getViewPortHeight());
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( Serial.readStringUntil('\n').c_str() );
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;
}
}
}