diff options
author | amorita <amorita@FreeBSD.org> | 2002-03-23 12:36:19 +0000 |
---|---|---|
committer | amorita <amorita@FreeBSD.org> | 2002-03-23 12:36:19 +0000 |
commit | 4033e72cfb2cb652fe04c1cc726b166b268a6132 (patch) | |
tree | eba2de2a3691e2a2553346033bd524ea9b2f3280 /sys/dev/syscons/dragon | |
parent | d28168db048670ce4d3a2fccc387d0cb65bf1464 (diff) | |
download | FreeBSD-src-4033e72cfb2cb652fe04c1cc726b166b268a6132.zip FreeBSD-src-4033e72cfb2cb652fe04c1cc726b166b268a6132.tar.gz |
Add new graphical screen saver (dragon_saver).
Add support for NEC PC-9821 PEGC screen (fire/logo/rain/warp_saver).
Diffstat (limited to 'sys/dev/syscons/dragon')
-rw-r--r-- | sys/dev/syscons/dragon/dragon_saver.c | 275 |
1 files changed, 275 insertions, 0 deletions
diff --git a/sys/dev/syscons/dragon/dragon_saver.c b/sys/dev/syscons/dragon/dragon_saver.c new file mode 100644 index 0000000..f157e9c --- /dev/null +++ b/sys/dev/syscons/dragon/dragon_saver.c @@ -0,0 +1,275 @@ +/*- + * Copyright (c) 2000 Chiharu Shibata + * 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. + * + * $FreeBSD$ + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/module.h> +#include <sys/syslog.h> +#include <sys/consio.h> +#include <sys/fbio.h> + +#include <sys/random.h> + +#include <dev/fb/fbreg.h> +#include <dev/fb/splashreg.h> +#include <dev/syscons/syscons.h> + +#define SAVER_NAME "dragon_saver" + +static u_char *vid; +static int blanked; + +#ifdef PC98 +#define VIDEO_MODE M_PC98_EGC640x400 +#define VIDEO_MODE_NAME "M_PC98_EGC640x400" +#define SCRW 640 +#define SCRH 400 +#else +#define VIDEO_MODE M_VGA_CG320 +#define VIDEO_MODE_NAME "M_VGA_CG320" +#define SCRW 320 +#define SCRH 200 +#endif +#define ORDER 13 +#define CURVE 3 +#define OUT 100 + +static int cur_x, cur_y; +static int curve; +static u_char dragon_pal[3*256]; /* zero-filled by the compiler */ + +static __inline int +gpset(int x, int y, int val) +{ + if (x < 0 || y < 0 || SCRW <= x || SCRH <= y) { + return 0; + } +#ifdef PC98 + vid[(x + y * SCRW) >> 3] = (0x80 >> (x & 7)); /* write new dot */ +#else + vid[x + y * SCRW] = val; +#endif + return 1; +} + +static int +gdraw(int dx, int dy, int val) +{ + int i; + int set = 0; + +#ifdef PC98 + outb(0x7c, 0xcc); /* GRCG on & RMW mode(disable planeI,G) */ + outb(0x7e, (val & 1) ? 0xff: 0); /* tile B */ + outb(0x7e, (val & 2) ? 0xff: 0); /* tile R */ +#endif + if (dx != 0) { + i = cur_x; + cur_x += dx; + if (dx < 0) { + i += dx; + dx = -dx; + } + /* horizontal line */ + for (; dx >= 0; --dx, ++i) { + set |= gpset(i, cur_y, val); + } + } + else { /* dy != 0 */ + i = cur_y; + cur_y += dy; + if (dy < 0) { + i += dy; + dy = -dy; + } + /* vertical line */ + for (; dy >= 0; --dy, ++i) { + set |= gpset(cur_x, i, val); + } + } +#ifdef PC98 + outb(0x7c, 0); /* GRCG off */ +#endif + return set; +} + +static void +gcls(void) +{ +#ifdef PC98 + outb(0x7c, 0x80); /* GRCG on & TDW mode */ + outb(0x7e, 0); /* tile B */ + outb(0x7e, 0); /* tile R */ + outb(0x7e, 0); /* tile G */ + outb(0x7e, 0); /* tile I */ + + fillw(0, vid, 0x8000); + + outb(0x7c, 0); /* GRCG off */ +#else + bzero(vid, SCRW*SCRH); +#endif +} + +static void +dragon_update(video_adapter_t *adp) +{ + static int i, p, q; + static int order, mul, out; + static int org_x, org_y; + static int dx, dy; + static unsigned char fold[1 << (ORDER - 3)]; +#define GET_FOLD(x) (fold[(x) >> 3] & (1 << ((x) & 7))) +#define SET_FOLD(x) (fold[(x) >> 3] |= (1 << ((x) & 7))) +#define CLR_FOLD(x) (fold[(x) >> 3] &= ~(1 << ((x) & 7))) + int tmp; + + if (curve > CURVE) { + gcls(); + + /* set palette of each curves */ + for (tmp = 0; tmp < 3*CURVE; ++tmp) { + dragon_pal[3+tmp] = (u_char)random(); + } + load_palette(adp, dragon_pal); + + mul = ((random() & 7) + 1) * (SCRW / 320); + org_x = random() % SCRW; org_y = random() % SCRH; + + curve = 0; + order = ORDER; + } + + if (order >= ORDER) { + ++curve; + + cur_x = org_x; cur_y = org_y; + + switch (curve) { + case 1: + dx = 0; dy = mul; + break; + case 2: + dx = mul; dy = 0; + break; + case 3: + dx = 0; dy = -mul; + break; + } + (void)gdraw(dx, dy, curve); out = 0; + + order = 0; + q = p = 0; i = q + 1; + } + + if (i > q) { + SET_FOLD(p); q = p * 2; + + ++order; + i = p; p = q + 1; + } + + if (GET_FOLD(q-i) != 0) { + CLR_FOLD(i); + tmp = dx; dx = dy; dy = -tmp; /* turn right */ + } + else { + SET_FOLD(i); + tmp = dx; dx = -dy; dy = tmp; /* turn left */ + } + if (gdraw(dx, dy, curve)) { + out = 0; + } + else { + if (++out > OUT) { + order = ORDER; /* force to terminate this curve */ + } + } + ++i; +} + +static int +dragon_saver(video_adapter_t *adp, int blank) +{ + int pl; + + if (blank) { + /* switch to graphics mode */ + if (blanked <= 0) { + pl = splhigh(); + set_video_mode(adp, VIDEO_MODE); + vid = (u_char *)adp->va_window; + curve = CURVE + 1; + ++blanked; + splx(pl); + } + + /* update display */ + dragon_update(adp); + } + else { + blanked = 0; + } + return 0; +} + +static int +dragon_init(video_adapter_t *adp) +{ + video_info_t info; + + /* check that the console is capable of running in 320x200x256 */ + if (get_mode_info(adp, VIDEO_MODE, &info)) { + log(LOG_NOTICE, + "%s: the console does not support " VIDEO_MODE_NAME "\n", + SAVER_NAME); + return ENODEV; + } + + blanked = 0; + return 0; +} + +static int +dragon_term(video_adapter_t *adp) +{ + return 0; +} + +static scrn_saver_t dragon_module = { + SAVER_NAME, + dragon_init, + dragon_term, + dragon_saver, + NULL, +}; + +SAVER_MODULE(dragon_saver, dragon_module); |