Home | History | Annotate | Line # | Download | only in rasops
rasops24.c revision 1.2
      1 /* $NetBSD: rasops24.c,v 1.2 1999/04/13 00:40:09 ad Exp $ */
      2 
      3 /*
      4  * Copyright (c) 1999 Andy Doran <ad (at) NetBSD.org>
      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  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  *
     28  */
     29 
     30 #include <sys/cdefs.h>
     31 __KERNEL_RCSID(0, "$NetBSD: rasops24.c,v 1.2 1999/04/13 00:40:09 ad Exp $");
     32 
     33 #include "opt_rasops.h"
     34 #ifdef RASOPS24
     35 #error This is dangerously incomplete.
     36 
     37 #include <sys/types.h>
     38 #include <sys/param.h>
     39 #include <sys/systm.h>
     40 #include <sys/time.h>
     41 
     42 #include <dev/wscons/wsdisplayvar.h>
     43 #include <dev/wscons/wsconsio.h>
     44 #include <dev/rasops/rasops.h>
     45 
     46 static void 	rasops24_putchar __P((void *, int, int, u_int, long attr));
     47 static void 	rasops24_erasecols __P((void *, int, int, int, long));
     48 static void 	rasops24_eraserows __P((void *, int, int, long));
     49 static int	rasops24_alloc_attr __P((void *, int, int, int, long *));
     50 static void	rasops24_make_bgstamp __P((int, u_char *));
     51 static int32_t	rasops24_fg_color __P((struct rasops_info *, long));
     52 static int32_t	rasops24_bg_color __P((struct rasops_info *, long));
     53 static void	rasops24_do_cursor __P((struct rasops_info *));
     54 
     55 void	rasops24_init __P((struct rasops_info *ri));
     56 
     57 /*
     58  * Initalize rasops_info struct for this colordepth.
     59  */
     60 void
     61 rasops24_init(ri)
     62 	struct rasops_info *ri;
     63 {
     64 
     65 	switch (ri->ri_font->fontwidth) {
     66 	case 8:
     67 		ri->ri_ops.putchar = rasops15_putchar8;
     68 		break;
     69 
     70 	case 12:
     71 		ri->ri_ops.putchar = rasops15_putchar12;
     72 		break;
     73 
     74 	case 16:
     75 		ri->ri_ops.putchar = rasops15_putchar16;
     76 		break;
     77 
     78 	default:
     79 		ri->ri_ops.putchar = rasops15_putchar;
     80 		break;
     81 	}
     82 
     83 	/* Select defaults for color positions if none selected */
     84 	if (ri->ri_rnum == 0) {
     85 		ri->ri_rnum = 8;
     86 		ri->ri_gnum = 8;
     87 		ri->ri_bnum = 8;
     88 		ri->ri_rpos = 0;
     89 		ri->ri_gpos = 8;
     90 		ri->ri_bpos = 16;
     91 	}
     92 
     93 	ri->ri_ops.erasecols = rasops25_erasecols;
     94 	ri->ri_ops.eraserows = rasops25_eraserows;
     95 	ri->ri_do_cursor = rasops25_do_cursor;
     96 	rasops_init_devcmap(ri);
     97 }
     98 
     99 /*
    100  * Get foreground color from attribute and copy across all 4 bytes
    101  * in a int32_t.
    102  */
    103 static __inline__ int32_t
    104 rasops24_fg_color(ri, attr)
    105 	struct rasops_info *ri;
    106 	long attr;
    107 {
    108 	int32_t fg;
    109 
    110 	fg = ri->ri_devcmap[((u_int)attr >> 24) & 15];
    111 
    112 	/* Copy across all 4 bytes if the color is gray */
    113 	if (attr & 2)
    114 		fg |= fg << 8;
    115 
    116 	return fg;
    117 }
    118 
    119 
    120 /*
    121  * Get background color from attribute and copy across all 4 bytes
    122  * in a int32_t.
    123  */
    124 static __inline__ int32_t
    125 rasops24_bg_color(ri, attr)
    126 	struct rasops_info *ri;
    127 	long attr;
    128 {
    129 	int32_t bg;
    130 
    131 	bg = ri->ri_devcmap[((u_int)attr >> 16) & 15];
    132 
    133 	/* Copy across all 4 bytes if the color is gray */
    134 	if (attr & 4)
    135 		bg |= bg << 8;
    136 
    137 	return bg;
    138 }
    139 
    140 
    141 /*
    142  * Actually turn the cursor on or off. This does the dirty work for
    143  * rasops_cursor().
    144  */
    145 static void
    146 rasops24_do_cursor(ri)
    147 	struct rasops_info *ri;
    148 {
    149 	int full1, height, cnt, slop1, slop2, row, col;
    150 	u_char *dp, *rp;
    151 
    152 	row = ri->ri_crow;
    153 	col = ri->ri_ccol;
    154 
    155 	rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
    156 	height = ri->ri_font->fontheight;
    157 
    158 	slop1 = (int)rp & 3;
    159 	slop2 = (ri->ri_xscale - slop1) & 3;
    160 	full1 = (ri->ri_xscale - slop1 - slop2) >> 2;
    161 
    162 	while (height--) {
    163 		dp = rp;
    164 		rp += ri->ri_stride;
    165 
    166 		for (cnt = slop1; cnt; cnt--)
    167 			*dp++ ^= 0xff;
    168 
    169 		for (cnt = full1; cnt; cnt--) {
    170 			*(int32_t *)dp ^= 0xffffffff;
    171 			dp += 4;
    172 		}
    173 
    174 		for (cnt = slop2; cnt; cnt--)
    175 			*dp++ ^= 0xff;
    176 	}
    177 }
    178 
    179 
    180 /*
    181  * Erase columns.
    182  */
    183 static void
    184 rasops24_erasecols(cookie, row, col, num, attr)
    185 	void *cookie;
    186 	int row, col, num;
    187 	long attr;
    188 {
    189 	struct rasops_info *ri;
    190 	int32_t *dp;
    191 	u_char *rp;
    192 	int n8, n1, clr, height, cnt, slop1, slop2;
    193 
    194 	ri = (struct rasops_info *)cookie;
    195 
    196 #ifdef RASOPS_CLIPPING
    197 	/* Catches 'row < 0' case too */
    198 	if ((unsigned)row >= (unsigned)ri->ri_rows)
    199 		return;
    200 
    201 	if (col < 0) {
    202 		num += col;
    203 		col = 0;
    204 	}
    205 
    206 	if ((col + num) > ri->ri_cols)
    207 		num = ri->ri_cols - col;
    208 
    209 	if (num <= 0)
    210 		return;
    211 #endif
    212 
    213 	rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
    214 	num *= ri->ri_xscale;
    215 	clr = rasops24_bg_color(ri, attr);
    216 	height = ri->ri_font->fontheight;
    217 
    218 	slop1 = (int)rp & 2;
    219 	slop2 = (num - slop1) & 2;
    220 	n8 = num >> 5;
    221 	n1 = (num >> 2) & 7;
    222 
    223 	while (height--) {
    224 		cnt = num;
    225 		dp = (u_int32_t *)rp;
    226 		rp += ri->ri_stride;
    227 
    228 		/* Align span to 4 bytes */
    229 		if (slop1) {
    230 			*(int16_t *)dp = (int16_t)clr;
    231 			DELTA(dp, 2, int32_t *);
    232 		}
    233 
    234 		/* Write 32 bytes per loop */
    235 		for (cnt = n8; cnt; cnt--) {
    236 			dp[0] = clr;
    237 			dp[1] = clr;
    238 			dp[2] = clr;
    239 			dp[3] = clr;
    240 			dp[4] = clr;
    241 			dp[5] = clr;
    242 			dp[6] = clr;
    243 			dp[7] = clr;
    244 			dp += 8;
    245 		}
    246 
    247 		/* Write 4 bytes per loop */
    248 		for (cnt = n1; cnt; cnt--)
    249 			*dp++ = clr;
    250 
    251 		/* Write unaligned trailing slop */
    252 		if (slop2)
    253 			*(int16_t *)dp = (int16_t)clr;
    254 	}
    255 }
    256 
    257 
    258 /*
    259  * Paint a single character.
    260  */
    261 static void
    262 rasops24_putchar(cookie, row, col, uc, attr)
    263 	void *cookie;
    264 	int row, col;
    265 	u_int uc;
    266 	long attr;
    267 {
    268 	struct rasops_info *ri;
    269 	u_char *dp, *rp;
    270 	int32_t *fr, clr[16], fb;
    271 	int width, height, cnt;
    272 
    273 	if (uc == (u_int)-1) {
    274 		rasops24_erasecols(cookie, row, col, 1, attr);
    275 		return;
    276 	}
    277 
    278 	ri = (struct rasops_info *)cookie;
    279 
    280 #ifdef RASOPS_CLIPPING
    281 	if ((unsigned)row >= (unsigned)ri->ri_rows)
    282 		return;
    283 
    284 	if ((unsigned)col >= (unsigned)ri->ri_cols)
    285 		return;
    286 #endif
    287 
    288 	rp = ri->ri_bits + row * ri->ri_yscale + col * ri->ri_xscale;
    289 	fr = (int32_t *)ri->ri_font->data + uc * ri->ri_font->fontheight;
    290 
    291 	height = ri->ri_font->fontheight;
    292 	width = ri->ri_font->fontwidth;
    293 
    294 	clr[1] = ri->ri_devcmap[((u_int)attr >> 24)];
    295 	clr[0] = ri->ri_devcmap[((u_int)attr >> 16)];
    296 
    297 	while (height--) {
    298 		dp = rp;
    299 		fb = *fr++;
    300 		rp += ri->ri_stride;
    301 
    302 		for (cnt = width; cnt; cnt--) {
    303 			*(int16_t *)dp = (int16_t)clr[fb & 1];
    304 			fb >>= 1;
    305 			dp += 2;
    306 		}
    307 	}
    308 }
    309 
    310 
    311 /*
    312  * Construct a 12 byte by 1 byte blitting stamp. This uses the background
    313  * color only (for erasecols()/eraserows()).
    314  */
    315 static void
    316 rasops24_make_bgstamp(i, bp)
    317 	int i;
    318 	u_char *bp;
    319 {
    320 	u_char r, g, b;
    321 
    322 	i = (i >> 8) & 0xff;
    323 	i = (i << 1) + i;
    324 	r = rasops_cmap[i+0];
    325 	g = rasops_cmap[i+1];
    326 	b = rasops_cmap[i+2];
    327 
    328 #if BYTE_ORDER == LITTLE_ENDIAN
    329 	bp[0] = r; bp[1] = g; bp[2] = b;  bp[3] = r;
    330 	bp[4] = g; bp[5] = b; bp[6] = r;  bp[7] = g;
    331 	bp[8] = b; bp[9] = r; bp[10] = g; bp[11] = b;
    332 #else
    333 	bp[3] = r;  bp[2] = g;  bp[1] = b; bp[0] = r;
    334 	bp[7] = g;  bp[6] = b;  bp[5] = r; bp[4] = g;
    335 	bp[11] = b; bp[10] = r; bp[9] = g; bp[8] = b;
    336 #endif
    337 }
    338 
    339 
    340 /*
    341  * Erase rows.
    342  */
    343 static void
    344 rasops24_eraserows(cookie, row, num, attr)
    345 	void *cookie;
    346 	int row, num;
    347 	long attr;
    348 {
    349 	struct rasops_info *ri;
    350 	int32_t *dp, clr, stamp[3];
    351 	int n9, n3, n1, cnt;
    352 
    353 	ri = (struct rasops_info *)cookie;
    354 
    355 #ifdef RASOPS_CLIPPING
    356 	if (row < 0) {
    357 		num += row;
    358 		row = 0;
    359 	}
    360 
    361 	if ((row + num) > ri->ri_rows)
    362 		num = ri->ri_rows - row;
    363 
    364 	if (num <= 0)
    365 		return;
    366 #endif
    367 
    368 	num *= ri->ri_font->fontheight;
    369 	dp = (int32_t *)(ri->ri_bits + row * ri->ri_yscale);
    370 
    371 	n9 = ri->ri_emustride / 36;
    372 	cnt = (n9 << 5) + (n9 << 2); /* (32*n9) + (4*n9) */
    373 
    374 	n3 = (ri->ri_emustride - cnt) / 12;
    375 	cnt += (n3 << 3) + (n3 << 2); /* (8*n3) + (4*n3) */
    376 
    377 	n1 = (ri->ri_emustride - cnt) >> 2;
    378 
    379 	/* If the color is gray, we can cheat... */
    380 	if (attr & ATTR_GRAY_BG) {
    381 		clr = rasops24_bg_color(ri, attr);
    382 
    383 		while (num--) {
    384 			for (cnt = n9; cnt; cnt--) {
    385 				dp[0] = clr;
    386 				dp[1] = clr;
    387 				dp[2] = clr;
    388 				dp[3] = clr;
    389 				dp[4] = clr;
    390 				dp[5] = clr;
    391 				dp[6] = clr;
    392 				dp[7] = clr;
    393 				dp[8] = clr;
    394 				dp += 9;
    395 			}
    396 
    397 			for (cnt = n3; cnt; cnt--) {
    398 				dp[0] = clr;
    399 				dp[1] = clr;
    400 				dp[2] = clr;
    401 				dp += 3;
    402 			}
    403 
    404 			for (cnt = n1; cnt; cnt--)
    405 				*dp++ = clr;
    406 
    407 			DELTA(dp, ri->ri_delta, int32_t *);
    408 		}
    409 	} else {
    410 		rasops24_make_bgstamp((int)attr, (u_char *)stamp);
    411 
    412 		while (num--) {
    413 			for (cnt = n9; cnt; cnt--) {
    414 				dp[0] = stamp[0];
    415 				dp[1] = stamp[1];
    416 				dp[2] = stamp[2];
    417 				dp[3] = stamp[0];
    418 				dp[4] = stamp[1];
    419 				dp[5] = stamp[2];
    420 				dp[6] = stamp[0];
    421 				dp[7] = stamp[1];
    422 				dp[8] = stamp[2];
    423 				dp += 9;
    424 			}
    425 
    426 			for (cnt = n3; cnt; cnt--) {
    427 				dp[0] = stamp[0];
    428 				dp[1] = stamp[1];
    429 				dp[2] = stamp[2];
    430 				dp += 3;
    431 			}
    432 
    433 			for (cnt = 0; cnt < n1; cnt++)
    434 				*dp++ = stamp[cnt];
    435 
    436 			DELTA(dp, ri->ri_delta, int32_t *);
    437 		}
    438 	}
    439 }
    440 
    441 #endif /* RASOPS24 */
    442