~ubuntu-branches/ubuntu/karmic/xscreensaver/karmic

« back to all changes in this revision

Viewing changes to hacks/fireworkx.c

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-12-08 16:00:22 UTC
  • mto: (2.1.2 etch)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20051208160022-7ten2wfh180wf89a
Tags: upstream-4.23
ImportĀ upstreamĀ versionĀ 4.23

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
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>
4
4
 *
 
5
 * From Kerala, INDIA
 
6
 * 
5
7
 * url: http://www.ronybc.8k.com
6
8
 *
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>
22
24
 *
 
25
 * Freed 'free'ing up of memory by adding the forgotten 'XSync's
 
26
 * Renuka S <renuka@local.net>
 
27
 *
23
28
 */
24
29
 
25
30
#include <math.h>
26
31
#include "screenhack.h"
27
32
#include <X11/Xutil.h>
28
33
 
29
 
#define FWXVERSION "1.3"
 
34
#define FWXVERSION "1.5"
30
35
 
31
 
#define WIDTH 640
32
 
#define HEIGHT 480
33
 
#define SHELLCOUNT 3
 
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      */
41
40
 
 
41
#if HAVE_X86_MMX
 
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);
 
44
#endif
 
45
 
 
46
#define rnd(x) ((int)(random() % (x)))
 
47
 
42
48
static int depth;
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;
48
 
static int delay     = 0;
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;
 
54
static int width;
 
55
static int height;
 
56
static int rndlife;
 
57
static int minlife;
 
58
static int delay = 0;
 
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;
67
71
  float yv;}firepix;
68
72
 
69
73
typedef struct {
 
74
  unsigned int cx,cy;
70
75
  unsigned int life;
71
76
  unsigned int color;
72
 
  unsigned int cx,cy;
73
77
  unsigned int special;
74
78
  unsigned int cshift;
75
79
  unsigned int vgn,shy;
76
 
  float air,lum;
 
80
  float air,flash;
77
81
  firepix *fpix; }fireshell;
78
82
 
79
 
int seed = 2387776;
80
 
int rnd(int x)
81
 
{   /* xscreensaver */
82
 
  if ((seed = seed % 44488 * 48271 - seed / 44488 * 3399) < 0)
83
 
  seed += 2147483647;
84
 
  return (seed-1) % x;
85
 
}
86
 
 
87
83
int explode(fireshell *fs)
88
84
{
89
 
  float air,adg = 0.001;     /* gravity */
 
85
  float air,adg = 0.001;         /* gravity */
90
86
  unsigned int n,c;
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;
96
92
  if(fs->vgn){
97
93
    if(--fs->cy == fs->shy){  
98
 
      fs->vgn = 0;
99
 
      fs->lum = 20000;}    /* millions of jouls..! */
 
94
      fs->vgn   = 0;
 
95
      fs->flash = rnd(30000)+15000;}
100
96
    else{  
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;
102
100
      return(1);}}    
103
101
  if(fs->cshift) --fs->cshift;
104
102
  if((fs->cshift+1)%50==0) fs->color = ~fs->color;
105
103
  c = fs->color;
106
104
  air = fs->air;
107
 
  fs->lum *= light_fade;
 
105
  fs->flash *= flash_fade;
108
106
  for(n=PIXCOUNT;n;n--){
109
107
  if(fp->burn){ --fp->burn; 
110
108
  if(fs->special){
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; }
113
111
  else{
114
112
  fp->x += fp->xv = fp->xv * air + (float)(rnd(200)-100)/20000;
115
113
  fp->y += fp->yv = fp->yv * air + adg; }
120
118
     prgb = (unsigned int *)(palaka + ((int)fp->y * w + (int)fp->x)*4);
121
119
    *prgb = c; }
122
120
  } fp++;
123
 
  } return(--(fs->life));
124
 
}
 
121
  } return(--fs->life); }
125
122
 
126
123
void recycle(fireshell *fs,int x,int y)
127
124
{
130
127
  fs->vgn = shoot;
131
128
  fs->shy = y;
132
129
  fs->cx = x;
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  |
136
133
               rnd(255);
137
134
  fs->life = rnd(rndlife)+minlife;
138
135
  fs->air  = 1-(float)(rnd(200))/10000;
139
 
  fs->lum  = 20000;
 
136
  fs->flash   = rnd(30000)+15000;        /* million jouls */
140
137
  fs->cshift  = !rnd(5) ? 120:0; 
141
138
  fs->special = !rnd(10) ? 1:0; 
 
139
  if(verbose)
 
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;
148
147
  fp->x = x;
149
148
  fp->y = y; 
150
 
  fp++;             }
151
 
}
152
 
 
153
 
void blur_best(void)
154
 
{
155
 
  int n;
156
 
  unsigned int w = fsc_width;
157
 
  unsigned int h = fsc_height;
 
149
  fp++;             }}
 
150
 
 
151
void glow(void)
 
152
{
 
153
  unsigned int n,q;
 
154
  unsigned int w = width;
 
155
  unsigned int h = height;
 
156
  unsigned char *pa, *pb, *pm, *po;
 
157
  pm = palaka1;
 
158
  po = palaka2;
 
159
  for(n=0;n<w*4;n++) 
 
160
  {pm[n]=0; po[n]=0;}    /* clean first line */
 
161
  pm+=n; po+=n; h-=2; 
 
162
  pa = pm-(w*4);
 
163
  pb = pm+(w*4);
 
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];
 
168
  q    -= q>8 ? 8:q;
 
169
  pm[n] = q/16;
 
170
  q     = q/8;
 
171
  if(q>255) q=255;
 
172
  po[n] = q;}
 
173
  pm+=n; po+=n;
 
174
  for(n=0;n<w*4;n++)
 
175
  {pm[n]=0; po[n]=0;}}   /* clean last line */
 
176
 
 
177
void blur(void)
 
178
{
 
179
  unsigned int n,q;
 
180
  unsigned int w = width;
 
181
  unsigned int h = height;
158
182
  unsigned char *pa, *pb, *pm;
159
183
  pm = palaka1;
160
 
  for(n=0;n<w*4;n++) pm[n]=0;    /* clean first line */
161
 
  pm+=n;
162
 
  h-=2; 
 
184
  pm += w*4; h-=2;  /* line 0&h */
163
185
  pa = pm-(w*4);
164
186
  pb = pm+(w*4);
165
 
  if(fade_on){
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;}}
171
 
  else{
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;}}
176
 
  pm+=n;
177
 
  for(n=0;n<w*4;n++) pm[n]=0;    /* clean last line */
178
 
}
 
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];
 
191
  q    -= q>8 ? 8:q;
 
192
  pm[n] = q>>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]; }
179
197
 
180
198
void light_2x2(fireshell *fss)
181
199
{
182
200
  unsigned int l,t,n,x,y;
183
201
  float s;
184
 
  int w = fsc_width;
185
 
  int h = fsc_height;
 
202
  int w = width;
 
203
  int h = height;
186
204
  unsigned char *dim = palaka2;
187
205
  unsigned char *sim = palaka1;
188
206
  int nl = w*4;
189
207
  fireshell *f;
 
208
  if(glow_on) sim=dim;
190
209
  for(y=0;y<h;y+=2){
191
210
  for(x=0;x<w;x+=2){
192
211
  f = fss; s = 0;
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)));}
195
215
  l = s;
196
216
 
197
217
  t = l + sim[0];
198
 
  dim[0] = (t > 255 ? 255 : t);  /* cmov's */
 
218
  dim[0] = (t > 255 ? 255 : t); 
199
219
  t = l + sim[1];
200
220
  dim[1] = (t > 255 ? 255 : t);
201
221
  t = l + sim[2];
222
242
  t = l + sim[nl+6];
223
243
  dim[nl+6] = (t > 255 ? 255 : t);
224
244
 
225
 
  sim += 8; dim += 8; } sim += nl; dim += nl;}
226
 
}
 
245
  sim += 8; dim += 8; } sim += nl; dim += nl;}}
227
246
 
228
247
void resize(Display *display, Window win)
229
248
{
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) {
 
254
  width  = xwa.width;
 
255
  height = xwa.height;
 
256
  if (verbose)
 
257
  printf("sky size: %dx%d ------------------------------\n",width,height);
 
258
  XSync(display,0);
237
259
  if (xim) {
238
260
  if (xim->data==(char *)palaka2) xim->data=NULL;  
239
261
  XDestroyImage(xim);
240
 
  if (palaka2!=palaka1) free(real_palaka2);
241
 
  free(real_palaka1); 
 
262
  XSync(display,0);
 
263
  if (palaka2!=palaka1) free(palaka2 - 8);
 
264
  free(palaka1 - 8); 
242
265
  }
243
 
  palaka1 = NULL;     
244
 
  palaka2 = NULL; 
 
266
  palaka1 = NULL;
 
267
  palaka2 = NULL;
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;
249
 
  if(light_on) {
250
 
       real_palaka2 = calloc(xim->height + 4,xim->width*4);
251
 
       palaka2 = real_palaka2 + xim->width * 4 * 2;
252
 
  } else {
253
 
       palaka2 = palaka1;
254
 
  }
 
269
                     width, height, 8, 0);
 
270
  palaka1 = (unsigned char *) calloc(xim->height+1,xim->width*4) + 8;
 
271
  if(flash_on|glow_on)
 
272
  palaka2 = (unsigned char *) calloc(xim->height+1,xim->width*4) + 8;
 
273
  else
 
274
  palaka2 = palaka1;
255
275
  if (depth>=24)
256
276
  xim->data = (char *)palaka2;
257
277
  else
258
 
  xim->data = calloc(xim->height,xim->bytes_per_line);       
259
 
 }
260
 
}
 
278
  xim->data = calloc(xim->height,xim->bytes_per_line); }}
261
279
 
262
280
void put_image(Display *display, Window win, GC gc, XImage *xim)
263
281
{
319
337
     xim->data[i++] = (((7*g)/256)*36)+(((6*r)/256)*6)+((6*b)/256);
320
338
     }
321
339
  }
322
 
  XPutImage(display,win,gc,xim,0,0,0,0,xim->width,xim->height); 
323
 
}
 
340
  XPutImage(display,win,gc,xim,0,0,0,0,xim->width,xim->height); }
324
341
 
325
342
void sniff_events(Display *dis, Window win, fireshell *fss)
326
343
{
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);}
333
 
}
 
349
  screenhack_handle_event(dis,&e); }}
334
350
 
335
351
 
336
352
char *progclass = "Fireworkx";
338
354
char *defaults [] = {
339
355
  ".background: black",
340
356
  ".foreground: white",
341
 
  "*delay:      5000",
342
 
  "*maxlife:    1200",
343
 
  "*light:      True",
344
 
  "*fade:       False",
 
357
  "*delay:      10000",  /* never default to zero! */
 
358
  "*maxlife:    2000",
 
359
  "*flash:      True",
 
360
  "*glow:       True",
345
361
  "*shoot:      False",
346
362
  "*verbose:    False",
347
363
  0
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" },
357
373
  { 0, 0, 0, 0 }
367
383
  XWindowAttributes xwa;
368
384
  GC gc;
369
385
  XGCValues gcv;
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;
382
397
  if(verbose){
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");}
386
401
 
387
402
  XGetWindowAttributes(display,win,&xwa);
392
407
 
393
408
  if(depth==8){
394
409
  if(verbose){
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);
402
417
 
403
418
  resize(display,win);   /* initialize palakas */ 
404
 
  seed += time(0);
405
419
  
406
 
  fpixs = malloc(sizeof(firepix) * PIXCOUNT * SHELLCOUNT);
407
 
  fshells = malloc(sizeof(fireshell) * SHELLCOUNT);
408
 
  fshell = fshells;
409
 
  fpix = fpixs;
 
420
  ffpix = malloc(sizeof(firepix) * PIXCOUNT * SHELLCOUNT);
 
421
  ffshell = malloc(sizeof(fireshell) * SHELLCOUNT);
 
422
  fshell = ffshell;
 
423
  fpix = ffpix;
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));
413
427
  fshell++; 
414
428
  fpix += PIXCOUNT; }
415
429
  
416
430
  while(1) {
417
431
  for(q=FTWEAK;q;q--){
418
 
  fshell=fshells;
 
432
  fshell=ffshell;
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)); }
422
436
       fshell++; }}
423
 
  if(light_on) light_2x2(fshells);
 
437
#if HAVE_X86_MMX
 
438
  if(glow_on) mmx_glow(palaka1,width,height,8,palaka2);
 
439
#else
 
440
  if(glow_on) glow();
 
441
#endif
 
442
  if(flash_on) light_2x2(ffshell);
424
443
  put_image(display,win,gc,xim);
425
444
  usleep(delay);
426
445
  XSync(display,0);
427
 
  sniff_events(display, win, fshells);
428
 
  blur_best();}
 
446
  sniff_events(display, win, ffshell);
 
447
#if HAVE_X86_MMX
 
448
  if(!glow_on) mmx_blur(palaka1,width,height,8);
 
449
#else
 
450
  if(!glow_on) blur();
 
451
#endif
429
452
 
430
 
}
 
453
}}