Home | History | Annotate | Line # | Download | only in splash
      1  1.13   khorben /* $NetBSD: splash.c,v 1.13 2016/04/25 22:26:50 khorben Exp $ */
      2   1.1  jmcneill 
      3   1.1  jmcneill /*-
      4   1.1  jmcneill  * Copyright (c) 2006 Jared D. McNeill <jmcneill (at) invisible.ca>
      5   1.1  jmcneill  * All rights reserved.
      6   1.1  jmcneill  *
      7   1.1  jmcneill  * Redistribution and use in source and binary forms, with or without
      8   1.1  jmcneill  * modification, are permitted provided that the following conditions
      9   1.1  jmcneill  * are met:
     10   1.1  jmcneill  * 1. Redistributions of source code must retain the above copyright
     11   1.1  jmcneill  *    notice, this list of conditions and the following disclaimer.
     12   1.1  jmcneill  * 2. Redistributions in binary form must reproduce the above copyright
     13   1.1  jmcneill  *    notice, this list of conditions and the following disclaimer in the
     14   1.1  jmcneill  *    documentation and/or other materials provided with the distribution.
     15   1.6    martin  * 3. All advertising materials mentioning features or use of this software
     16   1.6    martin  *    must display the following acknowledgement:
     17   1.6    martin  *        This product includes software developed by the NetBSD
     18   1.6    martin  *        Foundation, Inc. and its contributors.
     19   1.6    martin  * 4. Neither the name of The NetBSD Foundation nor the names of its
     20   1.6    martin  *    contributors may be used to endorse or promote products derived
     21   1.6    martin  *    from this software without specific prior written permission.
     22   1.1  jmcneill  *
     23   1.1  jmcneill  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     24   1.1  jmcneill  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     25   1.1  jmcneill  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     26   1.1  jmcneill  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     27   1.1  jmcneill  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     28   1.1  jmcneill  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     29   1.1  jmcneill  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     30   1.1  jmcneill  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     31   1.1  jmcneill  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     32   1.1  jmcneill  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     33   1.1  jmcneill  * POSSIBILITY OF SUCH DAMAGE.
     34   1.1  jmcneill  */
     35   1.1  jmcneill 
     36   1.1  jmcneill #include <sys/cdefs.h>
     37  1.13   khorben __KERNEL_RCSID(0, "$NetBSD: splash.c,v 1.13 2016/04/25 22:26:50 khorben Exp $");
     38   1.1  jmcneill 
     39   1.1  jmcneill #include "opt_splash.h"
     40   1.1  jmcneill 
     41   1.1  jmcneill /* XXX */
     42   1.9  jmcneill #define NSPLASH8  1
     43   1.1  jmcneill #define	NSPLASH16 1
     44   1.1  jmcneill #define	NSPLASH32 1
     45   1.1  jmcneill 
     46   1.1  jmcneill #include <sys/param.h>
     47   1.8     ahoka #include <sys/device.h>
     48   1.1  jmcneill #include <sys/systm.h>
     49   1.1  jmcneill #include <sys/types.h>
     50   1.1  jmcneill #include <sys/kernel.h>
     51   1.1  jmcneill #include <sys/kthread.h>
     52   1.1  jmcneill 
     53   1.1  jmcneill #include <dev/splash/splash.h>
     54   1.9  jmcneill #include <dev/stbi/stbi.h>
     55   1.1  jmcneill 
     56   1.1  jmcneill #ifdef SPLASHSCREEN
     57   1.1  jmcneill 
     58   1.9  jmcneill static struct {
     59   1.9  jmcneill 	const u_char	*data;
     60   1.9  jmcneill 	size_t		datalen;
     61   1.9  jmcneill } splash_image = { NULL, 0 };
     62   1.9  jmcneill 
     63   1.9  jmcneill #define SPLASH_INDEX(r, g, b)						\
     64   1.9  jmcneill 	((((r) >> 6) << 4) | (((g) >> 6) << 2) | (((b) >> 6) << 0))
     65   1.9  jmcneill 
     66   1.9  jmcneill static uint8_t splash_palette[SPLASH_CMAP_SIZE][3] = {
     67   1.9  jmcneill 	{ 0x00, 0x00, 0x00 },
     68   1.9  jmcneill 	{ 0x00, 0x00, 0x55 },
     69   1.9  jmcneill 	{ 0x00, 0x00, 0xaa },
     70   1.9  jmcneill 	{ 0x00, 0x00, 0xff },
     71   1.9  jmcneill 	{ 0x00, 0x55, 0x00 },
     72   1.9  jmcneill 	{ 0x00, 0x55, 0x55 },
     73   1.9  jmcneill 	{ 0x00, 0x55, 0xaa },
     74   1.9  jmcneill 	{ 0x00, 0x55, 0xff },
     75   1.9  jmcneill 	{ 0x00, 0xaa, 0x00 },
     76   1.9  jmcneill 	{ 0x00, 0xaa, 0x55 },
     77   1.9  jmcneill 	{ 0x00, 0xaa, 0xaa },
     78   1.9  jmcneill 	{ 0x00, 0xaa, 0xff },
     79   1.9  jmcneill 	{ 0x00, 0xff, 0x00 },
     80   1.9  jmcneill 	{ 0x00, 0xff, 0x55 },
     81   1.9  jmcneill 	{ 0x00, 0xff, 0xaa },
     82   1.9  jmcneill 	{ 0x00, 0xff, 0xff },
     83   1.9  jmcneill 	{ 0x55, 0x00, 0x00 },
     84   1.9  jmcneill 	{ 0x55, 0x00, 0x55 },
     85   1.9  jmcneill 	{ 0x55, 0x00, 0xaa },
     86   1.9  jmcneill 	{ 0x55, 0x00, 0xff },
     87   1.9  jmcneill 	{ 0x55, 0x55, 0x00 },
     88   1.9  jmcneill 	{ 0x55, 0x55, 0x55 },
     89   1.9  jmcneill 	{ 0x55, 0x55, 0xaa },
     90   1.9  jmcneill 	{ 0x55, 0x55, 0xff },
     91   1.9  jmcneill 	{ 0x55, 0xaa, 0x00 },
     92   1.9  jmcneill 	{ 0x55, 0xaa, 0x55 },
     93   1.9  jmcneill 	{ 0x55, 0xaa, 0xaa },
     94   1.9  jmcneill 	{ 0x55, 0xaa, 0xff },
     95   1.9  jmcneill 	{ 0x55, 0xff, 0x00 },
     96   1.9  jmcneill 	{ 0x55, 0xff, 0x55 },
     97   1.9  jmcneill 	{ 0x55, 0xff, 0xaa },
     98   1.9  jmcneill 	{ 0x55, 0xff, 0xff },
     99   1.9  jmcneill 	{ 0xaa, 0x00, 0x00 },
    100   1.9  jmcneill 	{ 0xaa, 0x00, 0x55 },
    101   1.9  jmcneill 	{ 0xaa, 0x00, 0xaa },
    102   1.9  jmcneill 	{ 0xaa, 0x00, 0xff },
    103   1.9  jmcneill 	{ 0xaa, 0x55, 0x00 },
    104   1.9  jmcneill 	{ 0xaa, 0x55, 0x55 },
    105   1.9  jmcneill 	{ 0xaa, 0x55, 0xaa },
    106   1.9  jmcneill 	{ 0xaa, 0x55, 0xff },
    107   1.9  jmcneill 	{ 0xaa, 0xaa, 0x00 },
    108   1.9  jmcneill 	{ 0xaa, 0xaa, 0x55 },
    109   1.9  jmcneill 	{ 0xaa, 0xaa, 0xaa },
    110   1.9  jmcneill 	{ 0xaa, 0xaa, 0xff },
    111   1.9  jmcneill 	{ 0xaa, 0xff, 0x00 },
    112   1.9  jmcneill 	{ 0xaa, 0xff, 0x55 },
    113   1.9  jmcneill 	{ 0xaa, 0xff, 0xaa },
    114   1.9  jmcneill 	{ 0xaa, 0xff, 0xff },
    115   1.9  jmcneill 	{ 0xff, 0x00, 0x00 },
    116   1.9  jmcneill 	{ 0xff, 0x00, 0x55 },
    117   1.9  jmcneill 	{ 0xff, 0x00, 0xaa },
    118   1.9  jmcneill 	{ 0xff, 0x00, 0xff },
    119   1.9  jmcneill 	{ 0xff, 0x55, 0x00 },
    120   1.9  jmcneill 	{ 0xff, 0x55, 0x55 },
    121   1.9  jmcneill 	{ 0xff, 0x55, 0xaa },
    122   1.9  jmcneill 	{ 0xff, 0x55, 0xff },
    123   1.9  jmcneill 	{ 0xff, 0xaa, 0x00 },
    124   1.9  jmcneill 	{ 0xff, 0xaa, 0x55 },
    125   1.9  jmcneill 	{ 0xff, 0xaa, 0xaa },
    126   1.9  jmcneill 	{ 0xff, 0xaa, 0xff },
    127   1.9  jmcneill 	{ 0xff, 0xff, 0x00 },
    128   1.9  jmcneill 	{ 0xff, 0xff, 0x55 },
    129   1.9  jmcneill 	{ 0xff, 0xff, 0xaa },
    130   1.9  jmcneill 	{ 0xff, 0xff, 0xff },
    131   1.9  jmcneill };
    132   1.1  jmcneill 
    133   1.1  jmcneill #if NSPLASH8 > 0
    134   1.1  jmcneill static void	splash_render8(struct splash_info *, const char *, int,
    135   1.1  jmcneill 			       int, int, int, int);
    136   1.1  jmcneill #endif
    137   1.1  jmcneill #if NSPLASH16 > 0
    138   1.1  jmcneill static void	splash_render16(struct splash_info *, const char *, int,
    139   1.1  jmcneill 				int, int, int, int);
    140   1.1  jmcneill #endif
    141   1.1  jmcneill #if NSPLASH32 > 0
    142   1.1  jmcneill static void	splash_render32(struct splash_info *, const char *, int,
    143   1.1  jmcneill 				int, int, int, int);
    144   1.1  jmcneill #endif
    145   1.1  jmcneill 
    146   1.9  jmcneill int
    147   1.9  jmcneill splash_setimage(const void *imgdata, size_t imgdatalen)
    148   1.9  jmcneill {
    149   1.9  jmcneill 	if (splash_image.data != NULL) {
    150   1.9  jmcneill 		aprint_debug("WARNING: %s: already initialized\n", __func__);
    151   1.9  jmcneill 		return EBUSY;
    152   1.9  jmcneill 	}
    153   1.9  jmcneill 
    154  1.11  jmcneill 	aprint_verbose("%s: splash image @ %p, %zu bytes\n",
    155   1.9  jmcneill 	    __func__, imgdata, imgdatalen);
    156   1.9  jmcneill 	splash_image.data = imgdata;
    157   1.9  jmcneill 	splash_image.datalen = imgdatalen;
    158   1.9  jmcneill 
    159   1.9  jmcneill 	return 0;
    160   1.9  jmcneill }
    161   1.9  jmcneill 
    162   1.9  jmcneill int
    163   1.9  jmcneill splash_get_cmap(int index, uint8_t *r, uint8_t *g, uint8_t *b)
    164   1.9  jmcneill {
    165   1.9  jmcneill 	if (index < SPLASH_CMAP_OFFSET ||
    166   1.9  jmcneill 	    index >= SPLASH_CMAP_OFFSET + SPLASH_CMAP_SIZE)
    167   1.9  jmcneill 		return ERANGE;
    168   1.9  jmcneill 
    169   1.9  jmcneill 	*r = splash_palette[index - SPLASH_CMAP_OFFSET][0];
    170   1.9  jmcneill 	*g = splash_palette[index - SPLASH_CMAP_OFFSET][1];
    171   1.9  jmcneill 	*b = splash_palette[index - SPLASH_CMAP_OFFSET][2];
    172   1.9  jmcneill 
    173   1.9  jmcneill 	return 0;
    174   1.9  jmcneill }
    175   1.9  jmcneill 
    176   1.9  jmcneill int
    177   1.1  jmcneill splash_render(struct splash_info *si, int flg)
    178   1.1  jmcneill {
    179   1.9  jmcneill 	char *data = NULL;
    180   1.9  jmcneill 	int xoff, yoff, width, height, comp;
    181   1.9  jmcneill 	int error = 0;
    182   1.9  jmcneill 
    183   1.9  jmcneill 	if (splash_image.data == NULL) {
    184   1.9  jmcneill 		aprint_error("WARNING: %s: not initialized\n", __func__);
    185   1.9  jmcneill 		return ENXIO;
    186   1.9  jmcneill 	}
    187   1.9  jmcneill 
    188   1.9  jmcneill 	data = stbi_load_from_memory(splash_image.data,
    189   1.9  jmcneill 	    splash_image.datalen, &width, &height, &comp, STBI_rgb);
    190   1.9  jmcneill 	if (data == NULL) {
    191   1.9  jmcneill 		aprint_error("WARNING: couldn't load splash image: %s\n",
    192   1.9  jmcneill 		    stbi_failure_reason());
    193   1.9  jmcneill 		return EINVAL;
    194   1.9  jmcneill 	}
    195   1.9  jmcneill 	aprint_debug("%s: splash loaded, width %d height %d comp %d\n",
    196   1.9  jmcneill 	    __func__, width, height, comp);
    197   1.1  jmcneill 
    198  1.13   khorben 	if ((width > si->si_width) || (height > si->si_height)) {
    199  1.13   khorben 		aprint_error(
    200  1.13   khorben 			"WARNING: splash size (%dx%d) too big for framebuffer (%dx%d)\n",
    201  1.13   khorben 			width, height, si->si_width, si->si_height);
    202  1.13   khorben 		stbi_image_free(data);
    203  1.13   khorben 		return EINVAL;
    204  1.13   khorben 	}
    205  1.13   khorben 
    206   1.1  jmcneill 	/* XXX */
    207   1.1  jmcneill 	if (flg & SPLASH_F_CENTER) {
    208   1.9  jmcneill 		xoff = (si->si_width - width) / 2;
    209   1.9  jmcneill 		yoff = (si->si_height - height) / 2;
    210   1.1  jmcneill 	} else
    211   1.1  jmcneill 		xoff = yoff = 0;
    212   1.1  jmcneill 
    213   1.1  jmcneill 	switch (si->si_depth) {
    214   1.1  jmcneill #if NSPLASH8 > 0
    215   1.1  jmcneill 	case 8:
    216   1.9  jmcneill 		splash_render8(si, data, xoff, yoff, width, height, flg);
    217   1.1  jmcneill 		break;
    218   1.1  jmcneill #endif
    219   1.1  jmcneill #if NSPLASH16 > 0
    220   1.1  jmcneill 	case 16:
    221   1.9  jmcneill 		splash_render16(si, data, xoff, yoff, width, height, flg);
    222   1.1  jmcneill 		break;
    223   1.1  jmcneill #endif
    224   1.1  jmcneill #if NSPLASH32 > 0
    225   1.1  jmcneill 	case 32:
    226   1.9  jmcneill 		splash_render32(si, data, xoff, yoff, width, height, flg);
    227   1.1  jmcneill 		break;
    228   1.1  jmcneill #endif
    229   1.1  jmcneill 	default:
    230   1.1  jmcneill 		aprint_error("WARNING: Splash not supported at %dbpp\n",
    231   1.1  jmcneill 		    si->si_depth);
    232   1.9  jmcneill 		error = EINVAL;
    233   1.1  jmcneill 	}
    234   1.1  jmcneill 
    235   1.9  jmcneill 	if (data)
    236   1.9  jmcneill 		stbi_image_free(data);
    237   1.9  jmcneill 
    238   1.9  jmcneill 	return error;
    239   1.1  jmcneill }
    240   1.1  jmcneill 
    241   1.1  jmcneill #if NSPLASH8 > 0
    242   1.9  jmcneill 
    243   1.1  jmcneill static void
    244   1.1  jmcneill splash_render8(struct splash_info *si, const char *data, int xoff, int yoff,
    245   1.1  jmcneill 	       int swidth, int sheight, int flg)
    246   1.1  jmcneill {
    247   1.9  jmcneill 	const char *d;
    248   1.9  jmcneill 	u_char *fb, *p;
    249   1.9  jmcneill 	u_char pix[3];
    250   1.1  jmcneill 	int x, y, i;
    251   1.1  jmcneill 	int filled;
    252   1.1  jmcneill 
    253   1.1  jmcneill 	fb = si->si_bits;
    254   1.9  jmcneill 
    255   1.1  jmcneill 	if (flg & SPLASH_F_FILL)
    256   1.1  jmcneill 		filled = 0;
    257   1.1  jmcneill 	else
    258   1.1  jmcneill 		filled = 1;
    259   1.1  jmcneill 
    260   1.9  jmcneill 	d = data;
    261   1.9  jmcneill 	fb += xoff + yoff * si->si_stride;
    262   1.9  jmcneill 
    263   1.1  jmcneill 	for (y = 0; y < sheight; y++) {
    264   1.1  jmcneill 		for (x = 0; x < swidth; x++) {
    265   1.9  jmcneill 			pix[0] = *d++;
    266   1.9  jmcneill 			pix[1] = *d++;
    267   1.9  jmcneill 			pix[2] = *d++;
    268   1.1  jmcneill 			if (filled == 0) {
    269   1.9  jmcneill 				p = si->si_bits;
    270   1.9  jmcneill 				i = 0;
    271   1.9  jmcneill 				while (i < si->si_height*si->si_stride) {
    272   1.9  jmcneill 					p[i] = SPLASH_INDEX(
    273   1.9  jmcneill 					    pix[0], pix[1], pix[2]) +
    274   1.9  jmcneill 					    SPLASH_CMAP_OFFSET;
    275   1.9  jmcneill 					i++;
    276   1.9  jmcneill 				}
    277   1.1  jmcneill 				filled = 1;
    278   1.1  jmcneill 			}
    279   1.9  jmcneill 			fb[x] = SPLASH_INDEX(pix[0], pix[1], pix[2]) +
    280   1.9  jmcneill 				    SPLASH_CMAP_OFFSET;
    281   1.1  jmcneill 		}
    282  1.12    martin 		fb += si->si_stride;
    283   1.1  jmcneill 	}
    284   1.1  jmcneill 
    285   1.1  jmcneill 	/* If we've just written to the shadow fb, copy it to the display */
    286   1.1  jmcneill 	if (si->si_hwbits) {
    287   1.1  jmcneill 		if (flg & SPLASH_F_FILL) {
    288   1.1  jmcneill 			memcpy(si->si_hwbits, si->si_bits,
    289   1.9  jmcneill 			    si->si_height*si->si_width);
    290   1.1  jmcneill 		} else {
    291   1.1  jmcneill 			u_char *rp, *hrp;
    292   1.1  jmcneill 
    293   1.1  jmcneill 			rp = si->si_bits + xoff + (yoff * si->si_width);
    294   1.1  jmcneill 			hrp = si->si_hwbits + xoff + (yoff * si->si_width);
    295   1.1  jmcneill 
    296   1.1  jmcneill 			for (y = 0; y < sheight; y++) {
    297   1.1  jmcneill 				memcpy(hrp, rp, swidth);
    298   1.9  jmcneill 				rp += si->si_stride;
    299   1.1  jmcneill 				hrp += si->si_stride;
    300   1.1  jmcneill 			}
    301   1.1  jmcneill 		}
    302   1.1  jmcneill 	}
    303   1.1  jmcneill 
    304   1.1  jmcneill 	return;
    305   1.1  jmcneill }
    306   1.1  jmcneill #endif /* !NSPLASH8 > 0 */
    307   1.1  jmcneill 
    308   1.1  jmcneill #if NSPLASH16 > 0
    309   1.1  jmcneill #define RGBTO16(b, o, x, c)					\
    310   1.1  jmcneill 	do {							\
    311   1.1  jmcneill 		uint16_t *_ptr = (uint16_t *)(&(b)[(o)]);	\
    312   1.1  jmcneill 		*_ptr = (((c)[(x)*3+0] / 8) << 11) |		\
    313   1.1  jmcneill 			(((c)[(x)*3+1] / 4) << 5) |		\
    314   1.1  jmcneill 			(((c)[(x)*3+2] / 8) << 0);		\
    315   1.1  jmcneill 	} while (0)
    316   1.1  jmcneill 
    317   1.1  jmcneill static void
    318   1.1  jmcneill splash_render16(struct splash_info *si, const char *data, int xoff, int yoff,
    319   1.1  jmcneill 		int swidth, int sheight, int flg)
    320   1.1  jmcneill {
    321   1.1  jmcneill 	const char *d;
    322   1.1  jmcneill 	u_char *fb, *p;
    323   1.1  jmcneill 	u_char pix[3];
    324   1.1  jmcneill 	int x, y, i;
    325   1.1  jmcneill 	int filled;
    326   1.1  jmcneill 
    327   1.1  jmcneill 	fb = si->si_bits;
    328   1.1  jmcneill 
    329   1.1  jmcneill 	if (flg & SPLASH_F_FILL)
    330   1.1  jmcneill 		filled = 0;
    331   1.1  jmcneill 	else
    332   1.1  jmcneill 		filled = 1;
    333   1.1  jmcneill 
    334   1.1  jmcneill 	d = data;
    335   1.1  jmcneill 	fb += xoff * 2 + yoff * si->si_stride;
    336   1.1  jmcneill 
    337   1.1  jmcneill 	for (y = 0; y < sheight; y++) {
    338   1.1  jmcneill 		for (x = 0; x < swidth; x++) {
    339   1.9  jmcneill 			pix[0] = *d++;
    340   1.9  jmcneill 			pix[1] = *d++;
    341   1.9  jmcneill 			pix[2] = *d++;
    342   1.1  jmcneill 			if (filled == 0) {
    343   1.1  jmcneill 				p = si->si_bits;
    344   1.1  jmcneill 				i = 0;
    345   1.1  jmcneill 				while (i < si->si_height*si->si_stride) {
    346   1.1  jmcneill 					RGBTO16(p, i, 0, pix);
    347   1.1  jmcneill 					i += 2;
    348   1.1  jmcneill 				}
    349   1.1  jmcneill 				filled = 1;
    350   1.1  jmcneill 			}
    351   1.1  jmcneill 			RGBTO16(fb, x*2, 0, pix);
    352   1.1  jmcneill 		}
    353   1.1  jmcneill 		fb += si->si_stride;
    354   1.1  jmcneill 	}
    355   1.1  jmcneill 
    356   1.1  jmcneill 	/* If we've just written to the shadow fb, copy it to the display */
    357   1.1  jmcneill 	if (si->si_hwbits) {
    358   1.1  jmcneill 		if (flg & SPLASH_F_FILL) {
    359   1.1  jmcneill 			memcpy(si->si_hwbits, si->si_bits,
    360   1.1  jmcneill 			    si->si_height*si->si_stride);
    361   1.1  jmcneill 		} else {
    362   1.1  jmcneill 			u_char *rp, *hrp;
    363   1.1  jmcneill 
    364   1.1  jmcneill 			rp = si->si_bits + (xoff * 2) + (yoff * si->si_stride);
    365   1.1  jmcneill 			hrp = si->si_hwbits + (xoff * 2) +
    366   1.1  jmcneill 			    (yoff * si->si_stride);
    367   1.1  jmcneill 
    368   1.1  jmcneill 			for (y = 0; y < sheight; y++) {
    369   1.1  jmcneill 				memcpy(hrp, rp, swidth * 2);
    370   1.1  jmcneill 				rp += si->si_stride;
    371   1.1  jmcneill 				hrp += si->si_stride;
    372   1.1  jmcneill 			}
    373   1.1  jmcneill 		}
    374   1.1  jmcneill 	}
    375   1.1  jmcneill 
    376   1.1  jmcneill 	return;
    377   1.1  jmcneill }
    378   1.1  jmcneill #undef RGBTO16
    379   1.1  jmcneill #endif /* !NSPLASH16 > 0 */
    380   1.1  jmcneill 
    381   1.1  jmcneill #if NSPLASH32 > 0
    382   1.1  jmcneill static void
    383   1.1  jmcneill splash_render32(struct splash_info *si, const char *data, int xoff, int yoff,
    384   1.1  jmcneill 		int swidth, int sheight, int flg)
    385   1.1  jmcneill {
    386   1.1  jmcneill 	const char *d;
    387   1.1  jmcneill 	u_char *fb, *p;
    388   1.1  jmcneill 	u_char pix[3];
    389   1.1  jmcneill 	int x, y, i;
    390   1.1  jmcneill 	int filled;
    391   1.1  jmcneill 
    392   1.1  jmcneill 	fb = si->si_bits;
    393   1.1  jmcneill 
    394   1.1  jmcneill 	if (flg & SPLASH_F_FILL)
    395   1.1  jmcneill 		filled = 0;
    396   1.1  jmcneill 	else
    397   1.1  jmcneill 		filled = 1;
    398   1.1  jmcneill 
    399   1.1  jmcneill 	d = data;
    400   1.1  jmcneill 	fb += xoff * 4 + yoff * si->si_stride;
    401   1.1  jmcneill 
    402   1.1  jmcneill 	for (y = 0; y < sheight; y++) {
    403   1.1  jmcneill 		for (x = 0; x < swidth; x++) {
    404   1.9  jmcneill 			pix[0] = *d++;
    405   1.9  jmcneill 			pix[1] = *d++;
    406   1.9  jmcneill 			pix[2] = *d++;
    407   1.1  jmcneill 			if (filled == 0) {
    408   1.1  jmcneill 				p = si->si_bits;
    409   1.1  jmcneill 				i = 0;
    410   1.1  jmcneill 				while (i < si->si_height*si->si_stride) {
    411   1.1  jmcneill 					p[i++] = pix[2];
    412   1.1  jmcneill 					p[i++] = pix[1];
    413   1.1  jmcneill 					p[i++] = pix[0];
    414   1.1  jmcneill 					p[i++] = 0;
    415   1.1  jmcneill 				}
    416   1.1  jmcneill 				filled = 1;
    417   1.1  jmcneill 			}
    418   1.1  jmcneill 			fb[x*4+0] = pix[2];
    419   1.1  jmcneill 			fb[x*4+1] = pix[1];
    420   1.1  jmcneill 			fb[x*4+2] = pix[0];
    421   1.1  jmcneill 			fb[x*4+3] = 0;
    422   1.1  jmcneill 		}
    423   1.1  jmcneill 		fb += si->si_stride;
    424   1.1  jmcneill 	}
    425   1.1  jmcneill 
    426   1.1  jmcneill 	/* If we've just written to the shadow fb, copy it to the display */
    427   1.1  jmcneill 	if (si->si_hwbits) {
    428   1.1  jmcneill 		if (flg & SPLASH_F_FILL) {
    429   1.1  jmcneill 			memcpy(si->si_hwbits, si->si_bits,
    430   1.1  jmcneill 			    si->si_height*si->si_stride);
    431   1.1  jmcneill 		} else {
    432   1.1  jmcneill 			u_char *rp, *hrp;
    433   1.1  jmcneill 
    434   1.1  jmcneill 			rp = si->si_bits + (xoff * 4) + (yoff * si->si_stride);
    435   1.1  jmcneill 			hrp = si->si_hwbits + (xoff * 4) +
    436   1.1  jmcneill 			    (yoff * si->si_stride);
    437   1.1  jmcneill 
    438   1.1  jmcneill 			for (y = 0; y < sheight; y++) {
    439   1.1  jmcneill 				memcpy(hrp, rp, swidth * 4);
    440   1.1  jmcneill 				rp += si->si_stride;
    441   1.1  jmcneill 				hrp += si->si_stride;
    442   1.1  jmcneill 			}
    443   1.1  jmcneill 		}
    444   1.1  jmcneill 	}
    445   1.1  jmcneill 
    446   1.1  jmcneill 	return;
    447   1.1  jmcneill }
    448   1.1  jmcneill #endif /* !NSPLASH32 > 0 */
    449   1.1  jmcneill 
    450   1.1  jmcneill #endif /* !SPLASHSCREEN */
    451