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.6 2006/09/03 18:52:26 dillon 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 #include <sys/thread.h> 40 #include <sys/thread2.h> 41 42 #include <sys/random.h> 43 44 #include <dev/video/fb/fbreg.h> 45 #include <dev/video/fb/splashreg.h> 46 #include "../syscons.h" 47 48 #define SAVER_NAME "dragon_saver" 49 50 static u_char *vid; 51 static int blanked; 52 53 #define VIDEO_MODE M_VGA_CG320 54 #define VIDEO_MODE_NAME "M_VGA_CG320" 55 #define SCRW 320 56 #define SCRH 200 57 #define ORDER 13 58 #define CURVE 3 59 #define OUT 100 60 61 static int cur_x, cur_y; 62 static int curve; 63 static u_char dragon_pal[3*256]; /* zero-filled by the compiler */ 64 65 static __inline int 66 gpset(int x, int y, int val) 67 { 68 if (x < 0 || y < 0 || SCRW <= x || SCRH <= y) { 69 return 0; 70 } 71 vid[x + y * SCRW] = val; 72 return 1; 73 } 74 75 static int 76 gdraw(int dx, int dy, int val) 77 { 78 int i; 79 int set = 0; 80 81 if (dx != 0) { 82 i = cur_x; 83 cur_x += dx; 84 if (dx < 0) { 85 i += dx; 86 dx = -dx; 87 } 88 /* horizontal line */ 89 for (; dx >= 0; --dx, ++i) { 90 set |= gpset(i, cur_y, val); 91 } 92 } 93 else { /* dy != 0 */ 94 i = cur_y; 95 cur_y += dy; 96 if (dy < 0) { 97 i += dy; 98 dy = -dy; 99 } 100 /* vertical line */ 101 for (; dy >= 0; --dy, ++i) { 102 set |= gpset(cur_x, i, val); 103 } 104 } 105 return set; 106 } 107 108 static void 109 dragon_update(video_adapter_t *adp) 110 { 111 static int i, p, q; 112 static int order, mul, out; 113 static int org_x, org_y; 114 static int dx, dy; 115 static unsigned char fold[1 << (ORDER - 3)]; 116 #define GET_FOLD(x) (fold[(x) >> 3] & (1 << ((x) & 7))) 117 #define SET_FOLD(x) (fold[(x) >> 3] |= (1 << ((x) & 7))) 118 #define CLR_FOLD(x) (fold[(x) >> 3] &= ~(1 << ((x) & 7))) 119 int tmp; 120 121 if (curve > CURVE) { 122 bzero(vid, SCRW*SCRH); 123 124 /* set palette of each curves */ 125 for (tmp = 0; tmp < 3*CURVE; ++tmp) { 126 dragon_pal[3+tmp] = (u_char)krandom(); 127 } 128 load_palette(adp, dragon_pal); 129 130 mul = ((krandom() & 7) + 1) * (SCRW / 320); 131 org_x = krandom() % SCRW; org_y = krandom() % SCRH; 132 133 curve = 0; 134 order = ORDER; 135 } 136 137 if (order >= ORDER) { 138 ++curve; 139 140 cur_x = org_x; cur_y = org_y; 141 142 switch (curve) { 143 case 1: 144 dx = 0; dy = mul; 145 break; 146 case 2: 147 dx = mul; dy = 0; 148 break; 149 case 3: 150 dx = 0; dy = -mul; 151 break; 152 } 153 (void)gdraw(dx, dy, curve); out = 0; 154 155 order = 0; 156 q = p = 0; i = q + 1; 157 } 158 159 if (i > q) { 160 SET_FOLD(p); q = p * 2; 161 162 ++order; 163 i = p; p = q + 1; 164 } 165 166 if (GET_FOLD(q-i) != 0) { 167 CLR_FOLD(i); 168 tmp = dx; dx = dy; dy = -tmp; /* turn right */ 169 } 170 else { 171 SET_FOLD(i); 172 tmp = dx; dx = -dy; dy = tmp; /* turn left */ 173 } 174 if (gdraw(dx, dy, curve)) { 175 out = 0; 176 } 177 else { 178 if (++out > OUT) { 179 order = ORDER; /* force to terminate this curve */ 180 } 181 } 182 ++i; 183 } 184 185 static int 186 dragon_saver(video_adapter_t *adp, int blank) 187 { 188 if (blank) { 189 /* switch to graphics mode */ 190 if (blanked <= 0) { 191 crit_enter(); 192 set_video_mode(adp, VIDEO_MODE); 193 vid = (u_char *)adp->va_window; 194 curve = CURVE + 1; 195 ++blanked; 196 crit_exit(); 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