PCX loader for pseudo-device splash.
This commit is contained in:
parent
791f19da95
commit
2dc3d69d77
262
sys/dev/fb/splash_pcx.c
Normal file
262
sys/dev/fb/splash_pcx.c
Normal file
@ -0,0 +1,262 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/linker.h>
|
||||
|
||||
#include <machine/console.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(const 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, *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(const 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_info.vi_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;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
# $Id: $
|
||||
# $Id: Makefile,v 1.1 1999/01/11 03:34:52 yokota Exp $
|
||||
|
||||
SUBDIR= bmp
|
||||
SUBDIR= bmp pcx
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
|
8
sys/modules/splash/pcx/Makefile
Normal file
8
sys/modules/splash/pcx/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
# $Id$
|
||||
|
||||
KMOD= splash_pcx
|
||||
SRCS= splash_pcx
|
||||
|
||||
NOMAN=
|
||||
|
||||
.include <bsd.kmod.mk>
|
262
sys/modules/splash/pcx/splash_pcx.c
Normal file
262
sys/modules/splash/pcx/splash_pcx.c
Normal file
@ -0,0 +1,262 @@
|
||||
/*-
|
||||
* 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/linker.h>
|
||||
|
||||
#include <machine/console.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(const 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, *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(const 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_info.vi_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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user