X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdos%2Fvideo.c;h=468207fbf6ff45742968543d8422f894867ec9e5;hb=2d5313db72354ef52e5d041c8c2efac52efc12a9;hp=9d50952c52730c82976a70ccbea594e22f226a75;hpb=e69bfe74d7f887fb516f300f575d43b9903d9ab3;p=mesa.git diff --git a/src/mesa/drivers/dos/video.c b/src/mesa/drivers/dos/video.c index 9d50952c527..468207fbf6f 100644 --- a/src/mesa/drivers/dos/video.c +++ b/src/mesa/drivers/dos/video.c @@ -1,625 +1,442 @@ -/* - * Mesa 3-D graphics library - * Version: 4.0 - * - * Copyright (C) 1999 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * DOS/DJGPP device driver v0.4 for Mesa 4.0 - * - * Copyright (C) 2002 - Borca Daniel - * Email : dborca@yahoo.com - * Web : http://www.geocities.com/dborca - */ - - -#include -#include -#include -#include -#include -#include -#include - -#include "video.h" -#include "dpmiint.h" - - - -typedef unsigned char word8; -typedef unsigned short word16; -typedef unsigned long word32; - -typedef struct vl_mode { - int mode; - int xres, yres; - int scanlen; - int bpp; -} vl_mode; - -#define _16_ *(word16 *)& -#define _32_ *(word32 *)& - -static int init; - -static vl_mode modes[64]; - -/* card specific: valid forever */ -static word16 vesa_ver; -static word32 hw_granularity, hw_linearfb; -static unsigned int gran_shift, gran_mask; -/* based upon mode specific data: valid entire session */ -static int video_selector, banked_selector, linear_selector; -static int video_scanlen, video_bypp; -/* valid until next buffer */ -static int current_offset, current_delta, current_width; - - - -/* lookup table for scaling 5 bit colors up to 8 bits */ -static int _rgb_scale_5[32] = -{ - 0, 8, 16, 24, 32, 41, 49, 57, - 65, 74, 82, 90, 98, 106, 115, 123, - 131, 139, 148, 156, 164, 172, 180, 189, - 197, 205, 213, 222, 230, 238, 246, 255 -}; - -/* lookup table for scaling 6 bit colors up to 8 bits */ -static int _rgb_scale_6[64] = -{ - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60, - 64, 68, 72, 76, 80, 85, 89, 93, - 97, 101, 105, 109, 113, 117, 121, 125, - 129, 133, 137, 141, 145, 149, 153, 157, - 161, 165, 170, 174, 178, 182, 186, 190, - 194, 198, 202, 206, 210, 214, 218, 222, - 226, 230, 234, 238, 242, 246, 250, 255 -}; - - - -/* - * virtual clearing - */ -void (*vl_clear) (void *buffer, int len, int color); - -#define v_clear15 v_clear16 -extern void v_clear16 (void *buffer, int len, int color); -extern void v_clear32 (void *buffer, int len, int color); -__asm__("\n\ - .text \n\ - .balign 4 \n\ - .global _v_clear16 \n\ -_v_clear16: \n\ - movl 12(%esp), %eax \n\ - pushw %ax \n\ - pushw %ax \n\ - popl %eax \n\ - jmp _v_clear_common \n\ - .balign 4 \n\ - .global _v_clear32 \n\ -_v_clear32: \n\ - movl 12(%esp), %eax \n\ - .balign 4 \n\ -_v_clear_common: \n\ - movl 8(%esp), %ecx \n\ - movl 4(%esp), %edx \n\ - shrl $2, %ecx \n\ - 0: \n\ - .balign 4 \n\ - movl %eax, (%edx) \n\ - addl $4, %edx \n\ - decl %ecx \n\ - jnz 0b \n\ - ret"); -extern void v_clear24 (void *buffer, int len, int color); -__asm__("\n\ - .text \n\ - .balign 4 \n\ - .global _v_clear24 \n\ -_v_clear24: \n\ - movl 8(%esp), %edx \n\ - movl $0xaaaaaaab, %eax \n\ - mull %edx \n\ - movl 12(%esp), %eax \n\ - movl %edx, %ecx \n\ - movl 4(%esp), %edx \n\ - pushl %ebx \n\ - shrl %ecx \n\ - movb 18(%esp), %bl \n\ - .balign 4 \n\ - 0: \n\ - movw %ax, (%edx) \n\ - movb %bl, 2(%edx) \n\ - addl $3, %edx \n\ - decl %ecx \n\ - jnz 0b \n\ - popl %ebx \n\ - ret"); - - - -/* - * virtual rectangle clearing - */ -void vl_rect (void *buffer, int x, int y, int width, int height, int color) -{ - int offset = y*current_width + x; - int delta = current_width - width; - - for (y=0; y>3)<<10)|((rgb[1]>>3)<<5)|(rgb[2]>>3); -} -static int vl_mixrgb16 (const unsigned char rgb[]) -{ - return ((rgb[0]>>3)<<11)|((rgb[1]>>2)<<5)|(rgb[2]>>3); -} -#define vl_mixrgb24 vl_mixrgb32 -static int vl_mixrgb32 (const unsigned char rgb[]) -{ - return (rgb[0]<<16)|(rgb[1]<<8)|(rgb[2]); -} - - - -/* - * vl_putpixel* - */ -void (*vl_putpixel) (void *buffer, int offset, int color); - -#define v_putpixel15 v_putpixel16 -extern void v_putpixel16 (void *buffer, int offset, int color); -__asm__("\n\ - .text \n\ - .balign 4 \n\ - .global _v_putpixel16 \n\ -_v_putpixel16: \n\ - movl 8(%esp), %edx \n\ - shll %edx \n\ - movl 12(%esp), %eax \n\ - addl 4(%esp), %edx \n\ - movw %ax, (%edx) \n\ - ret"); -extern void v_putpixel24 (void *buffer, int offset, int color); -__asm__("\n\ - .text \n\ - .balign 4 \n\ - .global _v_putpixel24 \n\ -_v_putpixel24: \n\ - movl 8(%esp), %edx \n\ - leal (%edx, %edx, 2), %edx \n\ - movl 12(%esp), %eax \n\ - addl 4(%esp), %edx \n\ - movw %ax, (%edx) \n\ - shrl $16, %eax \n\ - movb %al, 2(%edx) \n\ - ret"); -extern void v_putpixel32 (void *buffer, int offset, int color); -__asm__("\n\ - .text \n\ - .balign 4 \n\ - .global _v_putpixel32 \n\ -_v_putpixel32: \n\ - movl 8(%esp), %edx \n\ - shll $2, %edx \n\ - movl 12(%esp), %eax \n\ - addl 4(%esp), %edx \n\ - movl %eax, (%edx) \n\ - ret"); - - - -/* - * get pixel and decompose R, G, B, A - */ -void (*vl_getrgba) (void *buffer, int offset, unsigned char rgba[4]); - -/* - * v_getrgba* - */ -static void v_getrgba15 (void *buffer, int offset, unsigned char rgba[4]) -{ - int c = ((word16 *)buffer)[offset]; - rgba[0] = _rgb_scale_5[(c >> 10) & 0x1F]; - rgba[1] = _rgb_scale_5[(c >> 5) & 0x1F]; - rgba[2] = _rgb_scale_5[c & 0x1F]; - rgba[3] = 255; -} -static void v_getrgba16 (void *buffer, int offset, unsigned char rgba[4]) -{ - int c = ((word16 *)buffer)[offset]; - rgba[0] = _rgb_scale_5[(c >> 11) & 0x1F]; - rgba[1] = _rgb_scale_6[(c >> 5) & 0x3F]; - rgba[2] = _rgb_scale_5[c & 0x1F]; - rgba[3] = 255; -} -static void v_getrgba24 (void *buffer, int offset, unsigned char rgba[4]) -{ - int c = *(word32 *)((long)buffer+offset*3); - rgba[0] = c >> 16; - rgba[1] = c >> 8; - rgba[2] = c; - rgba[3] = 255; -} -static void v_getrgba32 (void *buffer, int offset, unsigned char rgba[4]) -{ - int c = ((word32 *)buffer)[offset]; - rgba[0] = c >> 16; - rgba[1] = c >> 8; - rgba[2] = c; - rgba[3] = c >> 24; -} - - - -/* - * sync buffer with video hardware - */ -void *vl_sync_buffer (void *buffer, int x, int y, int width, int height) -{ - void *newbuf; - - if (width&3) { - return NULL; - } else { - current_offset = video_scanlen * y + video_bypp * x; - if ((newbuf=realloc(buffer, width*height*video_bypp))!=NULL) { - current_width = width; - current_delta = video_scanlen - video_bypp * width; - return newbuf; - } else { - return NULL; - } - } -} - - - -/* - * attempts to detect VESA and video modes - */ -static word16 vl_vesa_init (void) -{ - __dpmi_regs r; - unsigned short *p; - vl_mode *q; - char vesa_info[512], tmp[512]; - int maxsize = 0; - - _farpokel(_stubinfo->ds_selector, 0, 0x32454256); - r.x.ax = 0x4f00; - r.x.di = 0; - r.x.es = _stubinfo->ds_segment; - __dpmi_int(0x10, &r); - if (r.x.ax==0x004f) { - movedata(_stubinfo->ds_selector, 0, _my_ds(), (unsigned)vesa_info, 512); - if ((_32_ vesa_info[0])==0x41534556) { - p = (unsigned short *)(((_16_ vesa_info[0x10])<<4) + (_16_ vesa_info[0x0e])); - q = modes; - do { - if ((q->mode=_farpeekw(__djgpp_dos_sel, (unsigned long)(p++)))==0xffff) { - break; - } - - r.x.ax = 0x4f01; - r.x.cx = q->mode; - r.x.di = 512; - r.x.es = _stubinfo->ds_segment; - __dpmi_int(0x10, &r); - movedata(_stubinfo->ds_selector, 512, _my_ds(), (unsigned)tmp, 256); - switch (tmp[0x19]) { - case 16: - q->bpp = tmp[0x1f] + tmp[0x21] + tmp[0x23]; - break; - case 15: - case 24: - case 32: - q->bpp = tmp[0x19]; - break; - default: - q->bpp = 0; - } - if ((r.x.ax==0x004f)&&((tmp[0]&0x11)==0x11)&&q->bpp) { - q->xres = _16_ tmp[0x12]; - q->yres = _16_ tmp[0x14]; - q->scanlen = _16_ tmp[0x10]; - hw_granularity = (_16_ tmp[4])<<10; - if (tmp[0]&0x80) { - *(q+1) = *q++; - hw_linearfb = _32_ tmp[0x28]; - q->mode |= 0x4000; - } - if (maxsize<(q->scanlen*q->yres)) { - maxsize = q->scanlen*q->yres; - } - q++; - } - } while (!0); - - if (hw_linearfb) { - maxsize = ((maxsize+0xfffUL)&~0xfffUL); - if (_create_selector(&linear_selector, hw_linearfb, maxsize)) { - return 0; - } - } - if (_create_selector(&banked_selector, 0xa0000, hw_granularity)) { - _remove_selector(&linear_selector); - return 0; - } - - return _16_ vesa_info[4]; - } - } - - return 0; -} - - - -/* - * setup mode - */ -static int vl_setup_mode (vl_mode *p) -{ - if (p->mode&0x4000) { - video_selector = linear_selector; - vl_flip = l_dump_virtual; - } else { - { int n; for (gran_shift=0, n=hw_granularity; n; gran_shift++, n>>=1) ; } - gran_mask = (1<<(--gran_shift)) - 1; - if (hw_granularity!=(gran_mask+1)) { - return -1; - } - video_selector = banked_selector; - vl_flip = b_dump_virtual; - } - -#define INITPTR(bpp) \ - vl_putpixel = v_putpixel##bpp; \ - vl_getrgba = v_getrgba##bpp; \ - vl_clear = v_clear##bpp; \ - vl_mixrgb = vl_mixrgb##bpp; \ - vl_mixrgba = vl_mixrgba##bpp; - - switch (p->bpp) { - case 15: - INITPTR(15); - break; - case 16: - INITPTR(16); - break; - case 24: - INITPTR(24); - break; - case 32: - INITPTR(32); - break; - default: - return -1; - } - -#undef INITPTR - - video_bypp = (p->bpp+7)/8; - video_scanlen = p->scanlen; - - return 0; -} - - - -/* - * shutdown the video engine - */ -void vl_video_exit (int textmode) -{ - if (init) { - if (textmode) { - __asm__("movw $0x3, %%ax; int $0x10":::"%eax"); - } - - _remove_selector(&linear_selector); - _remove_selector(&banked_selector); - - init = !init; - } -} - - - -/* - * initialize video engine - * - * success: 0 - * failure: -1 - */ -int vl_video_init (int width, int height, int bpp) -{ - vl_mode *p, *q; - unsigned int min; - - /* check for prior initialization */ - if (init) { - return 0; - } - - /* initialize hardware */ - if (!(vesa_ver=vl_vesa_init())) { - return -1; - } - init = !init; - - /* search for a mode that fits our request */ - for (min=-1, p=NULL, q=modes; q->mode!=0xffff; q++) { - if ((q->xres>=width)&&(q->yres>=height)&&(q->bpp==bpp)) { - if (min>=(unsigned)(q->xres*q->yres)) { - min = q->xres*q->yres; - p = q; - } - } - } - - if (p) { - vl_setup_mode(p); - __asm__("movw $0x4f02, %%ax; int $0x10"::"b"(p->mode):"%eax"); - return 0; - } else { - /* no suitable mode found, abort */ - vl_video_exit(0); - return -1; - } -} +/* + * Mesa 3-D graphics library + * Version: 4.0 + * + * Copyright (C) 1999 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * DOS/DJGPP device driver for Mesa + * + * Author: Daniel Borca + * Email : dborca@users.sourceforge.net + * Web : http://www.geocities.com/dborca + * + * Thanks to CrazyPyro (Neil Funk) for FakeColor + */ + + +#include + +#include "internal.h" +#include "vesa.h" +#include "vga.h" +#include "null.h" +#include "video.h" + + +static vl_driver *drv; +/* based upon mode specific data: valid entire session */ +int vl_video_selector; +static vl_mode *video_mode; +static int video_scanlen, video_bypp; +/* valid until next buffer */ +void *vl_current_draw_buffer, *vl_current_read_buffer; +int vl_current_stride, vl_current_width, vl_current_height, vl_current_bytes; +int vl_current_offset, vl_current_delta; + + +void (*vl_flip) (void); + + +/* FakeColor data */ +#define R_CNT 6 +#define G_CNT 6 +#define B_CNT 6 + +#define R_BIAS 7 +#define G_BIAS 7 +#define B_BIAS 7 + +static word32 VGAPalette[256]; +word8 array_r[256]; +word8 array_g[256]; +word8 array_b[256]; +word8 tab_16_8[0x10000]; + + +/* lookup table for scaling 5 bit colors up to 8 bits */ +static int _rgb_scale_5[32] = { + 0, 8, 16, 25, 33, 41, 49, 58, + 66, 74, 82, 90, 99, 107, 115, 123, + 132, 140, 148, 156, 165, 173, 181, 189, + 197, 206, 214, 222, 230, 239, 247, 255 +}; + +/* lookup table for scaling 6 bit colors up to 8 bits */ +static int _rgb_scale_6[64] = { + 0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 45, 49, 53, 57, 61, + 65, 69, 73, 77, 81, 85, 89, 93, + 97, 101, 105, 109, 113, 117, 121, 125, + 130, 134, 138, 142, 146, 150, 154, 158, + 162, 166, 170, 174, 178, 182, 186, 190, + 194, 198, 202, 206, 210, 215, 219, 223, + 227, 231, 235, 239, 243, 247, 251, 255 +}; + + +/* Desc: color composition (w/o ALPHA) + * + * In : array of integers (R, G, B) + * Out : color + * + * Note: - + */ +static int +v_mixrgb8fake (const unsigned char rgb[]) +{ + return array_b[rgb[2]]*G_CNT*R_CNT + + array_g[rgb[1]]*R_CNT + + array_r[rgb[0]]; +} + + +/* Desc: color decomposition + * + * In : pixel offset, array of integers to hold color components (R, G, B, A) + * Out : - + * + * Note: uses current read buffer + */ +static void +v_getrgb8fake6 (unsigned int offset, unsigned char rgb[]) +{ + word32 c = VGAPalette[((word8 *)vl_current_read_buffer)[offset]]; + rgb[0] = _rgb_scale_6[(c >> 16) & 0x3F]; + rgb[1] = _rgb_scale_6[(c >> 8) & 0x3F]; + rgb[2] = _rgb_scale_6[ c & 0x3F]; +} +static void +v_getrgb8fake8 (unsigned int offset, unsigned char rgb[]) +{ + word32 c = VGAPalette[((word8 *)vl_current_read_buffer)[offset]]; + rgb[0] = c >> 16; + rgb[1] = c >> 8; + rgb[2] = c; +} + + +/* Desc: create R5G6B5 to FakeColor table lookup + * + * In : - + * Out : - + * + * Note: - + */ +static void +init_tab_16_8 (void) +{ + int i; + for (i = 0; i < 0x10000; i++) { + unsigned char rgb[3]; + rgb[0] = _rgb_scale_5[(i >> 11) & 0x1F]; + rgb[1] = _rgb_scale_6[(i >> 5) & 0x3F]; + rgb[2] = _rgb_scale_5[ i & 0x1F]; + tab_16_8[i] = v_mixrgb8fake(rgb); + } + (void)v_getrgb8fake6; + (void)v_getrgb8fake8; +} + + +/* Desc: set one palette entry + * + * In : index, R, G, B + * Out : - + * + * Note: color components are in range [0.0 .. 1.0] + */ +void +vl_setCI (int index, float red, float green, float blue) +{ + drv->setCI_f(index, red, green, blue); +} + + +/* Desc: set one palette entry + * + * In : color, R, G, B + * Out : - + * + * Note: - + */ +static void +fake_setcolor (int c, int r, int g, int b) +{ + VGAPalette[c] = 0xff000000 | (r<<16) | (g<<8) | b; + + drv->setCI_i(c, r, g, b); +} + + +/* Desc: build FakeColor palette + * + * In : CI precision in bits + * Out : - + * + * Note: - + */ +static void +fake_buildpalette (int bits) +{ + double c_r, c_g, c_b; + int r, g, b, color = 0; + + double max = (1 << bits) - 1; + + for (b = 0; b < B_CNT; ++b) { + for (g = 0; g < G_CNT; ++g) { + for (r = 0; r < R_CNT; ++r) { + c_r = 0.5 + (double)r * (max-R_BIAS) / (R_CNT-1.) + R_BIAS; + c_g = 0.5 + (double)g * (max-G_BIAS) / (G_CNT-1.) + G_BIAS; + c_b = 0.5 + (double)b * (max-B_BIAS) / (B_CNT-1.) + B_BIAS; + fake_setcolor(color++, (int)c_r, (int)c_g, (int)c_b); + } + } + } + + for (color = 0; color < 256; color++) { + c_r = (double)color * R_CNT / 256.; + c_g = (double)color * G_CNT / 256.; + c_b = (double)color * B_CNT / 256.; + array_r[color] = (int)c_r; + array_g[color] = (int)c_g; + array_b[color] = (int)c_b; + } +} + + +/* Desc: initialize hardware + * + * In : - + * Out : list of available modes + * + * Note: when returning non-NULL, global variable `drv' is guaranteed to be ok + */ +static vl_mode * +v_init_hw (void) +{ + static vl_mode *q = NULL; + + if (q == NULL) { + /* are we forced to NUL driver? */ + if (getenv("DMESA_NULDRV")) { + if ((q = NUL.init()) != NULL) { + drv = &NUL; + } + return q; + } + /* initialize hardware */ + if ((q = VESA.init()) != NULL) { + drv = &VESA; + } else if ((q = VGA.init()) != NULL) { + drv = &VGA; + } else { + drv = NULL; + } + } + + return q; +} + + +/* Desc: sync buffer with video hardware + * + * In : ptr to old buffer, position, size + * Out : 0 if success + * + * Note: - + */ +int +vl_sync_buffer (void **buffer, int x, int y, int width, int height) +{ + if ((/*XXX*/width & 7) || (x < 0) || (y < 0) || (x+width > video_mode->xres) || (y+height > video_mode->yres)) { + return -1; + } else { + void *newbuf = *buffer; + + if ((newbuf == NULL) || (vl_current_width != width) || (vl_current_height != height)) { + newbuf = realloc(newbuf, width * height * video_bypp); + } + + if (newbuf == NULL) { + return -2; + } + + vl_current_width = width; + vl_current_height = height; + vl_current_stride = vl_current_width * video_bypp; + vl_current_bytes = vl_current_stride * height; + + vl_current_offset = video_scanlen * y + video_bypp * x; + vl_current_delta = video_scanlen - vl_current_stride; + + vl_current_draw_buffer = vl_current_read_buffer = *buffer = newbuf; + return 0; + } +} + + +/* Desc: state retrieval + * + * In : name, storage + * Out : -1 for an error + * + * Note: - + */ +int +vl_get (int pname, int *params) +{ + switch (pname) { + case VL_GET_SCREEN_SIZE: + params[0] = video_mode->xres; + params[1] = video_mode->yres; + break; + case VL_GET_VIDEO_MODES: { + int n; + vl_mode *q; + if ((q = v_init_hw()) == NULL) { + return -1; + } + /* count available visuals */ + for (n = 0; q->mode != 0xffff; q++) { + if ((q + 1)->mode == (q->mode | 0x4000)) { + /* same mode, but linear */ + q++; + } + if (params) { + params[n] = (int)q; + } + n++; + } + return n; + } + default: + return (drv != NULL) ? drv->get(pname, params) : -1; + } + return 0; +} + + +/* Desc: setup mode + * + * In : ptr to mode definition + * Out : 0 if success + * + * Note: - + */ +static int +vl_setup_mode (vl_mode *p) +{ + if (p == NULL) { + return -1; + } + + switch (p->bpp) { + case 8: + break; + case 15: + break; + case 16: + break; + case 24: + break; + case 32: + break; + default: + return -1; + } + + video_mode = p; + video_bypp = (p->bpp+7)/8; + video_scanlen = p->scanlen; + vl_video_selector = p->sel; + + return 0; +} + + +/* Desc: restore to the mode prior to first call to `vl_video_init'. + * + * In : - + * Out : - + * + * Note: - + */ +void +vl_video_exit (void) +{ + drv->restore(); + drv->fini(); + video_mode = NULL; +} + + +/* Desc: enter mode + * + * In : xres, yres, bits/pixel, RGB, refresh rate + * Out : pixel width in bits if success + * + * Note: - + */ +int +vl_video_init (int width, int height, int bpp, int rgb, int refresh, int fbbits) +{ + int fake; + vl_mode *p, *q; + unsigned int min; + + fake = 0; + if (!rgb) { + bpp = 8; + } else if (bpp == 8) { + fake = 1; + } + + /* initialize hardware */ + if ((q = v_init_hw()) == NULL) { + return 0; + } + + /* search for a mode that fits our request */ + for (min = -1, p = NULL; q->mode != 0xffff; q++) { + if ((q->xres >= width) && (q->yres >= height) && (q->bpp == bpp)) { + if (min >= (unsigned)(q->xres * q->yres)) { + min = q->xres * q->yres; + p = q; + } + } + } + + /* setup and enter mode */ + if ((vl_setup_mode(p) == 0) && (drv->entermode(p, refresh, fbbits) == 0)) { + vl_flip = drv->blit; + if (fake) { + drv->get(VL_GET_CI_PREC, (int *)(&min)); + fake_buildpalette(min); + init_tab_16_8(); + } + return bpp; + } + + /* abort */ + return 0; +}