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