X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=dosdemo;a=blobdiff_plain;f=src%2Fdos%2Fgfx.c;h=b5670bfaf75ac49f35258d853959e39d40cbd4a9;hp=558646b73001943f204731954e51db97afc27f11;hb=7deef4d5a20da09044bf7311c6ee274090cde5e6;hpb=8a64d603ee67cd98070360b40938e123ea845154 diff --git a/src/dos/gfx.c b/src/dos/gfx.c index 558646b..b5670bf 100644 --- a/src/dos/gfx.c +++ b/src/dos/gfx.c @@ -1,171 +1,121 @@ -#ifndef GFX_H_ -#define GFX_H_ - #include -#include -#include -#include +#include "gfx.h" #include "vbe.h" -#include "dpmi.h" -#include "logger.h" +#include "vga.h" +#include "cdpmi.h" -#define REALPTR(s, o) (void*)(((uint32_t)(s) << 4) + (uint32_t)(o)) -#define VBEPTR(x) REALPTR(((x) & 0xffff0000) >> 16, (x) & 0xffff) -#define VBEPTR_SEG(x) (((x) & 0xffff0000) >> 16) -#define VBEPTR_OFF(x) ((x) & 0xffff) +#ifdef __DJGPP__ +#include +#define REALPTR(s, o) (void*)(((uint32_t)(s) << 4) - __djgpp_base_address + ((uint32_t)(o))) +#else +#define REALPTR(s, o) (void*)(((uint32_t)(s) << 4) + ((uint32_t)(o))) +#endif -#define SAME_BPP(a, b) \ - ((a) == (b) || (a) == 16 && (b) == 15 || (a) == 15 && (b) == 16 || (a) == 32 && (b) == 24 || (a) == 24 && (b) == 32) +#define SAME_BPP(a, b) \ + ((a) == (b) || ((a) == 16 && (b) == 15) || ((a) == 15 && (b) == 16) || \ + ((a) == 32 && (b) == 24) || ((a) == 24 && (b) == 32)) -static unsigned int make_mask(int sz, int pos); +static int vbe_init_ver; +static struct vbe_info vbe; +static int mode, pgsize, fbsize; +static struct vbe_mode_info mode_info; -static struct vbe_info *vbe_info; -static struct vbe_mode_info *mode_info; -static int pal_bits = 6; +static void *vpgaddr[2]; +static int fbidx; + +static int init_vbe(void) +{ + if(vbe_info(&vbe) == -1) { + return -1; + } + + vbe_print_info(stdout, &vbe); + fflush(stdout); + + vbe_init_ver = VBE_VER_MAJOR(vbe.ver); + return 0; +} void *set_video_mode(int xsz, int ysz, int bpp) { - int i; - uint16_t *modes, best = 0; - unsigned int fbsize; - - /* check for VBE2 support and output some info */ - if(!vbe_info) { - if(!(vbe_info = vbe_get_info())) { - fprintf(stderr, "VESA BIOS Extensions not available\n"); + int i, nmodes; + int best_match_mode = -1; + struct vbe_mode_info minf; + + if(!vbe_init_ver) { + if(init_vbe() == -1) { + fprintf(stderr, "failed to initialize VBE\n"); return 0; } - - printlog("VBE Version: %x.%x\n", vbe_info->version >> 8, vbe_info->version & 0xff); - if(vbe_info->version < 0x200) { - fprintf(stderr, "This program requires VBE 2.0 or greater. Try running UniVBE\n"); + if(vbe_init_ver < 2) { + fprintf(stderr, "VBE >= 2.0 required\n"); return 0; } - - printlog("Graphics adapter: %s, %s (%s)\n", VBEPTR(vbe_info->oem_vendor_name_ptr), - VBEPTR(vbe_info->oem_product_name_ptr), VBEPTR(vbe_info->oem_product_rev_ptr)); - printlog("Video memory: %dkb\n", vbe_info->total_mem << 6); - - modes = VBEPTR(vbe_info->vid_mode_ptr); } - for(i=0; i<1024; i++) { /* impose an upper limit to avoid inf-loops */ - if(modes[i] == 0xffff) { - break; /* reached the end */ + mode = -1; + nmodes = vbe_num_modes(&vbe); + for(i=0; ixres != xsz || mode_info->yres != ysz) { - continue; - } - if(SAME_BPP(mode_info->bpp, bpp)) { - best = modes[i]; + if(SAME_BPP(minf.bpp, bpp)) { + best_match_mode = mode; } } - if(best) { - mode_info = vbe_get_mode_info(best); - } else { - fprintf(stderr, "Requested video mode (%dx%d %dbpp) is unavailable\n", xsz, ysz, bpp); - return 0; + if(mode == -1) { + if(best_match_mode == -1) { + fprintf(stderr, "failed to find requested video mode (%dx%d %d bpp)\n", xsz, ysz, bpp); + return 0; + } + mode = best_match_mode; } - if(vbe_set_mode(best | VBE_MODE_LFB) == -1) { - fprintf(stderr, "Failed to set video mode %dx%d %dbpp\n", mode_info->xres, mode_info->yres, mode_info->bpp); - return 0; - } + vbe_mode_info(mode, &mode_info); + printf("setting video mode %x: (%dx%d %d)\n", (unsigned int)mode, mode_info.xres, + mode_info.yres, mode_info.bpp); - /* attempt to set 8 bits of color per component in palettized modes */ - /*if(bpp <= 8) { - pal_bits = vbe_set_palette_bits(8); - printlog("palette bits per color primary: %d\n", pal_bits); + if(vbe_setmode(mode) == -1) { + fprintf(stderr, "failed to set video mode\n"); + return 0; } - */ - - fbsize = xsz * ysz * mode_info->num_img_pages * (bpp / CHAR_BIT); - return (void*)dpmi_mmap(mode_info->fb_addr, fbsize); -} -int set_text_mode(void) -{ - vbe_set_mode(0x3); - return 0; -} + pgsize = mode_info.xres * mode_info.yres * (bpp / 8); + fbsize = mode_info.num_img_pages * pgsize; -int get_color_depth(void) -{ - if(!mode_info) { - return -1; - } - return mode_info->bpp; -} + vpgaddr[0] = (void*)dpmi_mmap(mode_info.fb_addr, fbsize); -int get_color_bits(int *rbits, int *gbits, int *bbits) -{ - if(!mode_info) { - return -1; + if(mode_info.num_img_pages > 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; } - *rbits = mode_info->rmask_size; - *gbits = mode_info->gmask_size; - *bbits = mode_info->bmask_size; - return 0; -} -int get_color_mask(unsigned int *rmask, unsigned int *gmask, unsigned int *bmask) -{ - if(!mode_info) { - return -1; - } - *rmask = make_mask(mode_info->rmask_size, mode_info->rpos); - *gmask = make_mask(mode_info->gmask_size, mode_info->gpos); - *bmask = make_mask(mode_info->bmask_size, mode_info->bpos); - return 0; + return vpgaddr[0]; } -int get_color_shift(int *rshift, int *gshift, int *bshift) +int set_text_mode(void) { - if(!mode_info) { - return -1; - } - *rshift = mode_info->rpos; - *gshift = mode_info->gpos; - *bshift = mode_info->bpos; + vga_setmode(3); return 0; } -void set_palette(int idx, int r, int g, int b) +void *page_flip(int vsync) { - int col[3]; - col[0] = r; - col[1] = g; - col[2] = b; - vbe_set_palette(idx, col, 1, pal_bits); -} - -void wait_vsync(void) -{ - __asm { - mov dx, 0x3da - l1: - in al, dx - and al, 0x8 - jnz l1 - l2: - in al, dx - and al, 0x8 - jz l2 + if(!vpgaddr[1]) { + /* page flipping not supported */ + return vpgaddr[0]; } -} -static unsigned int make_mask(int sz, int pos) -{ - unsigned int i, mask = 0; + vbe_swap(fbidx ? pgsize : 0, vsync ? VBE_SWAP_VBLANK : VBE_SWAP_NOW); + fbidx = (fbidx + 1) & 1; - for(i=0; i