2 * Mesa 3-D graphics library
5 * Copyright (C) 1999 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 * DOS/DJGPP device driver v1.3 for Mesa 5.0
28 * Copyright (C) 2002 - Borca Daniel
29 * Email : dborca@yahoo.com
30 * Web : http://www.geocities.com/dborca
32 * Thanks to CrazyPyro (Neil Funk) for FakeColor
40 #include "vesa/vesa.h"
45 static vl_driver
*drv
;
46 /* based upon mode specific data: valid entire session */
47 int vl_video_selector
;
48 static int video_scanlen
, video_bypp
;
49 /* valid until next buffer */
50 void *vl_current_draw_buffer
, *vl_current_read_buffer
;
51 int vl_current_stride
, vl_current_width
, vl_current_height
, vl_current_bytes
;
52 int vl_current_offset
, vl_current_delta
;
56 /* lookup table for scaling 5 bit colors up to 8 bits */
57 static int _rgb_scale_5
[32] = {
58 0, 8, 16, 24, 32, 41, 49, 57,
59 65, 74, 82, 90, 98, 106, 115, 123,
60 131, 139, 148, 156, 164, 172, 180, 189,
61 197, 205, 213, 222, 230, 238, 246, 255
64 /* lookup table for scaling 6 bit colors up to 8 bits */
65 static int _rgb_scale_6
[64] = {
66 0, 4, 8, 12, 16, 20, 24, 28,
67 32, 36, 40, 44, 48, 52, 56, 60,
68 64, 68, 72, 76, 80, 85, 89, 93,
69 97, 101, 105, 109, 113, 117, 121, 125,
70 129, 133, 137, 141, 145, 149, 153, 157,
71 161, 165, 170, 174, 178, 182, 186, 190,
72 194, 198, 202, 206, 210, 214, 218, 222,
73 226, 230, 234, 238, 242, 246, 250, 255
85 static word32 VGAPalette
[256];
86 static word8 array_r
[256];
87 static word8 array_g
[256];
88 static word8 array_b
[256];
92 int (*vl_mixfix
) (fixed r
, fixed g
, fixed b
);
93 int (*vl_mixrgb
) (const unsigned char rgb
[]);
94 int (*vl_mixrgba
) (const unsigned char rgba
[]);
95 void (*vl_getrgba
) (unsigned int offset
, unsigned char rgba
[4]);
96 void (*vl_clear
) (int color
);
97 void (*vl_rect
) (int x
, int y
, int width
, int height
, int color
);
98 void (*vl_flip
) (void);
99 void (*vl_putpixel
) (unsigned int offset
, int color
);
103 /* Desc: color composition (w/o ALPHA)
110 static int vl_mixfix8fake (fixed r
, fixed g
, fixed b
)
112 return array_b
[b
>>FIXED_SHIFT
]*G_CNT
*R_CNT
113 + array_g
[g
>>FIXED_SHIFT
]*R_CNT
114 + array_r
[r
>>FIXED_SHIFT
];
116 #define vl_mixfix8 vl_mixfix8fake
117 static int vl_mixfix15 (fixed r
, fixed g
, fixed b
)
119 return ((r
>>(3+FIXED_SHIFT
))<<10)
120 |((g
>>(3+FIXED_SHIFT
))<<5)
121 |(b
>>(3+FIXED_SHIFT
));
123 static int vl_mixfix16 (fixed r
, fixed g
, fixed b
)
125 return ((r
>>(3+FIXED_SHIFT
))<<11)
126 |((g
>>(2+FIXED_SHIFT
))<<5)
127 |(b
>>(3+FIXED_SHIFT
));
129 #define vl_mixfix24 vl_mixfix32
130 static int vl_mixfix32 (fixed r
, fixed g
, fixed b
)
132 return ((r
>>FIXED_SHIFT
)<<16)
133 |((g
>>FIXED_SHIFT
)<<8)
139 /* Desc: color composition (w/ ALPHA)
141 * In : array of integers (R, G, B, A)
146 #define vl_mixrgba8 vl_mixrgb8fake
147 #define vl_mixrgba15 vl_mixrgb15
148 #define vl_mixrgba16 vl_mixrgb16
149 #define vl_mixrgba24 vl_mixrgb24
150 static int vl_mixrgba32 (const unsigned char rgba
[])
152 return (rgba
[3]<<24)|(rgba
[0]<<16)|(rgba
[1]<<8)|(rgba
[2]);
157 /* Desc: color composition (w/o ALPHA)
159 * In : array of integers (R, G, B)
164 static int vl_mixrgb8fake (const unsigned char rgba
[])
166 return array_b
[rgba
[2]]*G_CNT
*R_CNT
167 + array_g
[rgba
[1]]*R_CNT
170 #define vl_mixrgb8 vl_mixrgb8fake
171 static int vl_mixrgb15 (const unsigned char rgb
[])
173 return ((rgb
[0]>>3)<<10)|((rgb
[1]>>3)<<5)|(rgb
[2]>>3);
175 static int vl_mixrgb16 (const unsigned char rgb
[])
177 return ((rgb
[0]>>3)<<11)|((rgb
[1]>>2)<<5)|(rgb
[2]>>3);
179 #define vl_mixrgb24 vl_mixrgb32
180 static int vl_mixrgb32 (const unsigned char rgb
[])
182 return (rgb
[0]<<16)|(rgb
[1]<<8)|(rgb
[2]);
187 /* Desc: color decomposition
189 * In : pixel offset, array of integers to hold color components (R, G, B, A)
192 * Note: uses current read buffer
194 static void v_getrgba8fake6 (unsigned int offset
, unsigned char rgba
[])
196 word32 c
= VGAPalette
[((word8
*)vl_current_read_buffer
)[offset
]];
197 rgba
[0] = _rgb_scale_6
[(c
>> 16) & 0x3F];
198 rgba
[1] = _rgb_scale_6
[(c
>> 8) & 0x3F];
199 rgba
[2] = _rgb_scale_6
[c
& 0x3F];
202 static void v_getrgba8fake8 (unsigned int offset
, unsigned char rgba
[])
204 word32 c
= VGAPalette
[((word8
*)vl_current_read_buffer
)[offset
]];
210 #define v_getrgba8 v_getrgba8fake6
211 static void v_getrgba15 (unsigned int offset
, unsigned char rgba
[4])
213 word32 c
= ((word16
*)vl_current_read_buffer
)[offset
];
214 rgba
[0] = _rgb_scale_5
[(c
>> 10) & 0x1F];
215 rgba
[1] = _rgb_scale_5
[(c
>> 5) & 0x1F];
216 rgba
[2] = _rgb_scale_5
[c
& 0x1F];
219 static void v_getrgba16 (unsigned int offset
, unsigned char rgba
[4])
221 word32 c
= ((word16
*)vl_current_read_buffer
)[offset
];
222 rgba
[0] = _rgb_scale_5
[(c
>> 11) & 0x1F];
223 rgba
[1] = _rgb_scale_6
[(c
>> 5) & 0x3F];
224 rgba
[2] = _rgb_scale_5
[c
& 0x1F];
227 static void v_getrgba24 (unsigned int offset
, unsigned char rgba
[4])
229 word32 c
= *(word32
*)((long)vl_current_read_buffer
+offset
*3);
235 static void v_getrgba32 (unsigned int offset
, unsigned char rgba
[4])
237 word32 c
= ((word32
*)vl_current_read_buffer
)[offset
];
246 /* Desc: set one palette entry
248 * In : index, R, G, B
251 * Note: color components are in range [0.0 .. 1.0]
253 void vl_setCI (int index
, float red
, float green
, float blue
)
255 drv
->setCI_f(index
, red
, green
, blue
);
260 /* Desc: read pixel from 8bit buffer
265 * Note: used only for CI modes
267 int vl_getCIpixel (unsigned int offset
)
269 return ((word8
*)vl_current_read_buffer
)[offset
];
274 /* Desc: set one palette entry
276 * In : color, R, G, B
279 * Note: color components are in range [0 .. 63]
281 static void fake_setcolor (int c
, int r
, int g
, int b
)
283 VGAPalette
[c
] = 0xff000000 | (r
<<16) | (g
<<8) | b
;
285 drv
->setCI_i(c
, r
, g
, b
);
290 /* Desc: build FakeColor palette
292 * In : CI precision in bits
297 static void fake_buildpalette (int bits
)
299 double c_r
, c_g
, c_b
;
300 int r
, g
, b
, color
= 0;
302 double max
= (1 << bits
) - 1;
304 for (b
=0; b
<B_CNT
; ++b
) {
305 for (g
=0; g
<G_CNT
; ++g
) {
306 for (r
=0; r
<R_CNT
; ++r
) {
307 c_r
= 0.5 + (double)r
*(max
-R_BIAS
)/(R_CNT
-1.) + R_BIAS
;
308 c_g
= 0.5 + (double)g
*(max
-G_BIAS
)/(G_CNT
-1.) + G_BIAS
;
309 c_b
= 0.5 + (double)b
*(max
-B_BIAS
)/(B_CNT
-1.) + B_BIAS
;
310 fake_setcolor(color
++, (int)c_r
, (int)c_g
, (int)c_b
);
315 for (color
=0; color
<256; color
++) {
316 c_r
= (double)color
*R_CNT
/256.;
317 c_g
= (double)color
*G_CNT
/256.;
318 c_b
= (double)color
*B_CNT
/256.;
319 array_r
[color
] = (int)c_r
;
320 array_g
[color
] = (int)c_g
;
321 array_b
[color
] = (int)c_b
;
327 /* Desc: sync buffer with video hardware
329 * In : old buffer, position, size
334 void *vl_sync_buffer (void *buffer
, int x
, int y
, int width
, int height
)
341 if ((newbuf
=realloc(buffer
, width
* height
* video_bypp
)) != NULL
) {
342 vl_current_width
= width
;
343 vl_current_height
= height
;
344 vl_current_stride
= vl_current_width
* video_bypp
;
345 vl_current_bytes
= vl_current_stride
* height
;
347 vl_current_offset
= video_scanlen
* y
+ video_bypp
* x
;
348 vl_current_delta
= video_scanlen
- vl_current_stride
;
350 return vl_current_draw_buffer
= vl_current_read_buffer
= newbuf
;
356 /* Desc: retrieve CPU MMX capability
359 * Out : FALSE if CPU cannot do MMX
363 int vl_can_mmx (void)
366 extern int _mesa_identify_x86_cpu_features (void);
367 int _mesa_x86_cpu_features
= _mesa_identify_x86_cpu_features();
368 return (_mesa_x86_cpu_features
& 0x00800000);
378 * In : ptr to mode definition
383 static int vl_setup_mode (vl_mode
*p
)
385 #define INITPTR(bpp) \
386 vl_putpixel = v_putpixel##bpp; \
387 vl_getrgba = v_getrgba##bpp; \
388 vl_rect = v_rect##bpp; \
389 vl_mixfix = vl_mixfix##bpp; \
390 vl_mixrgb = vl_mixrgb##bpp; \
391 vl_mixrgba = vl_mixrgba##bpp; \
392 vl_clear = vl_can_mmx() ? v_clear##bpp##_mmx : v_clear##bpp
416 video_bypp
= (p
->bpp
+7)/8;
417 video_scanlen
= p
->scanlen
;
418 vl_video_selector
= p
->sel
;
425 /* Desc: restore to the mode prior to first call to `vl_video_init'.
432 void vl_video_exit (void)
442 * In : xres, yres, bits/pixel, RGB, refresh rate
443 * Out : pixel width in bits if success
447 int vl_video_init (int width
, int height
, int bpp
, int rgb
, int refresh
)
456 } else if (bpp
== 8) {
460 /* initialize hardware */
462 if ((q
=drv
->init()) == NULL
) {
464 if ((q
=drv
->init()) == NULL
) {
469 /* search for a mode that fits our request */
470 for (min
=-1, p
=NULL
; q
->mode
!=0xffff; q
++) {
471 if ((q
->xres
>=width
) && (q
->yres
>=height
) && (q
->bpp
==bpp
)) {
472 if (min
>=(unsigned)(q
->xres
*q
->yres
)) {
473 min
= q
->xres
*q
->yres
;
479 /* check, setup and enter mode */
480 if ((p
!=NULL
) && (vl_setup_mode(p
) == 0) && (drv
->entermode(p
, refresh
) == 0)) {
483 min
= drv
->getCIprec();
484 fake_buildpalette(min
);
486 vl_getrgba
= v_getrgba8fake8
;