146409Sjkh/*- 246409Sjkh * Copyright (c) 1999 Brad Forschinger 346409Sjkh * All rights reserved. 446409Sjkh * 546409Sjkh * Redistribution and use in source and binary forms, with or without 646409Sjkh * modification, are permitted provided that the following conditions 746409Sjkh * are met: 846409Sjkh * 1. Redistributions of source code must retain the above copyright 946409Sjkh * notice, this list of conditions and the following disclaimer, 1046409Sjkh * without modification, immediately at the beginning of the file. 1146409Sjkh * 2. Redistributions in binary form must reproduce the above copyright 1246409Sjkh * notice, this list of conditions and the following disclaimer in the 1346409Sjkh * documentation and/or other materials provided with the distribution. 1446409Sjkh * 1546409Sjkh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1646409Sjkh * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1746409Sjkh * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1846409Sjkh * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1946409Sjkh * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2046409Sjkh * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2146409Sjkh * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2246409Sjkh * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2346409Sjkh * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2446409Sjkh * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2546409Sjkh * 2650477Speter * $FreeBSD$ 2746409Sjkh */ 2846407Sjkh 2946407Sjkh/* 3046899Sdes * brad forschinger, 19990504 <retch@flag.blackened.net> 3146407Sjkh * 3246407Sjkh * written with much help from warp_saver.c 3346407Sjkh * 3446407Sjkh */ 3546407Sjkh 3646407Sjkh#include <sys/param.h> 3746407Sjkh#include <sys/systm.h> 3846407Sjkh#include <sys/kernel.h> 3946407Sjkh#include <sys/module.h> 4046407Sjkh#include <sys/syslog.h> 4148104Syokota#include <sys/consio.h> 4293011Samorita#include <sys/malloc.h> 4348104Syokota#include <sys/fbio.h> 4446407Sjkh 4548104Syokota#include <dev/fb/fbreg.h> 4648104Syokota#include <dev/fb/splashreg.h> 4748104Syokota#include <dev/syscons/syscons.h> 4846407Sjkh 4993011Samorita#define SAVER_NAME "fire_saver" 5046407Sjkh 5193011Samorita#define RED(n) ((n) * 3 + 0) 5293011Samorita#define GREEN(n) ((n) * 3 + 1) 5393011Samorita#define BLUE(n) ((n) * 3 + 2) 5446407Sjkh 55166868Sphilip#define SET_ORIGIN(adp, o) do { \ 56166868Sphilip int oo = o; \ 57166868Sphilip if (oo != last_origin) \ 58174985Swkoszek vidd_set_win_org(adp, last_origin = oo); \ 59166868Sphilip } while (0) 60166868Sphilip 6193011Samoritastatic u_char *buf; 6293011Samoritastatic u_char *vid; 6393011Samoritastatic int banksize, scrmode, bpsl, scrw, scrh; 6493011Samoritastatic u_char fire_pal[768]; 6593011Samoritastatic int blanked; 6693011Samorita 6793011Samoritastatic void 6893011Samoritafire_update(video_adapter_t *adp) 6946689Sdes{ 7093011Samorita int x, y; 7193011Samorita int o, p; 72166868Sphilip int last_origin = -1; 7346407Sjkh 7446689Sdes /* make a new bottom line */ 7593011Samorita for (x = 0, y = scrh; x < scrw; x++) 7693011Samorita buf[x + (y * bpsl)] = random() % 160 + 96; 7746899Sdes 7846689Sdes /* fade the flames out */ 7993011Samorita for (y = 0; y < scrh; y++) { 8093011Samorita for (x = 0; x < scrw; x++) { 8193011Samorita buf[x + (y * scrw)] = 8293011Samorita (buf[(x + 0) + ((y + 0) * scrw)] + 8393011Samorita buf[(x - 1) + ((y + 1) * scrw)] + 8493011Samorita buf[(x + 0) + ((y + 1) * scrw)] + 8593011Samorita buf[(x + 1) + ((y + 1) * scrw)]) / 4; 8693011Samorita if (buf[x + (y * scrw)] > 0) 8793011Samorita buf[x + (y * scrw)]--; 8893011Samorita } 8946689Sdes } 9046899Sdes 9146689Sdes /* blit our buffer into video ram */ 9293011Samorita for (y = 0, p = 0, o = 0; y < scrh; y++, p += bpsl) { 9393011Samorita while (p > banksize) { 9493011Samorita p -= banksize; 9593011Samorita o += banksize; 9693011Samorita } 97166868Sphilip SET_ORIGIN(adp, o); 9893011Samorita if (p + scrw < banksize) { 9993011Samorita bcopy(buf + y * scrw, vid + p, scrw); 10093011Samorita } else { 10193011Samorita bcopy(buf + y * scrw, vid + p, banksize - p); 102166868Sphilip SET_ORIGIN(adp, o + banksize); 10393011Samorita bcopy(buf + y * scrw + (banksize - p), vid, 10493011Samorita scrw - (banksize - p)); 10593011Samorita p -= banksize; 10693011Samorita o += banksize; 10793011Samorita } 10893011Samorita } 10946899Sdes 11046407Sjkh} 11146407Sjkh 11246689Sdesstatic int 11393011Samoritafire_saver(video_adapter_t *adp, int blank) 11446899Sdes{ 115117833Snyan int pl; 11646899Sdes 11793011Samorita if (blank) { 11893011Samorita /* switch to graphics mode */ 11993011Samorita if (blanked <= 0) { 12093011Samorita pl = splhigh(); 121174985Swkoszek vidd_set_mode(adp, scrmode); 122174985Swkoszek vidd_load_palette(adp, fire_pal); 12393011Samorita blanked++; 12493011Samorita vid = (u_char *)adp->va_window; 12593011Samorita banksize = adp->va_window_size; 12693011Samorita bpsl = adp->va_line_width; 12793011Samorita splx(pl); 128174985Swkoszek vidd_clear(adp); 12993011Samorita } 13093011Samorita fire_update(adp); 13193011Samorita } else { 13293011Samorita blanked = 0; 13393011Samorita } 13446899Sdes 13546689Sdes return 0; 13646407Sjkh} 13746899Sdes 13846689Sdesstatic int 13993011Samoritafire_init(video_adapter_t *adp) 14046689Sdes{ 14193011Samorita video_info_t info; 14293011Samorita int i, red, green, blue; 14393011Samorita 144174985Swkoszek if (!vidd_get_info(adp, M_VGA_CG320, &info)) { 14593011Samorita scrmode = M_VGA_CG320; 146174985Swkoszek } else if (!vidd_get_info(adp, M_PC98_PEGC640x480, &info)) { 14793011Samorita scrmode = M_PC98_PEGC640x480; 148174985Swkoszek } else if (!vidd_get_info(adp, M_PC98_PEGC640x400, &info)) { 14993011Samorita scrmode = M_PC98_PEGC640x400; 15093011Samorita } else { 15193011Samorita log(LOG_NOTICE, 15293011Samorita "%s: the console does not support M_VGA_CG320\n", 15393011Samorita SAVER_NAME); 15493011Samorita return (ENODEV); 15593011Samorita } 15693011Samorita 15793011Samorita scrw = info.vi_width; 15893011Samorita scrh = info.vi_height; 15993011Samorita 16093011Samorita buf = (u_char *)malloc(scrw * (scrh + 1), M_DEVBUF, M_NOWAIT); 16193011Samorita if (buf) { 16293011Samorita bzero(buf, scrw * (scrh + 1)); 16393011Samorita } else { 16493011Samorita log(LOG_NOTICE, 16593011Samorita "%s: buffer allocation is failed\n", 16693011Samorita SAVER_NAME); 16793011Samorita return (ENODEV); 16893011Samorita } 16993011Samorita 17093011Samorita /* intialize the palette */ 17193011Samorita red = green = blue = 0; 17293011Samorita for (i = 0; i < 256; i++) { 17393011Samorita red++; 17493011Samorita if (red > 128) 17593011Samorita green += 2; 17693011Samorita fire_pal[RED(i)] = red; 17793011Samorita fire_pal[GREEN(i)] = green; 17893011Samorita fire_pal[BLUE(i)] = blue; 17993011Samorita } 18093011Samorita 18193011Samorita return (0); 18246407Sjkh} 18346407Sjkh 18493011Samoritastatic int 18593011Samoritafire_term(video_adapter_t *adp) 18693011Samorita{ 18793011Samorita free(buf, M_DEVBUF); 18893011Samorita return (0); 18993011Samorita} 19093011Samorita 19146407Sjkhstatic scrn_saver_t fire_module = { 19293011Samorita SAVER_NAME, 19393011Samorita fire_init, 19493011Samorita fire_term, 19593011Samorita fire_saver, 19693011Samorita NULL 19746407Sjkh}; 19846407Sjkh 19946407SjkhSAVER_MODULE(fire_saver, fire_module); 200