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 for Mesa
28 * Author: Daniel Borca
29 * Email : dborca@users.sourceforge.net
30 * Web : http://www.geocities.com/dborca
32 * Thanks to CrazyPyro (Neil Funk) for FakeColor
45 static vl_driver
*drv
;
46 /* based upon mode specific data: valid entire session */
47 int vl_video_selector
;
48 static vl_mode
*video_mode
;
49 static int video_scanlen
, video_bypp
;
50 /* valid until next buffer */
51 void *vl_current_draw_buffer
, *vl_current_read_buffer
;
52 int vl_current_stride
, vl_current_width
, vl_current_height
, vl_current_bytes
;
53 int vl_current_offset
, vl_current_delta
;
56 void (*vl_flip
) (void);
68 static word32 VGAPalette
[256];
72 word8 tab_16_8
[0x10000];
75 /* lookup table for scaling 5 bit colors up to 8 bits */
76 static int _rgb_scale_5
[32] = {
77 0, 8, 16, 25, 33, 41, 49, 58,
78 66, 74, 82, 90, 99, 107, 115, 123,
79 132, 140, 148, 156, 165, 173, 181, 189,
80 197, 206, 214, 222, 230, 239, 247, 255
83 /* lookup table for scaling 6 bit colors up to 8 bits */
84 static int _rgb_scale_6
[64] = {
85 0, 4, 8, 12, 16, 20, 24, 28,
86 32, 36, 40, 45, 49, 53, 57, 61,
87 65, 69, 73, 77, 81, 85, 89, 93,
88 97, 101, 105, 109, 113, 117, 121, 125,
89 130, 134, 138, 142, 146, 150, 154, 158,
90 162, 166, 170, 174, 178, 182, 186, 190,
91 194, 198, 202, 206, 210, 215, 219, 223,
92 227, 231, 235, 239, 243, 247, 251, 255
96 /* Desc: color composition (w/o ALPHA)
98 * In : array of integers (R, G, B)
104 v_mixrgb8fake (const unsigned char rgb
[])
106 return array_b
[rgb
[2]]*G_CNT
*R_CNT
107 + array_g
[rgb
[1]]*R_CNT
112 /* Desc: color decomposition
114 * In : pixel offset, array of integers to hold color components (R, G, B, A)
117 * Note: uses current read buffer
120 v_getrgb8fake6 (unsigned int offset
, unsigned char rgb
[])
122 word32 c
= VGAPalette
[((word8
*)vl_current_read_buffer
)[offset
]];
123 rgb
[0] = _rgb_scale_6
[(c
>> 16) & 0x3F];
124 rgb
[1] = _rgb_scale_6
[(c
>> 8) & 0x3F];
125 rgb
[2] = _rgb_scale_6
[ c
& 0x3F];
128 v_getrgb8fake8 (unsigned int offset
, unsigned char rgb
[])
130 word32 c
= VGAPalette
[((word8
*)vl_current_read_buffer
)[offset
]];
137 /* Desc: create R5G6B5 to FakeColor table lookup
148 for (i
= 0; i
< 0x10000; i
++) {
149 unsigned char rgb
[3];
150 rgb
[0] = _rgb_scale_5
[(i
>> 11) & 0x1F];
151 rgb
[1] = _rgb_scale_6
[(i
>> 5) & 0x3F];
152 rgb
[2] = _rgb_scale_5
[ i
& 0x1F];
153 tab_16_8
[i
] = v_mixrgb8fake(rgb
);
155 (void)v_getrgb8fake6
;
156 (void)v_getrgb8fake8
;
160 /* Desc: set one palette entry
162 * In : index, R, G, B
165 * Note: color components are in range [0.0 .. 1.0]
168 vl_setCI (int index
, float red
, float green
, float blue
)
170 drv
->setCI_f(index
, red
, green
, blue
);
174 /* Desc: set one palette entry
176 * In : color, R, G, B
182 fake_setcolor (int c
, int r
, int g
, int b
)
184 VGAPalette
[c
] = 0xff000000 | (r
<<16) | (g
<<8) | b
;
186 drv
->setCI_i(c
, r
, g
, b
);
190 /* Desc: build FakeColor palette
192 * In : CI precision in bits
198 fake_buildpalette (int bits
)
200 double c_r
, c_g
, c_b
;
201 int r
, g
, b
, color
= 0;
203 double max
= (1 << bits
) - 1;
205 for (b
= 0; b
< B_CNT
; ++b
) {
206 for (g
= 0; g
< G_CNT
; ++g
) {
207 for (r
= 0; r
< R_CNT
; ++r
) {
208 c_r
= 0.5 + (double)r
* (max
-R_BIAS
) / (R_CNT
-1.) + R_BIAS
;
209 c_g
= 0.5 + (double)g
* (max
-G_BIAS
) / (G_CNT
-1.) + G_BIAS
;
210 c_b
= 0.5 + (double)b
* (max
-B_BIAS
) / (B_CNT
-1.) + B_BIAS
;
211 fake_setcolor(color
++, (int)c_r
, (int)c_g
, (int)c_b
);
216 for (color
= 0; color
< 256; color
++) {
217 c_r
= (double)color
* R_CNT
/ 256.;
218 c_g
= (double)color
* G_CNT
/ 256.;
219 c_b
= (double)color
* B_CNT
/ 256.;
220 array_r
[color
] = (int)c_r
;
221 array_g
[color
] = (int)c_g
;
222 array_b
[color
] = (int)c_b
;
227 /* Desc: initialize hardware
230 * Out : list of available modes
232 * Note: when returning non-NULL, global variable `drv' is guaranteed to be ok
237 static vl_mode
*q
= NULL
;
240 /* are we forced to NUL driver? */
241 if (getenv("DMESA_NULDRV")) {
242 if ((q
= NUL
.init()) != NULL
) {
247 /* initialize hardware */
248 if ((q
= VESA
.init()) != NULL
) {
250 } else if ((q
= VGA
.init()) != NULL
) {
261 /* Desc: sync buffer with video hardware
263 * In : ptr to old buffer, position, size
269 vl_sync_buffer (void **buffer
, int x
, int y
, int width
, int height
)
271 if ((/*XXX*/width
& 7) || (x
< 0) || (y
< 0) || (x
+width
> video_mode
->xres
) || (y
+height
> video_mode
->yres
)) {
274 void *newbuf
= *buffer
;
276 if ((newbuf
== NULL
) || (vl_current_width
!= width
) || (vl_current_height
!= height
)) {
277 newbuf
= realloc(newbuf
, width
* height
* video_bypp
);
280 if (newbuf
== NULL
) {
284 vl_current_width
= width
;
285 vl_current_height
= height
;
286 vl_current_stride
= vl_current_width
* video_bypp
;
287 vl_current_bytes
= vl_current_stride
* height
;
289 vl_current_offset
= video_scanlen
* y
+ video_bypp
* x
;
290 vl_current_delta
= video_scanlen
- vl_current_stride
;
292 vl_current_draw_buffer
= vl_current_read_buffer
= *buffer
= newbuf
;
298 /* Desc: state retrieval
301 * Out : -1 for an error
306 vl_get (int pname
, int *params
)
309 case VL_GET_SCREEN_SIZE
:
310 params
[0] = video_mode
->xres
;
311 params
[1] = video_mode
->yres
;
313 case VL_GET_VIDEO_MODES
: {
316 if ((q
= v_init_hw()) == NULL
) {
319 /* count available visuals */
320 for (n
= 0; q
->mode
!= 0xffff; q
++) {
321 if ((q
+ 1)->mode
== (q
->mode
| 0x4000)) {
322 /* same mode, but linear */
333 return (drv
!= NULL
) ? drv
->get(pname
, params
) : -1;
341 * In : ptr to mode definition
347 vl_setup_mode (vl_mode
*p
)
369 video_bypp
= (p
->bpp
+7)/8;
370 video_scanlen
= p
->scanlen
;
371 vl_video_selector
= p
->sel
;
377 /* Desc: restore to the mode prior to first call to `vl_video_init'.
395 * In : xres, yres, bits/pixel, RGB, refresh rate
396 * Out : pixel width in bits if success
401 vl_video_init (int width
, int height
, int bpp
, int rgb
, int refresh
, int fbbits
)
410 } else if (bpp
== 8) {
414 /* initialize hardware */
415 if ((q
= v_init_hw()) == NULL
) {
419 /* search for a mode that fits our request */
420 for (min
= -1, p
= NULL
; q
->mode
!= 0xffff; q
++) {
421 if ((q
->xres
>= width
) && (q
->yres
>= height
) && (q
->bpp
== bpp
)) {
422 if (min
>= (unsigned)(q
->xres
* q
->yres
)) {
423 min
= q
->xres
* q
->yres
;
429 /* setup and enter mode */
430 if ((vl_setup_mode(p
) == 0) && (drv
->entermode(p
, refresh
, fbbits
) == 0)) {
433 drv
->get(VL_GET_CI_PREC
, (int *)(&min
));
434 fake_buildpalette(min
);