142108Sdes/*-
2230132Suqs * Copyright (c) 1998 Dag-Erling Co��dan Sm��rgrav
342108Sdes * All rights reserved.
442108Sdes *
542108Sdes * Redistribution and use in source and binary forms, with or without
642108Sdes * modification, are permitted provided that the following conditions
742108Sdes * are met:
842108Sdes * 1. Redistributions of source code must retain the above copyright
942108Sdes *    notice, this list of conditions and the following disclaimer
1042108Sdes *    in this position and unchanged.
1142108Sdes * 2. Redistributions in binary form must reproduce the above copyright
1242108Sdes *    notice, this list of conditions and the following disclaimer in the
1342108Sdes *    documentation and/or other materials provided with the distribution.
1442108Sdes * 3. The name of the author may not be used to endorse or promote products
1542108Sdes *    derived from this software without specific prior written permission
1642108Sdes *
1742108Sdes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1842108Sdes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1942108Sdes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2042108Sdes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2142108Sdes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2242108Sdes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2342108Sdes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2442108Sdes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2542108Sdes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2642108Sdes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2742108Sdes *
2850477Speter * $FreeBSD$
2942108Sdes */
3042108Sdes
3142108Sdes#include <sys/param.h>
3242108Sdes#include <sys/systm.h>
3342108Sdes#include <sys/kernel.h>
3442108Sdes#include <sys/module.h>
3542108Sdes#include <sys/syslog.h>
3648104Syokota#include <sys/consio.h>
3748104Syokota#include <sys/fbio.h>
3842108Sdes
3948104Syokota#include <dev/fb/fbreg.h>
4048104Syokota#include <dev/fb/splashreg.h>
4148104Syokota#include <dev/syscons/syscons.h>
4242108Sdes
4386120Sdes#define SAVER_NAME	 "warp_saver"
4486120Sdes#define SPP		 15
4586120Sdes#define STARS		 (SPP * (1 + 2 + 4 + 8))
4642108Sdes
47166868Sphilip#define SET_ORIGIN(adp, o) do {				\
48166868Sphilip	int oo = o;					\
49166868Sphilip	if (oo != last_origin)				\
50174985Swkoszek	    vidd_set_win_org(adp, last_origin = oo);		\
51166868Sphilip	} while (0)
52166868Sphilip
5386120Sdesstatic u_char		*vid;
5493011Samoritastatic int		 banksize, scrmode, bpsl, scrw, scrh;
5586120Sdesstatic int		 blanked;
5686120Sdesstatic int		 star[STARS];
5786120Sdesstatic u_char		 warp_pal[768] = {
5886120Sdes	0x00, 0x00, 0x00,
5986120Sdes	0x66, 0x66, 0x66,
6086120Sdes	0x99, 0x99, 0x99,
6186120Sdes	0xcc, 0xcc, 0xcc,
6286120Sdes	0xff, 0xff, 0xff
6386120Sdes	/* the rest is zero-filled by the compiler */
6442108Sdes};
6542108Sdes
6642108Sdesstatic void
6793011Samoritawarp_update(video_adapter_t *adp)
6842108Sdes{
6993011Samorita	int i, j, k, n, o, p;
70166868Sphilip	int last_origin = -1;
7193011Samorita
7286120Sdes	for (i = 1, k = 0, n = SPP*8; i < 5; i++, n /= 2) {
7386120Sdes		for (j = 0; j < n; j++, k++) {
7493011Samorita			p = (star[k] / scrw) *  bpsl + (star[k] % scrw);
7593011Samorita			o = 0;
7693011Samorita			while (p > banksize) {
7793011Samorita				p -= banksize;
7893011Samorita				o += banksize;
7993011Samorita			}
80166868Sphilip			SET_ORIGIN(adp, o);
8193011Samorita			vid[p] = 0;
8286120Sdes			star[k] += i;
8393011Samorita			if (star[k] > scrw*scrh)
8493011Samorita				star[k] -= scrw*scrh;
8593011Samorita			p = (star[k] / scrw) *  bpsl + (star[k] % scrw);
8693011Samorita			o = 0;
8793011Samorita			while (p > banksize) {
8893011Samorita				p -= banksize;
8993011Samorita				o += banksize;
9093011Samorita			}
91166868Sphilip			SET_ORIGIN(adp, o);
9293011Samorita			vid[p] = i;
9386120Sdes		}
9442108Sdes	}
9542108Sdes}
9642108Sdes
9742504Syokotastatic int
9842504Syokotawarp_saver(video_adapter_t *adp, int blank)
9942108Sdes{
100117833Snyan	int pl;
10186120Sdes
10286120Sdes	if (blank) {
10386120Sdes		/* switch to graphics mode */
10486120Sdes		if (blanked <= 0) {
10586120Sdes			pl = splhigh();
106174985Swkoszek			vidd_set_mode(adp, scrmode);
107174985Swkoszek			vidd_load_palette(adp, warp_pal);
108174985Swkoszek			vidd_set_border(adp, 0);
10986120Sdes			blanked++;
11086120Sdes			vid = (u_char *)adp->va_window;
11193011Samorita			banksize = adp->va_window_size;
11293011Samorita			bpsl = adp->va_line_width;
11386120Sdes			splx(pl);
114174985Swkoszek			vidd_clear(adp);
11586120Sdes		}
11686120Sdes		/* update display */
11793011Samorita		warp_update(adp);
11886120Sdes	} else {
11986120Sdes		blanked = 0;
12042108Sdes	}
12186120Sdes	return (0);
12242108Sdes}
12342108Sdes
12442108Sdesstatic int
12542504Syokotawarp_init(video_adapter_t *adp)
12642108Sdes{
12786120Sdes	video_info_t info;
12886120Sdes	int i;
12986120Sdes
130174985Swkoszek	if (!vidd_get_info(adp, M_VGA_CG320, &info)) {
13193011Samorita		scrmode = M_VGA_CG320;
132174985Swkoszek	} else if (!vidd_get_info(adp, M_PC98_PEGC640x480, &info)) {
13393011Samorita		scrmode = M_PC98_PEGC640x480;
134174985Swkoszek	} else if (!vidd_get_info(adp, M_PC98_PEGC640x400, &info)) {
13593011Samorita		scrmode = M_PC98_PEGC640x400;
13693011Samorita	} else {
13786120Sdes		log(LOG_NOTICE,
13886120Sdes		    "%s: the console does not support M_VGA_CG320\n",
13986120Sdes		    SAVER_NAME);
14086120Sdes		return (ENODEV);
14186120Sdes	}
14286120Sdes
14393011Samorita	scrw = info.vi_width;
14493011Samorita	scrh = info.vi_height;
14593011Samorita
14686120Sdes	/* randomize the star field */
14786120Sdes	for (i = 0; i < STARS; i++)
14893011Samorita		star[i] = random() % (scrw * scrh);
14986120Sdes
15086120Sdes	return (0);
15142108Sdes}
15242108Sdes
15342108Sdesstatic int
15442504Syokotawarp_term(video_adapter_t *adp)
15542108Sdes{
15686120Sdes	return (0);
15742108Sdes}
15842108Sdes
15942504Syokotastatic scrn_saver_t warp_module = {
16086120Sdes	SAVER_NAME,
16186120Sdes	warp_init,
16286120Sdes	warp_term,
16386120Sdes	warp_saver,
16486120Sdes	NULL
16542504Syokota};
16642504Syokota
16742504SyokotaSAVER_MODULE(warp_saver, warp_module);
168