]> git.0x19.co - doomgeneric-snom360/commitdiff
linuxvt: various framebuffer improvements
authortechflashYT <officialTechflashYT@gmail.com>
Sun, 10 Aug 2025 09:37:43 +0000 (02:37 -0700)
committertechflashYT <officialTechflashYT@gmail.com>
Sun, 10 Aug 2025 09:43:02 +0000 (02:43 -0700)
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.

doomgeneric/doomgeneric_linuxvt.c

index 74fb0d3454baa497f3934d82b2d66815f2389515..ed94dd9babd240b7c7c74d1d9517a379450e9898 100644 (file)
@@ -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)
                );
        }