Support for arbitrary FB resolutions.

This commit is contained in:
sorgelig
2019-05-30 02:14:14 +08:00
parent d637e11ee5
commit 7cbef7dc41

View File

@@ -1049,40 +1049,61 @@ void video_cmd(char *cmd)
if (video_fb_state())
{
int accept = 0;
if (!strncmp(cmd, "fb_cmd0 ", 8))
int fmt = 0, rb = 0, div = -1, width = -1, height = -1;
uint16_t hmin, hmax, vmin, vmax;
if (sscanf(cmd, "fb_cmd0 %d %d %d", &fmt, &rb, &div) == 3)
{
int fmt, rb, div;
if (sscanf(cmd + 8, "%d %d %d", &fmt, &rb, &div) == 3)
if (div >= 1 && div <= 4)
{
if ((fmt == 1555 || fmt == 565 || fmt == 8888) && (rb == 0 || rb == 1) && (div == 1 || div == 2 || div == 4))
{
int width = v_cur.item[1] / div;
int height = v_cur.item[5] / div;
int stride = ((width * ((fmt == 8888) ? 4 : 2)) + 255) & ~255;
printf("fb_cmd: new mode: %dx%d color=%d stride=%d\n", width, height, fmt, stride);
int sc_fmt = (fmt == 1555) ? 0 : (fmt == 565) ? 3 : 2;
spi_uio_cmd_cont(UIO_SET_FBUF);
spi_w((sc_fmt << 1) | (rb << 3) | 1); // format, enable flag
spi_w((uint16_t)FB_ADDR); // base address low word
spi_w(FB_ADDR >> 16); // base address high word
spi_w(width); // frame width
spi_w(height); // frame height
spi_w(0); // scaled left
spi_w(v_cur.item[1] - 1); // scaled right
spi_w(0); // scaled top
spi_w(v_cur.item[5] - 1); // scaled bottom
DisableIO();
sprintf(cmd, "echo %d %d %d %d %d >/sys/module/MiSTer_fb/parameters/mode", fmt, rb, width, height, stride);
system(cmd);
accept = 1;
}
width = v_cur.item[1] / div;
height = v_cur.item[5] / div;
hmin = vmin = 0;
hmax = v_cur.item[1] - 1;
vmax = v_cur.item[5] - 1;
accept = 1;
}
}
if (!accept) printf("video_cmd: unknown command or format.");
if (sscanf(cmd, "fb_cmd1 %d %d %d %d", &fmt, &rb, &width, &height) == 4)
{
if (width < 120 || width > (int)v_cur.item[1]) width = v_cur.item[1];
if (height < 120 || height > (int)v_cur.item[5]) height = v_cur.item[5];
div = 1;
while ((width*(div + 1)) <= (int)v_cur.item[1] && (height*(div + 1)) <= (int)v_cur.item[5]) div++;
hmin = (uint16_t)((v_cur.item[1] - (width * div)) / 2);
vmin = (uint16_t)((v_cur.item[5] - (height * div)) / 2);
hmax = hmin + (width * div) - 1;
vmax = vmin + (height * div) - 1;
accept = 1;
}
if (accept && (fmt == 1555 || fmt == 565 || fmt == 8888) && (rb == 0 || rb == 1))
{
int stride = ((width * ((fmt == 8888) ? 4 : 2)) + 255) & ~255;
int sc_fmt = (fmt == 1555) ? 0 : (fmt == 565) ? 3 : 2;
printf("fb_cmd: new mode: %dx%d => %dx%d color=%d stride=%d\n", width, height, hmax - hmin + 1, vmax - vmin + 1, fmt, stride);
spi_uio_cmd_cont(UIO_SET_FBUF);
spi_w((sc_fmt << 1) | (rb << 3) | 1); // format, enable flag
spi_w((uint16_t)FB_ADDR); // base address low word
spi_w(FB_ADDR >> 16); // base address high word
spi_w(width); // frame width
spi_w(height); // frame height
spi_w(hmin); // scaled left
spi_w(hmax); // scaled right
spi_w(vmin); // scaled top
spi_w(vmax); // scaled bottom
DisableIO();
sprintf(cmd, "echo %d %d %d %d %d >/sys/module/MiSTer_fb/parameters/mode", fmt, rb, width, height, stride);
system(cmd);
}
else
{
printf("video_cmd: unknown command or format.\n");
}
}
}