summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/modules/splash/bmp/Makefile2
-rw-r--r--sys/modules/splash/bmp/splash_bmp.c643
-rw-r--r--sys/modules/splash/pcx/Makefile2
-rw-r--r--sys/modules/splash/pcx/splash_pcx.c263
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;
-}
OpenPOWER on IntegriCloud