home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d7xx / d798 / aswarmii.lha / ASwarm / Source.lha / ASwarm.c next >
C/C++ Source or Header  |  1993-01-03  |  53KB  |  1,937 lines

  1. /*
  2.  
  3.    ASwarm II V1.3 - The Original One
  4.  
  5.    Written by Markus "Ill" Illenseer    markus@Techfak.Uni-Bielefeld.de
  6.    and Matthias "Tron" Scheler          tron@uni-paderborn.de
  7.  
  8.    Based upon Jeff Buterworths XSwarm.
  9.  
  10.    Please leave this source intact. ASwarm is freely distributable,
  11.    but no longer 'Public Domain'. If you have suggestions or Bug-Reports,
  12.    please contact us.
  13.  
  14.    Read the Manuals for known Bugs and Contact-Adresses.
  15.  
  16. */
  17.  
  18. #include <hardware/custom.h>
  19. #include <hardware/dmabits.h>
  20. #include <exec/memory.h>
  21. #include <exec/ports.h>
  22. #include <exec/execbase.h>
  23. #include <graphics/displayinfo.h>
  24. #include <graphics/gfxbase.h>
  25. #include <graphics/gfxmacros.h>
  26. #include <intuition/intuitionbase.h>
  27. #include <intuition/gadgetclass.h>
  28. #include <libraries/commodities.h>
  29. #include <libraries/gadtools.h>
  30. #include <workbench/startup.h>
  31. #include <workbench/icon.h>
  32. #include <workbench/workbench.h>
  33. #include <dos/dosextens.h>
  34. #include <dos/dostags.h>
  35. #include <dos/rdargs.h>
  36.  
  37. #include <clib/commodities_protos.h>
  38. #include <clib/dos_protos.h>
  39. #include <clib/exec_protos.h>
  40. #include <clib/gadtools_protos.h>
  41. #include <clib/graphics_protos.h>
  42. #include <clib/icon_protos.h>
  43. #include <clib/intuition_protos.h>
  44. #include <clib/macros.h>
  45.  
  46. #include <string.h>
  47. #include <stdlib.h>
  48.  
  49. #ifdef LATTICE /* some stuff for SAS-C */
  50.  
  51. #include <pragmas/commodities_pragmas.h>
  52. #include <pragmas/dos_pragmas.h>
  53. #include <pragmas/exec_pragmas.h>
  54. #include <pragmas/gadtools_pragmas.h>
  55. #include <pragmas/graphics_pragmas.h>
  56. #include <pragmas/icon_pragmas.h>
  57. #include <pragmas/intuition_pragmas.h>
  58.  
  59. #define VOID_INTERRUPT void __interrupt __saveds
  60. #define REGARGS        __regargs
  61. #define VOID_STDARGS   void __stdargs
  62.  
  63. CxObj *HotKey(UBYTE *,struct MsgPort *,long);
  64. void NewList(struct List *);
  65.  
  66. UBYTE *VersionString = "$VER: ASwarm II 1.3 (compiled with SAS/C)";
  67. /* Attention ! ASwarm<ALT SPACE>II ... */
  68.  
  69. void chkabort(void)
  70. {}
  71.  
  72. #else /* some stuff for Dice especially for -mR */
  73.  
  74. #define VOID_INTERRUPT __stkargs __geta4 void
  75. #define REGARGS
  76. #define VOID_STDARGS   __stkargs void
  77.  
  78. __stkargs CxObj *HotKey(UBYTE *,struct MsgPort *,long);
  79. __stkargs void NewList(struct List *);
  80.  
  81. UBYTE *VersionString = "$VER: ASwarm II 1.3 (compiled with DICE)";
  82. /* Attention ! ASwarm<ALT SPACE>II ... */
  83.  
  84. void main(LONG,UBYTE **);
  85.  
  86. void wbmain(struct WBStartup *WBS)
  87.  
  88. {
  89.  if (WBS->sm_NumArgs) (void)CurrentDir(WBS->sm_ArgList->wa_Lock);
  90.  
  91.  main(0L,(UBYTE **)WBS);
  92. }
  93.  
  94. #endif
  95.  
  96. /*
  97.  
  98.    Common Definitions
  99.  
  100. */
  101.  
  102. #define custom (*((struct Custom *)0xDFF000L))
  103.  
  104. extern struct ExecBase *SysBase;
  105. extern struct DosLibrary *DOSBase;
  106.  
  107. #define FINDPROCPORT (&((struct Process *)SysBase->ThisTask)->pr_MsgPort)
  108.  
  109. struct IntuitionBase *IntuitionBase;
  110. struct GfxBase *GfxBase;
  111.  
  112. struct Library *CxBase,*GadToolsBase,*IconBase;
  113.  
  114. LONG WBStarted;
  115.  
  116. #define NUMTOOLTYPES 14
  117.  
  118. char *ToolTypeIDs[NUMTOOLTYPES] =
  119.  {"CX_PRIORITY","CX_POPUP","CX_POPKEY","BLANKKEY",
  120.   "TIMEOUT","CLIENTTIMEOUT",
  121.   "DISPLAY","CYCLE","AIM",
  122.   "WASP","BEES","SPEED","TIGHTNESS","MOUSEBLANKMETHOD"};
  123.  
  124. /*
  125.  
  126.    Definitions for our Commodity
  127.  
  128. */
  129.  
  130. struct NewBroker NewBroker =
  131.  {NB_VERSION,"ASwarm II","Amiga Swarm II V1.3","Screen Blanker based on XSwarm",
  132.   NBU_NOTIFY|NBU_UNIQUE,COF_SHOW_HIDE,0,NULL,0};
  133. CxObj *Broker,*PopKeyFilter,*BlankKeyFilter;
  134. struct MsgPort *CxPort;
  135. LONG CxPri,CxPopUp;
  136.  
  137. UBYTE PopKey[32],BlankKey[32];
  138.  
  139. #define EVENT_OPEN_WINDOW 1L
  140. #define EVENT_BLANK       2L
  141.  
  142. #define DEF_CX_PRI 0L
  143. #define DEF_POPKEY   "CTRL ALT s"     /* Hot Key for the Edit Window */
  144. #define DEF_BLANKKEY "CTRL ALT b"     /* Hot Key for immediate Blank */
  145.  
  146. LONG TimeLeft,InitTimeLeft,TimeOut,ClientTimeOut;
  147.  
  148. #define MAX_TIMEOUT        3600L
  149. #define MAX_CLIENT_TIMEOUT 60L
  150.  
  151. #define DEF_TIMEOUT        60L
  152. #define DEF_CLIENT_TIMEOUT 5L
  153.  
  154. #define SERVER_PRI 5L                 /* Don't change this, saves live */
  155. #define CLIENT_PRI -40L
  156.  
  157. /*
  158.  
  159.    Definitions for our Blanker Screen
  160.  
  161. */
  162.  
  163. struct ModeNode
  164.  {
  165.   struct Node mn_Node;
  166.   UWORD mn_Index;
  167.   ULONG mn_DisplayID;
  168.   char mn_Name[DISPLAYNAMELEN];
  169.  };
  170.  
  171. struct List *ModeList;
  172. struct ModeNode *DisplayMode;
  173.  
  174. #define FindMode(l,n) ((struct ModeNode *)FindName(l,n))
  175.  
  176. #define DEF_MODE      HIRES
  177. #define DEF_MODE_NAME "HighRes"
  178.  
  179. /* Mini and Maximum definitions for possible parameters */
  180.  
  181. #define MAX_SPEED     4L
  182. #define MAX_WASPS     10L
  183. #define MAX_BEES      500L
  184. #define MAX_TIGHTNESS 10L
  185.  
  186. #define DEF_SPEED     4L
  187. #define DEF_WASPS     2L
  188. #define DEF_BEES      25L
  189. #define DEF_TIGHTNESS 5L
  190.  
  191. char *Template = /* extra extra extra long :-) */
  192.  "CX_PRIORITY/N/K,CX_POPKEY/K,CX_POPUP/S,BLANKKEY/K,SECONDS=TIMEOUT/N/K,"
  193.  "CLIENTTIMEOUT/N/K,DISPLAY/K,CYCLE/S,AIM/S,WASPS/N/K,BEES/N/K,SPEED/N/K,"
  194.  "TIGHTNESS/N/K,MOUSEBLANKMETHOD/K";
  195.  
  196. /*
  197.  
  198.    Definitions for our Configuration Window
  199.  
  200. */
  201.  
  202. #ifndef WFLG_NEWLOOKMENUS
  203. #define WFLG_NEWLOOKMENUS   0x200000L
  204. #endif
  205.  
  206. WORD LeftEdge=68,TopEdge=13;     /* Hard Coded, the window is too big to */
  207. struct Window *BlankerWindow;    /* let it open under the mouse pointer */
  208.  
  209. #define GID_HIDE      0  /* The Gadget-ID's */
  210. #define GID_BLANK     1
  211. #define GID_QUIT      2
  212. #define GID_MODE      3
  213. #define GID_TIMEOUT   4
  214. #define GID_CLIENT    5
  215. #define GID_SPEED     6
  216. #define GID_MOUSE     7
  217. #define GID_WASPS     8
  218. #define GID_BEES      9
  219. #define GID_TIGHT    10
  220. #define GID_CYCLE    11
  221. #define GID_AIMMODE  12
  222. #define GID_POPKEY   13
  223. #define GID_BLANKKEY 14
  224.  
  225. #define NUM_GADS 15
  226.  
  227. char *SpeedNames[] = /* List of Speed Modes */
  228.  {"Slow Motion","Very Slow","Slow","Normal","Fast","Very Fast",
  229.   "Incredible",NULL};
  230. char *MouseBlankMethods[] = /* List of Mouse Blank Methods */
  231.  {"Hardware","FreeSprite",NULL};
  232.  
  233. struct VisualInfo *BlankerVisualInfo;
  234. struct Menu *BlankerMenu;
  235. struct Gadget *BlankerContext,*BlankerGadgets[NUM_GADS];
  236. struct TextAttr BlankerAttr={"topaz.font",TOPAZ_EIGHTY,FS_NORMAL,FPF_ROMFONT};
  237.  
  238. #ifndef GTMN_NewLookMenus
  239. #define GTMN_NewLookMenus (TAG_USER+0x80043)
  240. #endif
  241.  
  242. struct NewMenu NewBlankerMenus[] =
  243.  {NM_TITLE,"Project",NULL,0,0L,NULL,
  244.   NM_ITEM,"Load Config","L",0,0L,NULL,
  245.   NM_ITEM,"Save Config","S",0,0L,NULL,
  246.   NM_ITEM,NM_BARLABEL,NULL,0,0L,NULL,
  247.   NM_ITEM,"About ...",NULL,0,0L,NULL,
  248.   NM_ITEM,NM_BARLABEL,NULL,0,0L,NULL,
  249.   NM_ITEM,"Hide","H",0,0L,NULL,
  250.   NM_ITEM,"Quit","Q",0,0L,NULL,
  251.   NM_TITLE,"Edit",NULL,0,0L,NULL,
  252.   NM_ITEM,"Reset To Defaults","D",0,0L,NULL,
  253.   NM_END,NULL,NULL,0,0L,NULL};
  254.  
  255. struct NewGadget NewBlankerGadgets[NUM_GADS] =
  256.  {16,161,48,12,"_Hide",&BlankerAttr,GID_HIDE,PLACETEXT_IN,NULL,NULL,
  257.   98,161,48,12,"_Blank",&BlankerAttr,GID_BLANK,PLACETEXT_IN,NULL,NULL,
  258.   180,161,48,12,"_Quit",&BlankerAttr,GID_QUIT,PLACETEXT_IN,NULL,NULL,
  259.   240,55,272,118,"Display Mode",&BlankerAttr,
  260.   GID_MODE,PLACETEXT_ABOVE,NULL,NULL,
  261.   172,10,56,12,"_Timeout",&BlankerAttr,GID_TIMEOUT,PLACETEXT_LEFT,NULL,NULL,
  262.   172,24,56,12,"C_lient Timeout",&BlankerAttr,
  263.   GID_CLIENT,PLACETEXT_LEFT,NULL,NULL,
  264.   104,55,124,12,"_Speed      ",&BlankerAttr,GID_SPEED,PLACETEXT_LEFT,NULL,NULL,
  265.   104,69,124,12,"_Mouse Blank",&BlankerAttr,GID_MOUSE,PLACETEXT_LEFT,NULL,NULL,
  266.   128,83,100,12,"_Wasps         ",&BlankerAttr,
  267.   GID_WASPS,PLACETEXT_LEFT,NULL,NULL,
  268.   128,97,100,12,"B_ees          ",&BlankerAttr,
  269.   GID_BEES,PLACETEXT_LEFT,NULL,NULL,
  270.   128,111,100,12,"T_ightness     ",&BlankerAttr,
  271.   GID_TIGHT,PLACETEXT_LEFT,NULL,NULL,
  272.   202,126,16,12,"_Color Cycling",&BlankerAttr,
  273.   GID_CYCLE,PLACETEXT_LEFT,NULL,NULL,
  274.   202,140,16,12,"_Aim Mode",&BlankerAttr,GID_AIMMODE,PLACETEXT_LEFT,NULL,NULL,
  275.   324,10,188,12,"_Pop Key",&BlankerAttr,GID_POPKEY,PLACETEXT_LEFT,NULL,NULL,
  276.   324,24,188,12,"Blank _Key",&BlankerAttr,
  277.   GID_BLANKKEY,PLACETEXT_LEFT,NULL,NULL};
  278.  
  279. UBYTE BlankerGadgetKinds[NUM_GADS] =
  280.  {BUTTON_KIND,BUTTON_KIND,BUTTON_KIND,LISTVIEW_KIND,
  281.   INTEGER_KIND,INTEGER_KIND,CYCLE_KIND,CYCLE_KIND,
  282.   SLIDER_KIND,SLIDER_KIND,SLIDER_KIND,
  283.   CHECKBOX_KIND,CHECKBOX_KIND,STRING_KIND,STRING_KIND};
  284. struct TagItem BlankerGadgetTags[] =
  285.  {GTLV_Labels,0L,GTLV_Selected,0L,GTLV_ShowSelected,NULL,TAG_DONE,0L,
  286.   GTIN_Number,0L,GTIN_MaxChars,4L,TAG_DONE,0L,
  287.   GTIN_Number,0L,GTIN_MaxChars,2L,TAG_DONE,0L,
  288.   GTCY_Labels,NULL,GTCY_Active,0,TAG_DONE,0L,
  289.   GTSL_Min,1L,GTSL_Max,MAX_WASPS,GTSL_Level,0L,
  290.   GTSL_MaxLevelLen,2L,GTSL_LevelFormat,(ULONG)"%2ld",
  291.   GA_RelVerify,TRUE,PGA_Freedom,LORIENT_HORIZ,TAG_DONE,0L,
  292.   GTSL_Min,1L,GTSL_Max,MAX_BEES,GTSL_Level,0L,
  293.   GTSL_MaxLevelLen,3L,GTSL_LevelFormat,(ULONG)"%3ld",
  294.   GA_RelVerify,TRUE,PGA_Freedom,LORIENT_HORIZ,TAG_DONE,0L,
  295.   GTSL_Min,1L,GTSL_Max,MAX_TIGHTNESS,GTSL_Level,0L,
  296.   GTSL_MaxLevelLen,2L,GTSL_LevelFormat,(ULONG)"%2ld",
  297.   GA_RelVerify,TRUE,PGA_Freedom,LORIENT_HORIZ,TAG_DONE,0L,
  298.   GTCB_Checked,0L,TAG_DONE,0L,
  299.   GTCB_Checked,0L,TAG_DONE,0L,
  300.   GTST_String,0L,GTST_MaxChars,31L,TAG_DONE,0L,
  301.   GTST_String,0L,GTST_MaxChars,31L,TAG_DONE,0L,
  302.   GTCY_Labels,NULL,GTCY_Active,0,TAG_DONE,0L};
  303. UBYTE BlankerTagsIndex[NUM_GADS] = {3,3,3,0,4,7,10,47,13,21,29,37,39,41,44};
  304.  
  305. struct EasyStruct AboutEasyStruct =
  306.  {sizeof(struct EasyStruct),0L,"About ...",
  307.   "ASwarm II V1.3 - The Original One\n"
  308.   "© 1992 by Markus Illenseer and Matthias Scheler\n"
  309.   "This program is freely distributable.","Ok"};
  310.  
  311. /*
  312.  
  313.     Definitions for Server/Client Communication
  314.  
  315. */
  316.  
  317. BYTE bsp_TimeOut,bsp_InputSig,bsp_ClientSig;
  318. struct Task *BlankerServerProcess;
  319.  
  320. #define MASK(n) (1L<<(n))
  321.  
  322. struct BlankerClientMsg
  323.  {
  324.   struct Message bcm_Message;
  325.   struct Screen *bcm_Screen;
  326.   LONG bcm_Status;
  327.   ULONG bcm_SigMask;
  328.   LONG bcm_Wasps,bcm_Bees,bcm_Speed,bcm_Tightness;
  329.   LONG bcm_Cycle,bcm_AimMode,bcm_MouseBlank;
  330.  } BlankerClientMsg;
  331.  
  332. /*
  333.  
  334.    Definitions or Swarm Movement
  335.  
  336. */
  337.  
  338. #define BEEACC  3
  339. #define BEEVEL  17
  340. #define WASPACC 5
  341. #define WASPVEL 21
  342. #define BORDER  5
  343.  
  344. #define BEE_PEN  1
  345. #define WASP_PEN 2
  346.  
  347. #define BEE_COL_NUM 33
  348.  
  349. UWORD BeeColors[BEE_COL_NUM] = /* Color Cycling Table */
  350.  {0x000F,0x000F,0x004F,0x008F,0x00BF,0x00FF,0x00FB,0x00F7,0x00F3,0x00F0,0x04F0,
  351.   0x08F0,0x09F0,0x0AF0,0x0BF0,0x0CF0,0x0DF0,0x0EF0,0x0FF0,0x0FE0,0x0FD0,0x0FC0,
  352.   0x0FB0,0x0F90,0x0F80,0x0F70,0x0F60,0x0F50,0x0F40,0x0F30,0x0F20,0x0F10,0x0F00};
  353.  
  354. #define RAND(m) (Random(m)-(m)/2)
  355.  
  356. UWORD SwarmColors[4] = {0x0000,0x0000,0x0FFF,0x0000};
  357. LONG NumWasps,NumBees,Speed,Tightness;
  358. LONG Cycle,AimMode,MouseBlank;
  359.  
  360. struct SwarmStruct /* structure for a swarm, including the wasp */
  361.  {
  362.   WORD ss_Width;   /* Width and */
  363.   WORD ss_Height;  /* Height of the used Screen, probably useful for
  364.                       future versions of ASwarm :) */
  365.   WORD ss_NumWasps;/* total number of the Wasps */
  366.   WORD *ss_WX[4];  /* The Wasps x-Position*/  /* WX[3] is used for Velocity */
  367.   WORD *ss_WY[4];  /* Y-Position */
  368.   WORD *ss_NB;     /* No. of Bees following this Wasp */
  369.   WORD ss_NumBees; /* Total (!) number of Bees */
  370.   WORD ss_BeeAcc;  /* Acceleration of the Bees */
  371.   WORD *ss_X[4];   /* The Bees X-Position */  /* X[3] used for Velocity */
  372.   WORD *ss_Y[4];   /* Y-Position */
  373.   WORD *ss_MW;     /* The aimed Wasp */
  374.  };
  375.  
  376. /* Ill's strange Macros for easy access to the above structure */
  377.  
  378. #define BXVel(I)   (SP->ss_X[3][I])
  379. #define BYVel(I)   (SP->ss_Y[3][I])
  380. #define BeeX(P,I)  (SP->ss_X[P][I])
  381. #define BeeY(P,I)  (SP->ss_Y[P][I])
  382. #define MyWasp(I)  (SP->ss_MW[I])
  383.  
  384. #define WaXVel(I)  (SP->ss_WX[3][I])
  385. #define WaYVel(I)  (SP->ss_WY[3][I])
  386. #define WaspX(P,I) (SP->ss_WX[P][I])
  387. #define WaspY(P,I) (SP->ss_WY[P][I])
  388.  
  389. /*
  390.  
  391.     The following functions are taken from my resource tracker library for
  392.     SAS/C. I normally use to link the programs with this library, but to make
  393.     it possible for other people to compile ASwarm II included the required
  394.     source codes.
  395.  
  396. */
  397.  
  398. struct ToolNode
  399.  {
  400.   struct ToolNode *Next;
  401.   void *Tool;
  402.   void (*RemProc)(void *,LONG); /* requires stack arguments !!! */
  403.   LONG Size;
  404.  } *ToolList;
  405.  
  406. void REGARGS RemTool(void *Tool)
  407.  
  408. {
  409.  struct ToolNode **Ptr,*ToolNode;
  410.  
  411.  Ptr=&ToolList;
  412.  while (*Ptr)
  413.   if ((*Ptr)->Tool==Tool)
  414.    {
  415.     ToolNode=*Ptr;
  416.     *Ptr=(*Ptr)->Next;
  417.  
  418.     ToolNode->RemProc(ToolNode->Tool,ToolNode->Size);
  419.     FreeVec ((APTR)ToolNode);
  420.  
  421.     return; /* This one was missing in ASwarm II V1.0-V1.1 and in
  422.                ASwarm III :-) */
  423.    }
  424.   else Ptr=&(*Ptr)->Next;
  425. }
  426.  
  427. void REGARGS Quit(int ReturnCode)
  428.  
  429. {
  430.  while (ToolList) RemTool (ToolList->Tool);
  431.  
  432.  exit (ReturnCode);
  433. }
  434.  
  435. void REGARGS AddTool(void *NewTool,void *ProcPtr,LONG NewSize)
  436.  
  437. {
  438.  struct ToolNode *Ptr;
  439.  void (*NewRemProc)(void *,LONG);
  440.  
  441.  NewRemProc=(void (*)(void *,LONG))ProcPtr;
  442.  if (NewTool==NULL) Quit (10);
  443.  
  444.  if ((Ptr=AllocVec(sizeof(struct ToolNode),0L))==NULL)
  445.   {
  446.    NewRemProc (NewTool,NewSize);
  447.    Quit (20);
  448.   }
  449.  Ptr->Next=ToolList;
  450.  Ptr->Tool=NewTool;
  451.  Ptr->RemProc=NewRemProc;
  452.  Ptr->Size=NewSize;
  453.  ToolList=Ptr;
  454. }
  455.  
  456. /*
  457.  
  458.    Some useful functions
  459.  
  460. */
  461.  
  462. VOID_STDARGS DeleteMsgPortSafely(struct MsgPort *AnyPort)
  463.  
  464. {
  465.  struct Message *AnyMsg;
  466.  
  467.  while (AnyMsg=GetMsg(AnyPort)) ReplyMsg (AnyMsg);
  468.  DeleteMsgPort (AnyPort);
  469. }
  470.  
  471. LONG RDArgsLong(LONG Param,LONG Default,LONG Min,LONG Max)
  472.  
  473. {
  474.  LONG *Ptr;
  475.  
  476.  if ((Ptr=(LONG *)Param)==NULL) return Default;
  477.  
  478.  if ((*Ptr<Min)||(*Ptr>Max)) return Default;
  479.  else return *Ptr;
  480. }
  481.  
  482. UWORD PutChar[2] = {0x16C0,0x4E75};
  483.  
  484. /* dirty hack to avoid assembler part :-)
  485.  
  486.    16C0: move.b d0,(a3)+
  487.    4E75: rts
  488. */
  489.  
  490. VOID_STDARGS SPrintF(char *Buffer,char *FormatString,...)
  491.  
  492. {
  493.  RawDoFmt (FormatString,(APTR)((LONG *)&FormatString+1L),
  494.            (void *)PutChar,Buffer);
  495. }
  496.  
  497. /*
  498.  
  499.    Functions for Handling the List of the avaible Graphics Modes
  500.  
  501. */
  502.  
  503. VOID_STDARGS DeleteModeList(struct List *ModeList)
  504.  
  505. {
  506.  struct ModeNode *ModeNode;
  507.  
  508.  while (ModeList->lh_Head->ln_Succ)
  509.   {
  510.    ModeNode=(struct ModeNode *)ModeList->lh_Head;
  511.    RemHead (ModeList);
  512.    FreeVec ((APTR)ModeNode);
  513.   }
  514.  FreeVec ((APTR)ModeList);
  515. }
  516.  
  517. struct List *CreateModeList(void)
  518.  
  519. {
  520.  struct List *ModeList;
  521.  UWORD Num;
  522.  ULONG DisplayID;
  523.  struct DimensionInfo DimInfo;
  524.  struct NameInfo NameInfo;
  525.  struct ModeNode *ModeNode;
  526.  
  527.  if (ModeList=AllocVec(sizeof(struct List),MEMF_PUBLIC)) NewList (ModeList);
  528.  else return NULL;
  529.  
  530.  Num=0;
  531.  DisplayID=INVALID_ID;
  532.  while ((DisplayID=NextDisplayInfo(DisplayID))!=INVALID_ID)
  533.   if ((DisplayID&MONITOR_ID_MASK)&&(ModeNotAvailable(DisplayID)==0L))
  534.    if (GetDisplayInfoData(NULL,(UBYTE *)&DimInfo,sizeof(struct DimensionInfo),
  535.                           DTAG_DIMS,DisplayID))
  536.     if (DimInfo.MaxDepth>1)
  537.      if (GetDisplayInfoData(NULL,(UBYTE *)&NameInfo,sizeof(struct NameInfo),
  538.                             DTAG_NAME,DisplayID))
  539.       if (ModeNode=AllocVec(sizeof(struct ModeNode),MEMF_PUBLIC))
  540.        {
  541.         (void)strcpy(ModeNode->mn_Node.ln_Name=ModeNode->mn_Name,
  542.                      NameInfo.Name);
  543.         ModeNode->mn_Index=Num++;
  544.         ModeNode->mn_DisplayID=DisplayID;
  545.         AddTail (ModeList,&ModeNode->mn_Node);
  546.        }
  547.  
  548.  if (ModeList->lh_Head->ln_Succ==NULL)
  549.   if (ModeNode=AllocVec(sizeof(struct ModeNode),MEMF_PUBLIC))
  550.    {
  551.     (void)strcpy(ModeNode->mn_Node.ln_Name=ModeNode->mn_Name,DEF_MODE_NAME);
  552.     ModeNode->mn_Index=Num;
  553.     ModeNode->mn_DisplayID=DEF_MODE;
  554.     AddTail (ModeList,&ModeNode->mn_Node);
  555.    }
  556.   else
  557.    {
  558.     FreeVec ((APTR)ModeList);
  559.     return NULL;
  560.    }
  561.  
  562.  return ModeList;
  563. }
  564.  
  565. struct ModeNode *GetDefaultMode(struct List *ModeList)
  566.  
  567. {
  568.  struct NameInfo NameInfo;
  569.  struct ModeNode *ModeNode;
  570.  
  571.  if (GetDisplayInfoData(NULL,(UBYTE *)&NameInfo,sizeof(struct NameInfo),
  572.                         DTAG_NAME,DEF_MODE))
  573.   if (ModeNode=FindMode(ModeList,NameInfo.Name)) return ModeNode;
  574.  
  575.  return (struct ModeNode *)ModeList->lh_Head;
  576. }
  577.  
  578. struct ModeNode *GetIndexMode(struct List *ModeList,UWORD Index)
  579.  
  580. {
  581.  struct ModeNode *ModeNode;
  582.  
  583.  ModeNode=(struct ModeNode *)ModeList->lh_Head;
  584.  while (ModeNode->mn_Node.ln_Succ)
  585.   if (ModeNode->mn_Index==Index) return ModeNode;
  586.   else ModeNode=(struct ModeNode *)ModeNode->mn_Node.ln_Succ;
  587.  
  588.  return (struct ModeNode *)ModeList->lh_Head;
  589. }
  590.  
  591. /*
  592.  
  593.    "icon.library" Stuff
  594.  
  595. */
  596.  
  597. char REGARGS *YesNo(LONG Flag)
  598.  
  599. {
  600.  return Flag?"YES":"NO";
  601. }
  602.  
  603. char REGARGS *ToolTypeString(struct DiskObject *DiskObject,char *ID,
  604.                              char *Default)
  605.  
  606. {
  607.  char *String;
  608.  
  609.  if (DiskObject==NULL) return Default;
  610.  
  611.  if (String=FindToolType(DiskObject->do_ToolTypes,ID)) return String;
  612.  else return Default;
  613. }
  614.  
  615. LONG REGARGS ToolTypeBoolean(struct DiskObject *DiskObject,char *ID,
  616.                              LONG Default)
  617.  
  618. {
  619.  if (Default) return (stricmp(ToolTypeString(DiskObject,ID,""),
  620.                               YesNo(FALSE))!=0);
  621.  else return (stricmp(ToolTypeString(DiskObject,ID,""),YesNo(TRUE))==0);
  622. }
  623.  
  624. LONG REGARGS ToolTypeLong(struct DiskObject *DiskObject,char *ID,LONG Default,
  625.                           LONG Min,LONG Max)
  626.  
  627. {
  628.  char *String;
  629.  
  630.  if (DiskObject==NULL) return Default;
  631.  
  632.  if (String=FindToolType(DiskObject->do_ToolTypes,ID))
  633.   {
  634.    LONG Value;
  635.  
  636.    Value=atol(String);
  637.    if ((Value<Min)||(Value>Max)) return Default;
  638.    else return Value;
  639.   }
  640.  else return Default;
  641. }
  642.  
  643. void REGARGS LoadConfig(char *Name)
  644.  
  645. {
  646.  struct DiskObject *DiskObject;
  647.  
  648.  if (Name) DiskObject=GetDiskObject(Name);
  649.  else DiskObject=NULL;
  650.  
  651.  CxPri=ToolTypeLong(DiskObject,ToolTypeIDs[0],0L,-128L,127L);
  652.  CxPopUp=ToolTypeBoolean(DiskObject,ToolTypeIDs[1],TRUE);
  653.  (void)strcpy(PopKey,ToolTypeString(DiskObject,ToolTypeIDs[2],DEF_POPKEY));
  654.  (void)strcpy(BlankKey,ToolTypeString(DiskObject,ToolTypeIDs[3],DEF_BLANKKEY));
  655.  
  656.  /* get Time Out, Client Time Out and Display mode */
  657.  
  658.  if ((TimeOut=ToolTypeLong(DiskObject,"SECONDS",0L,1L,MAX_TIMEOUT))==0L)
  659.   TimeOut=ToolTypeLong(DiskObject,ToolTypeIDs[4],DEF_TIMEOUT,1L,MAX_TIMEOUT);
  660.  
  661.  ClientTimeOut=ToolTypeLong(DiskObject,ToolTypeIDs[5],
  662.                             DEF_CLIENT_TIMEOUT,1L,MAX_CLIENT_TIMEOUT);
  663.  if ((DisplayMode=FindMode(ModeList,ToolTypeString(DiskObject,ToolTypeIDs[6],
  664.                                                    "")))==NULL)
  665.   DisplayMode=GetDefaultMode(ModeList);
  666.  
  667.  /* get Parameters for Graphics */
  668.  
  669.  Cycle=ToolTypeBoolean(DiskObject,ToolTypeIDs[7],TRUE);
  670.  AimMode=ToolTypeBoolean(DiskObject,ToolTypeIDs[8],FALSE);
  671.  
  672.  NumWasps=ToolTypeLong(DiskObject,ToolTypeIDs[9],DEF_WASPS,1L,MAX_WASPS);
  673.  NumBees=ToolTypeLong(DiskObject,ToolTypeIDs[10],DEF_BEES,1L,MAX_BEES);
  674.  Speed=ToolTypeLong(DiskObject,ToolTypeIDs[11],DEF_SPEED,1L,MAX_SPEED);
  675.  Tightness=ToolTypeLong(DiskObject,ToolTypeIDs[12],DEF_TIGHTNESS,1L,
  676.                         MAX_TIGHTNESS);
  677.  if (stricmp(ToolTypeString(DiskObject,ToolTypeIDs[13],""),
  678.              MouseBlankMethods[1])) MouseBlank=0L;
  679.  else MouseBlank=1L;
  680.  
  681.  if (BlankerWindow)
  682.   {
  683.    GT_SetGadgetAttrs (BlankerGadgets[GID_TIMEOUT],BlankerWindow,NULL,
  684.                       GTIN_Number,TimeOut,TAG_DONE);
  685.    GT_SetGadgetAttrs (BlankerGadgets[GID_CLIENT],BlankerWindow,NULL,
  686.                       GTIN_Number,ClientTimeOut,TAG_DONE);
  687.  
  688.    GT_SetGadgetAttrs (BlankerGadgets[GID_MODE],BlankerWindow,NULL,
  689.                       GTLV_Selected,DisplayMode->mn_Index,TAG_DONE);
  690.  
  691.    GT_SetGadgetAttrs (BlankerGadgets[GID_CYCLE],BlankerWindow,NULL,
  692.                       GTCB_Checked,Cycle,TAG_DONE);
  693.    GT_SetGadgetAttrs (BlankerGadgets[GID_AIMMODE],BlankerWindow,NULL,
  694.                       GTCB_Checked,AimMode,TAG_DONE);
  695.  
  696.    GT_SetGadgetAttrs (BlankerGadgets[GID_WASPS],BlankerWindow,NULL,
  697.                       GTSL_Level,NumWasps,TAG_DONE);
  698.    GT_SetGadgetAttrs (BlankerGadgets[GID_BEES],BlankerWindow,NULL,
  699.                       GTSL_Level,NumBees,TAG_DONE);
  700.    GT_SetGadgetAttrs (BlankerGadgets[GID_SPEED],BlankerWindow,NULL,
  701.                       GTCY_Active,Speed-1L,TAG_DONE);
  702.    GT_SetGadgetAttrs (BlankerGadgets[GID_MOUSE],BlankerWindow,NULL,
  703.                       GTCY_Active,MouseBlank,TAG_DONE);
  704.    GT_SetGadgetAttrs (BlankerGadgets[GID_TIGHT],BlankerWindow,NULL,
  705.                       GTSL_Level,Tightness,TAG_DONE);
  706.  
  707.    GT_SetGadgetAttrs (BlankerGadgets[GID_POPKEY],BlankerWindow,NULL,
  708.                       GTST_String,PopKey,TAG_DONE);
  709.    GT_SetGadgetAttrs (BlankerGadgets[GID_BLANKKEY],BlankerWindow,NULL,
  710.                       GTST_String,BlankKey,TAG_DONE);
  711.   }
  712.  
  713.  if (DiskObject) FreeDiskObject (DiskObject);
  714. }
  715.  
  716. void REGARGS SaveConfig(char *Name)
  717.  
  718. {
  719.  struct DiskObject *DiskObject;
  720.  ULONG Index;
  721.  char **NewToolTypes,**NextEntry,**OldToolTypes;
  722.  
  723.  if ((DiskObject=GetDiskObjectNew(Name))==NULL)
  724.   {
  725.    DisplayBeep (BlankerWindow->WScreen);
  726.    return;
  727.   }
  728.  
  729.  Index=0L;
  730.  OldToolTypes=DiskObject->do_ToolTypes;
  731.  while (OldToolTypes[Index]) Index++;
  732.  Index+=NUMTOOLTYPES+1L;
  733.  
  734.  if ((NewToolTypes=(char **)AllocVec(Index*4L+NUMTOOLTYPES*48L,
  735.                                      MEMF_PUBLIC|MEMF_CLEAR))==NULL)
  736.   {
  737.    FreeDiskObject (DiskObject);
  738.    return;
  739.   }
  740.  NextEntry=NewToolTypes;
  741.  
  742.  SPrintF (*NextEntry++=(char *)&NewToolTypes[Index],"%s=%ld",ToolTypeIDs[0],
  743.                                                     CxPri);
  744.  SPrintF (*NextEntry++=NewToolTypes[0]+48L,"%s=NO",ToolTypeIDs[1]);
  745.  SPrintF (*NextEntry++=NewToolTypes[1]+48L,"%s=%s",ToolTypeIDs[2],PopKey);
  746.  SPrintF (*NextEntry++=NewToolTypes[2]+48L,"%s=%s",ToolTypeIDs[3],BlankKey);
  747.  SPrintF (*NextEntry++=NewToolTypes[3]+48L,"%s=%ld",ToolTypeIDs[4],TimeOut);
  748.  SPrintF (*NextEntry++=NewToolTypes[4]+48L,"%s=%ld",ToolTypeIDs[5],
  749.           ClientTimeOut);
  750.  SPrintF (*NextEntry++=NewToolTypes[5]+48L,"%s=%s",ToolTypeIDs[6],
  751.           DisplayMode->mn_Name);
  752.  SPrintF (*NextEntry++=NewToolTypes[6]+48L,"%s=%s",ToolTypeIDs[7],
  753.           YesNo(Cycle));
  754.  SPrintF (*NextEntry++=NewToolTypes[7]+48L,"%s=%s",ToolTypeIDs[8],
  755.           YesNo(AimMode));
  756.  SPrintF (*NextEntry++=NewToolTypes[8]+48L,"%s=%ld",ToolTypeIDs[9],NumWasps);
  757.  SPrintF (*NextEntry++=NewToolTypes[9]+48L,"%s=%ld",ToolTypeIDs[10],NumBees);
  758.  SPrintF (*NextEntry++=NewToolTypes[10]+48L,"%s=%ld",ToolTypeIDs[11],Speed);
  759.  SPrintF (*NextEntry++=NewToolTypes[11]+48L,"%s=%ld",ToolTypeIDs[12],Tightness);
  760.  SPrintF (*NextEntry++=NewToolTypes[12]+48L,"%s=%s",ToolTypeIDs[13],
  761.           MouseBlankMethods[MouseBlank]);
  762.  
  763.  Index=0L;
  764.  while (OldToolTypes[Index])
  765.   {
  766.    char *Ptr,*Asgn;
  767.  
  768.    if (Ptr=(char *)AllocVec(strlen(OldToolTypes[Index])+1L,0L))
  769.     {
  770.      if (Asgn=strchr(strcpy(Ptr,OldToolTypes[Index]),'=')) *Asgn='\0';
  771.      if (FindToolType(NewToolTypes,Ptr)==NULL) *NextEntry++=OldToolTypes[Index];
  772.      FreeVec ((APTR)Ptr);
  773.     }
  774.    Index++;
  775.   }
  776.  
  777.  DiskObject->do_ToolTypes=NewToolTypes;
  778.  if (!PutDiskObject(Name,DiskObject)) DisplayBeep (BlankerWindow->WScreen);
  779.  DiskObject->do_ToolTypes=OldToolTypes;
  780.  
  781.  FreeVec ((APTR)NewToolTypes);
  782.  FreeDiskObject (DiskObject);
  783. }
  784.  
  785. /*
  786.  
  787.    Our "InputHandler"
  788.  
  789. */
  790.  
  791. VOID_INTERRUPT BlankerAction(CxMsg *CxMsg,CxObj *CO)
  792.  
  793. {
  794.  struct InputEvent *IE;
  795.  
  796.  IE=(struct InputEvent *)CxMsgData(CxMsg);
  797.  if (IE->ie_Class==IECLASS_TIMER)
  798.   {
  799.    if (TimeLeft)
  800.     {
  801.      TimeLeft--;
  802.      if (TimeLeft==0L) Signal (BlankerServerProcess,1L<<bsp_TimeOut);
  803.     }
  804.   }
  805.  else
  806.   {
  807.    Signal (BlankerServerProcess,1L<<bsp_InputSig);
  808.    TimeLeft=InitTimeLeft;
  809.   }
  810. }
  811.  
  812. /*
  813.  
  814.    Functions for Handling the Configuration Window
  815.  
  816. */
  817.  
  818. LONG GetNum(struct Gadget *Gadget,LONG *Data,LONG Max)
  819.  
  820. {
  821.  LONG NewData;
  822.  
  823.  NewData=((struct StringInfo *)Gadget->SpecialInfo)->LongInt;
  824.  if ((NewData<1L)||(NewData>Max))
  825.   {
  826.    GT_SetGadgetAttrs (Gadget,BlankerWindow,NULL,GTIN_Number,(ULONG)*Data,
  827.                       TAG_DONE);
  828.    return FALSE;
  829.   }
  830.  else
  831.   {
  832.    *Data=NewData;
  833.    return TRUE;
  834.   }
  835. }
  836.  
  837. void CloseBlankerWindow(void)
  838.  
  839. {
  840.  if (BlankerContext)
  841.   {
  842.    if (BlankerWindow)
  843.     {
  844.      LeftEdge=BlankerWindow->LeftEdge;
  845.      TopEdge=BlankerWindow->TopEdge;
  846.      ClearMenuStrip (BlankerWindow);
  847.      if (BlankerVisualInfo)
  848.       {
  849.        FreeVisualInfo (BlankerVisualInfo);
  850.        BlankerVisualInfo=NULL;
  851.        if (BlankerMenu)
  852.         {
  853.          FreeMenus (BlankerMenu);
  854.          BlankerMenu=NULL;
  855.         }
  856.       }
  857.      CloseWindow (BlankerWindow);
  858.      BlankerWindow=NULL;
  859.     }
  860.    FreeGadgets (BlankerContext);
  861.    BlankerContext=NULL;
  862.   }
  863. }
  864.  
  865. void OpenBlankerWindow(void)
  866.  
  867. {
  868.  struct Gadget *Ptr;
  869.  UWORD Index;
  870.  
  871.  if (BlankerWindow==NULL)
  872.   {
  873.    struct NewGadget NewGadget;
  874.  
  875.    BlankerContext=NULL;
  876.    if ((Ptr=CreateContext(&BlankerContext))==NULL) return;
  877.  
  878.    if ((BlankerWindow=OpenWindowTags(NULL,
  879.                                      WA_Left,LeftEdge,
  880.                                      WA_Top,TopEdge,
  881.                                      WA_IDCMP,IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW|
  882.                                       IDCMP_VANILLAKEY|IDCMP_MENUPICK|LISTVIEWIDCMP,
  883.                                      WA_Flags,WFLG_DRAGBAR|WFLG_DEPTHGADGET|
  884.                                       WFLG_CLOSEGADGET|WFLG_SIMPLE_REFRESH|
  885.                                       WFLG_NEWLOOKMENUS,
  886.                                      WA_Title,
  887.                                       (ULONG)"ASwarm II V1.3 © 1992 by Illenseer/Scheler",
  888.                                      WA_AutoAdjust,TRUE,
  889.                                      WA_InnerWidth,512,
  890.                                      WA_InnerHeight,175L,TAG_DONE))==NULL)
  891.     {
  892.      CloseBlankerWindow();
  893.      return;
  894.     }
  895.  
  896.    if ((BlankerVisualInfo=GetVisualInfo(BlankerWindow->WScreen,TAG_DONE))==NULL)
  897.     {
  898.      CloseBlankerWindow();
  899.      return;
  900.     }
  901.  
  902.    if (!WBStarted)
  903.     {
  904.      NewBlankerMenus[1].nm_Flags|=NM_ITEMDISABLED;
  905.      NewBlankerMenus[2].nm_Flags|=NM_ITEMDISABLED;
  906.     }
  907.    if ((BlankerMenu=CreateMenus(NewBlankerMenus,
  908.                                 GTMN_FullMenu,TRUE,
  909.                                 TAG_DONE))==NULL)
  910.     {
  911.      CloseBlankerWindow();
  912.      return;
  913.     }
  914.    if (!LayoutMenus(BlankerMenu,BlankerVisualInfo,
  915.                     GTMN_NewLookMenus,TRUE,TAG_DONE))
  916.     {
  917.      CloseBlankerWindow();
  918.      return;
  919.     }
  920.    else SetMenuStrip (BlankerWindow,BlankerMenu);
  921.  
  922.    BlankerGadgetTags[0].ti_Data=(ULONG)ModeList;
  923.    BlankerGadgetTags[1].ti_Data=(ULONG)DisplayMode->mn_Index;
  924.    BlankerGadgetTags[4].ti_Data=(ULONG)TimeOut;
  925.    BlankerGadgetTags[7].ti_Data=(ULONG)ClientTimeOut;
  926.    if (SysBase->AttnFlags&AFF_68020)
  927.     if (SysBase->AttnFlags&AFF_68030)
  928.      if (SysBase->AttnFlags&AFF_68040) BlankerGadgetTags[10].ti_Data=
  929.                                           (ULONG)&SpeedNames[3];
  930.      else
  931.       {
  932.        BlankerGadgetTags[10].ti_Data=(ULONG)&SpeedNames[2];
  933.        SpeedNames[6]=NULL;
  934.       }
  935.     else
  936.      {
  937.       BlankerGadgetTags[10].ti_Data=(ULONG)&SpeedNames[1];
  938.       SpeedNames[5]=NULL;
  939.      }
  940.    else
  941.     {
  942.      BlankerGadgetTags[10].ti_Data=(ULONG)&SpeedNames[0];
  943.      SpeedNames[4]=NULL;
  944.     }
  945.    BlankerGadgetTags[11].ti_Data=(ULONG)Speed-1L;
  946.    BlankerGadgetTags[15].ti_Data=(ULONG)NumWasps;
  947.    BlankerGadgetTags[23].ti_Data=(ULONG)NumBees;
  948.    BlankerGadgetTags[31].ti_Data=(ULONG)Tightness;
  949.    BlankerGadgetTags[37].ti_Data=(ULONG)Cycle;
  950.    BlankerGadgetTags[39].ti_Data=(ULONG)AimMode;
  951.    BlankerGadgetTags[41].ti_Data=(ULONG)PopKey;
  952.    BlankerGadgetTags[44].ti_Data=(ULONG)BlankKey;
  953.    BlankerGadgetTags[47].ti_Data=(ULONG)&MouseBlankMethods[0];
  954.    BlankerGadgetTags[48].ti_Data=(ULONG)MouseBlank;
  955.  
  956.    for (Index=0L; Index<NUM_GADS; Index++)
  957.     {
  958.      NewGadget=NewBlankerGadgets[Index];
  959.      NewGadget.ng_TopEdge+=BlankerWindow->BorderTop;
  960.      NewGadget.ng_VisualInfo=BlankerVisualInfo;
  961.      Ptr=CreateGadget((ULONG)BlankerGadgetKinds[Index],Ptr,&NewGadget,
  962.                       GT_Underscore,(ULONG)'_',TAG_MORE,
  963.                       &BlankerGadgetTags[BlankerTagsIndex[Index]]);
  964.      if ((BlankerGadgets[Index]=Ptr)==NULL)
  965.       {
  966.        CloseBlankerWindow();
  967.        return;
  968.       }
  969.     }
  970.  
  971.    AddGList (BlankerWindow,BlankerContext,0L,-1L,NULL);
  972.    RefreshGadgets (BlankerContext,BlankerWindow,NULL);
  973.    GT_RefreshWindow (BlankerWindow,NULL);
  974.   }
  975.  
  976.  ScreenToFront (BlankerWindow->WScreen);
  977.  WindowToFront (BlankerWindow);
  978.  ActivateWindow (BlankerWindow);
  979. }
  980.  
  981. void About(void)
  982.  
  983. {
  984.  ULONG IDCMPFlags;
  985.  
  986.  IDCMPFlags=0L;
  987.  (void)EasyRequestArgs(NULL,&AboutEasyStruct,&IDCMPFlags,NULL);
  988. }
  989.  
  990. /*
  991.  
  992.    Function to handle the Commodity Stuff
  993.  
  994. */
  995.  
  996. void REGARGS HandleCxMsg(CxMsg *CxMsg)
  997.  
  998. {
  999.  ULONG MsgType,MsgID;
  1000.  
  1001.  MsgType=CxMsgType(CxMsg);
  1002.  MsgID=CxMsgID(CxMsg);
  1003.  ReplyMsg ((struct Message *)CxMsg);
  1004.  
  1005.  switch (MsgType)
  1006.   {
  1007.    case CXM_IEVENT: /* PopKey was pressed */
  1008.     if (MsgID==EVENT_BLANK) InitTimeLeft=2L;
  1009.     else OpenBlankerWindow();
  1010.     break;
  1011.    case CXM_COMMAND:
  1012.     switch (MsgID)
  1013.      {
  1014.       case CXCMD_DISABLE:
  1015.        /* Message created by Exchange (except CXCMD_UNIQUE) */
  1016.        (void)ActivateCxObj(Broker,FALSE);
  1017.        break;
  1018.       case CXCMD_ENABLE:
  1019.        (void)ActivateCxObj(Broker,TRUE);
  1020.        break;
  1021.       case CXCMD_UNIQUE:
  1022.       case CXCMD_APPEAR:
  1023.        OpenBlankerWindow();
  1024.        break;
  1025.       case CXCMD_DISAPPEAR:
  1026.        CloseBlankerWindow();
  1027.        break;
  1028.       case CXCMD_KILL:
  1029.        Quit (0);
  1030.      }
  1031.    }
  1032. }
  1033.  
  1034. CxObj REGARGS *InstallHotKey(CxObj *Filter,char *Describ,LONG Event,
  1035.                              char *Default)
  1036.  
  1037. {
  1038.  if (Filter)
  1039.   {
  1040.    RemoveCxObj (Filter);
  1041.    DeleteCxObj (Filter);
  1042.   }
  1043.  
  1044.  if (Filter=HotKey(Describ,CxPort,Event))
  1045.   if (CxObjError(Filter)==0L)
  1046.    {
  1047.     AttachCxObj (Broker,Filter);
  1048.     return Filter;
  1049.    }
  1050.   else DeleteCxObj (Filter);
  1051.  
  1052.  if (Filter=HotKey(Default,CxPort,Event))
  1053.   if (CxObjError(Filter)==0L)
  1054.    {
  1055.     AttachCxObj (Broker,Filter);
  1056.     (void)strcpy(Describ,Default);
  1057.     return Filter;
  1058.    }
  1059.   else DeleteCxObj (Filter);
  1060.  
  1061.  (void)strcpy(Describ,"<NONE>");
  1062.  return NULL;
  1063. }
  1064.  
  1065. /*
  1066.  
  1067.    Functions fore Creating/Deleting the Client Process
  1068.  
  1069. */
  1070.  
  1071. VOID_STDARGS DeleteBlankerClient(struct MsgPort *BlankerClientPort,
  1072.                                  struct BlankerClientMsg *BlankerClientMsg)
  1073.  
  1074. {
  1075.  PutMsg (BlankerClientPort,(struct Message *)BlankerClientMsg);
  1076.  
  1077.  (void)SetTaskPri(BlankerClientPort->mp_SigTask,SERVER_PRI+1L);
  1078.  
  1079.  (void)WaitPort(BlankerClientMsg->bcm_Message.mn_ReplyPort);
  1080.  (void)GetMsg(BlankerClientMsg->bcm_Message.mn_ReplyPort);
  1081. }
  1082.  
  1083. struct MsgPort *REGARGS CreateBlankerClient(void *CodePtr,
  1084.                                      struct BlankerClientMsg *BlankerClientMsg)
  1085.  
  1086. {
  1087.  struct Process *BlankerClientProcess;
  1088.  
  1089.  if (BlankerClientProcess=CreateNewProcTags(NP_Entry,CodePtr,
  1090.                                             NP_Name,"BlankerClient",
  1091.                                             NP_StackSize,4000L,TAG_DONE))
  1092.   {
  1093.    PutMsg (&BlankerClientProcess->pr_MsgPort,
  1094.            (struct Message *)BlankerClientMsg);
  1095.  
  1096.    (void)WaitPort(BlankerClientMsg->bcm_Message.mn_ReplyPort);
  1097.    (void)GetMsg(BlankerClientMsg->bcm_Message.mn_ReplyPort);
  1098.  
  1099.    (void)SetTaskPri((struct Task *)BlankerClientProcess,CLIENT_PRI);
  1100.  
  1101.    if (BlankerClientMsg->bcm_Status) return &BlankerClientProcess->pr_MsgPort;
  1102.   }
  1103.  return NULL;
  1104. }
  1105.  
  1106. /*
  1107.  
  1108.    Open a Screen with the supplied DisplayID
  1109.  
  1110. */
  1111.  
  1112. void SpritesOff(void)
  1113.  
  1114. {
  1115.  ULONG Index;
  1116.  
  1117.  if (MouseBlank)
  1118.   {
  1119.    FreeSprite (0); /* hack required for DOMINO-Gfx-Board */
  1120.    GfxBase->SpriteReserved|=1;
  1121.   }
  1122.  else
  1123.   {
  1124.    OFF_SPRITE /* switch sprites off */
  1125.    for (Index=0L; Index<8L; Index++) custom.spr[Index].ctl=0;
  1126.   }
  1127. }
  1128.  
  1129. struct Screen *CreateScreen(struct List *ModeList,struct ModeNode *ModeNode)
  1130.  
  1131. {
  1132.  struct Screen *Screen;
  1133.  
  1134.  if (Screen=OpenScreenTags(NULL,
  1135.                            SA_Depth,2,
  1136.                            SA_Title,"ASwarm II",
  1137.                            SA_DisplayID,ModeNode->mn_DisplayID,
  1138.                            SA_Quiet,TRUE,TAG_DONE))
  1139.   {
  1140.    SetRGB4 (&Screen->ViewPort,0,0,0,0);
  1141.    SetRast (&Screen->RastPort,0);
  1142.  
  1143.    SpritesOff();
  1144.   }
  1145.  return Screen;
  1146. }
  1147.  
  1148. /*
  1149.  
  1150.    Functions for Creating/Drawing/Removing the Swarms
  1151.  
  1152. */
  1153.  
  1154. /* Ill's strange and genius Random Function :-) */
  1155.  
  1156. UWORD REGARGS Random(UWORD Max)
  1157.  
  1158. {
  1159.  static ULONG Num=0L; /* So the last random-number is still stored ! */
  1160.  ULONG Sec,Mic;
  1161.  
  1162.  CurrentTime((LONG *)&Sec,(LONG *)&Mic);
  1163.  
  1164.  Num*=Sec;
  1165.  Num+=Mic;
  1166.  
  1167.  while (Num>32767L) Num=Num>>1;
  1168.  
  1169.  return (UWORD)(Num%Max);
  1170. }
  1171.  
  1172. BYTE sqrt_tab[256] =
  1173.  {0,1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,
  1174.   4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,
  1175.   5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,
  1176.   6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  1177.   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
  1178.   8,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
  1179.   9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,
  1180.   10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,
  1181.   11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
  1182.   12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
  1183.   12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,
  1184.   13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
  1185.   13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14,
  1186.   14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
  1187.   14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
  1188.   15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15};
  1189.  
  1190.  
  1191. LONG FastSQRT(LONG x)
  1192.  
  1193. {
  1194.  LONG sr;
  1195.  
  1196.  sr=1L;
  1197.  while (x>255L)
  1198.   {
  1199.    x/=4L;
  1200.    sr*=2L;
  1201.   }
  1202.  return sr*(LONG)sqrt_tab[x];
  1203. }
  1204.  
  1205. ULONG SwarmSize(LONG NumWaps,LONG NumBees)
  1206.  
  1207. {
  1208.  return sizeof(struct SwarmStruct)+sizeof(WORD)*((ULONG)NumWaps*9L+
  1209.                                    (ULONG)NumBees*9L);
  1210. }
  1211.  
  1212. struct SwarmStruct *REGARGS CreateSwarms(struct Screen *SwarmScreen,
  1213.                                          LONG NumWasps,LONG NumBees,
  1214.                                          LONG Speed,LONG Tightness)
  1215.  
  1216. /* allocate Memory and initialize the Swarm(s) */
  1217.  
  1218. {
  1219.  LONG Index;
  1220.  struct SwarmStruct *SP;
  1221.  WORD *Ptr;
  1222.  
  1223.  if ((SP=AllocVec(SwarmSize(NumWasps,NumBees),0L))==NULL) return NULL;
  1224.  
  1225.  SP->ss_NumWasps=NumWasps;
  1226.  SP->ss_NumBees=NumBees;
  1227.  SP->ss_Width=SwarmScreen->Width;    /* Will probably be changed in a */
  1228.  SP->ss_Height=SwarmScreen->Height;  /* future version of ASwarm */
  1229.  SP->ss_BeeAcc=(Tightness*BEEACC)/MAX_SPEED+1;
  1230.  
  1231.  Ptr=(WORD *)&SP[1];
  1232.  for (Index=0L; Index<4L; Index++)
  1233.   {
  1234.    SP->ss_WX[Index]=Ptr;
  1235.    Ptr+=NumWasps;
  1236.    SP->ss_WY[Index]=Ptr;
  1237.    Ptr+=NumWasps;
  1238.    SP->ss_X[Index]=Ptr;
  1239.    Ptr+=NumBees;
  1240.    SP->ss_Y[Index]=Ptr;
  1241.    Ptr+=NumBees;
  1242.   }
  1243.  SP->ss_NB=Ptr;
  1244.  SP->ss_MW=Ptr+NumWasps;
  1245.  
  1246.  /* Wasps */
  1247.  for (Index=0L; Index<NumWasps; Index++)
  1248.   {
  1249.    WaspX(1,Index)=WaspX(0,Index)=BORDER+Random(SP->ss_Width-2*BORDER);
  1250.    WaspY(1,Index)=WaspY(0,Index)=BORDER+Random(SP->ss_Height-2*BORDER);
  1251.    WaXVel(Index)=RAND(WASPACC);
  1252.    WaYVel(Index)=RAND(WASPACC);
  1253.    SP->ss_NB[Index]=0;
  1254.   }
  1255.  
  1256.  /* Bees */
  1257.  for (Index=0L; Index<SP->ss_NumBees; Index++)
  1258.   {
  1259.    BeeX(1,Index)=BeeX(0,Index)=BORDER+Random(SP->ss_Width-2*BORDER);
  1260.    BeeY(1,Index)=BeeY(0,Index)=BORDER+Random(SP->ss_Height-2*BORDER);
  1261.    BXVel(Index)=RAND(SP->ss_BeeAcc);
  1262.    BYVel(Index)=RAND(SP->ss_BeeAcc);
  1263.    SP->ss_NB[MyWasp(Index)=Index%SP->ss_NumWasps]++;
  1264.   }
  1265.  
  1266.  return SP;
  1267. }
  1268.  
  1269. /* move Swarms and redraw it */
  1270.  
  1271. void REGARGS DrawSwarms(struct RastPort *RP,struct SwarmStruct *SP,LONG AimMode)
  1272.  
  1273. {
  1274.  LONG Index;
  1275.  
  1276.  /* Wasps */
  1277.  
  1278.  for (Index=0L; Index<SP->ss_NumWasps; Index++)
  1279.   {
  1280.    WaspX(2,Index)=WaspX(1,Index);
  1281.    WaspX(1,Index)=WaspX(0,Index);
  1282.    WaspY(2,Index)=WaspY(1,Index);
  1283.    WaspY(1,Index)=WaspY(0,Index);
  1284.  
  1285.    WaXVel(Index)+=RAND(WASPACC);
  1286.    WaYVel(Index)+=RAND(WASPACC);
  1287.  
  1288.    if (WaXVel(Index)>WASPVEL) WaXVel(Index)=WASPVEL;
  1289.    if (WaXVel(Index)<-WASPVEL) WaXVel(Index)=-WASPVEL;
  1290.    if (WaYVel(Index)>WASPVEL) WaYVel(Index)=WASPVEL;
  1291.    if (WaYVel(Index)<-WASPVEL) WaYVel(Index)=-WASPVEL;
  1292.  
  1293.    WaspX(0,Index)=WaspX(1,Index)+WaXVel(Index);
  1294.    WaspY(0,Index)=WaspY(1,Index)+WaYVel(Index);
  1295.  
  1296.    /* Bounce check for Wasps */
  1297.  
  1298.    if ((WaspX(0,Index)<BORDER)||(WaspX(0,Index)>SP->ss_Width-BORDER-1))
  1299.     {
  1300.      WaXVel(Index)=-WaXVel(Index);
  1301.      if (WaspX(0,Index)<BORDER) WaspX(0,Index)=BORDER;
  1302.      else WaspX(0,Index)=SP->ss_Width-BORDER-1;
  1303.     }
  1304.    if ((WaspY(0,Index)<BORDER)||(WaspY(0,Index)>SP->ss_Height-BORDER-1))
  1305.     {
  1306.      WaYVel(Index)=-WaYVel(Index);
  1307.      if (WaspY(0,Index)<BORDER) WaspY(0,Index)=BORDER;
  1308.      else WaspY(0,Index)=SP->ss_Height-BORDER-1;
  1309.     }
  1310.   }
  1311.  
  1312.  /* Bees */
  1313.  
  1314.  for (Index=0L; Index<SP->ss_NumBees; Index++)
  1315.   {
  1316.    WORD DX,DY,ChkIndex;
  1317.    LONG Distance,NewDistance;
  1318.  
  1319.    BeeX(2,Index)=BeeX(1,Index);
  1320.    BeeX(1,Index)=BeeX(0,Index);
  1321.    BeeY(2,Index)=BeeY(1,Index);
  1322.    BeeY(1,Index)=BeeY(0,Index);
  1323.  
  1324.    DX=WaspX(1,MyWasp(Index))-BeeX(1,Index);
  1325.    DY=WaspY(1,MyWasp(Index))-BeeY(1,Index);
  1326.    Distance=FastSQRT(DX*DX+DY*DY);
  1327.    if (Distance==0L) Distance=1L;
  1328.  
  1329.    if (AimMode) /* Look out for the nearest wasp if Aim-Mode is on */
  1330.     for (ChkIndex=0; ChkIndex<=SP->ss_NumWasps; ChkIndex++)
  1331.      if (ChkIndex!=MyWasp(Index))
  1332.       {
  1333.        LONG NewDX,NewDY;
  1334.  
  1335.        NewDX=WaspX(1,ChkIndex)-BeeX(1,Index);
  1336.        NewDY=WaspY(1,ChkIndex)-BeeY(1,Index);
  1337.        NewDistance=FastSQRT(NewDX*NewDX+NewDY*NewDY);
  1338.        if (Distance>NewDistance)
  1339.         {
  1340.          DX=NewDX;
  1341.          DY=NewDY;
  1342.          if (NewDistance==0L) Distance=1L;
  1343.          else Distance=NewDistance;
  1344.          SP->ss_NB[MyWasp(Index)]--;
  1345.          SP->ss_NB[MyWasp(Index)=ChkIndex]++; /* Mark a nearer Wasp */
  1346.         }
  1347.       }
  1348.  
  1349.    BXVel(Index)+=(DX*SP->ss_BeeAcc)/Distance+RAND(3);
  1350.    BYVel(Index)+=(DY*SP->ss_BeeAcc)/Distance+RAND(3);
  1351.  
  1352.    if (BXVel(Index)>BEEVEL)  BXVel(Index)=BEEVEL;
  1353.    if (BXVel(Index)<-BEEVEL) BXVel(Index)=-BEEVEL;
  1354.    if (BYVel(Index)>BEEVEL)  BYVel(Index)=BEEVEL;
  1355.    if (BYVel(Index)<-BEEVEL) BYVel(Index)=-BEEVEL;
  1356.  
  1357.    BeeX(0,Index)=BeeX(1,Index)+BXVel(Index);
  1358.    BeeY(0,Index)=BeeY(1,Index)+BYVel(Index);
  1359.  
  1360.   /* Bounce check for Bees */
  1361.  
  1362.    if ((BeeX(0,Index)<BORDER)||(BeeX(0,Index)>(SP->ss_Width-BORDER-1)))
  1363.     {
  1364.      BXVel(Index)=-BXVel(Index);
  1365.      BeeX(0,Index)=BeeX(1,Index)+BXVel(Index);
  1366.     }
  1367.    if ((BeeY(0,Index)<BORDER)||(BeeY(0,Index)>(SP->ss_Height-BORDER-1)))
  1368.     {
  1369.      BYVel(Index)=-BYVel(Index);
  1370.      BeeY(0,Index)=BeeY(1,Index)+BYVel(Index);
  1371.     }
  1372.   }
  1373.  
  1374.  
  1375.  /* Move our insects */
  1376.  
  1377.  for (Index=0L; Index<SP->ss_NumWasps; Index++)   /* Wasps */
  1378.   {
  1379.    SetAPen (RP,0);
  1380.    Move (RP,WaspX(2,Index),WaspY(2,Index));
  1381.    Draw (RP,WaspX(1,Index),WaspY(1,Index));
  1382.    SetAPen (RP,WASP_PEN);
  1383.    Draw (RP,WaspX(0,Index),WaspY(0,Index));
  1384.   }
  1385.  
  1386.  for (Index=0L; Index<SP->ss_NumBees; Index++)   /* Bees  */
  1387.   {
  1388.    SetAPen (RP,0);
  1389.    Move (RP,BeeX(2,Index),BeeY(2,Index));
  1390.    Draw (RP,BeeX(1,Index),BeeY(1,Index));
  1391.    SetAPen (RP,BEE_PEN);
  1392.    Draw (RP,BeeX(0,Index),BeeY(0,Index));
  1393.   }
  1394. }
  1395.  
  1396. /*
  1397.  
  1398.    This is the Client Process's Main Loop
  1399.  
  1400. */
  1401.  
  1402. VOID_INTERRUPT ASwarmClientProcess(void)
  1403.  
  1404. {
  1405.  struct BlankerClientMsg *BlankerClientMsg;
  1406.  struct MsgPort *BlankerClientPort;
  1407.  struct Task *BlankerServerTask;
  1408.  ULONG BlankerServerSigMask;
  1409.  struct Screen *SwarmScreen;
  1410.  LONG NumWasps,NumBees,Speed,Cycle,AimMode,Count,Tightness;
  1411.  struct SwarmStruct *Swarms;
  1412.  WORD Color,DColor;
  1413.  
  1414.  /* wait for Server's initial Message */
  1415.  
  1416.  BlankerClientPort=FINDPROCPORT;
  1417.  (void)WaitPort(BlankerClientPort);
  1418.  BlankerClientMsg=(struct BlankerClientMsg *)GetMsg(BlankerClientPort);
  1419.  
  1420.  BlankerServerTask=BlankerClientMsg->bcm_Message.mn_ReplyPort->mp_SigTask;
  1421.  BlankerServerSigMask=BlankerClientMsg->bcm_SigMask;
  1422.  
  1423.  NumWasps=BlankerClientMsg->bcm_Wasps;
  1424.  NumBees=BlankerClientMsg->bcm_Bees;
  1425.  SwarmScreen=BlankerClientMsg->bcm_Screen;
  1426.  Speed=BlankerClientMsg->bcm_Speed;
  1427.  Cycle=BlankerClientMsg->bcm_Cycle;
  1428.  AimMode=BlankerClientMsg->bcm_AimMode;
  1429.  Tightness=BlankerClientMsg->bcm_Tightness;
  1430.  
  1431.  /* initialize requested Number of Swarms */
  1432.  
  1433.  if ((Swarms=CreateSwarms(SwarmScreen,NumWasps,NumBees,Speed,Tightness))==NULL)
  1434.   {
  1435.    BlankerClientMsg->bcm_Status=FALSE;
  1436.    Forbid();
  1437.    ReplyMsg ((struct Message *)BlankerClientMsg);
  1438.    return;
  1439.   }
  1440.  BlankerClientMsg->bcm_Status=TRUE;
  1441.  ReplyMsg ((struct Message *)BlankerClientMsg);
  1442.  
  1443.  Color=BEE_COL_NUM-1;
  1444.  DColor=Cycle?1:0;
  1445.  Count=Speed;
  1446.  
  1447.  while ((BlankerClientMsg=(struct BlankerClientMsg *)
  1448.                            GetMsg(BlankerClientPort))==NULL)
  1449.   {
  1450.    /* Color Cycling */
  1451.  
  1452.    SwarmColors[BEE_PEN]=BeeColors[Color];
  1453.    LoadRGB4 (&SwarmScreen->ViewPort,SwarmColors,4);
  1454.    Color+=DColor;
  1455.    if ((Color==-1)||(Color==BEE_COL_NUM))
  1456.     {
  1457.      DColor=-DColor;
  1458.      Color+=2*DColor;
  1459.     }
  1460.  
  1461.    /* Synchronisation */
  1462.  
  1463.    WaitTOF();
  1464.    if (Count<MAX_SPEED)
  1465.     {
  1466.      Count++;
  1467.      continue;
  1468.     }
  1469.    Count=Speed;
  1470.  
  1471.    /* Move the Swarm(s) */
  1472.  
  1473.    DrawSwarms (&SwarmScreen->RastPort,Swarms,AimMode);
  1474.    if (IntuitionBase->FirstScreen!=SwarmScreen)
  1475.     {
  1476.      ScreenToFront (SwarmScreen);
  1477.      SpritesOff();
  1478.     }
  1479.    Signal (BlankerServerTask,BlankerServerSigMask);
  1480.   }
  1481.  FreeVec ((APTR)Swarms);
  1482.  
  1483.  /* We are requested to finish, so we do. */
  1484.  
  1485.  Forbid();
  1486.  ReplyMsg ((struct Message *)BlankerClientMsg);
  1487. }
  1488.  
  1489. /*
  1490.  
  1491.    The Main Loop
  1492.  
  1493. */
  1494.  
  1495. void main(LONG argc,UBYTE **argv)
  1496.  
  1497. {
  1498.  CxObj *ObjectList;
  1499.  struct IntuiMessage *IntMsg;
  1500.  CxMsg *BlankerCxMsg;
  1501.  struct Screen *BlankerScreen=NULL;
  1502.  struct MsgPort *BlankerClientPort=NULL;
  1503.  
  1504.  /* open our Libraries */
  1505.  
  1506.  AddTool (GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",37L),
  1507.           CloseLibrary,0L);
  1508.  AddTool (IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",
  1509.           37L),CloseLibrary,0L);
  1510.  AddTool (CxBase=OpenLibrary("commodities.library",37L),CloseLibrary,0L);
  1511.  AddTool (GadToolsBase=OpenLibrary("gadtools.library",37L),CloseLibrary,0L);
  1512.  
  1513.  /* create List of Graphics Modes */
  1514.  
  1515.  AddTool (ModeList=CreateModeList(),DeleteModeList,0L);
  1516.  
  1517.  /* get some Signals */
  1518.  
  1519.  BlankerServerProcess=SysBase->ThisTask;
  1520.  if ((bsp_TimeOut=AllocSignal(-1L))==-1) Quit (10);
  1521.  AddTool ((void *)bsp_TimeOut,FreeSignal,0L);
  1522.  if ((bsp_InputSig=AllocSignal(-1L))==-1) Quit (10);
  1523.  AddTool ((void *)bsp_InputSig,FreeSignal,0L);
  1524.  if ((bsp_ClientSig=AllocSignal(-1L))==-1) Quit (10);
  1525.  AddTool ((void *)bsp_ClientSig,FreeSignal,0L);
  1526.  
  1527.  /* Were we started from Workbench or from CLI ? */
  1528.  
  1529.  if (WBStarted=(argc==0L))
  1530.   {
  1531.    /* Workbench: load Config from DiskObject */
  1532.    struct WBStartup *WBenchMsg;
  1533.  
  1534.    AddTool (IconBase=OpenLibrary(ICONNAME,37L),CloseLibrary,0L);
  1535.  
  1536.    WBenchMsg=(struct WBStartup *)argv;
  1537.    LoadConfig (WBenchMsg->sm_NumArgs?WBenchMsg->sm_ArgList->wa_Name:NULL);
  1538.   }
  1539.  else
  1540.   {
  1541.    struct RDArgs *RDArgs;
  1542.    LONG Array[14];
  1543.  
  1544.    (void)memset(Array,'\0',sizeof(Array));
  1545.    if (RDArgs=ReadArgs(Template,Array,NULL))
  1546.     {
  1547.      AddTool (RDArgs,FreeArgs,0L);
  1548.  
  1549.      CxPri=RDArgsLong(Array[0],0L,-128L,127L);
  1550.      (void)strcpy(PopKey,Array[1]?(char *)Array[1]:DEF_POPKEY);
  1551.      CxPopUp=Array[2];
  1552.      (void)strcpy(BlankKey,Array[3]?(char *)Array[3]:DEF_BLANKKEY);
  1553.  
  1554.      /* get Time Out, Client Time Out and Display mode */
  1555.  
  1556.      TimeOut=RDArgsLong(Array[4],DEF_TIMEOUT,1L,MAX_TIMEOUT);
  1557.      ClientTimeOut=RDArgsLong(Array[5],DEF_CLIENT_TIMEOUT,1L,
  1558.                    MAX_CLIENT_TIMEOUT);
  1559.      if ((DisplayMode=FindMode(ModeList,Array[6]?(char *)Array[6]:""))==NULL)
  1560.       DisplayMode=GetDefaultMode(ModeList);
  1561.  
  1562.  
  1563.      /* get Parameters for Graphics */
  1564.  
  1565.      Cycle=Array[7];
  1566.      AimMode=Array[8];
  1567.  
  1568.      NumWasps=RDArgsLong(Array[9],DEF_WASPS,1L,MAX_WASPS);
  1569.      NumBees=RDArgsLong(Array[10],DEF_BEES,1L,MAX_BEES);
  1570.      Speed=RDArgsLong(Array[11],DEF_SPEED,1L,MAX_SPEED);
  1571.      Tightness=RDArgsLong(Array[12],DEF_TIGHTNESS,1L,MAX_TIGHTNESS);
  1572.      if (stricmp(Array[13]?(char *)Array[13]:"",MouseBlankMethods[1]))
  1573.       MouseBlank=0L;
  1574.      else MouseBlank=1L;
  1575.     }
  1576.    else
  1577.     {
  1578.      PrintFault (IoErr(),"ASwarm");
  1579.      Quit (10);
  1580.     }
  1581.   }
  1582.  
  1583.  /* initialize our Broker=install us as a Commodity */
  1584.  
  1585.  AddTool (CxPort=CreateMsgPort(),DeleteMsgPortSafely,0L);
  1586.  
  1587.  NewBroker.nb_Pri=(BYTE)CxPri;
  1588.  NewBroker.nb_Port=CxPort;
  1589.  AddTool (Broker=CxBroker(&NewBroker,NULL),DeleteCxObjAll,0L);
  1590.  
  1591.  /* install our Hot Keys */
  1592.  
  1593.  PopKeyFilter=InstallHotKey(NULL,PopKey,EVENT_OPEN_WINDOW,DEF_POPKEY);
  1594.  BlankKeyFilter=InstallHotKey(NULL,BlankKey,EVENT_BLANK,DEF_BLANKKEY);
  1595.  
  1596.  /* install our "InputHandler" */
  1597.  
  1598.  TimeLeft=InitTimeLeft=TimeOut*10L;
  1599.  ObjectList=CxCustom(BlankerAction,0L);
  1600.  AttachCxObj (Broker,ObjectList);
  1601.  if (CxObjError(ObjectList)) Quit (10);
  1602.  
  1603.  (void)ActivateCxObj(Broker,TRUE);
  1604.  AddTool (Broker,ActivateCxObj,FALSE);
  1605.  
  1606.  /* open Window on startup if not forbidden */
  1607.  
  1608.  AddTool ((void *)-1L,CloseBlankerWindow,0L);
  1609.  if (CxPopUp) OpenBlankerWindow();
  1610.  
  1611.  /* increase our Priority */
  1612.  
  1613.  AddTool (FindTask(NULL),SetTaskPri,(LONG)SetTaskPri(FindTask(NULL),
  1614.                          SERVER_PRI));
  1615.  
  1616.  /* start the Loop */
  1617.  
  1618.  FOREVER
  1619.   {
  1620.    ULONG Mask;
  1621.  
  1622.    if (BlankerWindow)
  1623.     Mask=Wait(MASK(bsp_TimeOut)|MASK(bsp_InputSig)|MASK(bsp_ClientSig)|
  1624.               MASK(CxPort->mp_SigBit)|MASK(BlankerWindow->UserPort->mp_SigBit)|
  1625.               SIGBREAKF_CTRL_C);
  1626.    else
  1627.     Mask=Wait(MASK(bsp_TimeOut)|MASK(bsp_InputSig)|MASK(bsp_ClientSig)|
  1628.               MASK(CxPort->mp_SigBit)|SIGBREAKF_CTRL_C);
  1629.  
  1630.    /* process Window Events */
  1631.  
  1632.    while ((BlankerWindow!=NULL)&&(IntMsg=GT_GetIMsg(BlankerWindow->UserPort)))
  1633.     switch (IntMsg->Class)
  1634.      {
  1635.       struct Gadget *Clicked;
  1636.       UWORD Code,Qualifier;
  1637.  
  1638.       case IDCMP_CLOSEWINDOW:
  1639.        GT_ReplyIMsg (IntMsg);
  1640.        CloseBlankerWindow();
  1641.        break;
  1642.       case IDCMP_REFRESHWINDOW:
  1643.        GT_BeginRefresh (BlankerWindow);
  1644.        GT_EndRefresh (BlankerWindow,TRUE);
  1645.        break;
  1646.       case IDCMP_GADGETUP:
  1647.        Code=IntMsg->Code;
  1648.        Qualifier=IntMsg->Qualifier;
  1649.        Clicked=(struct Gadget *)IntMsg->IAddress;
  1650.        GT_ReplyIMsg (IntMsg);
  1651.        switch (Clicked->GadgetID)
  1652.         {
  1653.          case GID_HIDE:
  1654.           CloseBlankerWindow();
  1655.           break;
  1656.          case GID_QUIT:
  1657.           Quit (0);
  1658.          case GID_BLANK:
  1659.           InitTimeLeft=2L;
  1660.           break;
  1661.          case GID_MODE:
  1662.           DisplayMode=GetIndexMode(ModeList,Code);
  1663.           break;
  1664.          case GID_TIMEOUT:
  1665.           if (GetNum(Clicked,&TimeOut,MAX_TIMEOUT))
  1666.            TimeLeft=InitTimeLeft=10L*TimeOut;
  1667.           break;
  1668.          case GID_CLIENT:
  1669.           GetNum(Clicked,&ClientTimeOut,MAX_CLIENT_TIMEOUT);
  1670.           break;
  1671.          case GID_SPEED:
  1672.           if (Qualifier&(IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT))
  1673.            if (Speed==1L) Speed=MAX_SPEED;
  1674.            else Speed--;
  1675.           else
  1676.            if (Speed==MAX_SPEED) Speed=1L;
  1677.            else Speed++;
  1678.           break;
  1679.          case GID_MOUSE:
  1680.           MouseBlank=1L-MouseBlank;
  1681.           break;
  1682.          case GID_WASPS:
  1683.           NumWasps=Code;
  1684.           break;
  1685.          case GID_BEES:
  1686.           NumBees=Code;
  1687.           break;
  1688.          case GID_TIGHT:
  1689.           Tightness=Code;
  1690.           break;
  1691.          case GID_CYCLE:
  1692.           Cycle=!Cycle;
  1693.           break;
  1694.          case GID_AIMMODE:
  1695.           AimMode=!AimMode;
  1696.           break;
  1697.          case GID_POPKEY:
  1698.           (void)strcpy(PopKey,((struct StringInfo *)
  1699.                                Clicked->SpecialInfo)->Buffer);
  1700.           PopKeyFilter=InstallHotKey(PopKeyFilter,PopKey,EVENT_OPEN_WINDOW,
  1701.                                      DEF_POPKEY);
  1702.           GT_SetGadgetAttrs (Clicked,BlankerWindow,NULL,GTST_String,PopKey,
  1703.                              TAG_DONE);
  1704.           break;
  1705.          case GID_BLANKKEY:
  1706.           (void)strcpy(BlankKey,((struct StringInfo *)
  1707.                                  Clicked->SpecialInfo)->Buffer);
  1708.           BlankKeyFilter=InstallHotKey(BlankKeyFilter,BlankKey,EVENT_BLANK,
  1709.                                        DEF_BLANKKEY);
  1710.           GT_SetGadgetAttrs (Clicked,BlankerWindow,NULL,GTST_String,BlankKey,
  1711.                              TAG_DONE);
  1712.         }
  1713.        break;
  1714.       case IDCMP_MENUPICK:
  1715.        Code=IntMsg->Code;
  1716.        GT_ReplyIMsg (IntMsg);
  1717.        switch (Code)
  1718.         {
  1719.          struct WBStartup *WBenchMsg;
  1720.  
  1721.          case 0xF800:
  1722.           WBenchMsg=(struct WBStartup *)argv;
  1723.           LoadConfig (WBenchMsg->sm_NumArgs?WBenchMsg->sm_ArgList->wa_Name:
  1724.                       NULL);
  1725.           PopKeyFilter=InstallHotKey(PopKeyFilter,PopKey,EVENT_OPEN_WINDOW,
  1726.                                      DEF_POPKEY);
  1727.           BlankKeyFilter=InstallHotKey(BlankKeyFilter,BlankKey,EVENT_BLANK,
  1728.                                        DEF_BLANKKEY);
  1729.           break;
  1730.          case 0xF820:
  1731.           WBenchMsg=(struct WBStartup *)argv;
  1732.           if (WBenchMsg->sm_NumArgs) SaveConfig(WBenchMsg->sm_ArgList->wa_Name);
  1733.           break;
  1734.          case 0xF860:
  1735.           About();
  1736.           break;
  1737.          case 0xF8A0:
  1738.           CloseBlankerWindow();
  1739.           break;
  1740.          case 0xF8C0:
  1741.           Quit (0);
  1742.           break;
  1743.          case 0xF801:
  1744.           LoadConfig (NULL);
  1745.           PopKeyFilter=InstallHotKey(PopKeyFilter,PopKey,EVENT_OPEN_WINDOW,
  1746.                                      DEF_POPKEY);
  1747.           BlankKeyFilter=InstallHotKey(BlankKeyFilter,BlankKey,EVENT_BLANK,
  1748.                                        DEF_BLANKKEY);
  1749.         }
  1750.        break;
  1751.       case IDCMP_VANILLAKEY:
  1752.        Code=IntMsg->Code;
  1753.        GT_ReplyIMsg (IntMsg);
  1754.        switch ((char)Code)
  1755.         {
  1756.          case 'H':
  1757.          case 'h':
  1758.           CloseBlankerWindow();
  1759.           break;
  1760.          case 'Q':
  1761.          case 'q':
  1762.           Quit (0);
  1763.          case 'B':
  1764.          case 'b':
  1765.           InitTimeLeft=2L;
  1766.           break;
  1767.          case 'T':
  1768.          case 't':
  1769.           ActivateGadget (BlankerGadgets[GID_TIMEOUT],BlankerWindow,NULL);
  1770.           break;
  1771.          case 'L':
  1772.          case 'l':
  1773.           ActivateGadget (BlankerGadgets[GID_CLIENT],BlankerWindow,NULL);
  1774.           break;
  1775.          case 'S':
  1776.           if (Speed==1L) Speed=MAX_SPEED;
  1777.           else Speed--;
  1778.           GT_SetGadgetAttrs (BlankerGadgets[GID_SPEED],BlankerWindow,
  1779.                              NULL,GTCY_Active,Speed-1L,TAG_DONE);
  1780.           break;
  1781.          case 's':
  1782.           if (Speed==MAX_SPEED) Speed=1L;
  1783.           else Speed++;
  1784.           GT_SetGadgetAttrs (BlankerGadgets[GID_SPEED],BlankerWindow,
  1785.                              NULL,GTCY_Active,Speed-1L,TAG_DONE);
  1786.           break;
  1787.          case 'W':
  1788.           if (NumWasps>1)
  1789.            {
  1790.             NumWasps--;
  1791.             GT_SetGadgetAttrs (BlankerGadgets[GID_WASPS],BlankerWindow,
  1792.                                NULL,GTSL_Level,NumWasps,TAG_DONE);
  1793.            }
  1794.           break;
  1795.          case 'w':
  1796.           if (NumWasps<MAX_WASPS)
  1797.            {
  1798.             NumWasps++;
  1799.             GT_SetGadgetAttrs (BlankerGadgets[GID_WASPS],BlankerWindow,
  1800.                                NULL,GTSL_Level,NumWasps,TAG_DONE);
  1801.            }
  1802.           break;
  1803.          case 'E':
  1804.           if (NumBees>1)
  1805.            {
  1806.             NumBees--;
  1807.             GT_SetGadgetAttrs (BlankerGadgets[GID_BEES],BlankerWindow,
  1808.                                NULL,GTSL_Level,NumBees,TAG_DONE);
  1809.            }
  1810.           break;
  1811.          case 'e':
  1812.           if (NumBees<MAX_BEES)
  1813.            {
  1814.             NumBees++;
  1815.             GT_SetGadgetAttrs (BlankerGadgets[GID_BEES],BlankerWindow,
  1816.                                NULL,GTSL_Level,NumBees,TAG_DONE);
  1817.            }
  1818.           break;
  1819.          case 'I':
  1820.           if (Tightness>1)
  1821.            {
  1822.             Tightness--;
  1823.             GT_SetGadgetAttrs (BlankerGadgets[GID_TIGHT],BlankerWindow,
  1824.                                NULL,GTSL_Level,Tightness,TAG_DONE);
  1825.            }
  1826.           break;
  1827.          case 'i':
  1828.           if (Tightness<MAX_TIGHTNESS)
  1829.            {
  1830.             Tightness++;
  1831.             GT_SetGadgetAttrs (BlankerGadgets[GID_TIGHT],BlankerWindow,
  1832.                                NULL,GTSL_Level,Tightness,TAG_DONE);
  1833.            }
  1834.           break;
  1835.          case 'C':
  1836.          case 'c':
  1837.           Cycle=!Cycle;
  1838.           GT_SetGadgetAttrs (BlankerGadgets[GID_CYCLE],BlankerWindow,
  1839.                              NULL,GTCB_Checked,Cycle,TAG_DONE);
  1840.           break;
  1841.          case 'A':
  1842.          case 'a':
  1843.           AimMode=!AimMode;
  1844.           GT_SetGadgetAttrs (BlankerGadgets[GID_AIMMODE],BlankerWindow,
  1845.                              NULL,GTCB_Checked,AimMode,TAG_DONE);
  1846.           break;
  1847.          case 'P':
  1848.          case 'p':
  1849.           ActivateGadget (BlankerGadgets[GID_POPKEY],BlankerWindow,NULL);
  1850.           break;
  1851.          case 'K':
  1852.          case 'k':
  1853.           ActivateGadget (BlankerGadgets[GID_BLANKKEY],BlankerWindow,NULL);
  1854.           break;
  1855.          case 'M':
  1856.          case 'm':
  1857.           MouseBlank=1L-MouseBlank;
  1858.           GT_SetGadgetAttrs (BlankerGadgets[GID_MOUSE],BlankerWindow,
  1859.                              NULL,GTCY_Active,MouseBlank,TAG_DONE);
  1860.         }
  1861.        break;
  1862.       default:
  1863.        GT_ReplyIMsg (IntMsg);
  1864.      }
  1865.  
  1866.    /* process Commodity Messages */
  1867.  
  1868.    while (BlankerCxMsg=(CxMsg *)GetMsg(CxPort)) HandleCxMsg (BlankerCxMsg);
  1869.  
  1870.    /* check for <CTRL>-C */
  1871.  
  1872.    if (Mask&SIGBREAKF_CTRL_C) Quit (0);
  1873.  
  1874.    /* Input detected, unblank if necessary */
  1875.  
  1876.    if (Mask&MASK(bsp_InputSig))
  1877.     {
  1878.      if (BlankerScreen)
  1879.       {
  1880.        if (BlankerClientPort) RemTool (BlankerClientPort);
  1881.        RemTool (BlankerScreen);
  1882.        BlankerScreen=NULL;
  1883.        InitTimeLeft=TimeOut*10L;
  1884.        ON_SPRITE
  1885.       }
  1886.      TimeLeft=InitTimeLeft;
  1887.     }
  1888.  
  1889.    /* client has confirmed that it is still alive */
  1890.  
  1891.    if (Mask&MASK(bsp_ClientSig)) TimeLeft=InitTimeLeft;
  1892.  
  1893.    /* time run out */
  1894.  
  1895.    if (TimeLeft==0L)
  1896.     if (BlankerScreen)
  1897.      {
  1898.       TimeLeft=10L; /* check again after on second to keep screen in front */
  1899.       SetRGB4 (&BlankerScreen->ViewPort,BEE_PEN,0,0,0);
  1900.       SetRGB4 (&BlankerScreen->ViewPort,WASP_PEN,0,0,0);
  1901.  
  1902.       if (IntuitionBase->FirstScreen!=BlankerScreen)
  1903.        {
  1904.         ScreenToFront (BlankerScreen);
  1905.         SpritesOff();
  1906.        }
  1907.       /* Client Time Out reached, turn entire screen black */
  1908.      }
  1909.     else
  1910.      {
  1911.       AddTool (BlankerScreen=CreateScreen(ModeList,DisplayMode),
  1912.                CloseScreen,0L);
  1913.       BlankerClientMsg.bcm_Message.mn_Node.ln_Type=NT_MESSAGE;
  1914.       BlankerClientMsg.bcm_Message.mn_Node.ln_Pri=0;
  1915.       BlankerClientMsg.bcm_Message.mn_Length=sizeof(struct BlankerClientMsg);
  1916.       BlankerClientMsg.bcm_Message.mn_ReplyPort=FINDPROCPORT;
  1917.  
  1918.       BlankerClientMsg.bcm_Screen=BlankerScreen;
  1919.       BlankerClientMsg.bcm_SigMask=1L<<bsp_ClientSig;
  1920.       BlankerClientMsg.bcm_Wasps=NumWasps;
  1921.       BlankerClientMsg.bcm_Bees=NumBees;
  1922.       BlankerClientMsg.bcm_Speed=Speed;
  1923.       BlankerClientMsg.bcm_Cycle=Cycle;
  1924.       BlankerClientMsg.bcm_AimMode=AimMode;
  1925.       BlankerClientMsg.bcm_Tightness=Tightness;
  1926.       /* try to start Client */
  1927.       if (BlankerClientPort=CreateBlankerClient(ASwarmClientProcess,
  1928.                                                 &BlankerClientMsg))
  1929.        {
  1930.         TimeLeft=InitTimeLeft=10L*ClientTimeOut;
  1931.         AddTool (BlankerClientPort,DeleteBlankerClient,
  1932.                  (LONG)&BlankerClientMsg);
  1933.        }
  1934.      }
  1935.   }
  1936. }
  1937.