2
* Fireworkx 1.3 - pyrotechnics simulation program
3
* Copyright (c) 1999-2004 Rony B Chandran <ronybc@asia.com>
2
* Fireworkx 1.5 - pyrotechnics simulation program
3
* Copyright (c) 1999-2005 Rony B Chandran <ronybc@asia.com>
5
7
* url: http://www.ronybc.8k.com
7
9
* Permission to use, copy, modify, distribute, and sell this software and its
20
22
* Fixed array access problems by beating on it with a large hammer.
21
23
* Nicholas Miell <nmiell@gmail.com>
25
* Freed 'free'ing up of memory by adding the forgotten 'XSync's
26
* Renuka S <renuka@local.net>
26
31
#include "screenhack.h"
27
32
#include <X11/Xutil.h>
29
#define FWXVERSION "1.3"
34
#define FWXVERSION "1.5"
36
#define SHELLCOUNT 3 /* 3 or 5 */
34
37
#define PIXCOUNT 500 /* 500 */
35
#define RNDLIFE0 250 /* violent */
36
#define RNDLIFE1 1200 /* 1200 */
37
#define MINLIFE0 50 /* violent */
38
#define MINLIFE1 500 /* 500 */
39
38
#define POWER 5 /* 5 */
40
39
#define FTWEAK 12 /* 12 */
42
void mmx_blur(char *a, int b, int c, int d);
43
void mmx_glow(char *a, int b, int c, int d, char *e);
46
#define rnd(x) ((int)(random() % (x)))
43
49
static int bigendian;
44
static Bool light_on = True;
45
static Bool fade_on = False;
46
static Bool shoot = False;
47
static Bool verbose = False;
49
static int fsc_width = 0;
50
static int fsc_height= 0;
51
static int rndlife = RNDLIFE1;
52
static int minlife = MINLIFE1;
53
static float light_fade = 0.99;
54
static unsigned char *real_palaka1 = NULL;
55
static unsigned char *real_palaka2 = NULL;
50
static Bool flash_on = True;
51
static Bool glow_on = True;
52
static Bool verbose = False;
53
static Bool shoot = False;
59
static float flash_fade = 0.99;
56
60
static unsigned char *palaka1=NULL;
57
61
static unsigned char *palaka2=NULL;
58
62
static XImage *xim=NULL;
71
76
unsigned int color;
73
77
unsigned int special;
74
78
unsigned int cshift;
75
79
unsigned int vgn,shy;
77
81
firepix *fpix; }fireshell;
82
if ((seed = seed % 44488 * 48271 - seed / 44488 * 3399) < 0)
87
83
int explode(fireshell *fs)
89
float air,adg = 0.001; /* gravity */
85
float air,adg = 0.001; /* gravity */
91
unsigned int h = fsc_height;
92
unsigned int w = fsc_width;
87
unsigned int h = height;
88
unsigned int w = width;
93
89
unsigned int *prgb;
94
90
unsigned char *palaka = palaka1;
95
91
firepix *fp = fs->fpix;
97
93
if(--fs->cy == fs->shy){
99
fs->lum = 20000;} /* millions of jouls..! */
95
fs->flash = rnd(30000)+15000;}
101
fs->lum = 50+(fs->cy - fs->shy)*2;
97
fs->flash = 50+(fs->cy - fs->shy)*2;
98
prgb=(unsigned int *)(palaka + (fs->cy * w + fs->cx + rnd(5)-2)*4);
99
*prgb=(rnd(8)+8)*0x000f0f10;
103
101
if(fs->cshift) --fs->cshift;
104
102
if((fs->cshift+1)%50==0) fs->color = ~fs->color;
107
fs->lum *= light_fade;
105
fs->flash *= flash_fade;
108
106
for(n=PIXCOUNT;n;n--){
109
107
if(fp->burn){ --fp->burn;
111
109
fp->x += fp->xv = fp->xv * air + (float)(rnd(200)-100)/2000;
112
fp->y += fp->yv = fp->yv * air + (float)(rnd(200)-100)/2000 +adg; }
110
fp->y += fp->yv = fp->yv * air + (float)(rnd(200)-100)/2000 + adg; }
114
112
fp->x += fp->xv = fp->xv * air + (float)(rnd(200)-100)/20000;
115
113
fp->y += fp->yv = fp->yv * air + adg; }
133
fs->cy = shoot ? fsc_height : y ;
130
fs->cy = shoot ? height : y ;
134
131
fs->color = (rnd(155)+100) <<16 |
135
132
(rnd(155)+100) <<8 |
137
134
fs->life = rnd(rndlife)+minlife;
138
135
fs->air = 1-(float)(rnd(200))/10000;
136
fs->flash = rnd(30000)+15000; /* million jouls */
140
137
fs->cshift = !rnd(5) ? 120:0;
141
138
fs->special = !rnd(10) ? 1:0;
140
printf("recycle(): color = %x air = %f life = %d \n",fs->color,fs->air,fs->life);
142
141
pixlife = rnd(fs->life)+fs->life/10+1; /* ! */
143
142
for(n=0;n<PIXCOUNT;n++){
144
143
fp->burn = rnd(pixlife)+32;
147
146
(float)(rnd(20000)-10000)/10000;
156
unsigned int w = fsc_width;
157
unsigned int h = fsc_height;
154
unsigned int w = width;
155
unsigned int h = height;
156
unsigned char *pa, *pb, *pm, *po;
160
{pm[n]=0; po[n]=0;} /* clean first line */
164
for(n=4;n<w*h*4-4;n++){
165
q = pm[n-4] + (pm[n]*8) + pm[n+4] +
166
pa[n-4] + pa[n] + pa[n+4] +
167
pb[n-4] + pb[n] + pb[n+4];
175
{pm[n]=0; po[n]=0;}} /* clean last line */
180
unsigned int w = width;
181
unsigned int h = height;
158
182
unsigned char *pa, *pb, *pm;
160
for(n=0;n<w*4;n++) pm[n]=0; /* clean first line */
184
pm += w*4; h-=2; /* line 0&h */
166
for(n=0;n<w*h*4;n++){
167
pm[n]=(pm[n-4] + pm[n] + pm[n+4] +
168
pa[n-4] + pa[n] + pa[n+4] +
169
pb[n-4] + pb[n] + pb[n+4] +
170
pm[n] + pm[n] + (pm[n]<<2))/ 16;}}
172
for(n=0;n<w*h*4;n++){
173
pm[n]=(pm[n-4] + pm[n] + pm[n+4] +
174
pa[n-4] + pa[n] + pa[n+4] +
175
pb[n-4] + pb[n] + pb[n+4])/ 9;}}
177
for(n=0;n<w*4;n++) pm[n]=0; /* clean last line */
187
for(n=4;n<w*h*4-4;n++){
188
q = pm[n-4] + (pm[n]*8) + pm[n+4] +
189
pa[n-4] + pa[n] + pa[n+4] +
190
pb[n-4] + pb[n] + pb[n+4];
193
pm += n-4; /* last line */
194
for(n=0;n<w*4+4;n++) pm[n]=0;
195
pm = palaka1; /* first line */
196
for(n=0;n<w*4+4;n++) pm[n]=pm[n+w*4]; }
180
198
void light_2x2(fireshell *fss)
182
200
unsigned int l,t,n,x,y;
186
204
unsigned char *dim = palaka2;
187
205
unsigned char *sim = palaka1;
190
209
for(y=0;y<h;y+=2){
191
210
for(x=0;x<w;x+=2){
193
212
for(n=SHELLCOUNT;n;n--,f++){
194
s += f->lum / ( 1 + sqrt((f->cx - x)*(f->cx - x)+(f->cy - y)*(f->cy - y))); }
213
s += f->flash/(sqrt(1+(f->cx - x)*(f->cx - x)+
214
(f->cy - y)*(f->cy - y)));}
198
dim[0] = (t > 255 ? 255 : t); /* cmov's */
218
dim[0] = (t > 255 ? 255 : t);
200
220
dim[1] = (t > 255 ? 255 : t);
222
242
t = l + sim[nl+6];
223
243
dim[nl+6] = (t > 255 ? 255 : t);
225
sim += 8; dim += 8; } sim += nl; dim += nl;}
245
sim += 8; dim += 8; } sim += nl; dim += nl;}}
228
247
void resize(Display *display, Window win)
230
249
XWindowAttributes xwa;
231
250
XGetWindowAttributes (display, win, &xwa);
232
xwa.width -= xwa.width % 4;
233
xwa.height -= xwa.height % 4;
234
if(xwa.height != fsc_height || xwa.width != fsc_width) {
235
fsc_width = xwa.width;
236
fsc_height = xwa.height;
251
xwa.width -= xwa.width % 2;
252
xwa.height -= xwa.height % 2;
253
if(xwa.height != height || xwa.width != width) {
257
printf("sky size: %dx%d ------------------------------\n",width,height);
238
260
if (xim->data==(char *)palaka2) xim->data=NULL;
239
261
XDestroyImage(xim);
240
if (palaka2!=palaka1) free(real_palaka2);
263
if (palaka2!=palaka1) free(palaka2 - 8);
245
268
xim = XCreateImage(display, xwa.visual, xwa.depth, ZPixmap, 0, 0,
246
fsc_width, fsc_height, 32, 0);
247
real_palaka1 = calloc(xim->height + 4,xim->width*4);
248
palaka1 = real_palaka1 + xim->width * 4 * 2;
250
real_palaka2 = calloc(xim->height + 4,xim->width*4);
251
palaka2 = real_palaka2 + xim->width * 4 * 2;
269
width, height, 8, 0);
270
palaka1 = (unsigned char *) calloc(xim->height+1,xim->width*4) + 8;
272
palaka2 = (unsigned char *) calloc(xim->height+1,xim->width*4) + 8;
256
276
xim->data = (char *)palaka2;
258
xim->data = calloc(xim->height,xim->bytes_per_line);
278
xim->data = calloc(xim->height,xim->bytes_per_line); }}
262
280
void put_image(Display *display, Window win, GC gc, XImage *xim)
319
337
xim->data[i++] = (((7*g)/256)*36)+(((6*r)/256)*6)+((6*b)/256);
322
XPutImage(display,win,gc,xim,0,0,0,0,xim->width,xim->height);
340
XPutImage(display,win,gc,xim,0,0,0,0,xim->width,xim->height); }
325
342
void sniff_events(Display *dis, Window win, fireshell *fss)
329
346
XNextEvent (dis, &e);
330
347
if (e.type == ConfigureNotify) resize(dis,win);
331
348
if (e.type == ButtonPress) recycle(fss,e.xbutton.x, e.xbutton.y);
332
screenhack_handle_event(dis,&e);}
349
screenhack_handle_event(dis,&e); }}
336
352
char *progclass = "Fireworkx";
350
366
XrmOptionDescRec options [] = {
351
367
{ "-delay", ".delay", XrmoptionSepArg, 0 },
352
368
{ "-maxlife", ".maxlife", XrmoptionSepArg, 0 },
353
{ "-nolight", ".light", XrmoptionNoArg, "False" },
354
{ "-fade", ".fade", XrmoptionNoArg, "True" },
369
{ "-noflash", ".flash", XrmoptionNoArg, "False" },
370
{ "-noglow", ".glow", XrmoptionNoArg, "False" },
355
371
{ "-shoot", ".shoot", XrmoptionNoArg, "True" },
356
372
{ "-verbose", ".verbose", XrmoptionNoArg, "True" },
367
383
XWindowAttributes xwa;
370
firepix *fpixs, *fpix;
371
fireshell *fshells, *fshell;
372
fade_on = get_boolean_resource("fade" , "Boolean");
373
light_on = get_boolean_resource("light" , "Boolean");
386
firepix *fpix, *ffpix;
387
fireshell *fshell, *ffshell;
388
glow_on = get_boolean_resource("glow" , "Boolean");
389
flash_on = get_boolean_resource("flash" , "Boolean");
374
390
shoot = get_boolean_resource("shoot" , "Boolean");
375
391
verbose = get_boolean_resource("verbose" , "Boolean");
376
392
rndlife = get_integer_resource("maxlife" , "Integer");
377
393
delay = get_integer_resource("delay" , "Integer");
378
394
minlife = rndlife/4;
379
if(rndlife<1000) light_fade=0.98;
380
if(rndlife<500) light_fade=0.97;
381
if(fade_on) light_fade=0.97;
395
if(rndlife<1000) flash_fade=0.98;
396
if(rndlife<500) flash_fade=0.97;
383
398
printf("Fireworkx %s - pyrotechnics simulation program \n", FWXVERSION);
384
printf("Copyright (c) 1999-2004 Rony B Chandran <ronybc@asia.com> \n\n");
399
printf("Copyright (c) 1999-2005 Rony B Chandran <ronybc@asia.com> \n\n");
385
400
printf("url: http://www.ronybc.8k.com \n\n");}
387
402
XGetWindowAttributes(display,win,&xwa);
395
printf("Pseudocolor color: use '-fade' & '-nolight' for better results.\n");}
410
printf("Pseudocolor color: use '-noflash' for better results.\n");}
396
411
colors = (XColor *) calloc(sizeof(XColor),ncolors+1);
397
412
writable = False;
398
413
make_smooth_colormap(display, vi, cmap, colors, &ncolors,
401
416
gc = XCreateGC(display, win, 0, &gcv);
403
418
resize(display,win); /* initialize palakas */
406
fpixs = malloc(sizeof(firepix) * PIXCOUNT * SHELLCOUNT);
407
fshells = malloc(sizeof(fireshell) * SHELLCOUNT);
420
ffpix = malloc(sizeof(firepix) * PIXCOUNT * SHELLCOUNT);
421
ffshell = malloc(sizeof(fireshell) * SHELLCOUNT);
410
424
for (n=0;n<SHELLCOUNT;n++){
411
425
fshell->fpix = fpix;
412
recycle (fshell,rnd(fsc_width),rnd(fsc_height));
426
recycle (fshell,rnd(width),rnd(height));
414
428
fpix += PIXCOUNT; }
417
431
for(q=FTWEAK;q;q--){
419
433
for(n=SHELLCOUNT;n;n--){
420
434
if (!explode(fshell)){
421
recycle(fshell,rnd(fsc_width),rnd(fsc_height)); }
435
recycle(fshell,rnd(width),rnd(height)); }
423
if(light_on) light_2x2(fshells);
438
if(glow_on) mmx_glow(palaka1,width,height,8,palaka2);
442
if(flash_on) light_2x2(ffshell);
424
443
put_image(display,win,gc,xim);
426
445
XSync(display,0);
427
sniff_events(display, win, fshells);
446
sniff_events(display, win, ffshell);
448
if(!glow_on) mmx_blur(palaka1,width,height,8);