fallback to banked modes if LFB is not available
authorJohn Tsiombikas <nuclear@member.fsf.org>
Tue, 3 Mar 2020 14:04:19 +0000 (16:04 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Tue, 3 Mar 2020 14:04:19 +0000 (16:04 +0200)
src/dos/gfx.c
src/dos/gfx.h
src/dos/main.c
src/dos/vbe.c
src/game.c
src/game.h

index b610f18..61ac7db 100644 (file)
@@ -1,5 +1,7 @@
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
+#include "cdpmi.h"
 #include "gfx.h"
 #include "vbe.h"
 #include "vga.h"
@@ -77,7 +79,14 @@ int init_video(void)
                        vmptr->gmask = calc_mask(minf.gsize, minf.gpos);
                        vmptr->bmask = calc_mask(minf.bsize, minf.bpos);
                }
-               vmptr->fb_addr = minf.fb_addr;
+               if(minf.attr & VBE_ATTR_LFB) {
+                       vmptr->fb_addr = minf.fb_addr;
+               } else {
+                       vmptr->bank_size = (uint32_t)minf.bank_size * 1024;
+                       if(!vmptr->bank_size) {
+                               vmptr->bank_size = 65536;
+                       }
+               }
                vmptr->max_pages = minf.num_img_pages;
 
                printf("%04x: ", vbe.modes[i]);
@@ -86,12 +95,6 @@ int init_video(void)
        fflush(stdout);
 
        vbe_init_ver = VBE_VER_MAJOR(vbe.ver);
-       if(vbe_init_ver < 2) {
-               fprintf(stderr, "VBE 2.0 required. Upgrade your video card or run univbe.\n");
-               free(vmodes);
-               vmodes = 0;
-               return -1;
-       }
        return 0;
 }
 
@@ -171,25 +174,28 @@ void *set_video_mode(int idx, int nbuf)
 
        printf("pgcount: %d, pgsize: %d, fbsize: %d\n", pgcount, pgsize, fbsize);
        printf("phys addr: %p\n", (void*)vm->fb_addr);
-
-       vpgaddr[0] = (void*)dpmi_mmap(vm->fb_addr, fbsize);
-       if(!vpgaddr[0]) {
-               fprintf(stderr, "failed to map framebuffer (phys: %lx, size: %d)\n",
-                               (unsigned long)vm->fb_addr, fbsize);
-               set_text_mode();
-               return 0;
-       }
-       //memset(vpgaddr[0], 0xaa, fbsize);
-
-       printf("vaddr: %p\n", vpgaddr[0]);
        fflush(stdout);
 
-       if(pgcount > 1) {
-               vpgaddr[1] = (char*)vpgaddr[0] + pgsize;
-               fbidx = 1;
-               page_flip(FLIP_NOW);    /* start with the second page visible */
+       if(vm->fb_addr) {
+               vpgaddr[0] = (void*)dpmi_mmap(vm->fb_addr, fbsize);
+               if(!vpgaddr[0]) {
+                       fprintf(stderr, "failed to map framebuffer (phys: %lx, size: %d)\n",
+                                       (unsigned long)vm->fb_addr, fbsize);
+                       set_text_mode();
+                       return 0;
+               }
+               memset(vpgaddr[0], 0xaa, fbsize);
+
+               if(pgcount > 1) {
+                       vpgaddr[1] = (char*)vpgaddr[0] + pgsize;
+                       fbidx = 1;
+                       page_flip(FLIP_NOW);    /* start with the second page visible */
+               } else {
+                       fbidx = 0;
+                       vpgaddr[1] = 0;
+               }
        } else {
-               fbidx = 0;
+               vpgaddr[0] = (void*)0xa0000;
                vpgaddr[1] = 0;
        }
        return vpgaddr[0];
index 731ab14..9556af1 100644 (file)
@@ -11,6 +11,7 @@ struct video_mode {
        uint32_t rmask, gmask, bmask;
        uint32_t fb_addr;
        short max_pages;
+       uint32_t bank_size;
 };
 
 #ifdef __cplusplus
index ca57152..c344df1 100644 (file)
@@ -12,11 +12,15 @@ static void draw(void);
 
 static struct video_mode *vmode;
 
+static void swap_lfb(void *pixels);
+static void swap_banked(void *pixels);
+
 
 int main(int argc, char **argv)
 {
+       void *fb_buf;
        struct video_mode *vmodes;
-       int vmidx;
+       int vmidx, status = 0;
 
        init_logger("game.log");
 
@@ -36,9 +40,22 @@ int main(int argc, char **argv)
        }
        vmode = vmodes + vmidx;
 
+       if(vmode->fb_addr) {
+               swap_buffers = swap_lfb;
+       } else {
+               swap_buffers = swap_banked;
+       }
+
        fb_width = vmode->xsz;
        fb_height = vmode->ysz;
-       fb_size = (vmode->xsz * vmode->bpp / 8) * vmode->ysz;
+       fb_size = vmode->pitch * vmode->ysz;
+
+       if(!(fb_buf = malloc(fb_size + vmode->pitch * 2))) {
+               fprintf(stderr, "failed to allocate framebuffer\n");
+               status = -1;
+               goto break_evloop;
+       }
+       fb_pixels = (char*)fb_buf + vmode->pitch;
 
        reset_timer();
 
@@ -53,16 +70,17 @@ int main(int argc, char **argv)
        }
 
 break_evloop:
+       free(fb_buf);
        set_text_mode();
        cleanup_video();
        kb_shutdown();
-       return 0;
+       return status;
 }
 
 static void draw(void)
 {
        int i, j;
-       uint16_t *pptr = vmem;
+       uint16_t *pptr = fb_pixels;
 
        for(i=0; i<fb_height; i++) {
                for(j=0; j<fb_width; j++) {
@@ -70,10 +88,34 @@ static void draw(void)
                        *pptr++ = chess ? 0xff00 : 0x00ff;
                }
        }
+
+       swap_buffers(fb_pixels);
 }
 
-void swap_buffers(void *pixels)
+static void swap_lfb(void *pixels)
 {
        wait_vsync();
        memcpy(vmem, pixels, fb_size);
 }
+
+static void swap_banked(void *pixels)
+{
+       int i, sz;
+       unsigned int pending;
+       unsigned char *pptr = pixels;
+       uint32_t offs = 0;
+
+       wait_vsync();
+
+       /* assume window is always at 0 at the beginning */
+       pending = fb_size;
+       while(pending > 0) {
+               sz = pending > vmode->bank_size ? vmode->bank_size : pending;
+               memcpy(vmem, pptr, sz);
+               pptr += sz;
+               pending -= sz;
+               vbe_setwin(0, ++offs);
+       }
+
+       vbe_setwin(0, 0);
+}
index 3ada182..713b792 100644 (file)
@@ -191,6 +191,8 @@ void vbe_print_mode_info(FILE *fp, struct vbe_mode_info *minf)
 
        if(minf->attr & VBE_ATTR_LFB) {
                fprintf(fp, " lfb@%lx", (unsigned long)minf->fb_addr);
+       } else {
+               fprintf(fp, " %xkb/bank", (unsigned int)minf->bank_size);
        }
 
        fprintf(fp, " [");
index 91ddb23..0fc762d 100644 (file)
@@ -6,6 +6,9 @@ void *fb_pixels, *vmem;
 
 long time_msec;
 
+void (*swap_buffers)(void*);
+
+
 int game_init(int argc, char **argv)
 {
        return 0;
index 12e051b..542aba2 100644 (file)
@@ -10,6 +10,8 @@ extern void *fb_pixels, *vmem;
 
 extern long time_msec;
 
+extern void (*swap_buffers)(void*);
+
 /* special keys */
 enum {
        KB_ESC = 27,