1/*- 2 * Copyright (c) 1999 Michael Smith <msmith@freebsd.org> 3 * Copyright (c) 1999 Kazutaka YOKOTA <yokota@freebsd.org> 4 * Copyright (c) 1999 Dag-Erling Co�dan Sm�rgrav 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer 12 * in this position and unchanged. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 *
| 1/*- 2 * Copyright (c) 1999 Michael Smith <msmith@freebsd.org> 3 * Copyright (c) 1999 Kazutaka YOKOTA <yokota@freebsd.org> 4 * Copyright (c) 1999 Dag-Erling Co�dan Sm�rgrav 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer 12 * in this position and unchanged. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 *
|
40#include <dev/fb/fbreg.h> 41#include <dev/fb/splashreg.h> 42 43#define FADE_TIMEOUT 300 /* sec */ 44 45static int splash_mode = -1; 46static int splash_on = FALSE; 47 48static int pcx_start(video_adapter_t *adp); 49static int pcx_end(video_adapter_t *adp); 50static int pcx_splash(video_adapter_t *adp, int on); 51static int pcx_init(const char *data, int sdepth); 52static int pcx_draw(video_adapter_t *adp); 53 54static splash_decoder_t pcx_decoder = { 55 "splash_pcx", pcx_start, pcx_end, pcx_splash, SPLASH_IMAGE, 56}; 57 58SPLASH_DECODER(splash_pcx, pcx_decoder); 59 60static struct 61{ 62 int width, height, bpsl; 63 int bpp, planes, zlen; 64 const u_char *zdata, *palette; 65} pcx_info; 66 67static int 68pcx_start(video_adapter_t *adp) 69{ 70 static int modes[] = { 71 M_VGA_CG320, 72 M_VESA_CG640x480, 73 M_VESA_CG800x600, 74 M_VESA_CG1024x768, 75 -1, 76 }; 77 video_info_t info; 78 int i; 79 80 if (pcx_decoder.data == NULL 81 || pcx_decoder.data_size <= 0 82 || pcx_init((u_char *)pcx_decoder.data, pcx_decoder.data_size)) 83 return ENODEV; 84 85 if (bootverbose) 86 printf("splash_pcx: image good:\n" 87 " width = %d\n" 88 " height = %d\n" 89 " depth = %d\n" 90 " planes = %d\n", 91 pcx_info.width, pcx_info.height, 92 pcx_info.bpp, pcx_info.planes); 93 94 for (i = 0; modes[i] >= 0; ++i) { 95 if (get_mode_info(adp, modes[i], &info) != 0) 96 continue; 97 if (bootverbose) 98 printf("splash_pcx: considering mode %d:\n" 99 " vi_width = %d\n" 100 " vi_height = %d\n" 101 " vi_depth = %d\n" 102 " vi_planes = %d\n", 103 modes[i], 104 info.vi_width, info.vi_height, 105 info.vi_depth, info.vi_planes); 106 if (info.vi_width >= pcx_info.width 107 && info.vi_height >= pcx_info.height 108 && info.vi_depth == pcx_info.bpp 109 && info.vi_planes == pcx_info.planes) 110 break; 111 } 112 113 splash_mode = modes[i]; 114 if (splash_mode == -1) 115 return ENODEV; 116 if (bootverbose) 117 printf("pcx_splash: selecting mode %d\n", splash_mode); 118 return 0; 119} 120 121static int 122pcx_end(video_adapter_t *adp) 123{ 124 /* nothing to do */ 125 return 0; 126} 127 128static int 129pcx_splash(video_adapter_t *adp, int on) 130{ 131 if (on) { 132 if (!splash_on) { 133 if (set_video_mode(adp, splash_mode) || pcx_draw(adp)) 134 return 1; 135 splash_on = TRUE; 136 } 137 return 0; 138 } else { 139 splash_on = FALSE; 140 return 0; 141 } 142} 143 144struct pcxheader { 145 u_char manufactor; 146 u_char version; 147 u_char encoding; 148 u_char bpp; 149 u_short xmin, ymin, xmax, ymax; 150 u_short hres, vres; 151 u_char colormap[48]; 152 u_char rsvd; 153 u_char nplanes; 154 u_short bpsl; 155 u_short palinfo; 156 u_short hsize, vsize; 157}; 158 159#define MAXSCANLINE 1024 160 161static int 162pcx_init(const char *data, int size) 163{ 164 const struct pcxheader *hdr; 165 166 hdr = (const struct pcxheader *)data; 167 168 if (size < 128 + 1 + 1 + 768 169 || hdr->manufactor != 10 170 || hdr->version != 5 171 || hdr->encoding != 1 172 || hdr->nplanes != 1 173 || hdr->bpp != 8 174 || hdr->bpsl > MAXSCANLINE 175 || data[size-769] != 12) { 176 printf("splash_pcx: invalid PCX image\n"); 177 return 1; 178 } 179 pcx_info.width = hdr->xmax - hdr->xmin + 1; 180 pcx_info.height = hdr->ymax - hdr->ymin + 1; 181 pcx_info.bpsl = hdr->bpsl; 182 pcx_info.bpp = hdr->bpp; 183 pcx_info.planes = hdr->nplanes; 184 pcx_info.zlen = size - (128 + 1 + 768); 185 pcx_info.zdata = data + 128; 186 pcx_info.palette = data + size - 768; 187 return 0; 188} 189 190static int 191pcx_draw(video_adapter_t *adp) 192{ 193 u_char *vidmem; 194 int swidth, sheight, sbpsl, sdepth, splanes; 195 int banksize, origin; 196 int c, i, j, pos, scan, x, y; 197 u_char line[MAXSCANLINE]; 198 199 if (pcx_info.zlen < 1) 200 return 1; 201 202 load_palette(adp, pcx_info.palette); 203 204 vidmem = (u_char *)adp->va_window; 205 swidth = adp->va_info.vi_width; 206 sheight = adp->va_info.vi_height; 207 sbpsl = adp->va_line_width; 208 sdepth = adp->va_info.vi_depth; 209 splanes = adp->va_info.vi_planes; 210 banksize = adp->va_info.vi_window_size; 211 212 for (origin = 0; origin < sheight*sbpsl; origin += banksize) { 213 set_origin(adp, origin); 214 bzero(vidmem, banksize); 215 } 216 217 x = (swidth - pcx_info.width) / 2; 218 y = (sheight - pcx_info.height) / 2; 219 origin = 0; 220 pos = y * sbpsl + x; 221 while (pos > banksize) { 222 pos -= banksize; 223 origin += banksize; 224 } 225 set_origin(adp, origin); 226 227 for (scan = i = 0; scan < pcx_info.height; ++scan, ++y, pos += sbpsl) { 228 for (j = 0; j < pcx_info.bpsl && i < pcx_info.zlen; ++i) { 229 if ((pcx_info.zdata[i] & 0xc0) == 0xc0) { 230 c = pcx_info.zdata[i++] & 0x3f; 231 if (i >= pcx_info.zlen) 232 return 1; 233 } else { 234 c = 1; 235 } 236 if (j + c > pcx_info.bpsl) 237 return 1; 238 while (c--) 239 line[j++] = pcx_info.zdata[i]; 240 } 241 242 if (pos > banksize) { 243 origin += banksize; 244 pos -= banksize; 245 set_origin(adp, origin); 246 } 247 248 if (pos + pcx_info.width > banksize) { 249 /* scanline crosses bank boundary */ 250 j = banksize - pos; 251 bcopy(line, vidmem + pos, j); 252 origin += banksize; 253 pos -= banksize; 254 set_origin(adp, origin); 255 bcopy(line + j, vidmem, pcx_info.width - j); 256 } else { 257 bcopy(line, vidmem + pos, pcx_info.width); 258 } 259 } 260 261 return 0; 262}
| 39#include <dev/fb/fbreg.h> 40#include <dev/fb/splashreg.h> 41 42#define FADE_TIMEOUT 300 /* sec */ 43 44static int splash_mode = -1; 45static int splash_on = FALSE; 46 47static int pcx_start(video_adapter_t *adp); 48static int pcx_end(video_adapter_t *adp); 49static int pcx_splash(video_adapter_t *adp, int on); 50static int pcx_init(const char *data, int sdepth); 51static int pcx_draw(video_adapter_t *adp); 52 53static splash_decoder_t pcx_decoder = { 54 "splash_pcx", pcx_start, pcx_end, pcx_splash, SPLASH_IMAGE, 55}; 56 57SPLASH_DECODER(splash_pcx, pcx_decoder); 58 59static struct 60{ 61 int width, height, bpsl; 62 int bpp, planes, zlen; 63 const u_char *zdata, *palette; 64} pcx_info; 65 66static int 67pcx_start(video_adapter_t *adp) 68{ 69 static int modes[] = { 70 M_VGA_CG320, 71 M_VESA_CG640x480, 72 M_VESA_CG800x600, 73 M_VESA_CG1024x768, 74 -1, 75 }; 76 video_info_t info; 77 int i; 78 79 if (pcx_decoder.data == NULL 80 || pcx_decoder.data_size <= 0 81 || pcx_init((u_char *)pcx_decoder.data, pcx_decoder.data_size)) 82 return ENODEV; 83 84 if (bootverbose) 85 printf("splash_pcx: image good:\n" 86 " width = %d\n" 87 " height = %d\n" 88 " depth = %d\n" 89 " planes = %d\n", 90 pcx_info.width, pcx_info.height, 91 pcx_info.bpp, pcx_info.planes); 92 93 for (i = 0; modes[i] >= 0; ++i) { 94 if (get_mode_info(adp, modes[i], &info) != 0) 95 continue; 96 if (bootverbose) 97 printf("splash_pcx: considering mode %d:\n" 98 " vi_width = %d\n" 99 " vi_height = %d\n" 100 " vi_depth = %d\n" 101 " vi_planes = %d\n", 102 modes[i], 103 info.vi_width, info.vi_height, 104 info.vi_depth, info.vi_planes); 105 if (info.vi_width >= pcx_info.width 106 && info.vi_height >= pcx_info.height 107 && info.vi_depth == pcx_info.bpp 108 && info.vi_planes == pcx_info.planes) 109 break; 110 } 111 112 splash_mode = modes[i]; 113 if (splash_mode == -1) 114 return ENODEV; 115 if (bootverbose) 116 printf("pcx_splash: selecting mode %d\n", splash_mode); 117 return 0; 118} 119 120static int 121pcx_end(video_adapter_t *adp) 122{ 123 /* nothing to do */ 124 return 0; 125} 126 127static int 128pcx_splash(video_adapter_t *adp, int on) 129{ 130 if (on) { 131 if (!splash_on) { 132 if (set_video_mode(adp, splash_mode) || pcx_draw(adp)) 133 return 1; 134 splash_on = TRUE; 135 } 136 return 0; 137 } else { 138 splash_on = FALSE; 139 return 0; 140 } 141} 142 143struct pcxheader { 144 u_char manufactor; 145 u_char version; 146 u_char encoding; 147 u_char bpp; 148 u_short xmin, ymin, xmax, ymax; 149 u_short hres, vres; 150 u_char colormap[48]; 151 u_char rsvd; 152 u_char nplanes; 153 u_short bpsl; 154 u_short palinfo; 155 u_short hsize, vsize; 156}; 157 158#define MAXSCANLINE 1024 159 160static int 161pcx_init(const char *data, int size) 162{ 163 const struct pcxheader *hdr; 164 165 hdr = (const struct pcxheader *)data; 166 167 if (size < 128 + 1 + 1 + 768 168 || hdr->manufactor != 10 169 || hdr->version != 5 170 || hdr->encoding != 1 171 || hdr->nplanes != 1 172 || hdr->bpp != 8 173 || hdr->bpsl > MAXSCANLINE 174 || data[size-769] != 12) { 175 printf("splash_pcx: invalid PCX image\n"); 176 return 1; 177 } 178 pcx_info.width = hdr->xmax - hdr->xmin + 1; 179 pcx_info.height = hdr->ymax - hdr->ymin + 1; 180 pcx_info.bpsl = hdr->bpsl; 181 pcx_info.bpp = hdr->bpp; 182 pcx_info.planes = hdr->nplanes; 183 pcx_info.zlen = size - (128 + 1 + 768); 184 pcx_info.zdata = data + 128; 185 pcx_info.palette = data + size - 768; 186 return 0; 187} 188 189static int 190pcx_draw(video_adapter_t *adp) 191{ 192 u_char *vidmem; 193 int swidth, sheight, sbpsl, sdepth, splanes; 194 int banksize, origin; 195 int c, i, j, pos, scan, x, y; 196 u_char line[MAXSCANLINE]; 197 198 if (pcx_info.zlen < 1) 199 return 1; 200 201 load_palette(adp, pcx_info.palette); 202 203 vidmem = (u_char *)adp->va_window; 204 swidth = adp->va_info.vi_width; 205 sheight = adp->va_info.vi_height; 206 sbpsl = adp->va_line_width; 207 sdepth = adp->va_info.vi_depth; 208 splanes = adp->va_info.vi_planes; 209 banksize = adp->va_info.vi_window_size; 210 211 for (origin = 0; origin < sheight*sbpsl; origin += banksize) { 212 set_origin(adp, origin); 213 bzero(vidmem, banksize); 214 } 215 216 x = (swidth - pcx_info.width) / 2; 217 y = (sheight - pcx_info.height) / 2; 218 origin = 0; 219 pos = y * sbpsl + x; 220 while (pos > banksize) { 221 pos -= banksize; 222 origin += banksize; 223 } 224 set_origin(adp, origin); 225 226 for (scan = i = 0; scan < pcx_info.height; ++scan, ++y, pos += sbpsl) { 227 for (j = 0; j < pcx_info.bpsl && i < pcx_info.zlen; ++i) { 228 if ((pcx_info.zdata[i] & 0xc0) == 0xc0) { 229 c = pcx_info.zdata[i++] & 0x3f; 230 if (i >= pcx_info.zlen) 231 return 1; 232 } else { 233 c = 1; 234 } 235 if (j + c > pcx_info.bpsl) 236 return 1; 237 while (c--) 238 line[j++] = pcx_info.zdata[i]; 239 } 240 241 if (pos > banksize) { 242 origin += banksize; 243 pos -= banksize; 244 set_origin(adp, origin); 245 } 246 247 if (pos + pcx_info.width > banksize) { 248 /* scanline crosses bank boundary */ 249 j = banksize - pos; 250 bcopy(line, vidmem + pos, j); 251 origin += banksize; 252 pos -= banksize; 253 set_origin(adp, origin); 254 bcopy(line + j, vidmem, pcx_info.width - j); 255 } else { 256 bcopy(line, vidmem + pos, pcx_info.width); 257 } 258 } 259 260 return 0; 261}
|