/* -------------------------------------------------------------------- * * A christmas blanker inspired by xsnow * * initialization/cleanup code copied from the dragon module * (dragon module: (C)Alexander Kneer and Michael D. Bayne) * * -------------------------------------------------------------------- */ #include #include #include #include "/includes.h" #define STAGES 2 /* Number of different shapes */ #define BLANKDELAY 100 /* This many snowflakes are displayed before * we check if to continue blanking */ #define COUNTLIMIT 6 /* max. number of moves in one direction */ #define COUNTMIN 1 /* min. number of moves in one direction */ /* random generation function macros */ #define COUNTFUNC RangeRand(COUNTLIMIT-COUNTMIN)+COUNTMIN #define DXFUNC RangeRand(5)-2; #define DYFUNC RangeRand(2)+1; typedef enum { false, true } bool; bool BIGFLAKES; int NUMSNOW; bool COLLECT; int patx[10] = { -1,-1, 1, 1, 0 , -1, 1, 0, 0, 0 }; int paty[10] = { -1, 1,-1, 1, 0 , 0, 0, 1,-1, 0 }; int *collect; typedef struct { int x,y; /* The current coordinates */ int dx,dy; /* Movement direction is (dx,dy) */ int count; /* How long to keep direction dx */ int stage; /* STAGES different shapes */ } snowflake; Triplet *ColorTable = 0L; #define PR_FLAKE 0 #define PR_BIG 2 #define PR_COLLECT 4 #define PR_MODE 6 VOID Defaults( PrefObject *Prefs ) { Prefs[PR_FLAKE].po_Level = 200; Prefs[PR_BIG].po_Level = 1; Prefs[PR_COLLECT].po_Level = 1; Prefs[PR_MODE].po_ModeID = getTopScreenMode(); } /* Remove a single snowflake's image from the screen */ __inline void undraw(snowflake *flake, struct RastPort *rp) { if (BIGFLAKES) { int *startx = patx + 5*(flake->stage); int *starty = paty + 5*(flake->stage); int i; SetAPen(rp,0); for (i=0; i<5; i++) { WritePixel(rp,flake->x+(*startx),flake->y+(*starty)); startx++; starty++; } } else { SetAPen(rp,0); WritePixel(rp,flake->x,flake->y); } } /* Draw a single snowflake's image to the screen */ __inline void draw(snowflake *flake, struct RastPort *rp) { if (BIGFLAKES) { int *startx = patx + 5*(flake->stage); int *starty = paty + 5*(flake->stage); int i; SetAPen(rp,1); for (i=0; i<5; i++) { WritePixel(rp,flake->x+(*startx),flake->y+(*starty)); startx++; starty++; } } else { SetAPen(rp,1); WritePixel(rp,flake->x,flake->y); } } /* change the position of a snowflake. If it leaves [0..width]x[0..height], * generate a new one with coordinates (,0) */ __inline void update(snowflake *curr, int width, int height, struct RastPort *rp) { bool gen_new; int oldx = curr->x; if (curr->count > 0) { curr->y = curr->y + curr->dy; if (curr->y >= height-1) { gen_new = true; } else { curr->x = curr->x + curr->dx; if (curr->x < 1 || curr->x >= width-1) { gen_new = true; } else { gen_new = false; (curr->count)--; if (curr->count <= 0) { curr->dx = DXFUNC; curr->count = COUNTFUNC; } if (curr->stage) { curr->stage--; } else { curr->stage = STAGES-1; } } } } /* do we have to compute a new flake? */ if (gen_new) { if (collect && curr->y > height-3) { collect[oldx]--; if (collect[oldx]x = oldx; curr->y = collect[oldx]; draw(curr,rp); } curr->x = RangeRand(width-2)+1; curr->y = 1; curr->dx = DXFUNC; curr->dy = DYFUNC; curr->count = COUNTFUNC; curr->stage = RangeRand(STAGES); } } LONG snow(struct Screen *scr, SHORT width, SHORT height) { unsigned int i; LONG flg_end; snowflake *flake,*curr; int blankcount; struct RastPort *rp = &(scr->RastPort); /* initialize the snow array */ flake = malloc(NUMSNOW*sizeof(snowflake)); curr = flake; for (i=0; ix = RangeRand(width-2)+1; curr->y = RangeRand(height-2)+1; curr->dx = DXFUNC; curr->dy = DYFUNC; curr->count = COUNTFUNC; curr->stage = RangeRand(STAGES); curr++; } /* and the collect array */ if (COLLECT) { collect = malloc(sizeof(int)*width); for (i=0; iViewPort ), 0, 0, 0, 0 ); ColorTable = RainbowPalette( Scr, 0L, 1L, 0L ); SetRGB4(&( Scr->ViewPort ), 1, 15, 15, 15 ); Wnd = BlankMousePointer( Scr ); do RetVal = snow( Scr, Scr->Width, Scr->Height ); while( RetVal == OK ); UnblankMousePointer( Wnd ); RainbowPalette( 0L, ColorTable, 1L, 0L ); CloseScreen( Scr ); } else RetVal = FAILED; return RetVal; }