home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format 61 / af061sub.adf / snow.lha / Snow / snow.c < prev    next >
C/C++ Source or Header  |  1993-12-15  |  13KB  |  672 lines

  1. #include <exec/memory.h>
  2. #include <exec/execbase.h>
  3. #include <graphics/displayinfo.h>
  4. #include <graphics/gfxbase.h>
  5. #include <graphics/gfxmacros.h>
  6. #include <intuition/intuitionbase.h>
  7. #include <intuition/gadgetclass.h>
  8. #include <libraries/gadtools.h>
  9. #include <workbench/startup.h>
  10. #include <workbench/workbench.h>
  11. #include <dos/stdio.h>
  12. #include <dos/dosextens.h>
  13. #include <dos/dostags.h>
  14. #include <dos/rdargs.h>
  15.  
  16. #include <clib/asl_protos.h>
  17. #include <clib/diskfont_protos.h>
  18. #include <clib/commodities_protos.h>
  19. #include <clib/dos_protos.h>
  20. #include <clib/exec_protos.h>
  21. #include <clib/gadtools_protos.h>
  22. #include <clib/graphics_protos.h>
  23. #include <clib/intuition_protos.h>
  24. #include <clib/macros.h>
  25. #include <clib/alib_protos.h>
  26.  
  27. #include <string.h>
  28. #include <stdlib.h>
  29. #include <stdio.h>
  30. #include <math.h>
  31.  
  32. #ifdef __SASC /* some stuff for SAS-C */
  33.  
  34. #include <pragmas/commodities_pragmas.h>
  35. #include <pragmas/dos_pragmas.h>
  36. #include <pragmas/exec_pragmas.h>
  37. #include <pragmas/gadtools_pragmas.h>
  38. #include <pragmas/graphics_pragmas.h>
  39. #include <pragmas/intuition_pragmas.h>
  40.  
  41. #define VOID_INTERRUPT void __interrupt __saveds
  42. #define REGARGS(rv) rv __regargs
  43. #define CHIP(dt)    dt __chip
  44.  
  45. //void NewList(struct List *);
  46.  
  47. UBYTE *VersionString = "$VER: Snow 0.1(compiled with SAS/C)";
  48.  
  49. void chkabort(void)
  50. {}
  51.  
  52. #else /* DICE */
  53.  
  54. CxObj *HotKey(UBYTE *,struct MsgPort *,long);
  55.  
  56. UBYTE *VersionString = "$VER: Snow 0.1(compiled with DICE)";
  57.  
  58. void main(LONG,UBYTE **);
  59.  
  60. void wbmain(struct WBStartup *WBS)
  61.  
  62. {
  63.  if (WBS->sm_NumArgs) (void)CurrentDir(WBS->sm_ArgList->wa_Lock);
  64.  
  65.  main(0L,(UBYTE **)WBS);
  66. }
  67. #endif
  68.  
  69. #define MASK(n) (1L<<(n))
  70. #define WHITEPEN 1
  71. #define BLACKPEN 0
  72.  
  73. extern struct IntuitionBase *IntuitionBase;
  74. extern struct GfxBase *GfxBase;
  75. extern struct Library *GadToolsBase;
  76. extern struct Library *DOSBase;
  77.  
  78. WORD LeftEdge=12,TopEdge=12;
  79. struct Window *TinyWindow;
  80. struct TextAttr TinyAttr={"topaz.font",TOPAZ_EIGHTY,FS_NORMAL,FPF_ROMFONT};
  81. struct Screen *PubScreen;
  82. struct RastPort *RP;
  83. LONG Depth;
  84. UWORD backdrop=FALSE;
  85.  
  86. /*
  87.  
  88.     The following functions are taken from Matthias Schelers' resource tracker
  89.     library for SAS/C. Thanks to Matthias.
  90.  
  91. */
  92.  
  93. struct ToolNode
  94.  {
  95.   struct ToolNode *Next;
  96.   void *Tool;
  97.   void (*RemProc)(void *,LONG); /* requires stack arguments !!! */
  98.   LONG Size;
  99.  } *ToolList;
  100.  
  101. REGARGS(void) RemTool(void *Tool)
  102.  
  103. {
  104.  struct ToolNode **Ptr,*ToolNode;
  105.  
  106.  Ptr=&ToolList;
  107.  while (ToolNode=*Ptr)
  108.   if (ToolNode->Tool==Tool)
  109.    {
  110.     *Ptr=ToolNode->Next;
  111.  
  112.     ToolNode->RemProc(ToolNode->Tool,ToolNode->Size);
  113.     FreeVec ((APTR)ToolNode);
  114.  
  115.     return; /* This one was missing in ASwarm II V1.0-V1.1 and in
  116.                ASwarm III :-) */
  117.    }
  118.   else Ptr=&ToolNode->Next;
  119. }
  120.  
  121. void RemoveAll(void)
  122.  
  123. {
  124.  while (ToolList) RemTool (ToolList->Tool);
  125. }
  126.  
  127. REGARGS(void) AddTool(void *NewTool,void *ProcPtr,LONG NewSize)
  128.  
  129. {
  130.  struct ToolNode *Ptr;
  131.  void (*NewRemProc)(void *,LONG);
  132.  static BOOL First=TRUE;
  133.  
  134.  NewRemProc=(void (*)(void *,LONG))ProcPtr;
  135.  if (NewTool==NULL) exit (10);
  136.  
  137.  if (First)
  138.   {
  139.    First=FALSE;
  140.    if (atexit(RemoveAll))
  141.     {
  142.      NewRemProc (NewTool,NewSize);
  143.      exit (20);
  144.     }
  145.   }
  146.  
  147.  if ((Ptr=AllocVec(sizeof(struct ToolNode),0L))==NULL)
  148.   {
  149.    NewRemProc (NewTool,NewSize);
  150.    exit (20);
  151.   }
  152.  Ptr->Next=ToolList;
  153.  Ptr->Tool=NewTool;
  154.  Ptr->RemProc=NewRemProc;
  155.  Ptr->Size=NewSize;
  156.  ToolList=Ptr;
  157. }
  158.  
  159. void CloseTinyWindow(void)
  160.  
  161. {
  162.  if (TinyWindow)
  163.     {
  164.      CloseWindow (TinyWindow);
  165.      TinyWindow=NULL;
  166.     }
  167. }
  168.  
  169. void OpenTinyWindow(void)
  170.  
  171. {
  172.  
  173.  ULONG Flags;
  174.  ULONG w,h;
  175.  
  176.  Flags=WFLG_DRAGBAR| WFLG_DEPTHGADGET| WFLG_CLOSEGADGET|WFLG_RMBTRAP|
  177.        WFLG_SMART_REFRESH| WFLG_SIZEGADGET| WFLG_SIZEBBOTTOM;
  178.  
  179.  if (TinyWindow==NULL)
  180.   {
  181.    if ((PubScreen=LockPubScreen(NULL))==NULL) return;
  182.  
  183.    Depth=PubScreen->BitMap.Depth;
  184.    if(backdrop)
  185.     {
  186.      Flags=Flags|WFLG_BACKDROP|WFLG_BORDERLESS;
  187.      h=PubScreen->Height;
  188.      w=PubScreen->Width;
  189.     }
  190.    else
  191.     {
  192.      w=300;
  193.      h=200;
  194.     }
  195.  
  196.  
  197.    if ((TinyWindow=OpenWindowTags(NULL,
  198.                     WA_Left,LeftEdge,
  199.                     WA_Top,TopEdge,
  200.  
  201.                     WA_IDCMP,IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW|
  202.                     IDCMP_NEWSIZE|IDCMP_VANILLAKEY|LISTVIEWIDCMP,
  203.  
  204.                     WA_Flags,Flags,
  205.  
  206.                     WA_AutoAdjust,TRUE,
  207.                     WA_Title,(ULONG)"Snow - happy X-Mas!",
  208.                     WA_PubScreen,PubScreen,
  209.  
  210.                     WA_InnerWidth,w,
  211.                     WA_InnerHeight,h,
  212.                     WA_MinWidth,50,
  213.                     WA_MaxWidth,PubScreen->Width,
  214.                     WA_MinHeight,50,
  215.                     WA_MaxHeight,PubScreen->Height,
  216.                     WA_GimmeZeroZero, TRUE,
  217.                     TAG_DONE))==NULL)
  218.     {
  219.      CloseTinyWindow();
  220.      return;
  221.     }
  222.  
  223.    GT_RefreshWindow (TinyWindow,NULL);
  224.  
  225.   }
  226.  UnlockPubScreen(NULL,PubScreen);
  227.  ScreenToFront (TinyWindow->WScreen);
  228.  if(!backdrop)WindowToFront (TinyWindow);
  229.  ActivateWindow (TinyWindow);
  230.  RP=TinyWindow->RPort;
  231. }
  232.  
  233. LONG RDArgsLong(LONG Param,LONG Default,LONG Min,LONG Max)
  234.  
  235. {
  236.  LONG *Ptr;
  237.  
  238.  if ((Ptr=(LONG *)Param)==NULL) return Default;
  239.  
  240.  if ((*Ptr<Min)||(*Ptr>Max)) return Default;
  241.  else return *Ptr;
  242. }
  243.  
  244.  
  245. #define RAND(m) (Random(m)-(m)/2)
  246. #define MAXRAND 32768.0
  247.  
  248. /* Ill's strange and genius Random Function :-) */
  249.  
  250. int Random(int Max)
  251. {
  252.  static ULONG Num=0L; /* So the last random-number is still stored ! */
  253.  ULONG Sec,Mic;
  254.  
  255.  CurrentTime((LONG *)&Sec,(LONG *)&Mic);
  256.  
  257.  Num*=Sec+1/Sec;
  258.  Num+=Mic;
  259.  
  260.  while (Num>MAXRAND) Num=Num>>1;
  261.  
  262.  return (int)(Num % Max);
  263. }
  264.  
  265. /* Template for ReadArg */
  266. static char *Template = "SNOWFLAKES/N/K,BACKDROP/S";
  267.  
  268.  
  269. #include "snowmap.h"
  270.  
  271. typedef unsigned long Pixel;
  272.  
  273. #define SCAMPER_EVENT    (LASTEvent + 1)
  274.  
  275. unsigned int display_width, display_height;
  276. int center_x, center_y;
  277.  
  278. int done = 0;
  279. int eventBlock = 0;
  280. int errorVal = 0;
  281.  
  282. int flake;
  283.  
  284. Snow *snowflakes;
  285. int maxSnowflakes = 100;
  286. int curSnowflakes = 0;
  287.  
  288. #define SNOWCOLOR 1
  289. #define SANTACOLOR 2
  290. #define BAUMCOLOR 3
  291. #define HATCOLOR 4
  292.  
  293. Santa Claus;
  294.  
  295. void Usage(void);
  296. void InitSnowflake(int);
  297. void UpdateSnowflake(int);
  298. void DrawSnowflake(int);
  299. void EraseSnowflake(int);
  300. void DrawTannenbaum(int,int);
  301. void InitSanta(void);
  302. void DrawSanta(void);
  303. void EraseSanta(void);
  304. void UpdateSanta(void);
  305. void usleep(unsigned int);
  306. void main_initsanta(int, char**);
  307. void drawsnowstorm(void);
  308. int RandInt(int);
  309. int SnowInRect(Snow*, int, int, int, int, unsigned int, unsigned int);
  310.  
  311. void main_initsanta(ac, av)
  312. int ac;
  313. char *av[];
  314. {
  315.     int i;
  316.  
  317.     display_width = TinyWindow->Width;
  318.     display_height = TinyWindow->Height;
  319.     center_x = display_width / 2;
  320.     center_y = display_height / 2;
  321.  
  322.  
  323.     /*
  324.         P I X M A P S
  325.     */
  326.  
  327.     /* Create the snowflake pixmaps */
  328.     /* Allocate structures containing the coordinates and things */
  329.     AddTool(snowflakes=(Snow *)AllocVec((sizeof(Snow)) * MAXSNOWFLAKES,MEMF_CLEAR),FreeVec,0L);
  330.  
  331.     SetAPen(RP,1);
  332.  
  333.     SetRast(RP,3);
  334.     SetBPen(RP,3);
  335.     SetDrMd(RP,JAM2);
  336.  
  337.     /* Initialize all snowflakes */
  338.     for (i=0; i<maxSnowflakes; i++) InitSnowflake(i);
  339.  
  340.     InitSanta();
  341.  
  342.     for (i=0; i<maxSnowflakes; i++) DrawSnowflake(i);
  343.  
  344. }
  345.  
  346. #define USEPRT(msg) fprintf(stderr, msg)
  347.  
  348. void drawsnowstorm()
  349. {
  350.  
  351.       int i;
  352.  
  353.       for (i=0; i<maxSnowflakes; i++) UpdateSnowflake(i);
  354.  
  355.       /* Draw dear Andrew */
  356.       DrawTannenbaum(display_width-150, display_height-500);
  357.       DrawTannenbaum(display_width-100, display_height-200);
  358.       DrawTannenbaum(100, display_height-200);
  359.       DrawTannenbaum(50, display_height-150);
  360.       DrawTannenbaum(center_x, display_height-100);
  361.       DrawTannenbaum(200,400);
  362.  
  363.       /* Dear Santa */
  364.       UpdateSanta();
  365.  
  366. }
  367.  
  368. /*
  369.    Generate random integer between 0 and maxVal-1.
  370. */
  371. int
  372. RandInt(maxVal)
  373. int maxVal;
  374. {
  375.     return rand() % maxVal;
  376. }
  377.  
  378. /*
  379.    Check for snow completely in specified rectangle.
  380. */
  381. int
  382. SnowInRect(snow, rx, ry, x, y, width, height)
  383. Snow *snow;
  384. int rx;
  385. int ry;
  386. int x;
  387. int y;
  388. unsigned int width;
  389. unsigned int height;
  390. {
  391.     if (rx < x) return 0;
  392.     if ((rx + snowPix[snow->whatFlake].Width) > (x + width)) return 0;
  393.     if (ry < y) return 0;
  394.     if ((ry + snowPix[snow->whatFlake].Height) > (y + height)) return 0;
  395.  
  396.     return 1;
  397. }
  398.  
  399.  
  400. /*
  401.    Give birth to a snowflake.
  402. */
  403. void
  404. InitSnowflake(rx)
  405. int rx;
  406. {
  407.     Snow *r;
  408.  
  409.     r = &snowflakes[rx];
  410.  
  411.     if (curSnowflakes < maxSnowflakes) {
  412.         r->whatFlake = Random(SNOWFLAKEMAXTYPE+1);
  413.     r->intX = Random(display_width - snowPix[r->whatFlake].Width);
  414.     r->intY =  Random(display_height/10);
  415.         r->yStep = Random(MAXYSTEP+1)+1;
  416.         r->xStep = Random(r->yStep/4+1);
  417.         if (Random(1000) > 500) r->xStep = -r->xStep;
  418.         r->active = 1;
  419.     }
  420. }
  421.  
  422.  
  423. /*
  424.    Move a snowflake by erasing and redraw
  425. */
  426. void
  427. UpdateSnowflake(rx)
  428. int rx;
  429. {
  430.     Snow *snow;
  431.  
  432.     /* move an active snowflake */
  433.  
  434.     snow = &snowflakes[rx];
  435.  
  436.     if (!snow->active)  {
  437.       InitSnowflake(rx);  /* For next time  */
  438.       }
  439.     else {
  440.       /* This is an active snowflake */
  441.       EraseSnowflake(rx);
  442.  
  443.       snow->intX = snow->intX + snow->xStep;
  444.       snow->intY = snow->intY + snow->yStep;
  445.  
  446.       /* If flake disappears offscreen it becomes inactive */
  447.  
  448.       snow->active = SnowInRect(snow, snow->intX, snow->intY,
  449.                             0, 0, display_width, display_height);
  450.  
  451.       /* Adjust horizontal speed to mimic whirling */
  452.       snow->xStep = snow->xStep + Random(WHIRLFACTOR+1);
  453.       if (Random(1000) > 500) snow->xStep = -snow->xStep;
  454.       if (snow->xStep > MAXXSTEP) snow->xStep = MAXXSTEP;
  455.       if (snow->xStep < -MAXXSTEP) snow->xStep = -MAXXSTEP;
  456.  
  457.       /* Draw if still active */
  458.       if (snow->active) DrawSnowflake(rx);
  459.     }
  460.  
  461. }
  462.  
  463.  
  464. /*
  465.    Draw a snowflake.
  466. */
  467. void
  468. DrawSnowflake(rx)
  469. int rx;
  470. {
  471.     Snow *snow;
  472.  
  473.     snow = &snowflakes[rx];
  474.  
  475.     DrawImage(RP,&snowPix[snow->whatFlake],snow->intX, snow->intY);
  476. }
  477.  
  478.  
  479. /*
  480.    Erase a snowflake.
  481. */
  482. void
  483. EraseSnowflake(rx)
  484. int rx;
  485. {
  486.     Snow *snow;
  487.  
  488.     snow = &snowflakes[rx];
  489.  
  490.     SetAPen(RP,3);
  491.     SetBPen(RP,1);
  492.     if (snow->intX >= 0) RectFill(RP,snow->intX,
  493.                                      snow->intY,
  494.                                      snow->intX+snowPix[snow->whatFlake].Width,
  495.                                      snow->intY+snowPix[snow->whatFlake].Height);
  496. }
  497.  
  498. /*
  499.    Draw a tree
  500. */
  501. void
  502. DrawTannenbaum(x,y)
  503. int x,y;
  504. {
  505.  
  506.    DrawImage(RP,&tannenbaumPix[0],x,y);
  507.  
  508. }
  509.  
  510.  
  511. /*
  512.    Give birth to a Santa. (What a conception)
  513. */
  514. void
  515. InitSanta()
  516. {
  517.   Claus.x = 0;
  518.   Claus.y = Random(display_height / 3);
  519.   Claus.xStep = 1;
  520.   Claus.yStep = 1;
  521.   Claus.whatSanta = 0;
  522. }
  523.  
  524.  
  525. /*
  526.   Update Santa (How can you update the oldest icon in the world? Oh well.
  527. */
  528. void
  529. UpdateSanta()
  530. {
  531.   EraseSanta();
  532.  
  533.   /* Move forward */
  534.   Claus.x = Claus.x + Claus.xStep;
  535.  
  536.   /* Move down */
  537.   if (Random(10) > 3) Claus.y = Claus.y + Claus.yStep;
  538.   if (Claus.y < 0) Claus.y = 0;
  539.   if (Random(100) > 80) Claus.yStep = -Claus.yStep;
  540.  
  541.   if (Claus.x >= display_width) InitSanta();
  542.  
  543.   /* Next sleigh */
  544.   Claus.whatSanta++;
  545.   if (Claus.whatSanta > 2) Claus.whatSanta = 0;
  546.  
  547.   DrawSanta();
  548. }
  549.  
  550.  
  551.  
  552.  
  553. /*
  554.   Draw Santa
  555. */
  556. void
  557. DrawSanta()
  558. {
  559.   DrawImage(RP,&sleighPix[Claus.whatSanta],Claus.x,Claus.y);
  560.  
  561.   /* The Man in the Red Suit himself */
  562.   DrawImage(RP,&santaPix[0],Claus.x,Claus.y);
  563.  
  564.   SetAPen(RP,HATCOLOR);
  565.   WritePixel(RP,Claus.x+5,Claus.y+1);
  566. }
  567.  
  568. /*
  569.   Erase Santa
  570. */
  571. void
  572. EraseSanta()
  573. {
  574.   if (Claus.x >= 0) {
  575.       SetAPen(RP,3);
  576.       RectFill(RP,Claus.x,Claus.y,Claus.x+sleighPix[Claus.whatSanta].Width,
  577.                   Claus.y+sleighPix[Claus.whatSanta].Height);
  578.    }
  579. }
  580.  
  581. #define MASK(n) (1L<<(n))
  582.  
  583. void main(LONG argc,UBYTE **argv)
  584.  
  585. {
  586.  struct IntuiMessage *IntMsg;
  587.  struct RDArgs *RDArgs;
  588.  LONG Array[2];
  589.  
  590.  
  591.  /* open our Libraries */
  592.  
  593.  AddTool (IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",
  594.           37L),CloseLibrary,0L);
  595.  AddTool (GadToolsBase=OpenLibrary("gadtools.library",37L),CloseLibrary,0L);
  596.  AddTool (GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",37L),
  597.           CloseLibrary,0L);
  598.  
  599.  /*
  600.     Process command line options.
  601.  */
  602.  
  603.  (void)memset(Array,'\0',sizeof(Array));
  604.  if (RDArgs=ReadArgs(Template,Array,NULL))
  605.  {
  606.   if(Array[0]) maxSnowflakes=RDArgsLong(Array[1],100,1,200);
  607.   if(Array[1]) backdrop=Array[1];
  608.  }
  609.  else
  610.  {
  611.   PrintFault(IoErr(),"Snow");
  612.   exit (10);
  613.  }
  614.  if (RDArgs) FreeArgs(RDArgs);
  615.  
  616.  
  617.  AddTool ((void *)-1L,CloseTinyWindow,0L);
  618.  OpenTinyWindow();
  619.  
  620.  main_initsanta(argc, argv);
  621.  
  622.  /* start the Loop */
  623.  
  624.  FOREVER
  625.   {
  626.    /* process Window Events */
  627.  
  628.    while((TinyWindow!=NULL)&&(IntMsg=GT_GetIMsg(TinyWindow->UserPort)))
  629.     switch (IntMsg->Class)
  630.      {
  631.       UWORD Code;
  632.  
  633.       case IDCMP_CLOSEWINDOW:
  634.        GT_ReplyIMsg (IntMsg);
  635.        CloseTinyWindow();
  636.        exit(0);
  637.        break;
  638.       case IDCMP_REFRESHWINDOW:
  639.        GT_BeginRefresh (TinyWindow);
  640.        GT_EndRefresh (TinyWindow,TRUE);
  641.        break;
  642.       case IDCMP_VANILLAKEY:
  643.        Code=IntMsg->Code;
  644.        GT_ReplyIMsg (IntMsg);
  645.        switch ((char)Code)
  646.         {
  647.          case 27: /* ESC */
  648.           CloseTinyWindow();
  649.           exit(0);
  650.           break;
  651.         }
  652.        break;
  653.       case IDCMP_NEWSIZE:
  654.        GT_ReplyIMsg (IntMsg);
  655.        main_initsanta(argc, argv);
  656.        break;
  657.       default:
  658.        GT_ReplyIMsg (IntMsg);
  659.      }
  660.  
  661.    /* Busy Loop draw *grin :-)* */
  662.    drawsnowstorm();
  663.  
  664.    if (SetSignal(0L, SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) {
  665.      exit(0);
  666.    }
  667.  
  668.  
  669.   }
  670.  
  671. }
  672.