Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

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