1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 1999 Brad Forschinger 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer, 12 * without modification, immediately at the beginning of the file. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * $FreeBSD$ 29 */ 30 31 /* 32 * brad forschinger, 19990504 <retch@flag.blackened.net> 33 * 34 * written with much help from warp_saver.c 35 * 36 */ 37 38 #include <sys/param.h> 39 #include <sys/systm.h> 40 #include <sys/kernel.h> 41 #include <sys/module.h> 42 #include <sys/syslog.h> 43 #include <sys/consio.h> 44 #include <sys/malloc.h> 45 #include <sys/fbio.h> 46 47 #include <dev/fb/fbreg.h> 48 #include <dev/fb/splashreg.h> 49 #include <dev/syscons/syscons.h> 50 51 #define SAVER_NAME "fire_saver" 52 53 #define RED(n) ((n) * 3 + 0) 54 #define GREEN(n) ((n) * 3 + 1) 55 #define BLUE(n) ((n) * 3 + 2) 56 57 #define SET_ORIGIN(adp, o) do { \ 58 int oo = o; \ 59 if (oo != last_origin) \ 60 vidd_set_win_org(adp, last_origin = oo); \ 61 } while (0) 62 63 static u_char *buf; 64 static u_char *vid; 65 static int banksize, scrmode, bpsl, scrw, scrh; 66 static u_char fire_pal[768]; 67 static int blanked; 68 69 static void 70 fire_update(video_adapter_t *adp) 71 { 72 int x, y; 73 int o, p; 74 int last_origin = -1; 75 76 /* make a new bottom line */ 77 for (x = 0, y = scrh; x < scrw; x++) 78 buf[x + (y * bpsl)] = random() % 160 + 96; 79 80 /* fade the flames out */ 81 for (y = 0; y < scrh; y++) { 82 for (x = 0; x < scrw; x++) { 83 buf[x + (y * scrw)] = 84 (buf[(x + 0) + ((y + 0) * scrw)] + 85 buf[(x - 1) + ((y + 1) * scrw)] + 86 buf[(x + 0) + ((y + 1) * scrw)] + 87 buf[(x + 1) + ((y + 1) * scrw)]) / 4; 88 if (buf[x + (y * scrw)] > 0) 89 buf[x + (y * scrw)]--; 90 } 91 } 92 93 /* blit our buffer into video ram */ 94 for (y = 0, p = 0, o = 0; y < scrh; y++, p += bpsl) { 95 while (p > banksize) { 96 p -= banksize; 97 o += banksize; 98 } 99 SET_ORIGIN(adp, o); 100 if (p + scrw < banksize) { 101 bcopy(buf + y * scrw, vid + p, scrw); 102 } else { 103 bcopy(buf + y * scrw, vid + p, banksize - p); 104 SET_ORIGIN(adp, o + banksize); 105 bcopy(buf + y * scrw + (banksize - p), vid, 106 scrw - (banksize - p)); 107 p -= banksize; 108 o += banksize; 109 } 110 } 111 112 } 113 114 static int 115 fire_saver(video_adapter_t *adp, int blank) 116 { 117 int pl; 118 119 if (blank) { 120 /* switch to graphics mode */ 121 if (blanked <= 0) { 122 pl = splhigh(); 123 vidd_set_mode(adp, scrmode); 124 vidd_load_palette(adp, fire_pal); 125 blanked++; 126 vid = (u_char *)adp->va_window; 127 banksize = adp->va_window_size; 128 bpsl = adp->va_line_width; 129 splx(pl); 130 vidd_clear(adp); 131 } 132 fire_update(adp); 133 } else { 134 blanked = 0; 135 } 136 137 return 0; 138 } 139 140 static int 141 fire_init(video_adapter_t *adp) 142 { 143 video_info_t info; 144 int i, red, green, blue; 145 146 if (!vidd_get_info(adp, M_VGA_CG320, &info)) { 147 scrmode = M_VGA_CG320; 148 } else { 149 log(LOG_NOTICE, 150 "%s: the console does not support M_VGA_CG320\n", 151 SAVER_NAME); 152 return (ENODEV); 153 } 154 155 scrw = info.vi_width; 156 scrh = info.vi_height; 157 158 buf = (u_char *)malloc(scrw * (scrh + 1), M_DEVBUF, M_NOWAIT); 159 if (buf) { 160 bzero(buf, scrw * (scrh + 1)); 161 } else { 162 log(LOG_NOTICE, 163 "%s: buffer allocation is failed\n", 164 SAVER_NAME); 165 return (ENODEV); 166 } 167 168 /* intialize the palette */ 169 red = green = blue = 0; 170 for (i = 0; i < 256; i++) { 171 red++; 172 if (red > 128) 173 green += 2; 174 fire_pal[RED(i)] = red; 175 fire_pal[GREEN(i)] = green; 176 fire_pal[BLUE(i)] = blue; 177 } 178 179 return (0); 180 } 181 182 static int 183 fire_term(video_adapter_t *adp) 184 { 185 free(buf, M_DEVBUF); 186 return (0); 187 } 188 189 static scrn_saver_t fire_module = { 190 SAVER_NAME, 191 fire_init, 192 fire_term, 193 fire_saver, 194 NULL 195 }; 196 197 SAVER_MODULE(fire_saver, fire_module); 198