diff options
-rw-r--r-- | sys/modules/splash/bmp/Makefile | 2 | ||||
-rw-r--r-- | sys/modules/splash/bmp/splash_bmp.c | 643 | ||||
-rw-r--r-- | sys/modules/splash/pcx/Makefile | 2 | ||||
-rw-r--r-- | sys/modules/splash/pcx/splash_pcx.c | 263 |
4 files changed, 4 insertions, 906 deletions
diff --git a/sys/modules/splash/bmp/Makefile b/sys/modules/splash/bmp/Makefile index 834ed76..a169fdf 100644 --- a/sys/modules/splash/bmp/Makefile +++ b/sys/modules/splash/bmp/Makefile @@ -1,5 +1,7 @@ # $FreeBSD$ +.PATH: ${.CURDIR}/../../../dev/fb + KMOD= splash_bmp SRCS= splash_bmp.c diff --git a/sys/modules/splash/bmp/splash_bmp.c b/sys/modules/splash/bmp/splash_bmp.c deleted file mode 100644 index ca4885c..0000000 --- a/sys/modules/splash/bmp/splash_bmp.c +++ /dev/null @@ -1,643 +0,0 @@ -/*- - * Copyright (c) 1999 Michael Smith <msmith@freebsd.org> - * Copyright (c) 1999 Kazutaka YOKOTA <yokota@freebsd.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/linker.h> -#include <sys/fbio.h> - -#include <dev/fb/fbreg.h> -#include <dev/fb/splashreg.h> -#ifndef PC98 -#include <dev/fb/vgareg.h> - -#include <isa/isareg.h> -#endif - -#define FADE_TIMEOUT 15 /* sec */ -#define FADE_LEVELS 10 - -static int splash_mode = -1; -static int splash_on = FALSE; - -static int bmp_start(video_adapter_t *adp); -static int bmp_end(video_adapter_t *adp); -static int bmp_splash(video_adapter_t *adp, int on); -static int bmp_Init(char *data, int swidth, int sheight, int sdepth); -static int bmp_Draw(video_adapter_t *adp); - -static splash_decoder_t bmp_decoder = { - "splash_bmp", bmp_start, bmp_end, bmp_splash, SPLASH_IMAGE, -}; - -SPLASH_DECODER(splash_bmp, bmp_decoder); - -static int -bmp_start(video_adapter_t *adp) -{ - /* currently only 256-color modes are supported XXX */ - static int modes[] = { -#ifdef PC98 - /* - * As 640x400 doesn't generally look great, - * it's least preferred here. - */ - M_PC98_PEGC640x400, - M_PC98_PEGC640x480, - M_PC98_EGC640x400, -#else - M_VESA_CG640x480, - M_VESA_CG800x600, - M_VESA_CG1024x768, - M_CG640x480, - /* - * As 320x200 doesn't generally look great, - * it's least preferred here. - */ - M_VGA_CG320, -#endif - -1, - }; - video_info_t info; - int i; - - if ((bmp_decoder.data == NULL) || (bmp_decoder.data_size <= 0)) { - printf("splash_bmp: No bitmap file found\n"); - return ENODEV; - } - for (i = 0; modes[i] >= 0; ++i) { - if (((*vidsw[adp->va_index]->get_info)(adp, modes[i], &info) == 0) - && (bmp_Init((u_char *)bmp_decoder.data, - info.vi_width, info.vi_height, info.vi_depth) == 0)) - break; - } - splash_mode = modes[i]; - if (splash_mode < 0) - printf("splash_bmp: No appropriate video mode found\n"); - if (bootverbose) - printf("bmp_start(): splash_mode:%d\n", splash_mode); - return ((splash_mode < 0) ? ENODEV : 0); -} - -static int -bmp_end(video_adapter_t *adp) -{ - /* nothing to do */ - return 0; -} - -static int -bmp_splash(video_adapter_t *adp, int on) -{ - static u_char pal[256*3]; - static long time_stamp; - u_char tpal[256*3]; - static int fading = TRUE, brightness = FADE_LEVELS; - struct timeval tv; - int i; - - if (on) { - if (!splash_on) { - /* set up the video mode and draw something */ - if ((*vidsw[adp->va_index]->set_mode)(adp, splash_mode)) - return 1; - if (bmp_Draw(adp)) - return 1; - (*vidsw[adp->va_index]->save_palette)(adp, pal); - time_stamp = 0; - splash_on = TRUE; - } - /* - * This is a kludge to fade the image away. This section of the - * code takes effect only after the system is completely up. - * FADE_TIMEOUT should be configurable. - */ - if (!cold) { - getmicrotime(&tv); - if (time_stamp == 0) - time_stamp = tv.tv_sec; - if (tv.tv_sec > time_stamp + FADE_TIMEOUT) { - if (fading) - if (brightness == 0) { - fading = FALSE; - brightness++; - } - else brightness--; - else - if (brightness == FADE_LEVELS) { - fading = TRUE; - brightness--; - } - else brightness++; - for (i = 0; i < sizeof(pal); ++i) { - tpal[i] = pal[i] * brightness / FADE_LEVELS; - } - (*vidsw[adp->va_index]->load_palette)(adp, tpal); - time_stamp = tv.tv_sec; - } - } - return 0; - } else { - /* the video mode will be restored by the caller */ - splash_on = FALSE; - return 0; - } -} - -/* -** Code to handle Microsoft DIB (".BMP") format images. -** -** Blame me (msmith@freebsd.org) if this is broken, not Soren. -*/ - -typedef struct tagBITMAPFILEHEADER { /* bmfh */ - u_short bfType __packed; - int bfSize __packed; - u_short bfReserved1 __packed; - u_short bfReserved2 __packed; - int bfOffBits __packed; -} BITMAPFILEHEADER; - -typedef struct tagBITMAPINFOHEADER { /* bmih */ - int biSize __packed; - int biWidth __packed; - int biHeight __packed; - short biPlanes __packed; - short biBitCount __packed; - int biCompression __packed; - int biSizeImage __packed; - int biXPelsPerMeter __packed; - int biYPelsPerMeter __packed; - int biClrUsed __packed; - int biClrImportant __packed; -} BITMAPINFOHEADER; - -typedef struct tagRGBQUAD { /* rgbq */ - u_char rgbBlue __packed; - u_char rgbGreen __packed; - u_char rgbRed __packed; - u_char rgbReserved __packed; -} RGBQUAD; - -typedef struct tagBITMAPINFO { /* bmi */ - BITMAPINFOHEADER bmiHeader __packed; - RGBQUAD bmiColors[256] __packed; -} BITMAPINFO; - -typedef struct tagBITMAPF -{ - BITMAPFILEHEADER bmfh __packed; - BITMAPINFO bmfi __packed; -} BITMAPF; - -#define BI_RGB 0 -#define BI_RLE8 1 -#define BI_RLE4 2 - -/* -** all we actually care about the image -*/ -typedef struct -{ - int width,height; /* image dimensions */ - int swidth,sheight; /* screen dimensions for the current mode */ - u_char depth; /* image depth (1, 4, 8, 24 bits) */ - u_char sdepth; /* screen depth (1, 4, 8 bpp) */ - int ncols; /* number of colours */ - u_char palette[256][3]; /* raw palette data */ - u_char format; /* one of the BI_* constants above */ - u_char *data; /* pointer to the raw data */ - u_char *index; /* running pointer to the data while drawing */ - u_char *vidmem; /* video memory allocated for drawing */ - video_adapter_t *adp; - int bank; -#ifdef PC98 - u_char prev_val; -#endif -} BMP_INFO; - -static BMP_INFO bmp_info; - -/* -** bmp_SetPix -** -** Given (info), set the pixel at (x),(y) to (val) -** -*/ -static void -bmp_SetPix(BMP_INFO *info, int x, int y, u_char val) -{ - int sofs, bofs; - int newbank; - - /* - * range check to avoid explosions - */ - if ((x < 0) || (x >= info->swidth) || (y < 0) || (y >= info->sheight)) - return; - - /* - * calculate offset into video memory; - * because 0,0 is bottom-left for DIB, we have to convert. - */ - sofs = ((info->height - (y+1) + (info->sheight - info->height) / 2) - * info->adp->va_line_width); - x += (info->swidth - info->width) / 2; - - switch(info->sdepth) { -#ifdef PC98 - case 4: - sofs += (x >> 3); - bofs = x & 0x7; /* offset within byte */ - - outb(0x7c, 0x80 | 0x40); /* GRCG on & RMW mode */ - if (val != info->prev_val) { - outb(0x7e, (val & 1) ? 0xff : 0); /* tile B */ - outb(0x7e, (val & 2) ? 0xff : 0); /* tile R */ - outb(0x7e, (val & 4) ? 0xff : 0); /* tile G */ - outb(0x7e, (val & 8) ? 0xff : 0); /* tile I */ - - info->prev_val = val; - } - - *(info->vidmem+sofs) = (0x80 >> bofs); /* write new bit */ - outb(0x7c, 0); /* GRCG off */ - break; -#else - case 4: - case 1: - /* EGA/VGA planar modes */ - sofs += (x >> 3); - newbank = sofs/info->adp->va_window_size; - if (info->bank != newbank) { - (*vidsw[info->adp->va_index]->set_win_org)(info->adp, newbank*info->adp->va_window_size); - info->bank = newbank; - } - sofs %= info->adp->va_window_size; - bofs = x & 0x7; /* offset within byte */ - outw(GDCIDX, (0x8000 >> bofs) | 0x08); /* bit mask */ - outw(GDCIDX, (val << 8) | 0x00); /* set/reset */ - *(info->vidmem + sofs) ^= 0xff; /* read-modify-write */ - break; -#endif - - case 8: - sofs += x; - newbank = sofs/info->adp->va_window_size; - if (info->bank != newbank) { - (*vidsw[info->adp->va_index]->set_win_org)(info->adp, newbank*info->adp->va_window_size); - info->bank = newbank; - } - sofs %= info->adp->va_window_size; - *(info->vidmem+sofs) = val; - break; - } -} - -/* -** bmp_DecodeRLE4 -** -** Given (data) pointing to a line of RLE4-format data and (line) being the starting -** line onscreen, decode the line. -*/ -static void -bmp_DecodeRLE4(BMP_INFO *info, int line) -{ - int count; /* run count */ - u_char val; - int x,y; /* screen position */ - - x = 0; /* starting position */ - y = line; - - /* loop reading data */ - for (;;) { - /* - * encoded mode starts with a run length, and then a byte with - * two colour indexes to alternate between for the run - */ - if (*info->index) { - for (count = 0; count < *info->index; count++, x++) { - if (count & 1) { /* odd count, low nybble */ - bmp_SetPix(info, x, y, *(info->index+1) & 0x0f); - } else { /* even count, high nybble */ - bmp_SetPix(info, x, y, (*(info->index+1) >>4) & 0x0f); - } - } - info->index += 2; - /* - * A leading zero is an escape; it may signal the end of the - * bitmap, a cursor move, or some absolute data. - */ - } else { /* zero tag may be absolute mode or an escape */ - switch (*(info->index+1)) { - case 0: /* end of line */ - info->index += 2; - return; - case 1: /* end of bitmap */ - info->index = NULL; - return; - case 2: /* move */ - x += *(info->index + 2); /* new coords */ - y += *(info->index + 3); - info->index += 4; - break; - default: /* literal bitmap data */ - for (count = 0; count < *(info->index + 1); count++, x++) { - val = *(info->index + 2 + (count / 2)); /* byte with nybbles */ - if (count & 1) { - val &= 0xf; /* get low nybble */ - } else { - val = (val >> 4); /* get high nybble */ - } - bmp_SetPix(info, x, y, val); - } - /* warning, this depends on integer truncation, do not hand-optimise! */ - info->index += 2 + ((count + 3) / 4) * 2; - break; - } - } - } -} - -/* -** bmp_DecodeRLE8 -** Given (data) pointing to a line of RLE8-format data and (line) being the starting -** line onscreen, decode the line. -*/ -static void -bmp_DecodeRLE8(BMP_INFO *info, int line) -{ - int count; /* run count */ - int x,y; /* screen position */ - - x = 0; /* starting position */ - y = line; - - /* loop reading data */ - for(;;) { - /* - * encoded mode starts with a run length, and then a byte with - * two colour indexes to alternate between for the run - */ - if (*info->index) { - for (count = 0; count < *info->index; count++, x++) - bmp_SetPix(info, x, y, *(info->index+1)); - info->index += 2; - /* - * A leading zero is an escape; it may signal the end of the - * bitmap, a cursor move, or some absolute data. - */ - } else { /* zero tag may be absolute mode or an escape */ - switch(*(info->index+1)) { - case 0: /* end of line */ - info->index += 2; - return; - case 1: /* end of bitmap */ - info->index = NULL; - return; - case 2: /* move */ - x += *(info->index + 2); /* new coords */ - y += *(info->index + 3); - info->index += 4; - break; - default: /* literal bitmap data */ - for (count = 0; count < *(info->index + 1); count++, x++) - bmp_SetPix(info, x, y, *(info->index + 2 + count)); - /* must be an even count */ - info->index += 2 + count + (count & 1); - break; - } - } - } -} - -/* -** bmp_DecodeLine -** -** Given (info) pointing to an image being decoded, (line) being the line currently -** being displayed, decode a line of data. -*/ -static void -bmp_DecodeLine(BMP_INFO *info, int line) -{ - int x; - u_char val, mask, *p; - - switch(info->format) { - case BI_RGB: - switch(info->depth) { - case 8: - for (x = 0; x < info->width; x++, info->index++) - bmp_SetPix(info, x, line, *info->index); - info->index += 3 - (--x % 4); - break; - case 4: - p = info->index; - for (x = 0; x < info->width; x++) { - if (x & 1) { - val = *p & 0xf; /* get low nybble */ - p++; - } else { - val = *p >> 4; /* get high nybble */ - } - bmp_SetPix(info, x, line, val); - } - /* warning, this depends on integer truncation, do not hand-optimise! */ - info->index += ((x + 7) / 8) * 4; - break; - case 1: - p = info->index; - mask = 0x80; - for (x = 0; x < info->width; x++) { - val = (*p & mask) ? 1 : 0; - mask >>= 1; - if (mask == 0) { - mask = 0x80; - p++; - } - bmp_SetPix(info, x, line, val); - } - /* warning, this depends on integer truncation, do not hand-optimise! */ - info->index += ((x + 31) / 32) * 4; - break; - } - break; - case BI_RLE4: - bmp_DecodeRLE4(info, line); - break; - case BI_RLE8: - bmp_DecodeRLE8(info, line); - break; - } -} - -/* -** bmp_Init -** -** Given a pointer (data) to the image of a BMP file, fill in bmp_info with what -** can be learnt from it. Return nonzero if the file isn't usable. -** -** Take screen dimensions (swidth), (sheight) and (sdepth) and make sure we -** can work with these. -*/ -static int -bmp_Init(char *data, int swidth, int sheight, int sdepth) -{ - BITMAPF *bmf = (BITMAPF *)data; - int pind; - - bmp_info.data = NULL; /* assume setup failed */ - - /* check file ID */ - if (bmf->bmfh.bfType != 0x4d42) { - printf("splash_bmp: not a BMP file\n"); - return(1); /* XXX check word ordering for big-endian ports? */ - } - - /* do we understand this bitmap format? */ - if (bmf->bmfi.bmiHeader.biSize > sizeof(bmf->bmfi.bmiHeader)) { - printf("splash_bmp: unsupported BMP format (size=%d)\n", - bmf->bmfi.bmiHeader.biSize); - return(1); - } - - /* save what we know about the screen */ - bmp_info.swidth = swidth; - bmp_info.sheight = sheight; - bmp_info.sdepth = sdepth; - - /* where's the data? */ - bmp_info.data = (u_char *)data + bmf->bmfh.bfOffBits; - - /* image parameters */ - bmp_info.width = bmf->bmfi.bmiHeader.biWidth; - bmp_info.height = bmf->bmfi.bmiHeader.biHeight; - bmp_info.depth = bmf->bmfi.bmiHeader.biBitCount; - bmp_info.format = bmf->bmfi.bmiHeader.biCompression; - - switch(bmp_info.format) { /* check compression format */ - case BI_RGB: - case BI_RLE4: - case BI_RLE8: - break; - default: - printf("splash_bmp: unsupported compression format\n"); - return(1); /* unsupported compression format */ - } - - /* palette details */ - bmp_info.ncols = (bmf->bmfi.bmiHeader.biClrUsed); - bzero(bmp_info.palette,sizeof(bmp_info.palette)); - if (bmp_info.ncols == 0) { /* uses all of them */ - bmp_info.ncols = 1 << bmf->bmfi.bmiHeader.biBitCount; - } - if ((bmp_info.height > bmp_info.sheight) || - (bmp_info.width > bmp_info.swidth) || - (bmp_info.ncols > (1 << sdepth))) { - if (bootverbose) - printf("splash_bmp: beyond screen capacity (%dx%d, %d colors)\n", - bmp_info.width, bmp_info.height, bmp_info.ncols); - return(1); - } - - /* read palette */ - for (pind = 0; pind < bmp_info.ncols; pind++) { - bmp_info.palette[pind][0] = bmf->bmfi.bmiColors[pind].rgbRed; - bmp_info.palette[pind][1] = bmf->bmfi.bmiColors[pind].rgbGreen; - bmp_info.palette[pind][2] = bmf->bmfi.bmiColors[pind].rgbBlue; - } - return(0); -} - -/* -** bmp_Draw -** -** Render the image. Return nonzero if that's not possible. -** -*/ -static int -bmp_Draw(video_adapter_t *adp) -{ - int line; -#if 0 -#ifndef PC98 - int i; -#endif -#endif - - if (bmp_info.data == NULL) { /* init failed, do nothing */ - return(1); - } - - /* clear the screen */ - bmp_info.vidmem = (u_char *)adp->va_window; - bmp_info.adp = adp; - (*vidsw[adp->va_index]->clear)(adp); - (*vidsw[adp->va_index]->set_win_org)(adp, 0); - bmp_info.bank = 0; - - /* initialise the info structure for drawing */ - bmp_info.index = bmp_info.data; -#ifdef PC98 - bmp_info.prev_val = 255; -#endif - - /* set the palette for our image */ - (*vidsw[adp->va_index]->load_palette)(adp, (u_char *)&bmp_info.palette); - -#if 0 -#ifndef PC98 - /* XXX: this is ugly, but necessary for EGA/VGA 1bpp/4bpp modes */ - if ((adp->va_type == KD_EGA) || (adp->va_type == KD_VGA)) { - inb(adp->va_crtc_addr + 6); /* reset flip-flop */ - outb(ATC, 0x14); - outb(ATC, 0); - for (i = 0; i < 16; ++i) { - outb(ATC, i); - outb(ATC, i); - } - inb(adp->va_crtc_addr + 6); /* reset flip-flop */ - outb(ATC, 0x20); /* enable palette */ - - outw(GDCIDX, 0x0f01); /* set/reset enable */ - - if (bmp_info.sdepth == 1) - outw(TSIDX, 0x0102); /* unmask plane #0 */ - } -#endif -#endif - - for (line = 0; (line < bmp_info.height) && bmp_info.index; line++) { - bmp_DecodeLine(&bmp_info, line); - } - return(0); -} diff --git a/sys/modules/splash/pcx/Makefile b/sys/modules/splash/pcx/Makefile index 597852c..188dafc 100644 --- a/sys/modules/splash/pcx/Makefile +++ b/sys/modules/splash/pcx/Makefile @@ -1,5 +1,7 @@ # $FreeBSD$ +.PATH: ${.CURDIR}/../../../dev/fb + KMOD= splash_pcx SRCS= splash_pcx.c diff --git a/sys/modules/splash/pcx/splash_pcx.c b/sys/modules/splash/pcx/splash_pcx.c deleted file mode 100644 index 92dceb4..0000000 --- a/sys/modules/splash/pcx/splash_pcx.c +++ /dev/null @@ -1,263 +0,0 @@ -/*- - * Copyright (c) 1999 Michael Smith <msmith@freebsd.org> - * Copyright (c) 1999 Kazutaka YOKOTA <yokota@freebsd.org> - * Copyright (c) 1999 Dag-Erling Coïdan Smørgrav - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer - * in this position and unchanged. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/linker.h> -#include <sys/module.h> -#include <sys/fbio.h> - -#include <dev/fb/fbreg.h> -#include <dev/fb/splashreg.h> - -#define FADE_TIMEOUT 300 /* sec */ - -static int splash_mode = -1; -static int splash_on = FALSE; - -static int pcx_start(video_adapter_t *adp); -static int pcx_end(video_adapter_t *adp); -static int pcx_splash(video_adapter_t *adp, int on); -static int pcx_init(char *data, int sdepth); -static int pcx_draw(video_adapter_t *adp); - -static splash_decoder_t pcx_decoder = { - "splash_pcx", pcx_start, pcx_end, pcx_splash, SPLASH_IMAGE, -}; - -SPLASH_DECODER(splash_pcx, pcx_decoder); - -static struct -{ - int width, height, bpsl; - int bpp, planes, zlen; - const u_char *zdata; - u_char *palette; -} pcx_info; - -static int -pcx_start(video_adapter_t *adp) -{ - static int modes[] = { - M_VGA_CG320, - M_VESA_CG640x480, - M_VESA_CG800x600, - M_VESA_CG1024x768, - -1, - }; - video_info_t info; - int i; - - if (pcx_decoder.data == NULL - || pcx_decoder.data_size <= 0 - || pcx_init((u_char *)pcx_decoder.data, pcx_decoder.data_size)) - return ENODEV; - - if (bootverbose) - printf("splash_pcx: image good:\n" - " width = %d\n" - " height = %d\n" - " depth = %d\n" - " planes = %d\n", - pcx_info.width, pcx_info.height, - pcx_info.bpp, pcx_info.planes); - - for (i = 0; modes[i] >= 0; ++i) { - if (get_mode_info(adp, modes[i], &info) != 0) - continue; - if (bootverbose) - printf("splash_pcx: considering mode %d:\n" - " vi_width = %d\n" - " vi_height = %d\n" - " vi_depth = %d\n" - " vi_planes = %d\n", - modes[i], - info.vi_width, info.vi_height, - info.vi_depth, info.vi_planes); - if (info.vi_width >= pcx_info.width - && info.vi_height >= pcx_info.height - && info.vi_depth == pcx_info.bpp - && info.vi_planes == pcx_info.planes) - break; - } - - splash_mode = modes[i]; - if (splash_mode == -1) - return ENODEV; - if (bootverbose) - printf("pcx_splash: selecting mode %d\n", splash_mode); - return 0; -} - -static int -pcx_end(video_adapter_t *adp) -{ - /* nothing to do */ - return 0; -} - -static int -pcx_splash(video_adapter_t *adp, int on) -{ - if (on) { - if (!splash_on) { - if (set_video_mode(adp, splash_mode) || pcx_draw(adp)) - return 1; - splash_on = TRUE; - } - return 0; - } else { - splash_on = FALSE; - return 0; - } -} - -struct pcxheader { - u_char manufactor; - u_char version; - u_char encoding; - u_char bpp; - u_short xmin, ymin, xmax, ymax; - u_short hres, vres; - u_char colormap[48]; - u_char rsvd; - u_char nplanes; - u_short bpsl; - u_short palinfo; - u_short hsize, vsize; -}; - -#define MAXSCANLINE 1024 - -static int -pcx_init(char *data, int size) -{ - const struct pcxheader *hdr; - - hdr = (const struct pcxheader *)data; - - if (size < 128 + 1 + 1 + 768 - || hdr->manufactor != 10 - || hdr->version != 5 - || hdr->encoding != 1 - || hdr->nplanes != 1 - || hdr->bpp != 8 - || hdr->bpsl > MAXSCANLINE - || data[size-769] != 12) { - printf("splash_pcx: invalid PCX image\n"); - return 1; - } - pcx_info.width = hdr->xmax - hdr->xmin + 1; - pcx_info.height = hdr->ymax - hdr->ymin + 1; - pcx_info.bpsl = hdr->bpsl; - pcx_info.bpp = hdr->bpp; - pcx_info.planes = hdr->nplanes; - pcx_info.zlen = size - (128 + 1 + 768); - pcx_info.zdata = data + 128; - pcx_info.palette = data + size - 768; - return 0; -} - -static int -pcx_draw(video_adapter_t *adp) -{ - u_char *vidmem; - int swidth, sheight, sbpsl, sdepth, splanes; - int banksize, origin; - int c, i, j, pos, scan, x, y; - u_char line[MAXSCANLINE]; - - if (pcx_info.zlen < 1) - return 1; - - load_palette(adp, pcx_info.palette); - - vidmem = (u_char *)adp->va_window; - swidth = adp->va_info.vi_width; - sheight = adp->va_info.vi_height; - sbpsl = adp->va_line_width; - sdepth = adp->va_info.vi_depth; - splanes = adp->va_info.vi_planes; - banksize = adp->va_window_size; - - for (origin = 0; origin < sheight*sbpsl; origin += banksize) { - set_origin(adp, origin); - bzero(vidmem, banksize); - } - - x = (swidth - pcx_info.width) / 2; - y = (sheight - pcx_info.height) / 2; - origin = 0; - pos = y * sbpsl + x; - while (pos > banksize) { - pos -= banksize; - origin += banksize; - } - set_origin(adp, origin); - - for (scan = i = 0; scan < pcx_info.height; ++scan, ++y, pos += sbpsl) { - for (j = 0; j < pcx_info.bpsl && i < pcx_info.zlen; ++i) { - if ((pcx_info.zdata[i] & 0xc0) == 0xc0) { - c = pcx_info.zdata[i++] & 0x3f; - if (i >= pcx_info.zlen) - return 1; - } else { - c = 1; - } - if (j + c > pcx_info.bpsl) - return 1; - while (c--) - line[j++] = pcx_info.zdata[i]; - } - - if (pos > banksize) { - origin += banksize; - pos -= banksize; - set_origin(adp, origin); - } - - if (pos + pcx_info.width > banksize) { - /* scanline crosses bank boundary */ - j = banksize - pos; - bcopy(line, vidmem + pos, j); - origin += banksize; - pos -= banksize; - set_origin(adp, origin); - bcopy(line + j, vidmem, pcx_info.width - j); - } else { - bcopy(line, vidmem + pos, pcx_info.width); - } - } - - return 0; -} |