xref: /freebsd/sys/dev/syscons/snake/snake_saver.c (revision 95ee2897e98f5d444f26ed2334cc7c439f9c16c6)
117ee9d00SSøren Schmidt /*-
2*718cf2ccSPedro F. Giffuni  * SPDX-License-Identifier: BSD-3-Clause
3*718cf2ccSPedro F. Giffuni  *
49a14aa01SUlrich Spörlein  * Copyright (c) 1995-1998 Søren Schmidt
517ee9d00SSøren Schmidt  * All rights reserved.
617ee9d00SSøren Schmidt  *
717ee9d00SSøren Schmidt  * Redistribution and use in source and binary forms, with or without
817ee9d00SSøren Schmidt  * modification, are permitted provided that the following conditions
917ee9d00SSøren Schmidt  * are met:
1017ee9d00SSøren Schmidt  * 1. Redistributions of source code must retain the above copyright
11a8445737SSøren Schmidt  *    notice, this list of conditions and the following disclaimer,
12a8445737SSøren Schmidt  *    without modification, immediately at the beginning of the file.
1317ee9d00SSøren Schmidt  * 2. Redistributions in binary form must reproduce the above copyright
1417ee9d00SSøren Schmidt  *    notice, this list of conditions and the following disclaimer in the
1517ee9d00SSøren Schmidt  *    documentation and/or other materials provided with the distribution.
1617ee9d00SSøren Schmidt  * 3. The name of the author may not be used to endorse or promote products
17a8445737SSøren Schmidt  *    derived from this software without specific prior written permission.
1817ee9d00SSøren Schmidt  *
1917ee9d00SSøren Schmidt  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2017ee9d00SSøren Schmidt  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2117ee9d00SSøren Schmidt  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2217ee9d00SSøren Schmidt  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2317ee9d00SSøren Schmidt  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2417ee9d00SSøren Schmidt  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2517ee9d00SSøren Schmidt  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2617ee9d00SSøren Schmidt  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2717ee9d00SSøren Schmidt  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2817ee9d00SSøren Schmidt  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2917ee9d00SSøren Schmidt  */
3017ee9d00SSøren Schmidt 
3117ee9d00SSøren Schmidt #include <sys/param.h>
3217ee9d00SSøren Schmidt #include <sys/systm.h>
330640d357SPeter Wemm #include <sys/module.h>
34ce834215SKazutaka YOKOTA #include <sys/malloc.h>
35ce834215SKazutaka YOKOTA #include <sys/kernel.h>
36ce834215SKazutaka YOKOTA #include <sys/sysctl.h>
376e8394b8SKazutaka YOKOTA #include <sys/consio.h>
386e8394b8SKazutaka YOKOTA #include <sys/fbio.h>
39c0414ca7SIvan Voras #include <sys/resourcevar.h>
40c0414ca7SIvan Voras #include <sys/smp.h>
41f6b4ae3cSBruce Evans 
4233b77e2dSBruce Evans #include <machine/pc/display.h>
43f6b4ae3cSBruce Evans 
446e8394b8SKazutaka YOKOTA #include <dev/fb/fbreg.h>
456e8394b8SKazutaka YOKOTA #include <dev/fb/splashreg.h>
466e8394b8SKazutaka YOKOTA #include <dev/syscons/syscons.h>
4717ee9d00SSøren Schmidt 
482eb8169aSYoshihiro Takahashi static u_char	*message;
496e8394b8SKazutaka YOKOTA static int	*messagep;
50ce834215SKazutaka YOKOTA static int	messagelen;
512ad872c5SKazutaka YOKOTA static int	blanked;
5217ee9d00SSøren Schmidt 
53c0414ca7SIvan Voras #define MSGBUF_LEN 	70
54c0414ca7SIvan Voras 
55c0414ca7SIvan Voras static int	nofancy = 0;
56c0414ca7SIvan Voras TUNABLE_INT("hw.syscons.saver_snake_nofancy", &nofancy);
57c0414ca7SIvan Voras 
58c0414ca7SIvan Voras #define FANCY_SNAKE 	(!nofancy)
59c0414ca7SIvan Voras #define LOAD_HIGH(ld) 	(((ld * 100 + FSCALE / 2) >> FSHIFT) / 100)
60c0414ca7SIvan Voras #define LOAD_LOW(ld) 	(((ld * 100 + FSCALE / 2) >> FSHIFT) % 100)
61c0414ca7SIvan Voras 
62c0414ca7SIvan Voras static inline void update_msg(void);
63c0414ca7SIvan Voras 
642ad872c5SKazutaka YOKOTA static int
snake_saver(video_adapter_t * adp,int blank)652ad872c5SKazutaka YOKOTA snake_saver(video_adapter_t *adp, int blank)
6617ee9d00SSøren Schmidt {
6717ee9d00SSøren Schmidt 	static int	dirx, diry;
68c0414ca7SIvan Voras 	int		f, color, load;
696e8394b8SKazutaka YOKOTA 	sc_softc_t	*sc;
706e8394b8SKazutaka YOKOTA 	scr_stat	*scp;
7117ee9d00SSøren Schmidt 
72ce834215SKazutaka YOKOTA /* XXX hack for minimal changes. */
73ce834215SKazutaka YOKOTA #define	save	message
74ce834215SKazutaka YOKOTA #define	savs	messagep
75ce834215SKazutaka YOKOTA 
766e8394b8SKazutaka YOKOTA 	sc = sc_find_softc(adp, NULL);
776e8394b8SKazutaka YOKOTA 	if (sc == NULL)
786e8394b8SKazutaka YOKOTA 		return EAGAIN;
796e8394b8SKazutaka YOKOTA 	scp = sc->cur_scp;
806e8394b8SKazutaka YOKOTA 
8117ee9d00SSøren Schmidt 	if (blank) {
822da199daSDag-Erling Smørgrav 		if (adp->va_info.vi_flags & V_INFO_GRAPHICS)
83f9e730bbSKazutaka YOKOTA 			return EAGAIN;
842ad872c5SKazutaka YOKOTA 		if (blanked <= 0) {
856e8394b8SKazutaka YOKOTA 			sc_vtb_clear(&scp->scr, sc->scr_map[0x20],
866e8394b8SKazutaka YOKOTA 				     (FG_LIGHTGREY | BG_BLACK) << 8);
879336e069SWojciech A. Koszek 			vidd_set_hw_cursor(adp, -1, -1);
882b944ee2SKazutaka YOKOTA 			sc_set_border(scp, 0);
8917ee9d00SSøren Schmidt 			dirx = (scp->xpos ? 1 : -1);
9017ee9d00SSøren Schmidt 			diry = (scp->ypos ?
9117ee9d00SSøren Schmidt 				scp->xsize : -scp->xsize);
92ce834215SKazutaka YOKOTA 			for (f=0; f< messagelen; f++)
936e8394b8SKazutaka YOKOTA 				savs[f] = scp->xpos + scp->ypos*scp->xsize;
946e8394b8SKazutaka YOKOTA 			sc_vtb_putc(&scp->scr, savs[0], sc->scr_map[*save],
956e8394b8SKazutaka YOKOTA 				    (FG_LIGHTGREY | BG_BLACK) << 8);
962ad872c5SKazutaka YOKOTA 			blanked = 1;
9717ee9d00SSøren Schmidt 		}
982ad872c5SKazutaka YOKOTA 		if (blanked++ < 4)
992ad872c5SKazutaka YOKOTA 			return 0;
1002ad872c5SKazutaka YOKOTA 		blanked = 1;
1016e8394b8SKazutaka YOKOTA 		sc_vtb_putc(&scp->scr, savs[messagelen - 1], sc->scr_map[0x20],
1026e8394b8SKazutaka YOKOTA 			    (FG_LIGHTGREY | BG_BLACK) << 8);
103ce834215SKazutaka YOKOTA 		for (f=messagelen-1; f > 0; f--)
10417ee9d00SSøren Schmidt 			savs[f] = savs[f-1];
1056e8394b8SKazutaka YOKOTA 		f = savs[0];
10617ee9d00SSøren Schmidt 		if ((f % scp->xsize) == 0 ||
10717ee9d00SSøren Schmidt 		    (f % scp->xsize) == scp->xsize - 1 ||
10817ee9d00SSøren Schmidt 		    (random() % 50) == 0)
10917ee9d00SSøren Schmidt 			dirx = -dirx;
11017ee9d00SSøren Schmidt 		if ((f / scp->xsize) == 0 ||
11117ee9d00SSøren Schmidt 		    (f / scp->xsize) == scp->ysize - 1 ||
11217ee9d00SSøren Schmidt 		    (random() % 20) == 0)
11317ee9d00SSøren Schmidt 			diry = -diry;
1146e8394b8SKazutaka YOKOTA 		savs[0] += dirx + diry;
115c0414ca7SIvan Voras 		if (FANCY_SNAKE) {
116c0414ca7SIvan Voras 			update_msg();
117b8bba24eSIvan Voras 			load = ((averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT);
118c0414ca7SIvan Voras 			if (load == 0)
119c0414ca7SIvan Voras 				color = FG_LIGHTGREY | BG_BLACK;
120c0414ca7SIvan Voras 			else if (load / mp_ncpus <= 50)
121c0414ca7SIvan Voras 				color = FG_LIGHTGREEN | BG_BLACK;
122c0414ca7SIvan Voras 			else if (load / mp_ncpus <= 75)
123c0414ca7SIvan Voras 				color = FG_YELLOW | BG_BLACK;
124c0414ca7SIvan Voras 			else if (load / mp_ncpus <= 99)
125c0414ca7SIvan Voras 				color = FG_LIGHTRED | BG_BLACK;
126c0414ca7SIvan Voras 			else
127c0414ca7SIvan Voras 				color = FG_RED | FG_BLINK | BG_BLACK;
128c0414ca7SIvan Voras 		} else
129c0414ca7SIvan Voras 			color = FG_LIGHTGREY | BG_BLACK;
130c0414ca7SIvan Voras 
131ce834215SKazutaka YOKOTA 		for (f=messagelen-1; f>=0; f--)
1326e8394b8SKazutaka YOKOTA 			sc_vtb_putc(&scp->scr, savs[f], sc->scr_map[save[f]],
133c0414ca7SIvan Voras 				    color << 8);
134f4acf7e9SYoshihiro Takahashi 	} else
1352ad872c5SKazutaka YOKOTA 		blanked = 0;
136f4acf7e9SYoshihiro Takahashi 
1372ad872c5SKazutaka YOKOTA 	return 0;
13817ee9d00SSøren Schmidt }
13917ee9d00SSøren Schmidt 
140c0414ca7SIvan Voras static inline void
update_msg(void)141c0414ca7SIvan Voras update_msg(void)
142c0414ca7SIvan Voras {
143c0414ca7SIvan Voras 	if (!FANCY_SNAKE) {
144c0414ca7SIvan Voras 		messagelen = sprintf(message, "%s %s", ostype, osrelease);
145c0414ca7SIvan Voras 		return;
146c0414ca7SIvan Voras 	}
147c0414ca7SIvan Voras 	messagelen = snprintf(message, MSGBUF_LEN,
148c0414ca7SIvan Voras 	    "%s %s (%d.%02d %d.%02d, %d.%02d)",
149c0414ca7SIvan Voras 	    ostype, osrelease,
150c0414ca7SIvan Voras 	    LOAD_HIGH(averunnable.ldavg[0]), LOAD_LOW(averunnable.ldavg[0]),
151c0414ca7SIvan Voras 	    LOAD_HIGH(averunnable.ldavg[1]), LOAD_LOW(averunnable.ldavg[1]),
152c0414ca7SIvan Voras 	    LOAD_HIGH(averunnable.ldavg[2]), LOAD_LOW(averunnable.ldavg[2]));
153c0414ca7SIvan Voras }
154c0414ca7SIvan Voras 
155b3e24f9cSBruce Evans static int
snake_init(video_adapter_t * adp)1562ad872c5SKazutaka YOKOTA snake_init(video_adapter_t *adp)
15717ee9d00SSøren Schmidt {
158c0414ca7SIvan Voras 	message = malloc(MSGBUF_LEN, M_DEVBUF, M_WAITOK);
159c0414ca7SIvan Voras 	messagep = malloc(MSGBUF_LEN * sizeof *messagep, M_DEVBUF, M_WAITOK);
160c0414ca7SIvan Voras 	update_msg();
1612ad872c5SKazutaka YOKOTA 	return 0;
16217ee9d00SSøren Schmidt }
16317ee9d00SSøren Schmidt 
164b3e24f9cSBruce Evans static int
snake_term(video_adapter_t * adp)1652ad872c5SKazutaka YOKOTA snake_term(video_adapter_t *adp)
16617ee9d00SSøren Schmidt {
167ce834215SKazutaka YOKOTA 	free(message, M_DEVBUF);
168ce834215SKazutaka YOKOTA 	free(messagep, M_DEVBUF);
1692ad872c5SKazutaka YOKOTA 	return 0;
17017ee9d00SSøren Schmidt }
17117ee9d00SSøren Schmidt 
1722ad872c5SKazutaka YOKOTA static scrn_saver_t snake_module = {
1732ad872c5SKazutaka YOKOTA 	"snake_saver", snake_init, snake_term, snake_saver, NULL,
1742ad872c5SKazutaka YOKOTA };
1752ad872c5SKazutaka YOKOTA 
1762ad872c5SKazutaka YOKOTA SAVER_MODULE(snake_saver, snake_module);
177