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_ */