correct window size in banked vbe, and added doublebuffered test
[vidsys] / main.c
diff --git a/main.c b/main.c
index ed2377e..a087561 100644 (file)
--- a/main.c
+++ b/main.c
@@ -1,24 +1,28 @@
 #include <stdio.h>
 #include <math.h>
+#include <limits.h>
 #include <conio.h>
 #include "vidsys.h"
 
 void test8bpp(void);
+void testrgb(void);
 
 struct vid_modeinfo *vm;
-void *vmem;
+void *vmem, *framebuf;
+int doublebuf;
 
 static const char *usage_fmt = "Usage %s: [options]\n"
        "Options:      \n"
        " -s <XxY>: video resolution\n"
-       " -b <bpp>: color depth\n";
+       " -b <bpp>: color depth\n"
+       " -d: double buffer\n";
 
 int main(int argc, char **argv)
 {
        int i;
        int mode;
-       int xres = 320;
-       int yres = 200;
+       int xres = 640;
+       int yres = 480;
        int bpp = 8;
 
        for(i=1; i<argc; i++) {
@@ -40,6 +44,11 @@ invalopt:            fprintf(stderr, "invalid option: %s\n", argv[i]);
                                        fprintf(stderr, "invalid color depth: %s\n", argv[i]);
                                        return 1;
                                }
+                               break;
+
+                       case 'd':
+                               doublebuf = 1;
+                               break;
 
                        case 'h':
                                printf(usage_fmt, argv[0]);
@@ -66,19 +75,22 @@ invalopt:           fprintf(stderr, "invalid option: %s\n", argv[i]);
                fprintf(stderr, "failed to find video mode: %dx%d %dbpp\n", xres, yres, bpp);
                return 1;
        }
+       vm = vid_modeinfo(mode);
+
+       if(!(framebuf = malloc(vm->pitch * vm->width))) {
+               fprintf(stderr, "failed to allocate main memory framebuffer\n");
+               return 1;
+       }
+
        if(!(vmem = vid_setmode(mode))) {
                fprintf(stderr, "failed to set video mode %04x\n", mode);
                return 1;
        }
-       vm = vid_modeinfo(mode);
 
-       switch(vm->bpp) {
-       case 8:
+       if(vm->bpp == 8) {
                test8bpp();
-               break;
-
-       default:
-               break;
+       } else {
+               testrgb();
        }
 
        for(;;) {
@@ -106,8 +118,9 @@ static float fmin(float a, float b)
 void test8bpp(void)
 {
        int i, j;
-       unsigned char *fb = vmem;
+       unsigned char *fb;
        struct vid_color cmap[256];
+       int winsz, winleft, winpos;
 
        for(i=0; i<256; i++) {
                float x = (float)i / (256.0f / TWO_PI);
@@ -117,12 +130,110 @@ void test8bpp(void)
        }
        vid_setpal(0, 256, cmap);
 
-       vid_vsync();
+       if(doublebuf) {
+               fb = framebuf;
+               for(i=0; i<vm->height; i++) {
+                       for(j=0; j<vm->width; j++) {
+                               *fb++ = i ^ j;
+                       }
+               }
+               vid_blitfb(framebuf, 0);
+       } else {
+               if(vid_islinear()) {
+                       winsz = INT_MAX;
+               } else {
+                       winsz = vm->win_size << 10;
+                       winpos = 0;
+                       vid_setwin(0, 0);
+               }
+               winleft = winsz;
+               fb = vmem;
+
+               vid_vsync();
+
+               for(i=0; i<vm->height; i++) {
+                       for(j=0; j<vm->width; j++) {
+                               if(winleft-- <= 0) {
+                                       winpos += vm->win_step;
+                                       vid_setwin(0, winpos);
+                                       winleft = winsz;
+                                       fb = vmem;
+                               }
+                               *fb++ = i ^ j;
+                       }
+               }
+       }
+}
+
+void testrgb(void)
+{
+       int i, j, r, g, b;
+       unsigned char *fb24;
+       uint16_t *fb16;
+       uint32_t *fb32;
+       uint32_t pcol;
+       int winsz, winleft, winpos;
+
+       if(!doublebuf) {
+               if(vid_islinear()) {
+                       winsz = INT_MAX;
+               } else {
+                       winsz = vm->win_size << 10;
+                       winpos = 0;
+                       vid_setwin(0, 0);
+               }
+               winleft = winsz;
+               fb24 = vmem;
+               fb32 = vmem;
+               fb16 = vmem;
+
+               vid_vsync();
+       } else {
+               fb24 = framebuf;
+               fb32 = framebuf;
+               fb16 = framebuf;
+       }
 
        for(i=0; i<vm->height; i++) {
                for(j=0; j<vm->width; j++) {
-                       int xor = i^j;
-                       *fb++ = xor;
+                       if(!doublebuf) {
+                               if(winleft <= 0) {
+                                       winpos += vm->win_step;
+                                       vid_setwin(0, winpos);
+                                       winleft = winsz;
+                                       fb24 = vmem;
+                                       fb16 = vmem;
+                                       fb32 = vmem;
+                               }
+                               winleft -= (vm->bpp + 7) >> 3;
+                       }
+                       r = (i ^ j) >> 1;
+                       g = i ^ j;
+                       b = (i ^ j) << 1;
+                       vm->ops.pack(&pcol, r, g, b);
+
+                       switch(vm->bpp) {
+                       case 15:
+                       case 16:
+                               *fb16++ = pcol;
+                               break;
+
+                       case 24:
+                               fb24[0] = r;
+                               fb24[1] = g;
+                               fb24[2] = b;
+                               fb24 += 3;
+                               break;
+
+                       case 32:
+                               *fb32++ = pcol;
+                               break;
+                       }
                }
        }
+
+       if(doublebuf) {
+               vid_vsync();
+               vid_blitfb(framebuf, 0);
+       }
 }