d3774e7c3e4355c21fa32cd763465615a0a01cb5
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.5 for Mesa
28 * Copyright (C) 2002 - Borca Daniel
29 * Email : dborca@users.sourceforge.net
30 * Web : http://www.geocities.com/dborca
32 * Thanks to CrazyPyro (Neil Funk) for FakeColor
46 static vl_driver
*drv
;
47 /* based upon mode specific data: valid entire session */
48 int vl_video_selector
;
49 static vl_mode
*video_mode
;
50 static int video_scanlen
, video_bypp
;
51 /* valid until next buffer */
52 void *vl_current_draw_buffer
, *vl_current_read_buffer
;
53 int vl_current_stride
, vl_current_width
, vl_current_height
, vl_current_bytes
;
54 int vl_current_offset
, vl_current_delta
;
59 /* These lookup tables are used to extract RGB values in [0,255]
60 * from 15/16-bit pixel values.
62 static unsigned char pix15r
[0x8000];
63 static unsigned char pix15g
[0x8000];
64 static unsigned char pix15b
[0x8000];
65 static unsigned char pix16r
[0x10000];
66 static unsigned char pix16g
[0x10000];
67 static unsigned char pix16b
[0x10000];
69 /* lookup table for scaling 5 bit colors up to 8 bits */
70 static int _rgb_scale_5
[32] = {
71 0, 8, 16, 25, 33, 41, 49, 58,
72 66, 74, 82, 90, 99, 107, 115, 123,
73 132, 140, 148, 156, 165, 173, 181, 189,
74 197, 206, 214, 222, 230, 239, 247, 255
78 /* lookup table for scaling 6 bit colors up to 8 bits */
79 static int _rgb_scale_6
[64] = {
80 0, 4, 8, 12, 16, 20, 24, 28,
81 32, 36, 40, 45, 49, 53, 57, 61,
82 65, 69, 73, 77, 81, 85, 89, 93,
83 97, 101, 105, 109, 113, 117, 121, 125,
84 130, 134, 138, 142, 146, 150, 154, 158,
85 162, 166, 170, 174, 178, 182, 186, 190,
86 194, 198, 202, 206, 210, 215, 219, 223,
87 227, 231, 235, 239, 243, 247, 251, 255
99 static word32 VGAPalette
[256];
100 static word8 array_r
[256];
101 static word8 array_g
[256];
102 static word8 array_b
[256];
106 int (*vl_mixfix
) (fixed r
, fixed g
, fixed b
);
107 int (*vl_mixrgb
) (const unsigned char rgb
[]);
108 int (*vl_mixrgba
) (const unsigned char rgba
[]);
109 void (*vl_getrgba
) (unsigned int offset
, unsigned char rgba
[4]);
110 int (*vl_getpixel
) (unsigned int offset
);
111 void (*vl_clear
) (int color
);
112 void (*vl_rect
) (int x
, int y
, int width
, int height
, int color
);
113 void (*vl_flip
) (void);
114 void (*vl_putpixel
) (unsigned int offset
, int color
);
118 /* Desc: color composition (w/o ALPHA)
125 static int vl_mixfix8fake (fixed r
, fixed g
, fixed b
)
127 return array_b
[b
>>FIXED_SHIFT
]*G_CNT
*R_CNT
128 + array_g
[g
>>FIXED_SHIFT
]*R_CNT
129 + array_r
[r
>>FIXED_SHIFT
];
131 #define vl_mixfix8 vl_mixfix8fake
132 static int vl_mixfix15 (fixed r
, fixed g
, fixed b
)
134 return ((r
>>(3+FIXED_SHIFT
))<<10)
135 |((g
>>(3+FIXED_SHIFT
))<<5)
136 |(b
>>(3+FIXED_SHIFT
));
138 static int vl_mixfix16 (fixed r
, fixed g
, fixed b
)
140 return ((r
>>(3+FIXED_SHIFT
))<<11)
141 |((g
>>(2+FIXED_SHIFT
))<<5)
142 |(b
>>(3+FIXED_SHIFT
));
144 #define vl_mixfix24 vl_mixfix32
145 static int vl_mixfix32 (fixed r
, fixed g
, fixed b
)
147 return ((r
>>FIXED_SHIFT
)<<16)
148 |((g
>>FIXED_SHIFT
)<<8)
154 /* Desc: color composition (w/ ALPHA)
156 * In : array of integers (R, G, B, A)
161 #define vl_mixrgba8 vl_mixrgb8fake
162 #define vl_mixrgba15 vl_mixrgb15
163 #define vl_mixrgba16 vl_mixrgb16
164 #define vl_mixrgba24 vl_mixrgb24
165 static int vl_mixrgba32 (const unsigned char rgba
[])
168 * currently, DMesa uses Mesa's alpha buffer;
169 * so we don't really care about alpha value here...
171 return /*(rgba[3]<<24)|*/(rgba
[0]<<16)|(rgba
[1]<<8)|(rgba
[2]);
176 /* Desc: color composition (w/o ALPHA)
178 * In : array of integers (R, G, B)
183 static int vl_mixrgb8fake (const unsigned char rgb
[])
185 return array_b
[rgb
[2]]*G_CNT
*R_CNT
186 + array_g
[rgb
[1]]*R_CNT
189 #define vl_mixrgb8 vl_mixrgb8fake
190 static int vl_mixrgb15 (const unsigned char rgb
[])
192 return ((rgb
[0]>>3)<<10)|((rgb
[1]>>3)<<5)|(rgb
[2]>>3);
194 static int vl_mixrgb16 (const unsigned char rgb
[])
196 return ((rgb
[0]>>3)<<11)|((rgb
[1]>>2)<<5)|(rgb
[2]>>3);
198 #define vl_mixrgb24 vl_mixrgb32
199 static int vl_mixrgb32 (const unsigned char rgb
[])
201 return (rgb
[0]<<16)|(rgb
[1]<<8)|(rgb
[2]);
206 /* Desc: color decomposition
208 * In : pixel offset, array of integers to hold color components (R, G, B, A)
211 * Note: uses current read buffer
213 static void v_getrgba8fake6 (unsigned int offset
, unsigned char rgba
[4])
215 word32 c
= VGAPalette
[((word8
*)vl_current_read_buffer
)[offset
]];
216 rgba
[0] = _rgb_scale_6
[(c
>> 16) & 0x3F];
217 rgba
[1] = _rgb_scale_6
[(c
>> 8) & 0x3F];
218 rgba
[2] = _rgb_scale_6
[c
& 0x3F];
219 /*rgba[3] = c >> 24;*/ /* dummy alpha; we have separate SW alpha, so ignore */
221 static void v_getrgba8fake8 (unsigned int offset
, unsigned char rgba
[4])
223 word32 c
= VGAPalette
[((word8
*)vl_current_read_buffer
)[offset
]];
227 /*rgba[3] = c >> 24;*/ /* dummy alpha; we have separate SW alpha, so ignore */
229 #define v_getrgba8 v_getrgba8fake6
230 static void v_getrgba15 (unsigned int offset
, unsigned char rgba
[4])
232 word32 c
= ((word16
*)vl_current_read_buffer
)[offset
];
239 rgba
[0] = _rgb_scale_5
[(c
>> 10) & 0x1F];
240 rgba
[1] = _rgb_scale_5
[(c
>> 5) & 0x1F];
241 rgba
[2] = _rgb_scale_5
[c
& 0x1F];
243 /*rgba[3] = 255;*/ /* dummy alpha; we have separate SW alpha, so ignore */
245 static void v_getrgba16 (unsigned int offset
, unsigned char rgba
[4])
247 word32 c
= ((word16
*)vl_current_read_buffer
)[offset
];
253 rgba
[0] = _rgb_scale_5
[(c
>> 11) & 0x1F];
254 rgba
[1] = _rgb_scale_6
[(c
>> 5) & 0x3F];
255 rgba
[2] = _rgb_scale_5
[c
& 0x1F];
257 /*rgba[3] = 255;*/ /* dummy alpha; we have separate SW alpha, so ignore */
259 static void v_getrgba24 (unsigned int offset
, unsigned char rgba
[4])
261 word32 c
= *(word32
*)((long)vl_current_read_buffer
+offset
*3);
265 /*rgba[3] = 255;*/ /* dummy alpha; we have separate SW alpha, so ignore */
267 static void v_getrgba32 (unsigned int offset
, unsigned char rgba
[4])
269 word32 c
= ((word32
*)vl_current_read_buffer
)[offset
];
273 /*rgba[3] = c >> 24;*/ /* dummy alpha; we have separate SW alpha, so ignore */
278 /* Desc: pixel retrieval
283 * Note: uses current read buffer
285 static int v_getpixel8 (unsigned int offset
)
287 return ((word8
*)vl_current_read_buffer
)[offset
];
289 #define v_getpixel15 v_getpixel16
290 static int v_getpixel16 (unsigned int offset
)
292 return ((word16
*)vl_current_read_buffer
)[offset
];
294 static int v_getpixel24 (unsigned int offset
)
296 return *(word32
*)((long)vl_current_read_buffer
+offset
*3);
298 static int v_getpixel32 (unsigned int offset
)
300 return ((word32
*)vl_current_read_buffer
)[offset
];
305 /* Desc: set one palette entry
307 * In : index, R, G, B
310 * Note: color components are in range [0.0 .. 1.0]
312 void vl_setCI (int index
, float red
, float green
, float blue
)
314 drv
->setCI_f(index
, red
, green
, blue
);
319 /* Desc: set one palette entry
321 * In : color, R, G, B
326 static void fake_setcolor (int c
, int r
, int g
, int b
)
328 VGAPalette
[c
] = 0xff000000 | (r
<<16) | (g
<<8) | b
;
330 drv
->setCI_i(c
, r
, g
, b
);
335 /* Desc: build FakeColor palette
337 * In : CI precision in bits
342 static void fake_buildpalette (int bits
)
344 double c_r
, c_g
, c_b
;
345 int r
, g
, b
, color
= 0;
347 double max
= (1 << bits
) - 1;
349 for (b
=0; b
<B_CNT
; ++b
) {
350 for (g
=0; g
<G_CNT
; ++g
) {
351 for (r
=0; r
<R_CNT
; ++r
) {
352 c_r
= 0.5 + (double)r
*(max
-R_BIAS
)/(R_CNT
-1.) + R_BIAS
;
353 c_g
= 0.5 + (double)g
*(max
-G_BIAS
)/(G_CNT
-1.) + G_BIAS
;
354 c_b
= 0.5 + (double)b
*(max
-B_BIAS
)/(B_CNT
-1.) + B_BIAS
;
355 fake_setcolor(color
++, (int)c_r
, (int)c_g
, (int)c_b
);
360 for (color
=0; color
<256; color
++) {
361 c_r
= (double)color
*R_CNT
/256.;
362 c_g
= (double)color
*G_CNT
/256.;
363 c_b
= (double)color
*B_CNT
/256.;
364 array_r
[color
] = (int)c_r
;
365 array_g
[color
] = (int)c_g
;
366 array_b
[color
] = (int)c_b
;
373 /* Desc: initialize lookup arrays
380 void v_init_pixeltables (void)
384 for (pixel
= 0; pixel
<= 0xffff; pixel
++) {
385 unsigned int r
, g
, b
;
387 if (pixel
<= 0x7fff) {
389 r
= (pixel
& 0x7c00) >> 8;
390 g
= (pixel
& 0x03E0) >> 3;
391 b
= (pixel
& 0x001F) << 2;
393 r
= (unsigned int)(((double)r
* 255. / 0x7c) + 0.5);
394 g
= (unsigned int)(((double)g
* 255. / 0x7c) + 0.5);
395 b
= (unsigned int)(((double)b
* 255. / 0x7c) + 0.5);
403 r
= (pixel
& 0xF800) >> 8;
404 g
= (pixel
& 0x07E0) >> 3;
405 b
= (pixel
& 0x001F) << 3;
407 r
= (unsigned int)(((double)r
* 255. / 0xF8) + 0.5);
408 g
= (unsigned int)(((double)g
* 255. / 0xFC) + 0.5);
409 b
= (unsigned int)(((double)b
* 255. / 0xF8) + 0.5);
420 /* Desc: initialize hardware
423 * Out : list of available modes
425 * Note: when returning non-NULL, global variable `drv' is guaranteed to be ok
427 static vl_mode
*v_init_hw (void)
429 static vl_mode
*q
= NULL
;
432 /* are we forced to NUL driver? */
433 if (getenv("DMESA_NULDRV")) {
434 if ((q
= NUL
.init()) != NULL
) {
439 /* initialize hardware */
440 if ((q
= VESA
.init()) != NULL
) {
442 } else if ((q
= VGA
.init()) != NULL
) {
454 /* Desc: sync buffer with video hardware
456 * In : ptr to old buffer, position, size
461 int vl_sync_buffer (void **buffer
, int x
, int y
, int width
, int height
)
463 if ((width
& 7) || (x
< 0) || (y
< 0) || (x
+width
> video_mode
->xres
) || (y
+height
> video_mode
->yres
)) {
466 void *newbuf
= *buffer
;
468 if ((newbuf
== NULL
) || (vl_current_width
!= width
) || (vl_current_height
!= height
)) {
469 newbuf
= realloc(newbuf
, width
* height
* video_bypp
);
472 if (newbuf
== NULL
) {
476 vl_current_width
= width
;
477 vl_current_height
= height
;
478 vl_current_stride
= vl_current_width
* video_bypp
;
479 vl_current_bytes
= vl_current_stride
* height
;
481 vl_current_offset
= video_scanlen
* y
+ video_bypp
* x
;
482 vl_current_delta
= video_scanlen
- vl_current_stride
;
484 vl_current_draw_buffer
= vl_current_read_buffer
= *buffer
= newbuf
;
491 /* Desc: state retrieval
494 * Out : -1 for an error
498 int vl_get (int pname
, int *params
)
501 case VL_GET_SCREEN_SIZE
:
502 params
[0] = video_mode
->xres
;
503 params
[1] = video_mode
->yres
;
505 case VL_GET_VIDEO_MODES
:
509 if ((q
= v_init_hw()) == NULL
) {
512 /* count available visuals */
513 for (n
= 0; q
->mode
!= 0xffff; q
++) {
514 if ((q
+ 1)->mode
== (q
->mode
| 0x4000)) {
515 /* same mode, but linear */
526 return (drv
!= NULL
) ? drv
->get(pname
, params
) : -1;
535 * In : ptr to mode definition
540 static int vl_setup_mode (vl_mode
*p
)
546 #define INITPTR(bpp) \
547 vl_putpixel = v_putpixel##bpp; \
548 vl_getrgba = v_getrgba##bpp; \
549 vl_getpixel = v_getpixel##bpp; \
550 vl_rect = v_rect##bpp; \
551 vl_mixfix = vl_mixfix##bpp; \
552 vl_mixrgb = vl_mixrgb##bpp; \
553 vl_mixrgba = vl_mixrgba##bpp; \
554 vl_clear = _can_mmx() ? v_clear##bpp##_mmx : v_clear##bpp
579 video_bypp
= (p
->bpp
+7)/8;
580 video_scanlen
= p
->scanlen
;
581 vl_video_selector
= p
->sel
;
588 /* Desc: restore to the mode prior to first call to `vl_video_init'.
595 void vl_video_exit (void)
606 * In : xres, yres, bits/pixel, RGB, refresh rate
607 * Out : pixel width in bits if success
611 int vl_video_init (int width
, int height
, int bpp
, int rgb
, int refresh
)
620 } else if (bpp
== 8) {
625 v_init_pixeltables();
629 /* initialize hardware */
630 if ((q
= v_init_hw()) == NULL
) {
634 /* search for a mode that fits our request */
635 for (min
=-1, p
=NULL
; q
->mode
!=0xffff; q
++) {
636 if ((q
->xres
>=width
) && (q
->yres
>=height
) && (q
->bpp
==bpp
)) {
637 if (min
>=(unsigned)(q
->xres
*q
->yres
)) {
638 min
= q
->xres
*q
->yres
;
644 /* setup and enter mode */
645 if ((vl_setup_mode(p
) == 0) && (drv
->entermode(p
, refresh
) == 0)) {
648 drv
->get(VL_GET_CI_PREC
, (int *)(&min
));
649 fake_buildpalette(min
);
651 vl_getrgba
= v_getrgba8fake8
;