rayzor

annotate src/gfx.c @ 18:859ccadca671

portability fixes
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 14 Apr 2014 18:35:37 +0300
parents 5fcf72837b69
children
rev   line source
nuclear@0 1 #ifndef GFX_H_
nuclear@0 2 #define GFX_H_
nuclear@0 3
nuclear@0 4 #include <stdio.h>
nuclear@0 5 #include <stdlib.h>
nuclear@0 6 #include <string.h>
nuclear@0 7 #include "vbe.h"
nuclear@6 8 #include "logger.h"
nuclear@0 9
nuclear@0 10 #define REALPTR(s, o) (void*)(((uint32_t)(s) << 4) + (uint32_t)(o))
nuclear@0 11 #define VBEPTR(x) REALPTR(((x) & 0xffff0000) >> 16, (x) & 0xffff)
nuclear@0 12 #define VBEPTR_SEG(x) (((x) & 0xffff0000) >> 16)
nuclear@0 13 #define VBEPTR_OFF(x) ((x) & 0xffff)
nuclear@0 14
nuclear@0 15 #define SAME_BPP(a, b) \
nuclear@0 16 ((a) == (b) || (a) == 16 && (b) == 15 || (a) == 15 && (b) == 16 || (a) == 32 && (b) == 24 || (a) == 24 && (b) == 32)
nuclear@0 17
nuclear@0 18 static unsigned int make_mask(int sz, int pos);
nuclear@0 19
nuclear@0 20 static struct vbe_info *vbe_info;
nuclear@0 21 static struct vbe_mode_info *mode_info;
nuclear@0 22 static int pal_bits = 6;
nuclear@0 23
nuclear@0 24 void *set_video_mode(int xsz, int ysz, int bpp)
nuclear@0 25 {
nuclear@0 26 int i;
nuclear@0 27 uint16_t *modes, best = 0;
nuclear@0 28 unsigned int fbsize;
nuclear@0 29
nuclear@0 30 /* check for VBE2 support and output some info */
nuclear@0 31 if(!vbe_info) {
nuclear@0 32 if(!(vbe_info = vbe_get_info())) {
nuclear@0 33 fprintf(stderr, "VESA BIOS Extensions not available\n");
nuclear@0 34 return 0;
nuclear@0 35 }
nuclear@0 36
nuclear@6 37 printlog("VBE Version: %x.%x\n", vbe_info->version >> 8, vbe_info->version & 0xff);
nuclear@0 38 if(vbe_info->version < 0x200) {
nuclear@0 39 fprintf(stderr, "This program requires VBE 2.0 or greater. Try running UniVBE\n");
nuclear@0 40 return 0;
nuclear@0 41 }
nuclear@0 42
nuclear@6 43 printlog("Graphics adapter: %s, %s (%s)\n", VBEPTR(vbe_info->oem_vendor_name_ptr),
nuclear@0 44 VBEPTR(vbe_info->oem_product_name_ptr), VBEPTR(vbe_info->oem_product_rev_ptr));
nuclear@6 45 printlog("Video memory: %dmb\n", vbe_info->total_mem << 6);
nuclear@0 46
nuclear@0 47 modes = VBEPTR(vbe_info->vid_mode_ptr);
nuclear@0 48 }
nuclear@0 49
nuclear@0 50 for(i=0; i<1024; i++) { /* impose an upper limit to avoid inf-loops */
nuclear@0 51 if(modes[i] == 0xffff) {
nuclear@0 52 break; /* reached the end */
nuclear@0 53 }
nuclear@0 54
nuclear@0 55 mode_info = vbe_get_mode_info(modes[i] | VBE_MODE_LFB);
nuclear@0 56 if(!mode_info || mode_info->xres != xsz || mode_info->yres != ysz) {
nuclear@0 57 continue;
nuclear@0 58 }
nuclear@0 59 if(SAME_BPP(mode_info->bpp, bpp)) {
nuclear@0 60 best = modes[i];
nuclear@0 61 }
nuclear@0 62 }
nuclear@0 63
nuclear@0 64 if(best) {
nuclear@0 65 mode_info = vbe_get_mode_info(best);
nuclear@0 66 } else {
nuclear@0 67 fprintf(stderr, "Requested video mode (%dx%d %dbpp) is unavailable\n", xsz, ysz, bpp);
nuclear@0 68 return 0;
nuclear@0 69 }
nuclear@0 70
nuclear@0 71 if(vbe_set_mode(best | VBE_MODE_LFB) == -1) {
nuclear@0 72 fprintf(stderr, "Failed to set video mode %dx%d %dbpp\n", mode_info->xres, mode_info->yres, mode_info->bpp);
nuclear@0 73 return 0;
nuclear@0 74 }
nuclear@0 75
nuclear@0 76 /* attempt to set 8 bits of color per component in palettized modes */
nuclear@0 77 if(bpp <= 8) {
nuclear@0 78 pal_bits = vbe_set_palette_bits(8);
nuclear@6 79 printlog("palette bits per color primary: %d\n", pal_bits);
nuclear@0 80 }
nuclear@0 81
nuclear@0 82 fbsize = xsz * ysz * mode_info->num_img_pages * (bpp / CHAR_BIT);
nuclear@0 83 return (void*)dpmi_mmap(mode_info->fb_addr, fbsize);
nuclear@0 84 }
nuclear@0 85
nuclear@0 86 int set_text_mode(void)
nuclear@0 87 {
nuclear@0 88 vbe_set_mode(0x3);
nuclear@0 89 return 0;
nuclear@0 90 }
nuclear@0 91
nuclear@0 92 int get_color_depth(void)
nuclear@0 93 {
nuclear@0 94 if(!mode_info) {
nuclear@0 95 return -1;
nuclear@0 96 }
nuclear@0 97 return mode_info->bpp;
nuclear@0 98 }
nuclear@0 99
nuclear@0 100 int get_color_bits(int *rbits, int *gbits, int *bbits)
nuclear@0 101 {
nuclear@0 102 if(!mode_info) {
nuclear@0 103 return -1;
nuclear@0 104 }
nuclear@0 105 *rbits = mode_info->rmask_size;
nuclear@0 106 *gbits = mode_info->gmask_size;
nuclear@0 107 *bbits = mode_info->bmask_size;
nuclear@0 108 return 0;
nuclear@0 109 }
nuclear@0 110
nuclear@0 111 int get_color_mask(unsigned int *rmask, unsigned int *gmask, unsigned int *bmask)
nuclear@0 112 {
nuclear@0 113 if(!mode_info) {
nuclear@0 114 return -1;
nuclear@0 115 }
nuclear@0 116 *rmask = make_mask(mode_info->rmask_size, mode_info->rpos);
nuclear@0 117 *gmask = make_mask(mode_info->gmask_size, mode_info->gpos);
nuclear@0 118 *bmask = make_mask(mode_info->bmask_size, mode_info->bpos);
nuclear@0 119 return 0;
nuclear@0 120 }
nuclear@0 121
nuclear@0 122 int get_color_shift(int *rshift, int *gshift, int *bshift)
nuclear@0 123 {
nuclear@0 124 if(!mode_info) {
nuclear@0 125 return -1;
nuclear@0 126 }
nuclear@0 127 *rshift = mode_info->rpos;
nuclear@0 128 *gshift = mode_info->gpos;
nuclear@0 129 *bshift = mode_info->bpos;
nuclear@0 130 return 0;
nuclear@0 131 }
nuclear@0 132
nuclear@0 133 void set_palette(int idx, int r, int g, int b)
nuclear@0 134 {
nuclear@0 135 int col[3];
nuclear@0 136 col[0] = r;
nuclear@0 137 col[1] = g;
nuclear@0 138 col[2] = b;
nuclear@0 139 vbe_set_palette(idx, col, 1, pal_bits);
nuclear@0 140 }
nuclear@0 141
nuclear@5 142 void wait_vsync(void)
nuclear@5 143 {
nuclear@5 144 /* TODO */
nuclear@5 145 }
nuclear@5 146
nuclear@0 147 static unsigned int make_mask(int sz, int pos)
nuclear@0 148 {
nuclear@0 149 unsigned int i, mask = 0;
nuclear@0 150
nuclear@0 151 for(i=0; i<sz; i++) {
nuclear@0 152 mask |= 1 << i;
nuclear@0 153 }
nuclear@0 154 return mask << pos;
nuclear@0 155 }
nuclear@0 156
nuclear@0 157
nuclear@0 158 #endif /* GFX_H_ */