142205Sdes/*-
2230132Suqs * Copyright (c) 1998 Dag-Erling Co��dan Sm��rgrav
342205Sdes * All rights reserved.
442205Sdes *
542205Sdes * Redistribution and use in source and binary forms, with or without
642205Sdes * modification, are permitted provided that the following conditions
742205Sdes * are met:
842205Sdes * 1. Redistributions of source code must retain the above copyright
942205Sdes *    notice, this list of conditions and the following disclaimer
1042205Sdes *    in this position and unchanged.
1142205Sdes * 2. Redistributions in binary form must reproduce the above copyright
1242205Sdes *    notice, this list of conditions and the following disclaimer in the
1342205Sdes *    documentation and/or other materials provided with the distribution.
1442205Sdes * 3. The name of the author may not be used to endorse or promote products
1542205Sdes *    derived from this software without specific prior written permission
1642205Sdes *
1742205Sdes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1842205Sdes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1942205Sdes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2042205Sdes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2142205Sdes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2242205Sdes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2342205Sdes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2442205Sdes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2542205Sdes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2642205Sdes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2742205Sdes *
2850477Speter * $FreeBSD$
2942205Sdes */
3042205Sdes
3142205Sdes#include <sys/param.h>
3242205Sdes#include <sys/systm.h>
3342205Sdes#include <sys/kernel.h>
3442205Sdes#include <sys/module.h>
3542205Sdes#include <sys/syslog.h>
3648104Syokota#include <sys/consio.h>
3748104Syokota#include <sys/fbio.h>
3842205Sdes
3948104Syokota#include <dev/fb/fbreg.h>
4048104Syokota#include <dev/fb/splashreg.h>
4148104Syokota#include <dev/syscons/syscons.h>
4242205Sdes
4386120Sdes#define SAVER_NAME	 "rain_saver"
44110235Salfred#ifdef MAX
45110235Salfred#undef MAX
46110235Salfred#endif
4786122Sdes#define MAX		 63	/* number of colors (in addition to black) */
4886122Sdes#define INCREMENT	 4	/* increment between colors */
4942205Sdes
5086122Sdes#define RED(n)		 ((n) * 3 + 0)
5186122Sdes#define GREEN(n)	 ((n) * 3 + 1)
5286122Sdes#define BLUE(n)		 ((n) * 3 + 2)
5386122Sdes
54166868Sphilip#define SET_ORIGIN(adp, o) do {				\
55166868Sphilip	int oo = o;					\
56166868Sphilip	if (oo != last_origin)				\
57174985Swkoszek	    vidd_set_win_org(adp, last_origin = oo);	\
58166868Sphilip	} while (0)
59166868Sphilip
6086120Sdesstatic u_char		*vid;
6193011Samoritastatic int		 banksize, scrmode, bpsl, scrw, scrh;
6286120Sdesstatic u_char		 rain_pal[768];
6386120Sdesstatic int		 blanked;
6442205Sdes
6542205Sdesstatic void
6642504Syokotarain_update(video_adapter_t *adp)
6742205Sdes{
6886120Sdes	int i, t;
6986122Sdes
7086122Sdes	t = rain_pal[BLUE(MAX)];
7186122Sdes	for (i = MAX; i > 1; i--)
7286122Sdes		rain_pal[BLUE(i)] = rain_pal[BLUE(i - 1)];
7386122Sdes	rain_pal[BLUE(1)] = t;
74174985Swkoszek	vidd_load_palette(adp, rain_pal);
7542205Sdes}
7642205Sdes
7742504Syokotastatic int
7842504Syokotarain_saver(video_adapter_t *adp, int blank)
7942205Sdes{
8093115Sbrooks	int i, j, o, p, pl;
8193011Samorita	u_char temp;
82166868Sphilip	int last_origin = -1;
8393011Samorita
8486120Sdes	if (blank) {
8586120Sdes		/* switch to graphics mode */
8686120Sdes		if (blanked <= 0) {
8786120Sdes			pl = splhigh();
88174985Swkoszek			vidd_set_mode(adp, scrmode);
89174985Swkoszek			vidd_load_palette(adp, rain_pal);
90174985Swkoszek			vidd_set_border(adp, 0);
9186120Sdes			blanked++;
9286120Sdes			vid = (u_char *)adp->va_window;
9393011Samorita			banksize = adp->va_window_size;
9493011Samorita			bpsl = adp->va_line_width;
9586120Sdes			splx(pl);
9693011Samorita			for (i = 0; i < bpsl*scrh; i += banksize) {
97166868Sphilip				SET_ORIGIN(adp, i);
9893011Samorita				if ((bpsl * scrh - i) < banksize)
9993011Samorita					bzero(vid, bpsl * scrh - i);
10093011Samorita				else
10193011Samorita					bzero(vid, banksize);
10293011Samorita			}
103166868Sphilip			SET_ORIGIN(adp, 0);
10493011Samorita			for (i = 0, o = 0, p = 0; i < scrw; i += 2, p += 2) {
10593011Samorita				if (p > banksize) {
10693011Samorita					p -= banksize;
10793011Samorita					o += banksize;
108166868Sphilip					SET_ORIGIN(adp, o);
10993011Samorita				}
11093011Samorita				vid[p] = 1 + (random() % MAX);
11193011Samorita			}
11293011Samorita			o = 0; p = 0;
11393011Samorita			for (j = 1; j < scrh; j++)
11493011Samorita			  for (i = 0, p = bpsl * (j - 1) - o; i < scrw; i += 2, p+= 2) {
11593011Samorita			  	while (p > banksize) {
11693011Samorita					p -= banksize;
11793011Samorita					o += banksize;
11893011Samorita				}
119166868Sphilip				SET_ORIGIN(adp, o);
12093011Samorita				temp = (vid[p] < MAX) ? 1 + vid[p] : 1;
12193011Samorita				if (p + bpsl < banksize) {
12293011Samorita					vid[p + bpsl] = temp;
12393011Samorita				} else {
124166868Sphilip					SET_ORIGIN(adp, o + banksize);
12593011Samorita					vid[p + bpsl - banksize] = temp;
12693011Samorita				}
12793011Samorita			  }
12886120Sdes		}
12986120Sdes
13086120Sdes		/* update display */
13186120Sdes		rain_update(adp);
13286120Sdes	} else {
13386120Sdes		blanked = 0;
13442205Sdes	}
13586120Sdes	return (0);
13642205Sdes}
13742205Sdes
13842205Sdesstatic int
13942504Syokotarain_init(video_adapter_t *adp)
14042205Sdes{
14186120Sdes	video_info_t info;
14286120Sdes	int i;
14386120Sdes
144174985Swkoszek	if (!vidd_get_info(adp, M_VGA_CG320, &info)) {
14593011Samorita		scrmode = M_VGA_CG320;
146174985Swkoszek	} else if (!vidd_get_info(adp, M_PC98_PEGC640x480, &info)) {
14793011Samorita		scrmode = M_PC98_PEGC640x480;
148174985Swkoszek	} else if (!vidd_get_info(adp, M_PC98_PEGC640x400, &info)) {
14993011Samorita		scrmode = M_PC98_PEGC640x400;
15093011Samorita	} else {
15186120Sdes		log(LOG_NOTICE,
15286120Sdes		    "%s: the console does not support M_VGA_CG320\n",
15386120Sdes		    SAVER_NAME);
15486120Sdes		return (ENODEV);
15586120Sdes	}
15686120Sdes
15793011Samorita	scrw = info.vi_width;
15893011Samorita	scrh = info.vi_height;
15993011Samorita
16086120Sdes	/* intialize the palette */
16186122Sdes	for (i = 1; i < MAX; i++)
16286122Sdes		rain_pal[BLUE(i)] = rain_pal[BLUE(i - 1)] + INCREMENT;
16386120Sdes
16486120Sdes	return (0);
16542205Sdes}
16642205Sdes
16742205Sdesstatic int
16842504Syokotarain_term(video_adapter_t *adp)
16942205Sdes{
17086120Sdes	return (0);
17142205Sdes}
17242205Sdes
17342504Syokotastatic scrn_saver_t rain_module = {
17486120Sdes	SAVER_NAME,
17586120Sdes	rain_init,
17686120Sdes	rain_term,
17786120Sdes	rain_saver,
17886120Sdes	NULL
17942504Syokota};
18042504Syokota
18142504SyokotaSAVER_MODULE(rain_saver, rain_module);
182