home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
348.lha
/
SnowFall
/
SnowFall.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-02-14
|
8KB
|
366 lines
#include <intuition/intuition.h>
#include <graphics/gfxbase.h>
#include <exec/memory.h>
#include <stdio.h>
#include "myiff.h"
#include <ctype.h>
#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<<bmhd.nplanes);
nw.Screen=s;
nw.Width=bmhd.w;
nw.Height=bmhd.h;
if ((w=(struct Window *)OpenWindow(&nw))==0) abort("No window here");
if (LoadBitMap(fd,&s->ViewPort,&bmhd)==-1) return(0);
LoadRGB4(&s->ViewPort,colortable,(long)1<<bmhd.nplanes);
return(1);
}
GetCMap(fd,formsize,colortable,modes)
FILE *fd;
long *formsize;
UWORD *colortable;
UWORD *modes;
{
struct ChunkHeader ch;
register UBYTE *ctable;
register int i,n;
ULONG temp=0;
*modes=0xffff;
while (*formsize > 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;i<mass;i++) y[i]=-(rand()%w->Height);
while ((msg=GetMsg(w->UserPort))==0)
{
if (refresh!=-1)
{
if (--refresh==0)
{
for (i=0;i<mass;i++)
*(bs->BitMap.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;i<mass;i++)
*(bs->BitMap.Planes[0]+(s->Width/8)*y[i]+x[i]/8) &= ~(128>>(x[i]%8));
refresh=timer;
}
}
for (i=0;i<mass;i++)
{
if (y[i]<-1) y[i]++;
else
{
cx=x[i];
cy=y[i];
if (cy==-1) {cy=0;cx=rand()%w->Width;}
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 (cx<w->Width-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<argc;i++)
{
if (argv[i][0]=='-')
switch (argv[i][1])
{
case 'p': strcpy(file,&argv[i][2]); break;
case 'n': number=atoi(&argv[i][2]); break;
case 't': refresh=atoi(&argv[i][2]); break;
case 'w': wind=atoi(&argv[i][2]); break;
default: DisplayUsage();
}
else DisplayUsage();
}
if (refresh>-1) OpenAll(file,1);
else OpenAll(file,0);
DoSnow((long)number,(long)refresh,(long)wind);
abort(0);
}