From: techflashYT Date: Sun, 10 Aug 2025 09:37:43 +0000 (-0700) Subject: linuxvt: various framebuffer improvements X-Git-Url: https://git.0x19.co/screenshots/static/gitweb.css?a=commitdiff_plain;h=c1b8396c324f3a1ec507407069002f049b4dd328;p=doomgeneric-snom360 linuxvt: various framebuffer improvements 2 main improvements coming in here: - Handling for nonstandard stride values, since some devices have non-linear framebuffers, and the previous assumption, that stride = width * bytesPerPixel, no longer necessarily holds true. This distinction doesn't matter for many devices (and thus, it can fall back to the former assumption if checking the real stride fails), but for those where it does matter (e.g. the NVIDIA Jetson Orin Nano I just tried it on), it does indeed make the game display correctly, whereas it didn't before. - Clean up the pointer math needed to center the image on screen a bit. It was previously a bit of a mess, this version should be marginally faster, and much easier to read/understand. --- diff --git a/doomgeneric/doomgeneric_linuxvt.c b/doomgeneric/doomgeneric_linuxvt.c index 74fb0d3..ed94dd9 100644 --- a/doomgeneric/doomgeneric_linuxvt.c +++ b/doomgeneric/doomgeneric_linuxvt.c @@ -407,6 +407,7 @@ static void checkInputDevs() { void DG_Init() { int ret; struct fb_var_screeninfo info; + struct fb_fix_screeninfo finfo; // // set up the framebuffer @@ -420,14 +421,23 @@ void DG_Init() { if (ret != 0) I_Error("Failed to get framebuffer info: %s", strerror(errno)); + // get other info (this can optionally fail, since we can guess the stride) + ret = ioctl(fbFd, FBIOGET_FSCREENINFO, &finfo); + if (ret != 0) { + printf("Failed to get framebuffer info: %s", strerror(errno)); + fbStride = fbWidth * fbBytesPerPixel; + } + else { + fbStride = finfo.line_length; + } + fbWidth = info.xres; fbHeight = info.yres; fbBytesPerPixel = info.bits_per_pixel / 8; - fbStride = fbWidth * fbBytesPerPixel; // to center the image on screen - fbOffsetX = (fbWidth - DOOMGENERIC_RESX) / 2; - fbOffsetY = (fbHeight - DOOMGENERIC_RESY) / 2; + fbOffsetX = ((fbWidth - DOOMGENERIC_RESX) / 2) * fbBytesPerPixel; + fbOffsetY = ((fbHeight - DOOMGENERIC_RESY) / 2) * fbStride; fbPtr = mmap(NULL, fbStride * fbHeight, PROT_READ | PROT_WRITE, MAP_SHARED, fbFd, 0); @@ -456,10 +466,8 @@ void DG_DrawFrame() { // larger than the doomgeneric render resolution. for (int line = 0; line < DOOMGENERIC_RESY; line++) { memcpy( - (fbPtr + (fbStride * (line + fbOffsetY)) + (fbOffsetX * fbBytesPerPixel)), - fbBytesPerPixel == 4 ? - DG_ScreenBuffer + (DOOMGENERIC_RESX * line) : - DG_ScreenBuffer + (DOOMGENERIC_RESX * (line / 2)), + (void *)((uintptr_t)(fbPtr) + (fbStride * line) + fbOffsetY + fbOffsetX), + (void *)(((uintptr_t)DG_ScreenBuffer) + (DOOMGENERIC_RESX * line * fbBytesPerPixel)), (fbBytesPerPixel * DOOMGENERIC_RESX) ); }