The Pedigree Project  0.1
fire.c
1 /*
2  *
3  * Copyright (c) 2008-2014, Pedigree Developers
4  *
5  * Please see the CONTRIB file in the root of the source tree for a full
6  * list of contributors.
7  *
8  * Permission to use, copy, modify, and distribute this software for any
9  * purpose with or without fee is hereby granted, provided that the above
10  * copyright notice and this permission notice appear in all copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19  */
20 
21 /* Fireworks demo written by Dave Ashley */
22 /* dash@xdr.com */
23 /* http://www.xdr.com/dash */
24 /* Sat Jun 13 02:46:09 PDT 1998 */
25 /* This is my first attempt at an SDL program */
26 /* See the SDL home page http://www.devolution.com/~slouken/projects/SDL/ */
27 
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <time.h>
32 
33 #include "SDL.h"
34 
35 #define XSIZE 640
36 #define YSIZE 480
37 
38 SDL_Surface *thescreen;
39 unsigned char *vmem1, *vmem2;
40 int mousex,mousey;
41 SDL_Color themap[256];
42 
43 int scrlock()
44 {
45  if(SDL_MUSTLOCK(thescreen))
46  {
47  if ( SDL_LockSurface(thescreen) < 0 )
48  {
49  fprintf(stderr, "Couldn't lock display surface: %s\n",
50  SDL_GetError());
51  return -1;
52  }
53  }
54  return 0;
55 }
56 void scrunlock(void)
57 {
58  if(SDL_MUSTLOCK(thescreen))
59  SDL_UnlockSurface(thescreen);
60  SDL_UpdateRect(thescreen, 0, 0, 0, 0);
61 }
62 
63 #define MOUSEFRAC 2
64 #define MAXBLOBS 512
65 #define BLOBFRAC 6
66 #define BLOBGRAVITY 5
67 #define THRESHOLD 20
68 #define SMALLSIZE 3
69 #define BIGSIZE 6
70 
71 #define ABS(x) ((x)<0 ? -(x) : (x))
72 
73 int explodenum;
74 
75 char sizes[]={2,3,4,5,8,5,4,3};
76 
77 
78 struct blob {
79  struct blob *blobnext;
80  int blobx;
81  int bloby;
82  int blobdx;
83  int blobdy;
84  int bloblife;
85  int blobsize;
86 } *blobs,*freeblobs,*activeblobs;
87 
88 
89 unsigned char **mul640;
90 int oldmode;
91 
92 char sqrttab[]={
93 0,1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,
94 4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,
95 5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,
96 6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
97 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
98 8,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
99 9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,
100 10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,
101 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
102 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
103 12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,
104 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
105 13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14,
106 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
107 14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
108 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15
109 };
110 
111 
112 void nomem(void)
113 {
114  printf("Not enough low memory!\n");
115  SDL_Quit();
116  exit(1);
117 }
118 
119 
120 
121 void fire(unsigned char *p1,unsigned char *p2,int pitch,char *map)
122 {
123 int x,y;
124 unsigned char *p3, *p4;
125 
126  for(y=2;y<YSIZE;y++)
127  {
128  for(x=0;x<XSIZE;x++)
129  {
130  p3 = p1+y*XSIZE+x;
131  p4 = p2+y*pitch+x;
132  *p4=map[*p3+p3[-XSIZE]+p3[-XSIZE-1]+p3[-XSIZE+1]+p3[-1]+p3[1]+p3[-XSIZE-XSIZE-1]+p3[-XSIZE-XSIZE]+p3[-XSIZE-XSIZE+1]];
133  }
134  }
135 }
136 
137 void disk(x,y,rad)
138 {
139 unsigned char *p;
140 int i,j,k,aj;
141 int rad2=rad*rad;
142 int w;
143 
144 
145  for(j=-rad;j<=rad;j++)
146  {
147  w=sqrttab[rad2-j*j];
148  aj=ABS(j)<<2;
149  if(w)
150  {
151  p=mul640[y+j]+x-w;
152  k=w+w+1;
153  i=-w;
154  while(k--) {*p++=255-(ABS(i)<<2)-aj;i++;}
155  }
156  }
157 }
158 void trydisk(void)
159 {
160  if(mousex>10 && mousex<XSIZE-10 && mousey>10 && mousey<YSIZE-10)
161  disk(mousex,mousey,8);
162 }
163 
164 void addblob(void)
165 {
166 int dx,dy;
167 struct blob *ablob;
168 
169  if(!freeblobs) return;
170  dx=(rand()&255)-128;
171  dy=(rand()%200)+340;
172  ablob=freeblobs;
173  freeblobs=freeblobs->blobnext;
174  ablob->bloblife=(rand()&511)+256;
175  ablob->blobdx=dx;
176  ablob->blobdy=dy;
177  ablob->blobx=(256+(rand()&127))<<BLOBFRAC;
178  ablob->bloby=2<<BLOBFRAC;
179  ablob->blobnext=activeblobs;
180  ablob->blobsize=BIGSIZE;
181  activeblobs=ablob;
182 }
183 void moveblobs(void)
184 {
185 struct blob **lastblob,*ablob;
186 int x,y;
187 
188  lastblob=&activeblobs;
189  while(ablob=*lastblob)
190  {
191  x=ablob->blobx>>BLOBFRAC;
192  y=ablob->bloby>>BLOBFRAC;
193  if(!--ablob->bloblife || y<0 || x<10 || x>XSIZE-10)
194  {
195  *lastblob=ablob->blobnext;
196  ablob->blobnext=freeblobs;
197  freeblobs=ablob;
198  continue;
199  }
200  ablob->blobx+=ablob->blobdx;
201  ablob->bloby+=ablob->blobdy;
202  ablob->blobdy-=BLOBGRAVITY;
203  lastblob=&ablob->blobnext;
204  }
205 }
206 void putblobs(void)
207 {
208 struct blob *ablob,*ablob2,*temp;
209 int x,y,dy;
210 int i,size;
211 long x2,y2,vel;
212 
213  ablob=activeblobs;
214  activeblobs=0;
215  while(ablob)
216  {
217  dy=ablob->blobdy;
218  if(ablob->blobsize!=SMALLSIZE && (dy>-THRESHOLD && dy<THRESHOLD && !(rand()&7) || (rand()&127)==63))
219  {
220  i=explodenum;
221  while(i-- && freeblobs)
222  {
223  ablob2=freeblobs;
224  freeblobs=freeblobs->blobnext;
225  ablob2->blobx=ablob->blobx;
226  ablob2->bloby=ablob->bloby;
227  for(;;)
228  {
229  x2=(rand()&511)-256;
230  y2=(rand()&511)-256;
231  vel=x2*x2+y2*y2;
232  if(vel>0x3000 && vel<0x10000L) break;
233  }
234  ablob2->blobdx=ablob->blobdx+x2;
235  ablob2->blobdy=ablob->blobdy+y2;
236  ablob2->bloblife=16+(rand()&31);
237  ablob2->blobsize=SMALLSIZE;
238  ablob2->blobnext=activeblobs;
239  activeblobs=ablob2;
240  ablob->bloblife=1;
241  }
242  }
243  x=ablob->blobx>>BLOBFRAC;
244  y=ablob->bloby>>BLOBFRAC;
245  size=ablob->blobsize;
246  if(size==BIGSIZE && ablob->blobdy>0 && ablob->blobdy<200)
247  size=sizes[ablob->bloblife&7];
248  if(x>10 && x<XSIZE-10 && y>10 && y<YSIZE-10)
249  disk(x,YSIZE-1-y,size);
250  temp=ablob;
251  ablob=ablob->blobnext;
252  temp->blobnext=activeblobs;
253  activeblobs=temp;
254  }
255 }
256 
257 
258 
259 #define RATE 1
260 void normal(char *map)
261 {
262 int i,j;
263  for(i=0;i<8192;i++)
264  {
265  j=i/9;
266  map[i]=j<256 ? (j>=RATE ? j-RATE : 0) : 255;
267  }
268 }
269 void bright(char *map)
270 {
271 int i;
272  for(i=0;i<8192;i++) map[i]=i>>3<255 ? (i>>3) : 255;
273 }
274 
275 void updatemap(void)
276 {
277  SDL_SetColors(thescreen, themap, 0, 256);
278 }
279 
280 
281 void loadcolor(int n,int r,int g,int b)
282 {
283  themap[n].r=r<<2;
284  themap[n].g=g<<2;
285  themap[n].b=b<<2;
286 }
287 
288 
289 void loadcolors(unsigned int which)
290 {
291 int i,j;
292 int r,g,b;
293 
294  which%=11;
295  for(i=0;i<256;i++)
296  {
297  switch(which)
298  {
299  case 0:
300  if(i<64) loadcolor(i,0,0,0);
301  else if(i<128) loadcolor(i,i-64,0,0);
302  else if(i<192) loadcolor(i,63,i-128,0);
303  else loadcolor(i,63,63,i-192);
304  break;
305  case 1:
306  if(i<64) loadcolor(i,0,0,0);
307  else if(i<128) loadcolor(i,0,0,i-64);
308  else loadcolor(i,(i-128)>>1,(i-128)>>1,63);
309  break;
310  case 2:
311  loadcolor(i,i>>2,i>>2,i>>2);
312  break;
313  case 3:
314  r=rand()&0x3f;
315  g=rand()&0x3f;
316  b=rand()&0x3f;
317  loadcolor(i,r*i>>8,g*i>>8,b*i>>8);
318  break;
319  case 4:
320  loadcolor(i,i>>2,0,0);
321  break;
322  case 5:
323  loadcolor(i,0,i>>2,0);
324  break;
325  case 6:
326  loadcolor(i,0,0,i>>2);
327  break;
328  case 7:
329  j=i&15;
330  if(i&16) j=15-j;
331  j=(i>>2)*j/16;
332  loadcolor(i,j,j,j);
333  break;
334  case 8:
335  j=0;
336  if(i>8 && i<128) j=63;
337  loadcolor(i,j,j,j);
338  break;
339  case 9:
340  j=31-(i&31)<<1;
341  r=i&32 ? j : 0;
342  g=i&64 ? j : 0;
343  b=i&128 ? j : 0;
344  loadcolor(i,r,g,b);
345  break;
346  case 10:
347  j=(i&15)<<2;
348  if(i&16) j=63-j;
349  r=i&32 ? j : 0;
350  g=i&64 ? j : 0;
351  b=i&128 ? j : 0;
352  loadcolor(i,r,g,b);
353  break;
354  }
355  }
356  updatemap();
357 }
358 
359 main(int argc, char *argv[])
360 {
361 int i,k;
362 char *remap,*remap2;
363 unsigned char *p1, *p2;
364 long frames;
365 int flash;
366 int whichmap;
367 int key;
368 int ispaused;
369 unsigned long videoflags;
370 int done;
371 int now;
372 SDL_Event event;
373 long starttime;
374 int buttonstate;
375 
376  srand(time(NULL));
377  if ( SDL_Init(SDL_INIT_VIDEO) < 0 )
378  {
379  fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
380  exit(1);
381  }
382  videoflags = SDL_SWSURFACE|SDL_FULLSCREEN|SDL_HWPALETTE;
383 
384  thescreen = SDL_SetVideoMode(XSIZE, YSIZE, 8, videoflags);
385  if ( thescreen == NULL )
386  {
387  fprintf(stderr, "Couldn't set display mode: %s\n",
388  SDL_GetError());
389  SDL_Quit();
390  exit(5);
391  }
392 
393  vmem1=NULL;
394  vmem2=malloc(XSIZE*YSIZE);
395  if(!vmem2) nomem();
396  mul640=malloc(YSIZE*sizeof(char *));
397  if(!mul640) nomem();
398  remap=malloc(16384);
399  if(!remap) nomem();
400  remap2=malloc(16384);
401  if(!remap2) nomem();
402  blobs=malloc(MAXBLOBS*sizeof(struct blob));
403  if(!blobs) nomem();
404 
405  puts("Fire demo by David Ashley (dash@xdr.com)");
406  puts("1 = Change color map");
407  puts("2 = Randomly change color map");
408  puts("p = Pause");
409  puts("spc = Fire");
410  puts("esc = Exit");
411  puts("Left mouse button = paint");
412  puts("Right mouse button, CR = ignite atmosphere");
413 
414  freeblobs=activeblobs=0;
415  for(i=0;i<MAXBLOBS;i++)
416  {
417  blobs[i].blobnext=freeblobs;
418  freeblobs=blobs+i;
419  }
420 
421  normal(remap);
422  bright(remap2);
423 
424  flash=0;
425  whichmap=0;
426  loadcolors(whichmap);
427  frames=0;
428  ispaused=0;
429  addblob();
430  done = 0;
431  now=0;
432  starttime=SDL_GetTicks();
433  buttonstate=0;
434  mousex=mousey=0;
435 
436  while(!done)
437  {
438  if ( scrlock() < 0 ) continue;
439  frames++;
440  if ( vmem1 != (unsigned char *)thescreen->pixels )
441  {
442  p1=vmem1=thescreen->pixels;
443  for (i=0;i<YSIZE;i++)
444  {
445  mul640[i]=i*thescreen->pitch+vmem1;
446  memset(p1,0,XSIZE);
447  p1+=thescreen->pitch;
448  }
449  }
450  if(!ispaused)
451  {
452  now++;
453  if(!flash)
454  {
455  if(explodenum>96 && explodenum<160 && !(rand()&511) || (buttonstate&8))
456  flash=60;
457  } else --flash;
458  explodenum=(now>>4)+1;if(explodenum==320) now=0;
459  if(explodenum>256) explodenum=256;
460  if(!(rand()&31))
461  addblob();
462  moveblobs();
463  putblobs();
464  if(buttonstate&2) trydisk();
465  p1=vmem1;
466  p2=vmem2;
467  k=thescreen->pitch;
468  for(i=0;i<YSIZE;i++)
469  {
470  memcpy(p2,p1,XSIZE);
471  p2+=XSIZE;
472  p1+=k;
473  }
474  fire(vmem2,vmem1,k,flash ? remap2 :remap);
475  }
476  scrunlock();
477 
478  while(SDL_PollEvent(&event))
479  {
480  switch (event.type)
481  {
482  case SDL_MOUSEBUTTONDOWN:
483  case SDL_MOUSEBUTTONUP:
484  if ( event.button.state == SDL_PRESSED )
485  buttonstate|=1<<event.button.button;
486  else
487  buttonstate&=~(1<<event.button.button);
488  mousex=event.button.x;
489  mousey=event.button.y;
490  if(!ispaused && buttonstate&2) trydisk();
491  break;
492  case SDL_MOUSEMOTION:
493  mousex=event.motion.x;
494  mousey=event.motion.y;
495  if(!ispaused && buttonstate&2) trydisk();
496  break;
497  case SDL_KEYDOWN:
498  key=event.key.keysym.sym;
499  if(key==SDLK_RETURN) {flash=60;break;}
500  if(key==SDLK_1 || key==SDLK_2)
501  {
502  if(key==SDLK_1)
503  ++whichmap;
504  else
505  whichmap=rand();
506  loadcolors(whichmap);
507  break;
508  }
509  if(key==SDLK_ESCAPE) {done=1;break;}
510  if(key==SDLK_SPACE && !ispaused) {addblob();break;}
511  if(key==SDLK_p) {ispaused=!ispaused;break;}
512  break;
513  case SDL_QUIT:
514  done = 1;
515  break;
516  default:
517  break;
518  }
519  }
520  }
521 
522  starttime=SDL_GetTicks()-starttime;
523  if(!starttime) starttime=1;
524  SDL_Quit();
525  printf("fps = %d\n",1000*frames/starttime);
526  exit(0);
527 }
Definition: fire.c:78