1 /*- 2 * Copyright (c) 2000 Chiharu Shibata 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer 10 * in this position and unchanged. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 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: src/sys/modules/syscons/dragon/dragon_saver.c,v 1.1.2.1 2003/05/11 01:17:02 murray Exp $ 29 * $DragonFly: src/sys/dev/misc/syscons/dragon/dragon_saver.c,v 1.4 2005/02/13 03:02:25 swildner Exp $ 30 */ 31 32 #include <sys/param.h> 33 #include <sys/systm.h> 34 #include <sys/kernel.h> 35 #include <sys/module.h> 36 #include <sys/syslog.h> 37 #include <sys/consio.h> 38 #include <sys/fbio.h> 39 40 #include <sys/random.h> 41 42 #include <dev/video/fb/fbreg.h> 43 #include <dev/video/fb/splashreg.h> 44 #include "../syscons.h" 45 46 #define SAVER_NAME "dragon_saver" 47 48 static u_char *vid; 49 static int blanked; 50 51 #define VIDEO_MODE M_VGA_CG320 52 #define VIDEO_MODE_NAME "M_VGA_CG320" 53 #define SCRW 320 54 #define SCRH 200 55 #define ORDER 13 56 #define CURVE 3 57 #define OUT 100 58 59 static int cur_x, cur_y; 60 static int curve; 61 static u_char dragon_pal[3*256]; /* zero-filled by the compiler */ 62 63 static __inline int 64 gpset(int x, int y, int val) 65 { 66 if (x < 0 || y < 0 || SCRW <= x || SCRH <= y) { 67 return 0; 68 } 69 vid[x + y * SCRW] = val; 70 return 1; 71 } 72 73 static int 74 gdraw(int dx, int dy, int val) 75 { 76 int i; 77 int set = 0; 78 79 if (dx != 0) { 80 i = cur_x; 81 cur_x += dx; 82 if (dx < 0) { 83 i += dx; 84 dx = -dx; 85 } 86 /* horizontal line */ 87 for (; dx >= 0; --dx, ++i) { 88 set |= gpset(i, cur_y, val); 89 } 90 } 91 else { /* dy != 0 */ 92 i = cur_y; 93 cur_y += dy; 94 if (dy < 0) { 95 i += dy; 96 dy = -dy; 97 } 98 /* vertical line */ 99 for (; dy >= 0; --dy, ++i) { 100 set |= gpset(cur_x, i, val); 101 } 102 } 103 return set; 104 } 105 106 static void 107 dragon_update(video_adapter_t *adp) 108 { 109 static int i, p, q; 110 static int order, mul, out; 111 static int org_x, org_y; 112 static int dx, dy; 113 static unsigned char fold[1 << (ORDER - 3)]; 114 #define GET_FOLD(x) (fold[(x) >> 3] & (1 << ((x) & 7))) 115 #define SET_FOLD(x) (fold[(x) >> 3] |= (1 << ((x) & 7))) 116 #define CLR_FOLD(x) (fold[(x) >> 3] &= ~(1 << ((x) & 7))) 117 int tmp; 118 119 if (curve > CURVE) { 120 bzero(vid, SCRW*SCRH); 121 122 /* set palette of each curves */ 123 for (tmp = 0; tmp < 3*CURVE; ++tmp) { 124 dragon_pal[3+tmp] = (u_char)random(); 125 } 126 load_palette(adp, dragon_pal); 127 128 mul = ((random() & 7) + 1) * (SCRW / 320); 129 org_x = random() % SCRW; org_y = random() % SCRH; 130 131 curve = 0; 132 order = ORDER; 133 } 134 135 if (order >= ORDER) { 136 ++curve; 137 138 cur_x = org_x; cur_y = org_y; 139 140 switch (curve) { 141 case 1: 142 dx = 0; dy = mul; 143 break; 144 case 2: 145 dx = mul; dy = 0; 146 break; 147 case 3: 148 dx = 0; dy = -mul; 149 break; 150 } 151 (void)gdraw(dx, dy, curve); out = 0; 152 153 order = 0; 154 q = p = 0; i = q + 1; 155 } 156 157 if (i > q) { 158 SET_FOLD(p); q = p * 2; 159 160 ++order; 161 i = p; p = q + 1; 162 } 163 164 if (GET_FOLD(q-i) != 0) { 165 CLR_FOLD(i); 166 tmp = dx; dx = dy; dy = -tmp; /* turn right */ 167 } 168 else { 169 SET_FOLD(i); 170 tmp = dx; dx = -dy; dy = tmp; /* turn left */ 171 } 172 if (gdraw(dx, dy, curve)) { 173 out = 0; 174 } 175 else { 176 if (++out > OUT) { 177 order = ORDER; /* force to terminate this curve */ 178 } 179 } 180 ++i; 181 } 182 183 static int 184 dragon_saver(video_adapter_t *adp, int blank) 185 { 186 int pl; 187 188 if (blank) { 189 /* switch to graphics mode */ 190 if (blanked <= 0) { 191 pl = splhigh(); 192 set_video_mode(adp, VIDEO_MODE); 193 vid = (u_char *)adp->va_window; 194 curve = CURVE + 1; 195 ++blanked; 196 splx(pl); 197 } 198 199 /* update display */ 200 dragon_update(adp); 201 } 202 else { 203 blanked = 0; 204 } 205 return 0; 206 } 207 208 static int 209 dragon_init(video_adapter_t *adp) 210 { 211 video_info_t info; 212 213 /* check that the console is capable of running in 320x200x256 */ 214 if (get_mode_info(adp, VIDEO_MODE, &info)) { 215 log(LOG_NOTICE, 216 "%s: the console does not support " VIDEO_MODE_NAME "\n", 217 SAVER_NAME); 218 return ENODEV; 219 } 220 221 blanked = 0; 222 return 0; 223 } 224 225 static int 226 dragon_term(video_adapter_t *adp) 227 { 228 return 0; 229 } 230 231 static scrn_saver_t dragon_module = { 232 SAVER_NAME, 233 dragon_init, 234 dragon_term, 235 dragon_saver, 236 NULL, 237 }; 238 239 SAVER_MODULE(dragon_saver, dragon_module); 240