fixed some UI glitches
[retroray] / src / dos / drv_vbe.c
index d639417..ae36be8 100644 (file)
@@ -6,6 +6,7 @@
 #include "vbe.h"
 #include "vga.h"
 #include "cdpmi.h"
+#include "logger.h"
 
 #define farptr_to_linear(rmaddr) \
        ((((intptr_t)(rmaddr) >> 12) & 0xffff0) + ((intptr_t)(rmaddr) & 0xffff))
@@ -19,10 +20,13 @@ static const char *memsize_str(long sz);
 static int get_mode_info(int mode, struct vbe_mode_info *mi);
 static int conv_vbeinfo(int mode, struct vid_modeinfo *mi, struct vbe_mode_info *vbemi);
 static unsigned int calc_mask(int nbits, int pos);
+static void print_mode_info(int mode, struct vid_modeinfo *mi);
 
 static void pack(uint32_t *pix, int r, int g, int b);
 static void unpack(uint32_t pix, int *r, int *g, int *b);
 static void clear(uint32_t color);
+static void blit_lfb(int x, int y, int w, int h, void *fb, int pitch);
+static void blit_banked(int x, int y, int w, int h, void *fb, int pitch);
 static void blitfb_lfb(void *fb, int pitch);
 static void blitfb_banked(void *fb, int pitch);
 static void flip(int vsync);
@@ -68,20 +72,20 @@ static int init(void)
        regs.es = bufseg;
        dpmi_rmint(0x10, &regs);
        if((regs.eax & 0xffff) != 0x4f || memcmp(vbe->sig, "VESA", 4) != 0) {
-               fprintf(stderr, "failed to get VBE controller information\n");
+               errormsg("failed to get VBE controller information\n");
                return -1;
        }
 
        vbe_ver = vbe->ver;
 
-       printf("Found VBE %d.%d\n", VBE_VER_MAJOR(vbe_ver), VBE_VER_MINOR(vbe_ver));
-       printf("OEM: %s\n", (char*)farptr_to_linear(vbe->oem_name));
+       infomsg("Found VBE %d.%d\n", VBE_VER_MAJOR(vbe_ver), VBE_VER_MINOR(vbe_ver));
+       infomsg("OEM: %s\n", (char*)farptr_to_linear(vbe->oem_name));
        if(vbe_ver >= 0x0200) {
-               printf("%s - %s (%s)\n", (char*)farptr_to_linear(vbe->vendor),
+               infomsg("%s - %s (%s)\n", (char*)farptr_to_linear(vbe->vendor),
                                (char*)farptr_to_linear(vbe->product),
                                (char*)farptr_to_linear(vbe->revstr));
        }
-       printf("Video RAM: %s\n", memsize_str((long)vbe->vmem_blk * 65536));
+       infomsg("Video RAM: %s\n", memsize_str((long)vbe->vmem_blk * 65536));
 
        vbe_modelist = (uint16_t*)farptr_to_linear(vbe->modelist_addr);
        count = 0;
@@ -91,7 +95,7 @@ static int init(void)
        }
 
        if(!(modelist = malloc(count * sizeof *modelist))) {
-               fprintf(stderr, "failed to allocate mode list\n");
+               errormsg("failed to allocate mode list\n");
                return -1;
        }
        for(i=0; i<count; i++) {
@@ -99,7 +103,7 @@ static int init(void)
        }
 
        if(!(drv.modes = malloc(count * sizeof *drv.modes))) {
-               fprintf(stderr, "failed to allocate mode list\n");
+               errormsg("failed to allocate mode list\n");
                free(modelist);
                return -1;
        }
@@ -165,10 +169,14 @@ retry:
        cur_pgsize = minf->height * minf->pitch;
 
        if(mode & VBE_MODE_LFB) {
+               minf->ops.blit = blit_lfb;
                minf->ops.blitfb = blitfb_lfb;
        } else {
+               minf->ops.blit = blit_banked;
                minf->ops.blitfb = blitfb_banked;
        }
+
+       print_mode_info(mode, minf);
        return 0;
 }
 
@@ -304,6 +312,7 @@ static int conv_vbeinfo(int mode, struct vid_modeinfo *mi, struct vbe_mode_info
        mi->ops.getpal = vga_getpal;
        mi->ops.vsync = vid_vsync;
        mi->ops.clear = clear;
+       mi->ops.blit = 0;
        mi->ops.blitfb = 0;
        mi->ops.flip = flip;
        return 0;
@@ -320,6 +329,28 @@ static unsigned int calc_mask(int nbits, int pos)
        return mask << pos;
 }
 
+static void print_mode_info(int mode, struct vid_modeinfo *mi)
+{
+       infomsg("VBE mode %04x\n", mode);
+       infomsg("  %dx%d %d bpp (%d colors)\n", mi->width, mi->height,
+                  mi->bpp, mi->ncolors);
+       infomsg("  pitch: %d bytes, %d vmem pages\n", mi->pitch, mi->pages);
+
+       if(mi->bpp > 8) {
+               infomsg("  RGB mask %06x %06x %06x (pos: %d %d %d)\n", (unsigned int)mi->rmask,
+                               (unsigned int)mi->gmask, (unsigned int)mi->bmask, mi->rshift,
+                               mi->gshift, mi->bshift);
+       }
+
+       if(mode & VBE_MODE_LFB) {
+               infomsg("  LFB address %xh, size: %d\n", (unsigned int)mi->vmem_addr,
+                               (int)mi->vmem_size);
+       } else {
+               infomsg("  banked window %d kb, granularity: %d kb, step: %d\n", mi->win_size,
+                               mi->win_gran, mi->win_step);
+       }
+}
+
 
 static void pack(uint32_t *pix, int r, int g, int b)
 {
@@ -339,16 +370,44 @@ static void clear(uint32_t color)
 {
 }
 
+static void blit_lfb(int x, int y, int w, int h, void *fb, int pitch)
+{
+       int i, pixsz, spansz;
+       unsigned char *dest, *src;
+
+       /*dbgmsg("blit: %d,%d (%dx%d)\n", x, y, w, h);*/
+
+       pixsz = (cur_mi->bpp + 7) >> 3;
+       spansz = w * pixsz;
+
+       dest = (char*)vid_vmem + cur_mi->pitch * y + x * pixsz;
+       src = fb;
+
+       for(i=0; i<h; i++) {
+               memcpy(dest, src, spansz);
+               dest += cur_mi->pitch;
+               src += pitch;
+       }
+}
+
+static void blit_banked(int x, int y, int w, int h, void *fb, int pitch)
+{
+       abort();
+}
+
 static void blitfb_lfb(void *fb, int pitch)
 {
-       int i;
+       int i, pixsz, spansz;
        unsigned char *dest, *src;
 
+       pixsz = (cur_mi->bpp + 7) >> 3;
+       spansz = cur_mi->width * pixsz;
+
        dest = vid_vmem;
        src = fb;
 
        for(i=0; i<cur_mi->height; i++) {
-               memcpy(dest, src, cur_mi->pitch);
+               memcpy(dest, src, spansz);
                dest += cur_mi->pitch;
                src += pitch;
        }
@@ -356,14 +415,16 @@ static void blitfb_lfb(void *fb, int pitch)
 
 static void blitfb_banked(void *fb, int pitch)
 {
-       int sz, offs, pending;
+       int sz, offs, pending, winsz;
        unsigned char *pptr = fb;
 
+       winsz = cur_mi->win_size << 10;
+
        /* assume initial window offset at 0 */
        offs = 0;
        pending = cur_pgsize;
        while(pending > 0) {
-               sz = pending > 65536 ? 65536 : pending;
+               sz = pending > winsz ? winsz : pending;
                memcpy((void*)0xa0000, pptr, sz);
                pptr += sz;
                pending -= sz;