142506Syokota/*- 242506Syokota * Copyright (c) 1999 Michael Smith <msmith@freebsd.org> 342506Syokota * Copyright (c) 1999 Kazutaka YOKOTA <yokota@freebsd.org> 442506Syokota * All rights reserved. 542506Syokota * 642506Syokota * Redistribution and use in source and binary forms, with or without 742506Syokota * modification, are permitted provided that the following conditions 842506Syokota * are met: 942506Syokota * 1. Redistributions of source code must retain the above copyright 1042506Syokota * notice, this list of conditions and the following disclaimer. 1142506Syokota * 2. Redistributions in binary form must reproduce the above copyright 1242506Syokota * notice, this list of conditions and the following disclaimer in the 1342506Syokota * documentation and/or other materials provided with the distribution. 1442506Syokota * 1542506Syokota * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 1642506Syokota * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1742506Syokota * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1842506Syokota * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 1942506Syokota * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2042506Syokota * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2142506Syokota * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2242506Syokota * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2342506Syokota * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2442506Syokota * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2542506Syokota * SUCH DAMAGE. 2642506Syokota * 2750477Speter * $FreeBSD$ 2842506Syokota */ 2942506Syokota 3042506Syokota#include <sys/param.h> 3142506Syokota#include <sys/systm.h> 3242506Syokota#include <sys/kernel.h> 33129880Sphk#include <sys/module.h> 3442506Syokota#include <sys/linker.h> 3548104Syokota#include <sys/fbio.h> 3642506Syokota 3742506Syokota#include <dev/fb/fbreg.h> 3842506Syokota#include <dev/fb/splashreg.h> 3959690Snyan#ifndef PC98 4059583Syokota#include <dev/fb/vgareg.h> 4142506Syokota 4259583Syokota#include <isa/isareg.h> 4359690Snyan#endif 4459583Syokota 4545119Syokota#define FADE_TIMEOUT 15 /* sec */ 4645119Syokota#define FADE_LEVELS 10 4742506Syokota 4842506Syokotastatic int splash_mode = -1; 4942506Syokotastatic int splash_on = FALSE; 5042506Syokota 5142506Syokotastatic int bmp_start(video_adapter_t *adp); 5242506Syokotastatic int bmp_end(video_adapter_t *adp); 5342506Syokotastatic int bmp_splash(video_adapter_t *adp, int on); 54106765Smuxstatic int bmp_Init(char *data, int swidth, int sheight, int sdepth); 5542506Syokotastatic int bmp_Draw(video_adapter_t *adp); 5642506Syokota 5742506Syokotastatic splash_decoder_t bmp_decoder = { 5842506Syokota "splash_bmp", bmp_start, bmp_end, bmp_splash, SPLASH_IMAGE, 5942506Syokota}; 6042506Syokota 6142506SyokotaSPLASH_DECODER(splash_bmp, bmp_decoder); 6242506Syokota 6342506Syokotastatic int 6442506Syokotabmp_start(video_adapter_t *adp) 6542506Syokota{ 6642998Syokota /* currently only 256-color modes are supported XXX */ 6742506Syokota static int modes[] = { 6859690Snyan#ifdef PC98 6959690Snyan /* 7059690Snyan * As 640x400 doesn't generally look great, 7159690Snyan * it's least preferred here. 7259690Snyan */ 7359690Snyan M_PC98_PEGC640x400, 7459690Snyan M_PC98_PEGC640x480, 7559690Snyan M_PC98_EGC640x400, 7659690Snyan#else 7742998Syokota M_VESA_CG640x480, 7842998Syokota M_VESA_CG800x600, 7942998Syokota M_VESA_CG1024x768, 8059583Syokota M_CG640x480, 8142998Syokota /* 8242998Syokota * As 320x200 doesn't generally look great, 8342998Syokota * it's least preferred here. 8442998Syokota */ 8542506Syokota M_VGA_CG320, 8659690Snyan#endif 8742506Syokota -1, 8842506Syokota }; 8942506Syokota video_info_t info; 9042506Syokota int i; 9142506Syokota 9247945Syokota if ((bmp_decoder.data == NULL) || (bmp_decoder.data_size <= 0)) { 9347945Syokota printf("splash_bmp: No bitmap file found\n"); 9442506Syokota return ENODEV; 9547945Syokota } 9642506Syokota for (i = 0; modes[i] >= 0; ++i) { 97174985Swkoszek if ((vidd_get_info(adp, modes[i], &info) == 0) && 98174985Swkoszek (bmp_Init((u_char *)bmp_decoder.data, info.vi_width, 99174985Swkoszek info.vi_height, info.vi_depth) == 0)) 10042506Syokota break; 10142506Syokota } 10242506Syokota splash_mode = modes[i]; 10347945Syokota if (splash_mode < 0) 10447945Syokota printf("splash_bmp: No appropriate video mode found\n"); 10542506Syokota if (bootverbose) 10642506Syokota printf("bmp_start(): splash_mode:%d\n", splash_mode); 10742506Syokota return ((splash_mode < 0) ? ENODEV : 0); 10842506Syokota} 10942506Syokota 11042506Syokotastatic int 11142506Syokotabmp_end(video_adapter_t *adp) 11242506Syokota{ 11342506Syokota /* nothing to do */ 11442506Syokota return 0; 11542506Syokota} 11642506Syokota 11742506Syokotastatic int 11842506Syokotabmp_splash(video_adapter_t *adp, int on) 11942506Syokota{ 12042506Syokota static u_char pal[256*3]; 12142506Syokota static long time_stamp; 12245119Syokota u_char tpal[256*3]; 12345119Syokota static int fading = TRUE, brightness = FADE_LEVELS; 12442506Syokota struct timeval tv; 12542506Syokota int i; 12642506Syokota 12742506Syokota if (on) { 12842506Syokota if (!splash_on) { 12942506Syokota /* set up the video mode and draw something */ 130174985Swkoszek if (vidd_set_mode(adp, splash_mode)) 13142506Syokota return 1; 13242506Syokota if (bmp_Draw(adp)) 13342506Syokota return 1; 134174985Swkoszek vidd_save_palette(adp, pal); 13542506Syokota time_stamp = 0; 13642506Syokota splash_on = TRUE; 13742506Syokota } 13842506Syokota /* 13942506Syokota * This is a kludge to fade the image away. This section of the 14042506Syokota * code takes effect only after the system is completely up. 14142998Syokota * FADE_TIMEOUT should be configurable. 14242506Syokota */ 14342506Syokota if (!cold) { 14442506Syokota getmicrotime(&tv); 14542506Syokota if (time_stamp == 0) 14642506Syokota time_stamp = tv.tv_sec; 14742506Syokota if (tv.tv_sec > time_stamp + FADE_TIMEOUT) { 14845119Syokota if (fading) 14945119Syokota if (brightness == 0) { 15045119Syokota fading = FALSE; 15145119Syokota brightness++; 15245119Syokota } 15345119Syokota else brightness--; 15445119Syokota else 15545119Syokota if (brightness == FADE_LEVELS) { 15645119Syokota fading = TRUE; 15745119Syokota brightness--; 15845119Syokota } 15945119Syokota else brightness++; 16042506Syokota for (i = 0; i < sizeof(pal); ++i) { 16145119Syokota tpal[i] = pal[i] * brightness / FADE_LEVELS; 16242506Syokota } 163174985Swkoszek vidd_load_palette(adp, tpal); 16445119Syokota time_stamp = tv.tv_sec; 16542506Syokota } 16642506Syokota } 16742506Syokota return 0; 16842506Syokota } else { 16942506Syokota /* the video mode will be restored by the caller */ 17042506Syokota splash_on = FALSE; 17142506Syokota return 0; 17242506Syokota } 17342506Syokota} 17442506Syokota 17542506Syokota/* 17642506Syokota** Code to handle Microsoft DIB (".BMP") format images. 17742506Syokota** 17842506Syokota** Blame me (msmith@freebsd.org) if this is broken, not Soren. 17942506Syokota*/ 18042506Syokota 18142506Syokotatypedef struct tagBITMAPFILEHEADER { /* bmfh */ 182171382Smjacob u_short bfType; 183171382Smjacob int bfSize; 184171382Smjacob u_short bfReserved1; 185171382Smjacob u_short bfReserved2; 186171382Smjacob int bfOffBits; 187171382Smjacob} __packed BITMAPFILEHEADER; 18842506Syokota 18942506Syokotatypedef struct tagBITMAPINFOHEADER { /* bmih */ 190171382Smjacob int biSize; 191171382Smjacob int biWidth; 192171382Smjacob int biHeight; 193171382Smjacob short biPlanes; 194171382Smjacob short biBitCount; 195171382Smjacob int biCompression; 196171382Smjacob int biSizeImage; 197171382Smjacob int biXPelsPerMeter; 198171382Smjacob int biYPelsPerMeter; 199171382Smjacob int biClrUsed; 200171382Smjacob int biClrImportant; 201171382Smjacob} __packed BITMAPINFOHEADER; 20242506Syokota 20342506Syokotatypedef struct tagRGBQUAD { /* rgbq */ 204171382Smjacob u_char rgbBlue; 205171382Smjacob u_char rgbGreen; 206171382Smjacob u_char rgbRed; 207171382Smjacob u_char rgbReserved; 208171382Smjacob} __packed RGBQUAD; 20942506Syokota 21042506Syokotatypedef struct tagBITMAPINFO { /* bmi */ 211171382Smjacob BITMAPINFOHEADER bmiHeader; 212171382Smjacob RGBQUAD bmiColors[256]; 213171382Smjacob} __packed BITMAPINFO; 21442506Syokota 21542506Syokotatypedef struct tagBITMAPF 21642506Syokota{ 217171382Smjacob BITMAPFILEHEADER bmfh; 218171382Smjacob BITMAPINFO bmfi; 219171382Smjacob} __packed BITMAPF; 22042506Syokota 22142506Syokota#define BI_RGB 0 22242506Syokota#define BI_RLE8 1 22342506Syokota#define BI_RLE4 2 22442506Syokota 22542506Syokota/* 22642506Syokota** all we actually care about the image 22742506Syokota*/ 22842506Syokotatypedef struct 22942506Syokota{ 23042506Syokota int width,height; /* image dimensions */ 23142506Syokota int swidth,sheight; /* screen dimensions for the current mode */ 23259583Syokota u_char depth; /* image depth (1, 4, 8, 24 bits) */ 23342506Syokota u_char sdepth; /* screen depth (1, 4, 8 bpp) */ 23442506Syokota int ncols; /* number of colours */ 23542506Syokota u_char palette[256][3]; /* raw palette data */ 23642506Syokota u_char format; /* one of the BI_* constants above */ 23742506Syokota u_char *data; /* pointer to the raw data */ 23842506Syokota u_char *index; /* running pointer to the data while drawing */ 23942506Syokota u_char *vidmem; /* video memory allocated for drawing */ 24042998Syokota video_adapter_t *adp; 24142998Syokota int bank; 24259690Snyan#ifdef PC98 24359690Snyan u_char prev_val; 24459690Snyan#endif 24542506Syokota} BMP_INFO; 24642506Syokota 24742506Syokotastatic BMP_INFO bmp_info; 24842506Syokota 24942506Syokota/* 25042506Syokota** bmp_SetPix 25142506Syokota** 25242506Syokota** Given (info), set the pixel at (x),(y) to (val) 25342506Syokota** 25442506Syokota*/ 25542506Syokotastatic void 25642506Syokotabmp_SetPix(BMP_INFO *info, int x, int y, u_char val) 25742506Syokota{ 25842506Syokota int sofs, bofs; 25942998Syokota int newbank; 26042506Syokota 26142506Syokota /* 26242506Syokota * range check to avoid explosions 26342506Syokota */ 26442506Syokota if ((x < 0) || (x >= info->swidth) || (y < 0) || (y >= info->sheight)) 26542506Syokota return; 26642506Syokota 26742506Syokota /* 26842506Syokota * calculate offset into video memory; 26942506Syokota * because 0,0 is bottom-left for DIB, we have to convert. 27042506Syokota */ 27142506Syokota sofs = ((info->height - (y+1) + (info->sheight - info->height) / 2) 27243664Syokota * info->adp->va_line_width); 27359583Syokota x += (info->swidth - info->width) / 2; 27442506Syokota 27542506Syokota switch(info->sdepth) { 27659690Snyan#ifdef PC98 27759583Syokota case 4: 27859690Snyan sofs += (x >> 3); 27959690Snyan bofs = x & 0x7; /* offset within byte */ 28059690Snyan 28159690Snyan outb(0x7c, 0x80 | 0x40); /* GRCG on & RMW mode */ 28259690Snyan if (val != info->prev_val) { 28359690Snyan outb(0x7e, (val & 1) ? 0xff : 0); /* tile B */ 28459690Snyan outb(0x7e, (val & 2) ? 0xff : 0); /* tile R */ 28559690Snyan outb(0x7e, (val & 4) ? 0xff : 0); /* tile G */ 28659690Snyan outb(0x7e, (val & 8) ? 0xff : 0); /* tile I */ 28759690Snyan 28859690Snyan info->prev_val = val; 28959690Snyan } 29059690Snyan 29159690Snyan *(info->vidmem+sofs) = (0x80 >> bofs); /* write new bit */ 29259690Snyan outb(0x7c, 0); /* GRCG off */ 29359690Snyan break; 29459690Snyan#else 29559690Snyan case 4: 29642506Syokota case 1: 29759583Syokota /* EGA/VGA planar modes */ 29859583Syokota sofs += (x >> 3); 29959583Syokota newbank = sofs/info->adp->va_window_size; 30059583Syokota if (info->bank != newbank) { 301174985Swkoszek vidd_set_win_org(info->adp, newbank*info->adp->va_window_size); 30259583Syokota info->bank = newbank; 30359583Syokota } 30459583Syokota sofs %= info->adp->va_window_size; 30542506Syokota bofs = x & 0x7; /* offset within byte */ 30659583Syokota outw(GDCIDX, (0x8000 >> bofs) | 0x08); /* bit mask */ 30759583Syokota outw(GDCIDX, (val << 8) | 0x00); /* set/reset */ 30859583Syokota *(info->vidmem + sofs) ^= 0xff; /* read-modify-write */ 30942506Syokota break; 31059690Snyan#endif 31142506Syokota 31242506Syokota case 8: 31359583Syokota sofs += x; 31442998Syokota newbank = sofs/info->adp->va_window_size; 31542998Syokota if (info->bank != newbank) { 316174985Swkoszek vidd_set_win_org(info->adp, newbank*info->adp->va_window_size); 31742998Syokota info->bank = newbank; 31842998Syokota } 31942998Syokota sofs %= info->adp->va_window_size; 32042506Syokota *(info->vidmem+sofs) = val; 32142506Syokota break; 32242506Syokota } 32342506Syokota} 32442506Syokota 32542506Syokota/* 32642506Syokota** bmp_DecodeRLE4 32742506Syokota** 32842506Syokota** Given (data) pointing to a line of RLE4-format data and (line) being the starting 32942506Syokota** line onscreen, decode the line. 33042506Syokota*/ 33142506Syokotastatic void 33242506Syokotabmp_DecodeRLE4(BMP_INFO *info, int line) 33342506Syokota{ 33442506Syokota int count; /* run count */ 33542506Syokota u_char val; 33642506Syokota int x,y; /* screen position */ 33742506Syokota 33842506Syokota x = 0; /* starting position */ 33942506Syokota y = line; 34042506Syokota 34142506Syokota /* loop reading data */ 34242506Syokota for (;;) { 34342506Syokota /* 34442506Syokota * encoded mode starts with a run length, and then a byte with 34542506Syokota * two colour indexes to alternate between for the run 34642506Syokota */ 34742506Syokota if (*info->index) { 34842506Syokota for (count = 0; count < *info->index; count++, x++) { 34942506Syokota if (count & 1) { /* odd count, low nybble */ 35042506Syokota bmp_SetPix(info, x, y, *(info->index+1) & 0x0f); 35142506Syokota } else { /* even count, high nybble */ 35242506Syokota bmp_SetPix(info, x, y, (*(info->index+1) >>4) & 0x0f); 35342506Syokota } 35442506Syokota } 35542506Syokota info->index += 2; 35642506Syokota /* 35742506Syokota * A leading zero is an escape; it may signal the end of the 35842506Syokota * bitmap, a cursor move, or some absolute data. 35942506Syokota */ 36042506Syokota } else { /* zero tag may be absolute mode or an escape */ 36142506Syokota switch (*(info->index+1)) { 36242506Syokota case 0: /* end of line */ 36342506Syokota info->index += 2; 36442506Syokota return; 36542506Syokota case 1: /* end of bitmap */ 36642506Syokota info->index = NULL; 36742506Syokota return; 36842506Syokota case 2: /* move */ 36942506Syokota x += *(info->index + 2); /* new coords */ 37042506Syokota y += *(info->index + 3); 37142506Syokota info->index += 4; 37242506Syokota break; 37342506Syokota default: /* literal bitmap data */ 37442506Syokota for (count = 0; count < *(info->index + 1); count++, x++) { 37542506Syokota val = *(info->index + 2 + (count / 2)); /* byte with nybbles */ 37642506Syokota if (count & 1) { 37742506Syokota val &= 0xf; /* get low nybble */ 37842506Syokota } else { 37942506Syokota val = (val >> 4); /* get high nybble */ 38042506Syokota } 38142506Syokota bmp_SetPix(info, x, y, val); 38242506Syokota } 38342506Syokota /* warning, this depends on integer truncation, do not hand-optimise! */ 38442506Syokota info->index += 2 + ((count + 3) / 4) * 2; 38542506Syokota break; 38642506Syokota } 38742506Syokota } 38842506Syokota } 38942506Syokota} 39042506Syokota 39142506Syokota/* 39242506Syokota** bmp_DecodeRLE8 39359583Syokota** Given (data) pointing to a line of RLE8-format data and (line) being the starting 39442506Syokota** line onscreen, decode the line. 39542506Syokota*/ 39642506Syokotastatic void 39742506Syokotabmp_DecodeRLE8(BMP_INFO *info, int line) 39842506Syokota{ 39942506Syokota int count; /* run count */ 40042506Syokota int x,y; /* screen position */ 40142506Syokota 40242506Syokota x = 0; /* starting position */ 40342506Syokota y = line; 40442506Syokota 40542506Syokota /* loop reading data */ 40642506Syokota for(;;) { 40742506Syokota /* 40842506Syokota * encoded mode starts with a run length, and then a byte with 40942506Syokota * two colour indexes to alternate between for the run 41042506Syokota */ 41142506Syokota if (*info->index) { 41242506Syokota for (count = 0; count < *info->index; count++, x++) 41342506Syokota bmp_SetPix(info, x, y, *(info->index+1)); 41442506Syokota info->index += 2; 41542506Syokota /* 41642506Syokota * A leading zero is an escape; it may signal the end of the 41742506Syokota * bitmap, a cursor move, or some absolute data. 41842506Syokota */ 41942506Syokota } else { /* zero tag may be absolute mode or an escape */ 42042506Syokota switch(*(info->index+1)) { 42142506Syokota case 0: /* end of line */ 42242506Syokota info->index += 2; 42342506Syokota return; 42442506Syokota case 1: /* end of bitmap */ 42542506Syokota info->index = NULL; 42642506Syokota return; 42742506Syokota case 2: /* move */ 42842506Syokota x += *(info->index + 2); /* new coords */ 42942506Syokota y += *(info->index + 3); 43042506Syokota info->index += 4; 43142506Syokota break; 43242506Syokota default: /* literal bitmap data */ 43342506Syokota for (count = 0; count < *(info->index + 1); count++, x++) 43442506Syokota bmp_SetPix(info, x, y, *(info->index + 2 + count)); 43542506Syokota /* must be an even count */ 43642506Syokota info->index += 2 + count + (count & 1); 43742506Syokota break; 43842506Syokota } 43942506Syokota } 44042506Syokota } 44142506Syokota} 44242506Syokota 44342506Syokota/* 44442506Syokota** bmp_DecodeLine 44542506Syokota** 44642506Syokota** Given (info) pointing to an image being decoded, (line) being the line currently 44742506Syokota** being displayed, decode a line of data. 44842506Syokota*/ 44942506Syokotastatic void 45042506Syokotabmp_DecodeLine(BMP_INFO *info, int line) 45142506Syokota{ 45242506Syokota int x; 45359583Syokota u_char val, mask, *p; 45442506Syokota 45542506Syokota switch(info->format) { 45642506Syokota case BI_RGB: 45759583Syokota switch(info->depth) { 45859583Syokota case 8: 45959583Syokota for (x = 0; x < info->width; x++, info->index++) 46059583Syokota bmp_SetPix(info, x, line, *info->index); 46159583Syokota info->index += 3 - (--x % 4); 46259583Syokota break; 46359583Syokota case 4: 46459583Syokota p = info->index; 46559583Syokota for (x = 0; x < info->width; x++) { 46659583Syokota if (x & 1) { 46759583Syokota val = *p & 0xf; /* get low nybble */ 46859583Syokota p++; 46959583Syokota } else { 47059583Syokota val = *p >> 4; /* get high nybble */ 47159583Syokota } 47259583Syokota bmp_SetPix(info, x, line, val); 47359583Syokota } 47459583Syokota /* warning, this depends on integer truncation, do not hand-optimise! */ 47559583Syokota info->index += ((x + 7) / 8) * 4; 47659583Syokota break; 47759583Syokota case 1: 47859583Syokota p = info->index; 47959583Syokota mask = 0x80; 48059583Syokota for (x = 0; x < info->width; x++) { 48159583Syokota val = (*p & mask) ? 1 : 0; 48259583Syokota mask >>= 1; 48359583Syokota if (mask == 0) { 48459583Syokota mask = 0x80; 48559583Syokota p++; 48659583Syokota } 48759583Syokota bmp_SetPix(info, x, line, val); 48859583Syokota } 48959583Syokota /* warning, this depends on integer truncation, do not hand-optimise! */ 49059583Syokota info->index += ((x + 31) / 32) * 4; 49159583Syokota break; 49259583Syokota } 49342506Syokota break; 49442506Syokota case BI_RLE4: 49542506Syokota bmp_DecodeRLE4(info, line); 49642506Syokota break; 49742506Syokota case BI_RLE8: 49842506Syokota bmp_DecodeRLE8(info, line); 49942506Syokota break; 50042506Syokota } 50142506Syokota} 50242506Syokota 50342506Syokota/* 50442506Syokota** bmp_Init 50542506Syokota** 50642506Syokota** Given a pointer (data) to the image of a BMP file, fill in bmp_info with what 50742506Syokota** can be learnt from it. Return nonzero if the file isn't usable. 50842506Syokota** 50942506Syokota** Take screen dimensions (swidth), (sheight) and (sdepth) and make sure we 51042506Syokota** can work with these. 51142506Syokota*/ 51242506Syokotastatic int 513106765Smuxbmp_Init(char *data, int swidth, int sheight, int sdepth) 51442506Syokota{ 51542506Syokota BITMAPF *bmf = (BITMAPF *)data; 51642506Syokota int pind; 51742506Syokota 51842506Syokota bmp_info.data = NULL; /* assume setup failed */ 51942506Syokota 52042506Syokota /* check file ID */ 52142506Syokota if (bmf->bmfh.bfType != 0x4d42) { 52247945Syokota printf("splash_bmp: not a BMP file\n"); 52342506Syokota return(1); /* XXX check word ordering for big-endian ports? */ 52442506Syokota } 52542506Syokota 52647945Syokota /* do we understand this bitmap format? */ 52747945Syokota if (bmf->bmfi.bmiHeader.biSize > sizeof(bmf->bmfi.bmiHeader)) { 52847945Syokota printf("splash_bmp: unsupported BMP format (size=%d)\n", 52947945Syokota bmf->bmfi.bmiHeader.biSize); 53047945Syokota return(1); 53147945Syokota } 53247945Syokota 53342506Syokota /* save what we know about the screen */ 53442506Syokota bmp_info.swidth = swidth; 53542506Syokota bmp_info.sheight = sheight; 53642506Syokota bmp_info.sdepth = sdepth; 53742506Syokota 53842506Syokota /* where's the data? */ 53942506Syokota bmp_info.data = (u_char *)data + bmf->bmfh.bfOffBits; 54042506Syokota 54142506Syokota /* image parameters */ 54242506Syokota bmp_info.width = bmf->bmfi.bmiHeader.biWidth; 54342506Syokota bmp_info.height = bmf->bmfi.bmiHeader.biHeight; 54459583Syokota bmp_info.depth = bmf->bmfi.bmiHeader.biBitCount; 54542506Syokota bmp_info.format = bmf->bmfi.bmiHeader.biCompression; 54642506Syokota 54742506Syokota switch(bmp_info.format) { /* check compression format */ 54842506Syokota case BI_RGB: 54942506Syokota case BI_RLE4: 55042506Syokota case BI_RLE8: 55142506Syokota break; 55242506Syokota default: 55347945Syokota printf("splash_bmp: unsupported compression format\n"); 55442506Syokota return(1); /* unsupported compression format */ 55542506Syokota } 55642506Syokota 55742506Syokota /* palette details */ 55842506Syokota bmp_info.ncols = (bmf->bmfi.bmiHeader.biClrUsed); 55942506Syokota bzero(bmp_info.palette,sizeof(bmp_info.palette)); 56042506Syokota if (bmp_info.ncols == 0) { /* uses all of them */ 56142623Syokota bmp_info.ncols = 1 << bmf->bmfi.bmiHeader.biBitCount; 56242506Syokota } 56342506Syokota if ((bmp_info.height > bmp_info.sheight) || 56442506Syokota (bmp_info.width > bmp_info.swidth) || 56542506Syokota (bmp_info.ncols > (1 << sdepth))) { 56659583Syokota if (bootverbose) 56759583Syokota printf("splash_bmp: beyond screen capacity (%dx%d, %d colors)\n", 56859583Syokota bmp_info.width, bmp_info.height, bmp_info.ncols); 56959583Syokota return(1); 57042506Syokota } 57142506Syokota 57242506Syokota /* read palette */ 57342506Syokota for (pind = 0; pind < bmp_info.ncols; pind++) { 57442506Syokota bmp_info.palette[pind][0] = bmf->bmfi.bmiColors[pind].rgbRed; 57542506Syokota bmp_info.palette[pind][1] = bmf->bmfi.bmiColors[pind].rgbGreen; 57642506Syokota bmp_info.palette[pind][2] = bmf->bmfi.bmiColors[pind].rgbBlue; 57742506Syokota } 57842506Syokota return(0); 57942506Syokota} 58042506Syokota 58142506Syokota/* 58242506Syokota** bmp_Draw 58342506Syokota** 58442506Syokota** Render the image. Return nonzero if that's not possible. 58542506Syokota** 58642506Syokota*/ 58742506Syokotastatic int 58842506Syokotabmp_Draw(video_adapter_t *adp) 58942506Syokota{ 59042506Syokota int line; 59173857Sjhb#if 0 59273857Sjhb#ifndef PC98 59359583Syokota int i; 59473857Sjhb#endif 59573857Sjhb#endif 59642506Syokota 59742506Syokota if (bmp_info.data == NULL) { /* init failed, do nothing */ 59842506Syokota return(1); 59942506Syokota } 60042506Syokota 60142506Syokota /* clear the screen */ 60242506Syokota bmp_info.vidmem = (u_char *)adp->va_window; 60342998Syokota bmp_info.adp = adp; 604174985Swkoszek vidd_clear(adp); 605174985Swkoszek vidd_set_win_org(adp, 0); 60642998Syokota bmp_info.bank = 0; 60742506Syokota 60842506Syokota /* initialise the info structure for drawing */ 60942506Syokota bmp_info.index = bmp_info.data; 61059690Snyan#ifdef PC98 61159690Snyan bmp_info.prev_val = 255; 61259690Snyan#endif 61342506Syokota 61442506Syokota /* set the palette for our image */ 615174985Swkoszek vidd_load_palette(adp, (u_char *)&bmp_info.palette); 61642506Syokota 61768050Snyan#if 0 61859690Snyan#ifndef PC98 61959583Syokota /* XXX: this is ugly, but necessary for EGA/VGA 1bpp/4bpp modes */ 62059583Syokota if ((adp->va_type == KD_EGA) || (adp->va_type == KD_VGA)) { 62159583Syokota inb(adp->va_crtc_addr + 6); /* reset flip-flop */ 62259583Syokota outb(ATC, 0x14); 62359583Syokota outb(ATC, 0); 62459583Syokota for (i = 0; i < 16; ++i) { 62559583Syokota outb(ATC, i); 62659583Syokota outb(ATC, i); 62759583Syokota } 62859583Syokota inb(adp->va_crtc_addr + 6); /* reset flip-flop */ 62959583Syokota outb(ATC, 0x20); /* enable palette */ 63059583Syokota 63159583Syokota outw(GDCIDX, 0x0f01); /* set/reset enable */ 63259583Syokota 63359583Syokota if (bmp_info.sdepth == 1) 63459583Syokota outw(TSIDX, 0x0102); /* unmask plane #0 */ 63559583Syokota } 63659690Snyan#endif 63768050Snyan#endif 63859583Syokota 63942506Syokota for (line = 0; (line < bmp_info.height) && bmp_info.index; line++) { 64042506Syokota bmp_DecodeLine(&bmp_info, line); 64142506Syokota } 64242506Syokota return(0); 64342506Syokota} 644