eobish
diff src/dos/vbegfx.c @ 7:6a350c554e46
started DOS port
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 19 Jan 2015 15:49:14 +0200 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/dos/vbegfx.c Mon Jan 19 15:49:14 2015 +0200 1.3 @@ -0,0 +1,158 @@ 1.4 +#ifndef GFX_H_ 1.5 +#define GFX_H_ 1.6 + 1.7 +#include <stdio.h> 1.8 +#include <stdlib.h> 1.9 +#include <string.h> 1.10 +#include "vbe.h" 1.11 +#include "logger.h" 1.12 + 1.13 +#define REALPTR(s, o) (void*)(((uint32_t)(s) << 4) + (uint32_t)(o)) 1.14 +#define VBEPTR(x) REALPTR(((x) & 0xffff0000) >> 16, (x) & 0xffff) 1.15 +#define VBEPTR_SEG(x) (((x) & 0xffff0000) >> 16) 1.16 +#define VBEPTR_OFF(x) ((x) & 0xffff) 1.17 + 1.18 +#define SAME_BPP(a, b) \ 1.19 + ((a) == (b) || (a) == 16 && (b) == 15 || (a) == 15 && (b) == 16 || (a) == 32 && (b) == 24 || (a) == 24 && (b) == 32) 1.20 + 1.21 +static unsigned int make_mask(int sz, int pos); 1.22 + 1.23 +static struct vbe_info *vbe_info; 1.24 +static struct vbe_mode_info *mode_info; 1.25 +static int pal_bits = 6; 1.26 + 1.27 +void *set_video_mode(int xsz, int ysz, int bpp) 1.28 +{ 1.29 + int i; 1.30 + uint16_t *modes, best = 0; 1.31 + unsigned int fbsize; 1.32 + 1.33 + /* check for VBE2 support and output some info */ 1.34 + if(!vbe_info) { 1.35 + if(!(vbe_info = vbe_get_info())) { 1.36 + fprintf(stderr, "VESA BIOS Extensions not available\n"); 1.37 + return 0; 1.38 + } 1.39 + 1.40 + printlog("VBE Version: %x.%x\n", vbe_info->version >> 8, vbe_info->version & 0xff); 1.41 + if(vbe_info->version < 0x200) { 1.42 + fprintf(stderr, "This program requires VBE 2.0 or greater. Try running UniVBE\n"); 1.43 + return 0; 1.44 + } 1.45 + 1.46 + printlog("Graphics adapter: %s, %s (%s)\n", VBEPTR(vbe_info->oem_vendor_name_ptr), 1.47 + VBEPTR(vbe_info->oem_product_name_ptr), VBEPTR(vbe_info->oem_product_rev_ptr)); 1.48 + printlog("Video memory: %dmb\n", vbe_info->total_mem << 6); 1.49 + 1.50 + modes = VBEPTR(vbe_info->vid_mode_ptr); 1.51 + } 1.52 + 1.53 + for(i=0; i<1024; i++) { /* impose an upper limit to avoid inf-loops */ 1.54 + if(modes[i] == 0xffff) { 1.55 + break; /* reached the end */ 1.56 + } 1.57 + 1.58 + mode_info = vbe_get_mode_info(modes[i] | VBE_MODE_LFB); 1.59 + if(!mode_info || mode_info->xres != xsz || mode_info->yres != ysz) { 1.60 + continue; 1.61 + } 1.62 + if(SAME_BPP(mode_info->bpp, bpp)) { 1.63 + best = modes[i]; 1.64 + } 1.65 + } 1.66 + 1.67 + if(best) { 1.68 + mode_info = vbe_get_mode_info(best); 1.69 + } else { 1.70 + fprintf(stderr, "Requested video mode (%dx%d %dbpp) is unavailable\n", xsz, ysz, bpp); 1.71 + return 0; 1.72 + } 1.73 + 1.74 + if(vbe_set_mode(best | VBE_MODE_LFB) == -1) { 1.75 + fprintf(stderr, "Failed to set video mode %dx%d %dbpp\n", mode_info->xres, mode_info->yres, mode_info->bpp); 1.76 + return 0; 1.77 + } 1.78 + 1.79 + /* attempt to set 8 bits of color per component in palettized modes */ 1.80 + if(bpp <= 8) { 1.81 + pal_bits = vbe_set_palette_bits(8); 1.82 + printlog("palette bits per color primary: %d\n", pal_bits); 1.83 + } 1.84 + 1.85 + fbsize = xsz * ysz * mode_info->num_img_pages * (bpp / CHAR_BIT); 1.86 + return (void*)dpmi_mmap(mode_info->fb_addr, fbsize); 1.87 +} 1.88 + 1.89 +int set_text_mode(void) 1.90 +{ 1.91 + vbe_set_mode(0x3); 1.92 + return 0; 1.93 +} 1.94 + 1.95 +int get_color_depth(void) 1.96 +{ 1.97 + if(!mode_info) { 1.98 + return -1; 1.99 + } 1.100 + return mode_info->bpp; 1.101 +} 1.102 + 1.103 +int get_color_bits(int *rbits, int *gbits, int *bbits) 1.104 +{ 1.105 + if(!mode_info) { 1.106 + return -1; 1.107 + } 1.108 + *rbits = mode_info->rmask_size; 1.109 + *gbits = mode_info->gmask_size; 1.110 + *bbits = mode_info->bmask_size; 1.111 + return 0; 1.112 +} 1.113 + 1.114 +int get_color_mask(unsigned int *rmask, unsigned int *gmask, unsigned int *bmask) 1.115 +{ 1.116 + if(!mode_info) { 1.117 + return -1; 1.118 + } 1.119 + *rmask = make_mask(mode_info->rmask_size, mode_info->rpos); 1.120 + *gmask = make_mask(mode_info->gmask_size, mode_info->gpos); 1.121 + *bmask = make_mask(mode_info->bmask_size, mode_info->bpos); 1.122 + return 0; 1.123 +} 1.124 + 1.125 +int get_color_shift(int *rshift, int *gshift, int *bshift) 1.126 +{ 1.127 + if(!mode_info) { 1.128 + return -1; 1.129 + } 1.130 + *rshift = mode_info->rpos; 1.131 + *gshift = mode_info->gpos; 1.132 + *bshift = mode_info->bpos; 1.133 + return 0; 1.134 +} 1.135 + 1.136 +void set_palette(int idx, int r, int g, int b) 1.137 +{ 1.138 + int col[3]; 1.139 + col[0] = r; 1.140 + col[1] = g; 1.141 + col[2] = b; 1.142 + vbe_set_palette(idx, col, 1, pal_bits); 1.143 +} 1.144 + 1.145 +void wait_vsync(void) 1.146 +{ 1.147 + /* TODO */ 1.148 +} 1.149 + 1.150 +static unsigned int make_mask(int sz, int pos) 1.151 +{ 1.152 + unsigned int i, mask = 0; 1.153 + 1.154 + for(i=0; i<sz; i++) { 1.155 + mask |= 1 << i; 1.156 + } 1.157 + return mask << pos; 1.158 +} 1.159 + 1.160 + 1.161 +#endif /* GFX_H_ */