/* Fireworks demo written by Dave Ashley */ /* dash@xdr.com */ /* http://www.xdr.com/dash */ /* Sat Jun 13 02:46:09 PDT 1998 */ /* This is my first attempt at an SDL program */ /* See the SDL home page http://www.devolution.com/~slouken/projects/SDL/ */ #include #include #include #include #include "SDL.h" #define XSIZE 240 #define YSIZE 160 SDL_Surface *thescreen; unsigned char *vmem1, *vmem2; int mousex,mousey; SDL_Color themap[256]; int scrlock() { if(SDL_MUSTLOCK(thescreen)) { if ( SDL_LockSurface(thescreen) < 0 ) { fprintf(stderr, "Couldn't lock display surface: %s\n", SDL_GetError()); return -1; } } return 0; } void scrunlock(void) { if(SDL_MUSTLOCK(thescreen)) SDL_UnlockSurface(thescreen); SDL_UpdateRect(thescreen, 0, 0, 0, 0); } #define MOUSEFRAC 2 #define MAXBLOBS 512 #define BLOBFRAC 6 #define BLOBGRAVITY 5 #define THRESHOLD 20 #define SMALLSIZE 3 #define BIGSIZE 6 #define ABS(x) ((x)<0 ? -(x) : (x)) int explodenum; char sizes[]={2,3,4,5,8,5,4,3}; struct blob { struct blob *blobnext; int blobx; int bloby; int blobdx; int blobdy; int bloblife; int blobsize; } *blobs,*freeblobs,*activeblobs; unsigned char **mul640; int oldmode; char sqrttab[]={ 0,1,1,1,2,2,2,2,2,3,3,3,3,3,3,3, 4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5, 5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6, 6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, 9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, 12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13, 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, 13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14, 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, 14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15 }; void nomem(void) { printf("Not enough low memory!\n"); SDL_Quit(); exit(1); } extern Uint32 __FarFunction (Uint32 (*ptr)(), ...); extern void __FarProcedure (void (*ptr)(), ...); void fire(Uint32* FuncAddr,unsigned char *p1,unsigned char *p2,int pitch,char *map) __attribute__ ((section(".iwram"))); void fire(Uint32* FuncAddr,unsigned char *p1,unsigned char *p2,int pitch,char *map) { int x,y; unsigned char *p3, *p4; for(y=2;y10 && mousex10 && mouseyblobnext; ablob->bloblife=(rand()&127)+128; ablob->blobdx=dx; ablob->blobdy=dy; ablob->blobx=(128+(rand()&127))<bloby=2<blobnext=activeblobs; ablob->blobsize=BIGSIZE; activeblobs=ablob; } void moveblobs(void) { struct blob **lastblob,*ablob; int x,y; lastblob=&activeblobs; while(ablob=*lastblob) { x=ablob->blobx>>BLOBFRAC; y=ablob->bloby>>BLOBFRAC; if(!--ablob->bloblife || y<0 || x<10 || x>XSIZE-10) { *lastblob=ablob->blobnext; ablob->blobnext=freeblobs; freeblobs=ablob; continue; } ablob->blobx+=ablob->blobdx; ablob->bloby+=ablob->blobdy; ablob->blobdy-=BLOBGRAVITY; lastblob=&ablob->blobnext; } } void putblobs(void) { struct blob *ablob,*ablob2,*temp; int x,y,dy; int i,size; long x2,y2,vel; ablob=activeblobs; activeblobs=0; while(ablob) { dy=ablob->blobdy; if(ablob->blobsize!=SMALLSIZE && (dy>-THRESHOLD && dyblobnext; ablob2->blobx=ablob->blobx; ablob2->bloby=ablob->bloby; for(;;) { x2=(rand()&511)-256; y2=(rand()&511)-256; vel=x2*x2+y2*y2; if(vel>0x3000 && vel<0x10000L) break; } ablob2->blobdx=ablob->blobdx+x2; ablob2->blobdy=ablob->blobdy+y2; ablob2->bloblife=16+(rand()&31); ablob2->blobsize=SMALLSIZE; ablob2->blobnext=activeblobs; activeblobs=ablob2; ablob->bloblife=1; } } x=ablob->blobx>>BLOBFRAC; y=ablob->bloby>>BLOBFRAC; size=ablob->blobsize; if(size==BIGSIZE && ablob->blobdy>0 && ablob->blobdy<200) size=sizes[ablob->bloblife&7]; if(x>10 && x10 && yblobnext; temp->blobnext=activeblobs; activeblobs=temp; } } #define RATE 1 void normal(char *map) { int i,j; for(i=0;i<8192;i++) { j=i/9; map[i]=j<256 ? (j>=RATE ? j-RATE : 0) : 255; } } void bright(char *map) { int i; for(i=0;i<8192;i++) map[i]=i>>3<255 ? (i>>3) : 255; } void updatemap(void) { SDL_SetColors(thescreen, themap, 0, 256); } void loadcolor(int n,int r,int g,int b) { themap[n].r=r<<2; themap[n].g=g<<2; themap[n].b=b<<2; } void loadcolors(unsigned int which) { int i,j; int r,g,b; which%=11; for(i=0;i<256;i++) { switch(which) { case 0: if(i<64) loadcolor(i,0,0,0); else if(i<128) loadcolor(i,i-64,0,0); else if(i<192) loadcolor(i,63,i-128,0); else loadcolor(i,63,63,i-192); break; case 1: if(i<64) loadcolor(i,0,0,0); else if(i<128) loadcolor(i,0,0,i-64); else loadcolor(i,(i-128)>>1,(i-128)>>1,63); break; case 2: loadcolor(i,i>>2,i>>2,i>>2); break; case 3: r=rand()&0x3f; g=rand()&0x3f; b=rand()&0x3f; loadcolor(i,r*i>>8,g*i>>8,b*i>>8); break; case 4: loadcolor(i,i>>2,0,0); break; case 5: loadcolor(i,0,i>>2,0); break; case 6: loadcolor(i,0,0,i>>2); break; case 7: j=i&15; if(i&16) j=15-j; j=(i>>2)*j/16; loadcolor(i,j,j,j); break; case 8: j=0; if(i>8 && i<128) j=63; loadcolor(i,j,j,j); break; case 9: j=31-(i&31)<<1; r=i&32 ? j : 0; g=i&64 ? j : 0; b=i&128 ? j : 0; loadcolor(i,r,g,b); break; case 10: j=(i&15)<<2; if(i&16) j=63-j; r=i&32 ? j : 0; g=i&64 ? j : 0; b=i&128 ? j : 0; loadcolor(i,r,g,b); break; } } updatemap(); } main(int argc, char *argv[]) { int i,k; char *remap,*remap2; unsigned char *p1, *p2; long frames; int flash; int whichmap; int key; int ispaused; unsigned long videoflags; int done; int now; SDL_Event event; long starttime; int buttonstate; __debug_shutup=1; srand(5 /*time(NULL)*/ ); if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError()); exit(1); } videoflags = SDL_SWSURFACE|SDL_FULLSCREEN|SDL_HWPALETTE; thescreen = SDL_SetVideoMode(XSIZE, YSIZE, 8, videoflags); if ( thescreen == NULL ) { fprintf(stderr, "Couldn't set display mode: %s\n", SDL_GetError()); SDL_Quit(); exit(5); } vmem1=NULL; vmem2=malloc(XSIZE*YSIZE); if(!vmem2) nomem(); mul640=malloc(YSIZE*sizeof(char *)); if(!mul640) nomem(); remap=malloc(16384); if(!remap) nomem(); remap2=malloc(16384); if(!remap2) nomem(); blobs=malloc(MAXBLOBS*sizeof(struct blob)); if(!blobs) nomem(); puts("Fire demo by David Ashley (dash@xdr.com)"); puts("1 = Change color map"); puts("2 = Randomly change color map"); puts("p = Pause"); puts("spc = Fire"); puts("esc = Exit"); puts("Left mouse button = paint"); puts("Right mouse button, CR = ignite atmosphere"); freeblobs=activeblobs=0; for(i=0;ipixels ) { p1=vmem1=thescreen->pixels; for (i=0;ipitch+vmem1; memset(p1,0,XSIZE); p1+=thescreen->pitch; } } if(!ispaused) { now++; if(!flash) { if(explodenum>96 && explodenum<160 && !(rand()&511) || (buttonstate&8)) flash=60; } else --flash; explodenum=(now>>4)+1;if(explodenum==320) now=0; if(explodenum>256) explodenum=256; if(!(rand()&31)) addblob(); moveblobs(); putblobs(); if(buttonstate&2) trydisk(); p1=vmem1; p2=vmem2; k=thescreen->pitch; memcpy(vmem2,vmem1,XSIZE*YSIZE); __FarProcedure(fire,vmem2,vmem1,(int)k,flash ? remap2 :remap); } scrunlock(); while(SDL_PollEvent(&event)) { switch (event.type) { case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: if ( event.button.state == SDL_PRESSED ) buttonstate|=1<