Add new graphical screen saver (dragon_saver).

Add support for NEC PC-9821 PEGC screen (fire/logo/rain/warp_saver).
This commit is contained in:
Akio Morita 2002-03-23 12:36:19 +00:00
parent 359052dbcc
commit 81b60c7395
7 changed files with 511 additions and 96 deletions

View File

@ -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);

View File

@ -39,96 +39,157 @@
#include <sys/module.h>
#include <sys/syslog.h>
#include <sys/consio.h>
#include <sys/malloc.h>
#include <sys/fbio.h>
#include <dev/fb/fbreg.h>
#include <dev/fb/splashreg.h>
#include <dev/syscons/syscons.h>
#define X_SIZE 320
#define Y_SIZE 200
#define SAVER_NAME "fire_saver"
static int blanked;
static u_char fire_pal[768];
static u_char buf[X_SIZE * (Y_SIZE + 1)];
static u_char *vid;
#define RED(n) ((n) * 3 + 0)
#define GREEN(n) ((n) * 3 + 1)
#define BLUE(n) ((n) * 3 + 2)
static u_char *buf;
static u_char *vid;
static int banksize, scrmode, bpsl, scrw, scrh;
static u_char fire_pal[768];
static int blanked;
static void
fire_update(video_adapter_t *adp)
{
int x, y;
int o, p;
/* make a new bottom line */
for (x = 0, y = scrh; x < scrw; x++)
buf[x + (y * bpsl)] = random() % 160 + 96;
/* fade the flames out */
for (y = 0; y < scrh; y++) {
for (x = 0; x < scrw; x++) {
buf[x + (y * scrw)] =
(buf[(x + 0) + ((y + 0) * scrw)] +
buf[(x - 1) + ((y + 1) * scrw)] +
buf[(x + 0) + ((y + 1) * scrw)] +
buf[(x + 1) + ((y + 1) * scrw)]) / 4;
if (buf[x + (y * scrw)] > 0)
buf[x + (y * scrw)]--;
}
}
/* blit our buffer into video ram */
for (y = 0, p = 0, o = 0; y < scrh; y++, p += bpsl) {
while (p > banksize) {
p -= banksize;
o += banksize;
}
set_origin(adp, o);
if (p + scrw < banksize) {
bcopy(buf + y * scrw, vid + p, scrw);
} else {
bcopy(buf + y * scrw, vid + p, banksize - p);
set_origin(adp, o + banksize);
bcopy(buf + y * scrw + (banksize - p), vid,
scrw - (banksize - p));
p -= banksize;
o += banksize;
}
}
}
static int
fire_saver(video_adapter_t *adp, int blank)
{
int x, y;
int i, pl;
if (blank) {
if (blanked <= 0) {
int red, green, blue;
int palette_index;
if (blank) {
/* switch to graphics mode */
if (blanked <= 0) {
pl = splhigh();
set_video_mode(adp, scrmode);
load_palette(adp, fire_pal);
blanked++;
vid = (u_char *)adp->va_window;
banksize = adp->va_window_size;
bpsl = adp->va_line_width;
splx(pl);
for (i = 0; i < bpsl * scrh; i += banksize) {
set_origin(adp, i);
bzero(vid, banksize);
}
}
fire_update(adp);
} else {
blanked = 0;
}
set_video_mode(adp, M_VGA_CG320);
return 0;
}
/* build and load palette */
red = green = blue = 0;
for (palette_index = 0; palette_index < 256; palette_index++) {
static int
fire_init(video_adapter_t *adp)
{
video_info_t info;
int i, red, green, blue;
if (!get_mode_info(adp, M_VGA_CG320, &info)) {
scrmode = M_VGA_CG320;
} else if (!get_mode_info(adp, M_PC98_PEGC640x480, &info)) {
scrmode = M_PC98_PEGC640x480;
} else if (!get_mode_info(adp, M_PC98_PEGC640x400, &info)) {
scrmode = M_PC98_PEGC640x400;
} else {
log(LOG_NOTICE,
"%s: the console does not support M_VGA_CG320\n",
SAVER_NAME);
return (ENODEV);
}
scrw = info.vi_width;
scrh = info.vi_height;
buf = (u_char *)malloc(scrw * (scrh + 1), M_DEVBUF, M_NOWAIT);
if (buf) {
bzero(buf, scrw * (scrh + 1));
} else {
log(LOG_NOTICE,
"%s: buffer allocation is failed\n",
SAVER_NAME);
return (ENODEV);
}
/* intialize the palette */
red = green = blue = 0;
for (i = 0; i < 256; i++) {
red++;
if (red > 128)
green += 2;
fire_pal[(palette_index * 3) + 0] = red;
fire_pal[(palette_index * 3) + 1] = green;
fire_pal[(palette_index * 3) + 2] = blue;
}
load_palette(adp, fire_pal);
blanked++;
vid = (u_char *) adp->va_window;
}
/* make a new bottom line */
for (x = 0, y = Y_SIZE; x < X_SIZE; x++)
buf[x + (y * X_SIZE)] = random() % 160 + 96;
/* fade the flames out */
for (y = 0; y < Y_SIZE; y++) {
for (x = 0; x < X_SIZE; x++) {
buf[x + (y * X_SIZE)] = (buf[(x + 0) + ((y + 0) * X_SIZE)] +
buf[(x - 1) + ((y + 1) * X_SIZE)] +
buf[(x + 0) + ((y + 1) * X_SIZE)] +
buf[(x + 1) + ((y + 1) * X_SIZE)]) / 4;
if (buf[x + (y * X_SIZE)] > 0)
buf[x + (y * X_SIZE)]--;
}
green += 2;
fire_pal[RED(i)] = red;
fire_pal[GREEN(i)] = green;
fire_pal[BLUE(i)] = blue;
}
/* blit our buffer into video ram */
memcpy(vid, buf, X_SIZE * Y_SIZE);
} else {
blanked = 0;
}
return 0;
return (0);
}
static int
fire_initialise(video_adapter_t *adp)
fire_term(video_adapter_t *adp)
{
video_info_t info;
/* check that the console is capable of running in 320x200x256 */
if (get_mode_info(adp, M_VGA_CG320, &info)) {
log(LOG_NOTICE, "fire_saver: the console does not support M_VGA_CG320\n");
return (ENODEV);
}
blanked = 0;
return 0;
}
static int
fire_terminate(video_adapter_t *adp)
{
return 0;
free(buf, M_DEVBUF);
return (0);
}
static scrn_saver_t fire_module = {
"fire_saver", fire_initialise, fire_terminate, fire_saver, NULL
SAVER_NAME,
fire_init,
fire_term,
fire_saver,
NULL
};
SAVER_MODULE(fire_saver, fire_module);

View File

@ -136,6 +136,10 @@ logo_init(video_adapter_t *adp)
scrmode = M_VESA_CG800x600;
} else if (!get_mode_info(adp, M_VGA_CG320, &info)) {
scrmode = M_VGA_CG320;
} else if (!get_mode_info(adp, M_PC98_PEGC640x480, &info)) {
scrmode = M_PC98_PEGC640x480;
} else if (!get_mode_info(adp, M_PC98_PEGC640x400, &info)) {
scrmode = M_PC98_PEGC640x400;
} else {
log(LOG_NOTICE,
"%s: the console does not support M_VGA_CG320\n",

View File

@ -41,8 +41,6 @@
#include <dev/syscons/syscons.h>
#define SAVER_NAME "rain_saver"
#define SCRW 320
#define SCRH 200
#define MAX 63 /* number of colors (in addition to black) */
#define INCREMENT 4 /* increment between colors */
@ -51,6 +49,7 @@
#define BLUE(n) ((n) * 3 + 2)
static u_char *vid;
static int banksize, scrmode, bpsl, scrw, scrh;
static u_char rain_pal[768];
static int blanked;
@ -69,25 +68,53 @@ rain_update(video_adapter_t *adp)
static int
rain_saver(video_adapter_t *adp, int blank)
{
int i, j, k, pl;
int i, j, k, o, p, pl;
u_char temp;
if (blank) {
/* switch to graphics mode */
if (blanked <= 0) {
pl = splhigh();
set_video_mode(adp, M_VGA_CG320);
set_video_mode(adp, scrmode);
load_palette(adp, rain_pal);
set_border(adp, 0);
blanked++;
vid = (u_char *)adp->va_window;
banksize = adp->va_window_size;
bpsl = adp->va_line_width;
splx(pl);
bzero(vid, SCRW * SCRH);
for (i = 0; i < SCRW; i += 2)
vid[i] = 1 + (random() % MAX);
for (j = 1, k = SCRW; j < SCRH; j++)
for (i = 0; i < SCRW; i += 2, k += 2)
vid[k] = (vid[k - SCRW] < MAX) ?
1 + vid[k - SCRW] : 1;
for (i = 0; i < bpsl*scrh; i += banksize) {
set_origin(adp, i);
if ((bpsl * scrh - i) < banksize)
bzero(vid, bpsl * scrh - i);
else
bzero(vid, banksize);
}
set_origin(adp, 0);
for (i = 0, o = 0, p = 0; i < scrw; i += 2, p += 2) {
if (p > banksize) {
p -= banksize;
o += banksize;
set_origin(adp, o);
}
vid[p] = 1 + (random() % MAX);
}
o = 0; p = 0;
for (j = 1; j < scrh; j++)
for (i = 0, p = bpsl * (j - 1) - o; i < scrw; i += 2, p+= 2) {
while (p > banksize) {
p -= banksize;
o += banksize;
}
set_origin(adp, o);
temp = (vid[p] < MAX) ? 1 + vid[p] : 1;
if (p + bpsl < banksize) {
vid[p + bpsl] = temp;
} else {
set_origin(adp, o + banksize);
vid[p + bpsl - banksize] = temp;
}
}
}
/* update display */
@ -104,14 +131,22 @@ rain_init(video_adapter_t *adp)
video_info_t info;
int i;
/* check that the console is capable of running in 320x200x256 */
if (get_mode_info(adp, M_VGA_CG320, &info)) {
if (!get_mode_info(adp, M_VGA_CG320, &info)) {
scrmode = M_VGA_CG320;
} else if (!get_mode_info(adp, M_PC98_PEGC640x480, &info)) {
scrmode = M_PC98_PEGC640x480;
} else if (!get_mode_info(adp, M_PC98_PEGC640x400, &info)) {
scrmode = M_PC98_PEGC640x400;
} else {
log(LOG_NOTICE,
"%s: the console does not support M_VGA_CG320\n",
SAVER_NAME);
return (ENODEV);
}
scrw = info.vi_width;
scrh = info.vi_height;
/* intialize the palette */
for (i = 1; i < MAX; i++)
rain_pal[BLUE(i)] = rain_pal[BLUE(i - 1)] + INCREMENT;

View File

@ -41,12 +41,11 @@
#include <dev/syscons/syscons.h>
#define SAVER_NAME "warp_saver"
#define SCRW 320
#define SCRH 200
#define SPP 15
#define STARS (SPP * (1 + 2 + 4 + 8))
static u_char *vid;
static int banksize, scrmode, bpsl, scrw, scrh;
static int blanked;
static int star[STARS];
static u_char warp_pal[768] = {
@ -59,17 +58,31 @@ static u_char warp_pal[768] = {
};
static void
warp_update(void)
warp_update(video_adapter_t *adp)
{
int i, j, k, n;
int i, j, k, n, o, p;
for (i = 1, k = 0, n = SPP*8; i < 5; i++, n /= 2) {
for (j = 0; j < n; j++, k++) {
vid[star[k]] = 0;
p = (star[k] / scrw) * bpsl + (star[k] % scrw);
o = 0;
while (p > banksize) {
p -= banksize;
o += banksize;
}
set_origin(adp, o);
vid[p] = 0;
star[k] += i;
if (star[k] > SCRW * SCRH)
star[k] -= SCRW * SCRH;
vid[star[k]] = i;
if (star[k] > scrw*scrh)
star[k] -= scrw*scrh;
p = (star[k] / scrw) * bpsl + (star[k] % scrw);
o = 0;
while (p > banksize) {
p -= banksize;
o += banksize;
}
set_origin(adp, o);
vid[p] = i;
}
}
}
@ -77,23 +90,27 @@ warp_update(void)
static int
warp_saver(video_adapter_t *adp, int blank)
{
int pl;
int i, pl;
if (blank) {
/* switch to graphics mode */
if (blanked <= 0) {
pl = splhigh();
set_video_mode(adp, M_VGA_CG320);
set_video_mode(adp, scrmode);
load_palette(adp, warp_pal);
set_border(adp, 0);
blanked++;
vid = (u_char *)adp->va_window;
banksize = adp->va_window_size;
bpsl = adp->va_line_width;
splx(pl);
bzero(vid, SCRW * SCRH);
for (i = 0; i < bpsl * scrh; i += banksize) {
set_origin(adp, i);
bzero(vid, banksize);
}
}
/* update display */
warp_update();
warp_update(adp);
} else {
blanked = 0;
}
@ -106,17 +123,25 @@ warp_init(video_adapter_t *adp)
video_info_t info;
int i;
/* check that the console is capable of running in 320x200x256 */
if (get_mode_info(adp, M_VGA_CG320, &info)) {
if (!get_mode_info(adp, M_VGA_CG320, &info)) {
scrmode = M_VGA_CG320;
} else if (!get_mode_info(adp, M_PC98_PEGC640x480, &info)) {
scrmode = M_PC98_PEGC640x480;
} else if (!get_mode_info(adp, M_PC98_PEGC640x400, &info)) {
scrmode = M_PC98_PEGC640x400;
} else {
log(LOG_NOTICE,
"%s: the console does not support M_VGA_CG320\n",
SAVER_NAME);
return (ENODEV);
}
scrw = info.vi_width;
scrh = info.vi_height;
/* randomize the star field */
for (i = 0; i < STARS; i++)
star[i] = random() % (SCRW * SCRH);
star[i] = random() % (scrw * scrh);
return (0);
}

View File

@ -3,6 +3,7 @@
SUBDIR =
SUBDIR += blank
SUBDIR += daemon
SUBDIR += dragon
SUBDIR += fade
SUBDIR += fire
SUBDIR += green

View File

@ -0,0 +1,14 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../../dev/syscons/dragon
KMOD= dragon_saver
SRCS= dragon_saver.c
#CWARNFLAGS= -Wall -Wno-long-long -pedantic
.if ${MACHINE} == "pc98"
CFLAGS+= -DPC98
.endif
.include <bsd.kmod.mk>