The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/syscons/plasma/plasma_saver.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2015 Dag-Erling Smørgrav
    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  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  *
   26  * $FreeBSD$
   27  *
   28  * To CJA, in appreciation of Nighthawk brunches past and future.
   29  */
   30 
   31 #include <sys/param.h>
   32 #include <sys/systm.h>
   33 #include <sys/kernel.h>
   34 #include <sys/module.h>
   35 #include <sys/syslog.h>
   36 #include <sys/consio.h>
   37 #include <sys/fbio.h>
   38 
   39 #include <dev/fb/fbreg.h>
   40 #include <dev/fb/splashreg.h>
   41 #include <dev/syscons/syscons.h>
   42 
   43 #define SAVER_NAME       "plasma_saver"
   44 
   45 #include "fp16.h"
   46 
   47 /*
   48  * Preferred video modes
   49  */
   50 static int modes[] = {
   51         M_VGA_CG640,
   52         M_VGA_CG320,
   53         -1
   54 };
   55 
   56 /*
   57  * Display parameters
   58  */
   59 static unsigned char *vid;
   60 static unsigned int banksize, scrmode, scrw, scrh;
   61 static unsigned int blanked;
   62 
   63 /*
   64  * List of foci
   65  */
   66 #define FOCI 3
   67 static struct {
   68         int x, y;               /* coordinates */
   69         int vx, vy;             /* velocity */
   70 } plasma_foci[FOCI];
   71 
   72 /*
   73  * Palette
   74  */
   75 static struct {
   76         unsigned char r, g, b;
   77 } plasma_pal[256];
   78 
   79 /*
   80  * Draw a new frame
   81  */
   82 static void
   83 plasma_update(video_adapter_t *adp)
   84 {
   85         unsigned int x, y;      /* coordinates */
   86         signed int dx, dy;      /* horizontal / vertical distance */
   87         fp16_t sqd, d;          /* square of distance and distance */
   88         fp16_t m;               /* magnitude */
   89         unsigned int org, off;  /* origin and offset */
   90         unsigned int i;         /* loop index */
   91 
   92         /* switch to bank 0 */
   93         vidd_set_win_org(adp, 0);
   94         /* for each scan line */
   95         for (y = org = off = 0; y < scrh; ++y) {
   96                 /* for each pixel on scan line */
   97                 for (x = 0; x < scrw; ++x, ++off) {
   98                         /* for each focus */
   99                         for (i = m = 0; i < FOCI; ++i) {
  100                                 dx = x - plasma_foci[i].x;
  101                                 dy = y - plasma_foci[i].y;
  102                                 sqd = ItoFP16(dx * dx + dy * dy);
  103                                 d = fp16_sqrt(sqd);
  104                                 /* divide by 4 to stretch out the pattern */
  105                                 m = fp16_sub(m, fp16_cos(d / 4));
  106                         }
  107                         /*
  108                          * m is now in the range +/- FOCI, but we need a
  109                          * value between 0 and 255.  We scale to +/- 127
  110                          * and add 127, which moves it into the range [0,
  111                          * 254].
  112                          */
  113                         m = fp16_mul(m, ItoFP16(127));
  114                         m = fp16_div(m, ItoFP16(FOCI));
  115                         m = fp16_add(m, ItoFP16(127));
  116                         /* switch banks if necessary */
  117                         if (off > banksize) {
  118                                 off -= banksize;
  119                                 org += banksize;
  120                                 vidd_set_win_org(adp, org);
  121                         }
  122                         /* plot */
  123                         vid[off] = FP16toI(m);
  124                 }
  125         }
  126         /* now move the foci */
  127         for (i = 0; i < FOCI; ++i) {
  128                 plasma_foci[i].x += plasma_foci[i].vx;
  129                 if (plasma_foci[i].x < 0) {
  130                         /* bounce against left wall */
  131                         plasma_foci[i].vx = -plasma_foci[i].vx;
  132                         plasma_foci[i].x = -plasma_foci[i].x;
  133                 } else if (plasma_foci[i].x >= scrw) {
  134                         /* bounce against right wall */
  135                         plasma_foci[i].vx = -plasma_foci[i].vx;
  136                         plasma_foci[i].x = scrw - (plasma_foci[i].x - scrw);
  137                 }
  138                 plasma_foci[i].y += plasma_foci[i].vy;
  139                 if (plasma_foci[i].y < 0) {
  140                         /* bounce against ceiling */
  141                         plasma_foci[i].vy = -plasma_foci[i].vy;
  142                         plasma_foci[i].y = -plasma_foci[i].y;
  143                 } else if (plasma_foci[i].y >= scrh) {
  144                         /* bounce against floor */
  145                         plasma_foci[i].vy = -plasma_foci[i].vy;
  146                         plasma_foci[i].y = scrh - (plasma_foci[i].y - scrh);
  147                 }
  148         }
  149 }
  150 
  151 /*
  152  * Start or stop the screensaver
  153  */
  154 static int
  155 plasma_saver(video_adapter_t *adp, int blank)
  156 {
  157         int pl;
  158 
  159         if (blank) {
  160                 /* switch to graphics mode */
  161                 if (blanked <= 0) {
  162                         pl = splhigh();
  163                         vidd_set_mode(adp, scrmode);
  164                         vidd_load_palette(adp, (unsigned char *)plasma_pal);
  165                         vidd_set_border(adp, 0);
  166                         blanked++;
  167                         vid = (unsigned char *)adp->va_window;
  168                         banksize = adp->va_window_size;
  169                         splx(pl);
  170                         vidd_clear(adp);
  171                 }
  172                 /* update display */
  173                 plasma_update(adp);
  174         } else {
  175                 blanked = 0;
  176         }
  177         return (0);
  178 }
  179 
  180 /*
  181  * Initialize on module load
  182  */
  183 static int
  184 plasma_init(video_adapter_t *adp)
  185 {
  186         video_info_t info;
  187         int i;
  188 
  189         /* select video mode */
  190         for (i = 0; modes[i] >= 0; ++i)
  191                 if (vidd_get_info(adp, modes[i], &info) == 0)
  192                         break;
  193         if (modes[i] < 0) {
  194                 log(LOG_NOTICE, "%s: no supported video modes\n", SAVER_NAME);
  195                 return (ENODEV);
  196         }
  197         scrmode = modes[i];
  198         scrw = info.vi_width;
  199         scrh = info.vi_height;
  200 
  201         /* initialize the palette */
  202         for (i = 0; i < 256; ++i)
  203                 plasma_pal[i].r = plasma_pal[i].g = plasma_pal[i].b = i;
  204 
  205         /* randomize the foci */
  206         for (i = 0; i < FOCI; i++) {
  207                 plasma_foci[i].x = random() % scrw;
  208                 plasma_foci[i].y = random() % scrh;
  209                 plasma_foci[i].vx = random() % 5 - 2;
  210                 plasma_foci[i].vy = random() % 5 - 2;
  211         }
  212 
  213         return (0);
  214 }
  215 
  216 /*
  217  * Clean up before module unload
  218  */
  219 static int
  220 plasma_term(video_adapter_t *adp)
  221 {
  222 
  223         return (0);
  224 }
  225 
  226 /*
  227  * Boilerplate
  228  */
  229 static scrn_saver_t plasma_module = {
  230         SAVER_NAME,
  231         plasma_init,
  232         plasma_term,
  233         plasma_saver,
  234         NULL
  235 };
  236 
  237 SAVER_MODULE(plasma_saver, plasma_module);

Cache object: b071aaa4075cfde9a1c28ced03ca336b


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.