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