X-Git-Url: http://git.hungrycats.org/cgi-bin/gitweb.cgi?p=xscreensaver;a=blobdiff_plain;f=hacks%2Ffireworkx.c;h=3271212b4648f17336c6778e1b4bbfe16ebdd408;hp=e8c27b5dc4604f2a03b9eda2295cec7611ddfe1e;hb=49f5b54f312fe4ac2e9bc47581a72451bd0e8439;hpb=ccb7f4903325f92555a9722bba74b58346654ba0 diff --git a/hacks/fireworkx.c b/hacks/fireworkx.c index e8c27b5d..3271212b 100644 --- a/hacks/fireworkx.c +++ b/hacks/fireworkx.c @@ -16,7 +16,7 @@ * * Additional programming: * ------------------------ - * Support for different display color modes: + * Support for different dpy color modes: * Jean-Pierre Demailly * * Fixed array access problems by beating on it with a large hammer. @@ -29,7 +29,6 @@ #include #include "screenhack.h" -#include #define FWXVERSION "1.5" @@ -45,24 +44,6 @@ void mmx_glow(char *a, int b, int c, int d, char *e); #define rnd(x) ((int)(random() % (x))) -static int depth; -static int bigendian; -static Bool flash_on = True; -static Bool glow_on = True; -static Bool verbose = False; -static Bool shoot = False; -static int width; -static int height; -static int rndlife; -static int minlife; -static int delay = 0; -static float flash_fade = 0.99; -static unsigned char *palaka1=NULL; -static unsigned char *palaka2=NULL; -static XImage *xim=NULL; -static XColor *colors; -static int ncolors = 255; - typedef struct { unsigned int burn; float x; @@ -80,14 +61,40 @@ typedef struct { float air,flash; firepix *fpix; }fireshell; -int explode(fireshell *fs) +struct state { + Display *dpy; + Window window; + + fireshell *fshell, *ffshell; + GC gc; + + int depth; + int bigendian; + Bool flash_on; + Bool glow_on; + Bool verbose; + Bool shoot; + int width; + int height; + int rndlife; + int minlife; + int delay; + float flash_fade; + unsigned char *palaka1; + unsigned char *palaka2; + XImage *xim; + XColor *colors; + int ncolors; +}; + +static int explode(struct state *st, fireshell *fs) { float air,adg = 0.001; /* gravity */ unsigned int n,c; - unsigned int h = height; - unsigned int w = width; + unsigned int h = st->height; + unsigned int w = st->width; unsigned int *prgb; - unsigned char *palaka = palaka1; + unsigned char *palaka = st->palaka1; firepix *fp = fs->fpix; if(fs->vgn){ if(--fs->cy == fs->shy){ @@ -102,7 +109,7 @@ int explode(fireshell *fs) if((fs->cshift+1)%50==0) fs->color = ~fs->color; c = fs->color; air = fs->air; - fs->flash *= flash_fade; + fs->flash *= st->flash_fade; for(n=PIXCOUNT;n;n--){ if(fp->burn){ --fp->burn; if(fs->special){ @@ -120,23 +127,23 @@ int explode(fireshell *fs) } fp++; } return(--fs->life); } -void recycle(fireshell *fs,int x,int y) +static void recycle(struct state *st, fireshell *fs,int x,int y) { unsigned int n,pixlife; firepix *fp = fs->fpix; - fs->vgn = shoot; + fs->vgn = st->shoot; fs->shy = y; fs->cx = x; - fs->cy = shoot ? height : y ; + fs->cy = st->shoot ? st->height : y ; fs->color = (rnd(155)+100) <<16 | (rnd(155)+100) <<8 | rnd(255); - fs->life = rnd(rndlife)+minlife; + fs->life = rnd(st->rndlife)+st->minlife; fs->air = 1-(float)(rnd(200))/10000; fs->flash = rnd(30000)+15000; /* million jouls */ fs->cshift = !rnd(5) ? 120:0; fs->special = !rnd(10) ? 1:0; - if(verbose) + if(st->verbose) printf("recycle(): color = %x air = %f life = %d \n",fs->color,fs->air,fs->life); pixlife = rnd(fs->life)+fs->life/10+1; /* ! */ for(n=0;ny = y; fp++; }} -void glow(void) +static void glow(struct state *st) { unsigned int n,q; - unsigned int w = width; - unsigned int h = height; + unsigned int w = st->width; + unsigned int h = st->height; unsigned char *pa, *pb, *pm, *po; - pm = palaka1; - po = palaka2; + pm = st->palaka1; + po = st->palaka2; for(n=0;nwidth; + unsigned int h = st->height; unsigned char *pa, *pb, *pm; - pm = palaka1; + pm = st->palaka1; pm += w*4; h-=2; /* line 0&h */ pa = pm-(w*4); pb = pm+(w*4); @@ -192,20 +199,20 @@ void blur(void) pm[n] = q>>4;} pm += n-4; /* last line */ for(n=0;npalaka1; /* first line */ for(n=0;nwidth; + int h = st->height; + unsigned char *dim = st->palaka2; + unsigned char *sim = st->palaka1; int nl = w*4; fireshell *f; - if(glow_on) sim=dim; + if(st->glow_on) sim=dim; for(y=0;ydpy, st->window, &xwa); xwa.width -= xwa.width % 2; xwa.height -= xwa.height % 2; - if(xwa.height != height || xwa.width != width) { - width = xwa.width; - height = xwa.height; - if (verbose) - printf("sky size: %dx%d ------------------------------\n",width,height); - XSync(display,0); - if (xim) { - if (xim->data==(char *)palaka2) xim->data=NULL; - XDestroyImage(xim); - XSync(display,0); - if (palaka2!=palaka1) free(palaka2 - 8); - free(palaka1 - 8); + if(xwa.height != st->height || xwa.width != st->width) { + st->width = xwa.width; + st->height = xwa.height; + if (st->verbose) + printf("sky size: %dx%d ------------------------------\n",st->width,st->height); + if (st->xim) { + if (st->xim->data==(char *)st->palaka2) st->xim->data=NULL; + XDestroyImage(st->xim); + if (st->palaka2!=st->palaka1) free(st->palaka2 - 8); + free(st->palaka1 - 8); } - palaka1 = NULL; - palaka2 = NULL; - xim = XCreateImage(display, xwa.visual, xwa.depth, ZPixmap, 0, 0, - width, height, 8, 0); - palaka1 = (unsigned char *) calloc(xim->height+1,xim->width*4) + 8; - if(flash_on|glow_on) - palaka2 = (unsigned char *) calloc(xim->height+1,xim->width*4) + 8; + st->palaka1 = NULL; + st->palaka2 = NULL; + st->xim = XCreateImage(st->dpy, xwa.visual, xwa.depth, ZPixmap, 0, 0, + st->width, st->height, 8, 0); + st->palaka1 = (unsigned char *) calloc(st->xim->height+1,st->xim->width*4) + 8; + if(st->flash_on|st->glow_on) + st->palaka2 = (unsigned char *) calloc(st->xim->height+1,st->xim->width*4) + 8; else - palaka2 = palaka1; - if (depth>=24) - xim->data = (char *)palaka2; + st->palaka2 = st->palaka1; + if (st->depth>=24) + st->xim->data = (char *)st->palaka2; else - xim->data = calloc(xim->height,xim->bytes_per_line); }} + st->xim->data = calloc(st->xim->height,st->xim->bytes_per_line); }} -void put_image(Display *display, Window win, GC gc, XImage *xim) +static void put_image(struct state *st) { int x,y,i,j; unsigned char r, g, b; i = 0; j = 0; - if (depth==16) { - if(bigendian) - for (y=0;yheight; y++) - for (x=0;xwidth; x++) { - r = palaka2[j++]; - g = palaka2[j++]; - b = palaka2[j++]; + if (st->depth==16) { + if(st->bigendian) + for (y=0;yxim->height; y++) + for (x=0;xxim->width; x++) { + r = st->palaka2[j++]; + g = st->palaka2[j++]; + b = st->palaka2[j++]; j++; - xim->data[i++] = (g&224)>>5 | (r&248); - xim->data[i++] = (b&248)>>3 | (g&28)<<3; + st->xim->data[i++] = (g&224)>>5 | (r&248); + st->xim->data[i++] = (b&248)>>3 | (g&28)<<3; } else - for (y=0;yheight; y++) - for (x=0;xwidth; x++) { - r = palaka2[j++]; - g = palaka2[j++]; - b = palaka2[j++]; + for (y=0;yxim->height; y++) + for (x=0;xxim->width; x++) { + r = st->palaka2[j++]; + g = st->palaka2[j++]; + b = st->palaka2[j++]; j++; - xim->data[i++] = (b&248)>>3 | (g&28)<<3; - xim->data[i++] = (g&224)>>5 | (r&248); + st->xim->data[i++] = (b&248)>>3 | (g&28)<<3; + st->xim->data[i++] = (g&224)>>5 | (r&248); } } - if (depth==15) { - if(bigendian) - for (y=0;yheight; y++) - for (x=0;xwidth; x++) { - r = palaka2[j++]; - g = palaka2[j++]; - b = palaka2[j++]; + if (st->depth==15) { + if(st->bigendian) + for (y=0;yxim->height; y++) + for (x=0;xxim->width; x++) { + r = st->palaka2[j++]; + g = st->palaka2[j++]; + b = st->palaka2[j++]; j++; - xim->data[i++] = (g&192)>>6 | (r&248)>>1; - xim->data[i++] = (b&248)>>3 | (g&56)<<2; + st->xim->data[i++] = (g&192)>>6 | (r&248)>>1; + st->xim->data[i++] = (b&248)>>3 | (g&56)<<2; } else - for (y=0;yheight; y++) - for (x=0;xwidth; x++) { - r = palaka2[j++]; - g = palaka2[j++]; - b = palaka2[j++]; + for (y=0;yxim->height; y++) + for (x=0;xxim->width; x++) { + r = st->palaka2[j++]; + g = st->palaka2[j++]; + b = st->palaka2[j++]; j++; - xim->data[i++] = (b&248)>>3 | (g&56)<<2; - xim->data[i++] = (g&192)>>6 | (r&248)>>1; + st->xim->data[i++] = (b&248)>>3 | (g&56)<<2; + st->xim->data[i++] = (g&192)>>6 | (r&248)>>1; } } - if (depth==8) { - for (y=0;yheight; y++) - for (x=0;xwidth; x++) { - r = palaka2[j++]; - g = palaka2[j++]; - b = palaka2[j++]; + if (st->depth==8) { + for (y=0;yxim->height; y++) + for (x=0;xxim->width; x++) { + r = st->palaka2[j++]; + g = st->palaka2[j++]; + b = st->palaka2[j++]; j++; - xim->data[i++] = (((7*g)/256)*36)+(((6*r)/256)*6)+((6*b)/256); + st->xim->data[i++] = (((7*g)/256)*36)+(((6*r)/256)*6)+((6*b)/256); } } - XPutImage(display,win,gc,xim,0,0,0,0,xim->width,xim->height); } - -void sniff_events(Display *dis, Window win, fireshell *fss) -{ - XEvent e; - while (XPending(dis)){ - XNextEvent (dis, &e); - if (e.type == ConfigureNotify) resize(dis,win); - if (e.type == ButtonPress) recycle(fss,e.xbutton.x, e.xbutton.y); - screenhack_handle_event(dis,&e); }} - + XPutImage(st->dpy,st->window,st->gc,st->xim,0,0,0,0,st->xim->width,st->xim->height); } -char *progclass = "Fireworkx"; -char *defaults [] = { - ".background: black", - ".foreground: white", - "*delay: 10000", /* never default to zero! */ - "*maxlife: 2000", - "*flash: True", - "*glow: True", - "*shoot: False", - "*verbose: False", - 0 -}; - -XrmOptionDescRec options [] = { - { "-delay", ".delay", XrmoptionSepArg, 0 }, - { "-maxlife", ".maxlife", XrmoptionSepArg, 0 }, - { "-noflash", ".flash", XrmoptionNoArg, "False" }, - { "-noglow", ".glow", XrmoptionNoArg, "False" }, - { "-shoot", ".shoot", XrmoptionNoArg, "True" }, - { "-verbose", ".verbose", XrmoptionNoArg, "True" }, - { 0, 0, 0, 0 } -}; - -void -screenhack (Display *display, Window win) +static void * +fireworkx_init (Display *dpy, Window win) { - unsigned int n,q; + struct state *st = (struct state *) calloc (1, sizeof(*st)); + unsigned int n; Visual *vi; Colormap cmap; Bool writable; XWindowAttributes xwa; - GC gc; XGCValues gcv; firepix *fpix, *ffpix; - fireshell *fshell, *ffshell; - glow_on = get_boolean_resource("glow" , "Boolean"); - flash_on = get_boolean_resource("flash" , "Boolean"); - shoot = get_boolean_resource("shoot" , "Boolean"); - verbose = get_boolean_resource("verbose" , "Boolean"); - rndlife = get_integer_resource("maxlife" , "Integer"); - delay = get_integer_resource("delay" , "Integer"); - minlife = rndlife/4; - if(rndlife<1000) flash_fade=0.98; - if(rndlife<500) flash_fade=0.97; - if(verbose){ + + st->dpy = dpy; + st->window = win; + + st->glow_on = get_boolean_resource(st->dpy, "glow" , "Boolean"); + st->flash_on = get_boolean_resource(st->dpy, "flash" , "Boolean"); + st->shoot = get_boolean_resource(st->dpy, "shoot" , "Boolean"); + st->verbose = get_boolean_resource(st->dpy, "verbose" , "Boolean"); + st->rndlife = get_integer_resource(st->dpy, "maxlife" , "Integer"); + st->delay = get_integer_resource(st->dpy, "delay" , "Integer"); + st->minlife = st->rndlife/4; + if(st->rndlife<1000) st->flash_fade=0.98; + if(st->rndlife<500) st->flash_fade=0.97; + if(st->verbose){ printf("Fireworkx %s - pyrotechnics simulation program \n", FWXVERSION); printf("Copyright (c) 1999-2005 Rony B Chandran \n\n"); printf("url: http://www.ronybc.8k.com \n\n");} - XGetWindowAttributes(display,win,&xwa); - depth = xwa.depth; + XGetWindowAttributes(st->dpy,win,&xwa); + st->depth = xwa.depth; vi = xwa.visual; cmap = xwa.colormap; - bigendian = (ImageByteOrder(display) == MSBFirst); + st->bigendian = (ImageByteOrder(st->dpy) == MSBFirst); - if(depth==8){ - if(verbose){ - printf("Pseudocolor color: use '-noflash' for better results.\n");} - colors = (XColor *) calloc(sizeof(XColor),ncolors+1); + if(st->depth==8){ + if(st->verbose){ + printf("Pseudocolor color: use '-no-flash' for better results.\n");} + st->colors = (XColor *) calloc(sizeof(XColor),st->ncolors+1); writable = False; - make_smooth_colormap(display, vi, cmap, colors, &ncolors, + make_smooth_colormap(st->dpy, vi, cmap, st->colors, &st->ncolors, False, &writable, True); } - gc = XCreateGC(display, win, 0, &gcv); + st->gc = XCreateGC(st->dpy, win, 0, &gcv); - resize(display,win); /* initialize palakas */ + resize(st); /* initialize palakas */ ffpix = malloc(sizeof(firepix) * PIXCOUNT * SHELLCOUNT); - ffshell = malloc(sizeof(fireshell) * SHELLCOUNT); - fshell = ffshell; + st->ffshell = malloc(sizeof(fireshell) * SHELLCOUNT); + st->fshell = st->ffshell; fpix = ffpix; for (n=0;nfpix = fpix; - recycle (fshell,rnd(width),rnd(height)); - fshell++; + st->fshell->fpix = fpix; + recycle (st, st->fshell,rnd(st->width),rnd(st->height)); + st->fshell++; fpix += PIXCOUNT; } - while(1) { + return st; +} + + +static unsigned long +fireworkx_draw (Display *dpy, Window win, void *closure) +{ + struct state *st = (struct state *) closure; + int q,n; for(q=FTWEAK;q;q--){ - fshell=ffshell; - for(n=SHELLCOUNT;n;n--){ - if (!explode(fshell)){ - recycle(fshell,rnd(width),rnd(height)); } - fshell++; }} + st->fshell=st->ffshell; + for(n=SHELLCOUNT;n;n--){ + if (!explode(st, st->fshell)){ + recycle(st, st->fshell,rnd(st->width),rnd(st->height)); } + st->fshell++; }} #if HAVE_X86_MMX - if(glow_on) mmx_glow(palaka1,width,height,8,palaka2); + if(st->glow_on) mmx_glow(st->palaka1,st->width,st->height,8,st->palaka2); #else - if(glow_on) glow(); + if(st->glow_on) glow(st); #endif - if(flash_on) light_2x2(ffshell); - put_image(display,win,gc,xim); - usleep(delay); - XSync(display,0); - sniff_events(display, win, ffshell); + if(st->flash_on) light_2x2(st, st->ffshell); + put_image(st); #if HAVE_X86_MMX - if(!glow_on) mmx_blur(palaka1,width,height,8); + if(!st->glow_on) mmx_blur(st->palaka1,st->width,st->height,8); #else - if(!glow_on) blur(); + if(!st->glow_on) blur(st); #endif -}} + return st->delay; +} + + +static void +fireworkx_reshape (Display *dpy, Window window, void *closure, + unsigned int w, unsigned int h) +{ + struct state *st = (struct state *) closure; + resize(st); +} + +static Bool +fireworkx_event (Display *dpy, Window window, void *closure, XEvent *event) +{ + struct state *st = (struct state *) closure; + if (event->type == ButtonPress) { + recycle(st, st->fshell, event->xbutton.x, event->xbutton.y); + return True; + } + return False; +} + +static void +fireworkx_free (Display *dpy, Window window, void *closure) +{ +} + + +static const char *fireworkx_defaults [] = { + ".background: black", + ".foreground: white", + "*delay: 20000", /* never default to zero! */ + "*maxlife: 2000", + "*flash: True", + "*glow: True", + "*shoot: False", + "*verbose: False", + 0 +}; + +static XrmOptionDescRec fireworkx_options [] = { + { "-delay", ".delay", XrmoptionSepArg, 0 }, + { "-maxlife", ".maxlife", XrmoptionSepArg, 0 }, + { "-no-flash", ".flash", XrmoptionNoArg, "False" }, + { "-no-glow", ".glow", XrmoptionNoArg, "False" }, + { "-shoot", ".shoot", XrmoptionNoArg, "True" }, + { "-verbose", ".verbose", XrmoptionNoArg, "True" }, + { 0, 0, 0, 0 } +}; + +XSCREENSAVER_MODULE ("Fireworkx", fireworkx)