summaryrefslogtreecommitdiffstats
path: root/sys/dev/syscons/dragon
diff options
context:
space:
mode:
authoramorita <amorita@FreeBSD.org>2002-03-23 12:36:19 +0000
committeramorita <amorita@FreeBSD.org>2002-03-23 12:36:19 +0000
commit4033e72cfb2cb652fe04c1cc726b166b268a6132 (patch)
treeeba2de2a3691e2a2553346033bd524ea9b2f3280 /sys/dev/syscons/dragon
parentd28168db048670ce4d3a2fccc387d0cb65bf1464 (diff)
downloadFreeBSD-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.c275
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);
OpenPOWER on IntegriCloud