nuclear@0: #ifndef GFX_H_ nuclear@0: #define GFX_H_ nuclear@0: nuclear@0: #include nuclear@0: #include nuclear@0: #include nuclear@0: #include "vbe.h" nuclear@0: nuclear@0: #define REALPTR(s, o) (void*)(((uint32_t)(s) << 4) + (uint32_t)(o)) nuclear@0: #define VBEPTR(x) REALPTR(((x) & 0xffff0000) >> 16, (x) & 0xffff) nuclear@0: #define VBEPTR_SEG(x) (((x) & 0xffff0000) >> 16) nuclear@0: #define VBEPTR_OFF(x) ((x) & 0xffff) nuclear@0: nuclear@0: #define SAME_BPP(a, b) \ nuclear@0: ((a) == (b) || (a) == 16 && (b) == 15 || (a) == 15 && (b) == 16 || (a) == 32 && (b) == 24 || (a) == 24 && (b) == 32) nuclear@0: nuclear@0: static unsigned int make_mask(int sz, int pos); nuclear@0: nuclear@0: static struct vbe_info *vbe_info; nuclear@0: static struct vbe_mode_info *mode_info; nuclear@0: static int pal_bits = 6; nuclear@0: nuclear@0: void *set_video_mode(int xsz, int ysz, int bpp) nuclear@0: { nuclear@0: int i; nuclear@0: uint16_t *modes, best = 0; nuclear@0: unsigned int fbsize; nuclear@0: nuclear@0: /* check for VBE2 support and output some info */ nuclear@0: if(!vbe_info) { nuclear@0: if(!(vbe_info = vbe_get_info())) { nuclear@0: fprintf(stderr, "VESA BIOS Extensions not available\n"); nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: printf("VBE Version: %x.%x\n", vbe_info->version >> 8, vbe_info->version & 0xff); nuclear@0: if(vbe_info->version < 0x200) { nuclear@0: fprintf(stderr, "This program requires VBE 2.0 or greater. Try running UniVBE\n"); nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: printf("Graphics adapter: %s, %s (%s)\n", VBEPTR(vbe_info->oem_vendor_name_ptr), nuclear@0: VBEPTR(vbe_info->oem_product_name_ptr), VBEPTR(vbe_info->oem_product_rev_ptr)); nuclear@0: printf("Video memory: %dmb\n", vbe_info->total_mem << 6); nuclear@0: nuclear@0: modes = VBEPTR(vbe_info->vid_mode_ptr); nuclear@0: } nuclear@0: nuclear@0: for(i=0; i<1024; i++) { /* impose an upper limit to avoid inf-loops */ nuclear@0: if(modes[i] == 0xffff) { nuclear@0: break; /* reached the end */ nuclear@0: } nuclear@0: nuclear@0: mode_info = vbe_get_mode_info(modes[i] | VBE_MODE_LFB); nuclear@0: if(!mode_info || mode_info->xres != xsz || mode_info->yres != ysz) { nuclear@0: continue; nuclear@0: } nuclear@0: if(SAME_BPP(mode_info->bpp, bpp)) { nuclear@0: best = modes[i]; nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: if(best) { nuclear@0: mode_info = vbe_get_mode_info(best); nuclear@0: } else { nuclear@0: fprintf(stderr, "Requested video mode (%dx%d %dbpp) is unavailable\n", xsz, ysz, bpp); nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: if(vbe_set_mode(best | VBE_MODE_LFB) == -1) { nuclear@0: fprintf(stderr, "Failed to set video mode %dx%d %dbpp\n", mode_info->xres, mode_info->yres, mode_info->bpp); nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: /* attempt to set 8 bits of color per component in palettized modes */ nuclear@0: if(bpp <= 8) { nuclear@0: pal_bits = vbe_set_palette_bits(8); nuclear@0: printf("palette bits per color primary: %d\n", pal_bits); nuclear@0: } nuclear@0: nuclear@0: fbsize = xsz * ysz * mode_info->num_img_pages * (bpp / CHAR_BIT); nuclear@0: return (void*)dpmi_mmap(mode_info->fb_addr, fbsize); nuclear@0: } nuclear@0: nuclear@0: int set_text_mode(void) nuclear@0: { nuclear@0: vbe_set_mode(0x3); nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: int get_color_depth(void) nuclear@0: { nuclear@0: if(!mode_info) { nuclear@0: return -1; nuclear@0: } nuclear@0: return mode_info->bpp; nuclear@0: } nuclear@0: nuclear@0: int get_color_bits(int *rbits, int *gbits, int *bbits) nuclear@0: { nuclear@0: if(!mode_info) { nuclear@0: return -1; nuclear@0: } nuclear@0: *rbits = mode_info->rmask_size; nuclear@0: *gbits = mode_info->gmask_size; nuclear@0: *bbits = mode_info->bmask_size; nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: int get_color_mask(unsigned int *rmask, unsigned int *gmask, unsigned int *bmask) nuclear@0: { nuclear@0: if(!mode_info) { nuclear@0: return -1; nuclear@0: } nuclear@0: *rmask = make_mask(mode_info->rmask_size, mode_info->rpos); nuclear@0: *gmask = make_mask(mode_info->gmask_size, mode_info->gpos); nuclear@0: *bmask = make_mask(mode_info->bmask_size, mode_info->bpos); nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: int get_color_shift(int *rshift, int *gshift, int *bshift) nuclear@0: { nuclear@0: if(!mode_info) { nuclear@0: return -1; nuclear@0: } nuclear@0: *rshift = mode_info->rpos; nuclear@0: *gshift = mode_info->gpos; nuclear@0: *bshift = mode_info->bpos; nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: void set_palette(int idx, int r, int g, int b) nuclear@0: { nuclear@0: int col[3]; nuclear@0: col[0] = r; nuclear@0: col[1] = g; nuclear@0: col[2] = b; nuclear@0: vbe_set_palette(idx, col, 1, pal_bits); nuclear@0: } nuclear@0: nuclear@5: void wait_vsync(void) nuclear@5: { nuclear@5: /* TODO */ nuclear@5: } nuclear@5: nuclear@0: static unsigned int make_mask(int sz, int pos) nuclear@0: { nuclear@0: unsigned int i, mask = 0; nuclear@0: nuclear@0: for(i=0; i