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