#include #include #include #include #include "myiff.h" #include #define MAXSNOWMASS 200 void *OpenLibrary(),*OpenScreen(),*OpenWindow(),*GetMsg(),*AllocMem(); struct GfxBase *GfxBase; struct IntuitionBase *IntuitionBase; struct Screen *s,*bs; struct Window *w; struct NewScreen ns={0,0,320,256,5,1,2,0,CUSTOMSCREEN,0,0,0,0}; struct NewWindow nw={0,0,320,256,-1,-1,CLOSEWINDOW,WINDOWCLOSE|BORDERLESS| SMART_REFRESH|NOCAREREFRESH|ACTIVATE,0,0,0,0,0,0,0,0,0,CUSTOMSCREEN}; UWORD BlackColors[32]; OpenAll(filename,backup) char *filename; int backup; { long sec,mic; if ((GfxBase=OpenLibrary("graphics.library",0L))==0) abort("No gfxbase"); if ((IntuitionBase=OpenLibrary("intuition.library",0L))==0) abort("No intuition"); CurrentTime(&sec,&mic); srand((int)mic); if ((LoadPicture(filename))==0) abort("Can't load picture"); if (backup) BltBitMap(&s->BitMap,0L,0L,&bs->BitMap,0L,0L,(long)s->Width,(long)s->Height,0xC0L,0xFFL,0L); } abort(errortext) char *errortext; { if (errortext!=0) puts(errortext); if (w) CloseWindow(w); if (bs) CloseScreen(bs); if (s) CloseScreen(s); if (GfxBase) CloseLibrary(GfxBase); if (IntuitionBase) CloseLibrary(IntuitionBase); exit(0); } LoadPicture(filename) char *filename; { FILE *fd; struct BitMapHeader bmhd; long formsize; UWORD *colortable[32],modes; if (!(fd = fopen (filename, "r"))) return(0); if (GetBMHD(fd,&bmhd,&formsize)==-1) return(0); if (GetCMap(fd,&formsize,colortable,&modes)==-1) return(0); /* buildupdascreen */ if (modes==0xffff) { modes=0; if (bmhd.w>452) modes|=HIRES; if (bmhd.h>352) modes|=LACE; } ns.LeftEdge=bmhd.x; ns.TopEdge=bmhd.y; ns.Width=bmhd.w; ns.Height=bmhd.h; ns.Depth=bmhd.nplanes; ns.ViewModes=modes; ns.Type=CUSTOMSCREEN; if ((bs=OpenScreen(&ns))==0) abort("Can't open backupscreen"); if ((s=(struct Screen *)OpenScreen(&ns))==0) abort("No memory for screen"); LoadRGB4(&s->ViewPort,BlackColors,(long)1<ViewPort,&bmhd)==-1) return(0); LoadRGB4(&s->ViewPort,colortable,(long)1< 0) { if (!fread (&ch, sizeof (ch), 1, fd)) return(-1); *formsize -= sizeof (ch); switch (ch.TYPE) { case CMAP: { ctable=(UBYTE *)AllocMem((long)ch.chunksize,0L); fread (ctable, (int) ch.chunksize, 1, fd); for (i = n = 0; n < ch.chunksize; i++, n+=3) colortable[i] = ((ctable[n]>>4 ) << 8) + ((ctable[n+1]>>4 ) << 4) + ( ctable[n+2]>>4 ); FreeMem(ctable,(long)ch.chunksize); break; } case CAMG: fread (&temp, (int) ch.chunksize, 1, fd); *modes = (UWORD) (temp & 0xffffffff); break; case BODY: return(0); break; case CRNG: case GRAB: case SPRT: case DPPV: /* Anyone know what this one is for? */ case DPPS: /* Anyone know what this one is for? */ fseek (fd, ch.chunksize, 1); break; default: printf("unrecognized chunk 0x%lx\n",ch.TYPE); fseek (fd, ch.chunksize, 1); } *formsize -= ch.chunksize; if (ch.chunksize & 1) /* Odd length chunk */ { *formsize --; fseek (fd, 1L, 1); } } return(-1); } GetBMHD(fd,bmhd,formsize) FILE *fd; struct BitMapHeader *bmhd; long *formsize; { long subtype; struct ChunkHeader ch; if (!fread (&ch, sizeof (ch), 1, fd)) { return(-1); } if (ch.TYPE != FORM) { return(-1); } *formsize=ch.chunksize; if (!fread (&subtype, sizeof (subtype), 1, fd)) return (-1); *formsize -= sizeof (subtype); if (subtype != ILBM) return(-1); if (!fread (&ch, sizeof (ch), 1, fd)) return(-1); *formsize -= sizeof (ch); fread (bmhd, (int) ch.chunksize, 1, fd); *formsize -= ch.chunksize; return(0); } /* This routine is a fairly direct copy from Leo Schwab's Yaiffr - tanx */ LoadBitMap (fd, vp, header) FILE *fd; struct ViewPort *vp; struct BitMapHeader *header; { register struct BitMap *bm; register int i, n; long plane_offset = 0; bm = vp -> RasInfo -> BitMap; if (header->Compression != cmpNone && header->Compression != cmpByteRun1) return(-1); for (i=0; i < bm->Rows; i++) { for (n=0; n < bm->Depth; n++) { /*- - - - - - - - - - -*/ if (!header->Compression) { /* No compression */ if (!fread (bm -> Planes[n] + plane_offset, bm -> BytesPerRow, 1, fd)) return(-1); } else { int so_far; register UBYTE *dest = bm -> Planes[n] + plane_offset; char len; /* * Note: All file I/O after this point is assumed to be sucessful. * This is clearly a poor assumption, but it saves on typing. * And besides, putting the checking in is simple :-) :-). */ so_far = bm -> BytesPerRow; while (so_far > 0) { if ((len = getc (fd)) >= 0) { /* Literal byte copy */ so_far -= ++len; if (!fread (dest, len, 1, fd)) return(-1); dest += len; } else if ( len == -128) /* NOP */ ; else if (len < 0) { /* Replication count */ UBYTE byte; len = -len + 1; so_far -= len; byte = getc (fd); while (--len >= 0) *dest++ = byte; } } if (so_far) return(-1); } /*- - - - - - - - - - -*/ } plane_offset += bm -> BytesPerRow; } return(0); } DoSnow(mass,refresh,wind) long mass,refresh,wind; { struct IntuiMessage *msg; register long cx,cy,i,end,oldx,*x,*y,timer; timer=refresh; x=AllocMem(800L,0L); y=AllocMem(800L,0L); if (mass>MAXSNOWMASS) mass=MAXSNOWMASS; for (i=0;iHeight); while ((msg=GetMsg(w->UserPort))==0) { if (refresh!=-1) { if (--refresh==0) { for (i=0;iBitMap.Planes[0]+(s->Width/8)*y[i]+x[i]/8) |= (128>>(x[i]%8)); BltBitMap(&bs->BitMap,0L,0L,&s->BitMap,0L,0L,(long)s->Width,(long)s->Height,0xC0L,0xFFL,0x00L); for (i=0;iBitMap.Planes[0]+(s->Width/8)*y[i]+x[i]/8) &= ~(128>>(x[i]%8)); refresh=timer; } } for (i=0;iWidth;} else { oldx=cx; cx+=(rand()%31-wind-15)/8; if (cx>s->Width-1) cx-=s->Width; if (cx<0) cx+=s->Width; if (ReadPixel(w->RPort,cx,cy+1)==0) { *(s->BitMap.Planes[0]+(s->Width/8)*cy+oldx/8)&=~(128>>(oldx%8)); cy++; *(s->BitMap.Planes[0]+(s->Width/8)*cy+cx/8) |= (128>>(cx%8)); } else { end=1; if ((ReadPixel(w->RPort,cx+1,cy+1)==0)&& (ReadPixel(w->RPort,cx-1,cy+1)==0)) { if ((cx>0)&&(rand()%2==1)) cx--; else if (cxWidth-1) cx++; else cx--; end=0; } if ((ReadPixel(w->RPort,cx+1,cy+1)==0)&&(end==1)/* &&(rand()%6!=1) */) {cx++; end=0;} if ((ReadPixel(w->RPort,cx-1,cy+1)==0)&&(end==1)/* &&(rand()%6!=1) */) {cx--; end=0;} if (end==0) { *(s->BitMap.Planes[0]+(s->Width/8)*cy+oldx/8)&=~(128>>(oldx%8)); cy++; } *(s->BitMap.Planes[0]+(s->Width/8)*cy+cx/8) |= (128>>(cx%8)); if (end==1) cy=-1; } } x[i]=cx; y[i]=cy; } } } FreeMem(x,800L); FreeMem(y,800L); } DisplayUsage() { puts("Snowfall - made December 1989 by Lars R. Clausen"); puts("Usage: SnowFall [-ppicture] [-n#snowflakes] [-trefreshtime] [-wwindforce]"); exit(0); } main(argc,argv) int argc; char **argv; { char file[100]; int number=40,refresh=10000,i,wind=0; if ((argc==2)&&(strcmp(argv[1],"?")==0)) DisplayUsage(); strcpy(file,"SnowPic"); for (i=1;i-1) OpenAll(file,1); else OpenAll(file,0); DoSnow((long)number,(long)refresh,(long)wind); abort(0); }