home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 2: PC / frozenfish_august_1995.bin / bbs / d09xx / d0991.lha / ASwarmII / Source / ASwarm.c next >
C/C++ Source or Header  |  1994-04-05  |  60KB  |  2,179 lines

  1. /*
  2.  
  3.    ASwarm II V2.0 - 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.    Now released as MUI Application.
  11.  
  12.    Please leave this source intact. ASwarm is freely distributable,
  13.    but no longer 'Public Domain'. If you have suggestions or Bug-Reports,
  14.    please contact us.
  15.  
  16.    Read the Manuals for known Bugs and Contact-Adresses.
  17.  
  18. */
  19.  
  20. #include <hardware/cia.h>
  21. #include <hardware/custom.h>
  22. #include <hardware/dmabits.h>
  23. #include <exec/memory.h>
  24. #include <exec/ports.h>
  25. #include <exec/execbase.h>
  26. #include <graphics/displayinfo.h>
  27. #include <graphics/gfxbase.h>
  28. #include <graphics/gfxmacros.h>
  29. #include <intuition/intuitionbase.h>
  30. #include <intuition/gadgetclass.h>
  31. #include <libraries/commodities.h>
  32. #include <libraries/gadtools.h>
  33. #include <libraries/mui.h>
  34. #include <workbench/startup.h>
  35. #include <workbench/icon.h>
  36. #include <workbench/workbench.h>
  37. #include <dos/dosextens.h>
  38. #include <dos/dostags.h>
  39. #include <dos/rdargs.h>
  40.  
  41. #include <clib/diskfont_protos.h>
  42. #include <clib/alib_protos.h>
  43. #include <clib/commodities_protos.h>
  44. #include <clib/dos_protos.h>
  45. #include <clib/exec_protos.h>
  46. #include <clib/graphics_protos.h>
  47. #include <clib/icon_protos.h>
  48. #include <clib/intuition_protos.h>
  49. #include <clib/macros.h>
  50. #include <clib/muimaster_protos.h>
  51.  
  52. #include <string.h>
  53. #include <stdlib.h>
  54.  
  55. #ifdef __SASC /* some stuff for SAS-C */
  56.  
  57. #include <pragmas/muimaster_pragmas.h>
  58. #include <pragmas/commodities_pragmas.h>
  59. #include <pragmas/dos_pragmas.h>
  60. #include <pragmas/exec_sysbase_pragmas.h>
  61. #include <pragmas/graphics_pragmas.h>
  62. #include <pragmas/icon_pragmas.h>
  63. #include <pragmas/intuition_pragmas.h>
  64.  
  65. #define VOID_GETA4  void __interrupt __saveds
  66. #define REGARGS(rv) rv __regargs
  67. #define CHIP(dt)    dt __chip
  68. #define ASM(rv)     rv __saveds __asm
  69. #define REG(r)      register __ ## r
  70.  
  71. CxObj *HotKey(UBYTE *,struct MsgPort *,long);
  72. void NewList(struct List *);
  73.  
  74. UBYTE *Version = "$VER: ASwarmáII 2.0 (compiled with SAS/C)";
  75. /* Attention ! ASwarm<ALT SPACE>II ... */
  76.  
  77. void chkabort(void)
  78. {}
  79.  
  80. #else /* some stuff for Dice */
  81.  
  82. #define VOID_GETA4  __stkargs __geta4 void
  83. #define REGARGS(rv) __regargs rv
  84. #define CHIP(dt)    __chip dt
  85. #define ASM(rv)     __geta4 rv
  86. #define REG(r)      __ ## r
  87.  
  88. UBYTE *Version = "$VER: ASwarmáII 2.0 (compiled with DICE)";
  89. /* Attention ! ASwarm<ALT SPACE>II ... */
  90.  
  91. void main(LONG,UBYTE **);
  92.  
  93. void wbmain(struct WBStartup *WBS)
  94.  
  95. {
  96.  if (WBS->sm_NumArgs) (void)CurrentDir(WBS->sm_ArgList->wa_Lock);
  97.  
  98.  main(0L,(UBYTE **)WBS);
  99. }
  100.  
  101. #endif
  102.  
  103. /*
  104.  
  105.    Common Definitions
  106.  
  107. */
  108.  
  109. #define custom (*((struct Custom *)0xDFF000L)) /* Hardwarebangers :-) */
  110. #define ciaa   (*((struct CIA *)0xBFE001L))
  111.  
  112. extern struct ExecBase *SysBase;
  113. extern struct DosLibrary *DOSBase;
  114.  
  115. #define FINDPROCPORT (&((struct Process *)SysBase->ThisTask)->pr_MsgPort)
  116.  
  117. struct IntuitionBase *IntuitionBase;
  118. struct GfxBase *GfxBase;
  119.  
  120. struct Library *CxBase,*MUIMasterBase,*IconBase;
  121.  
  122. LONG WBStarted;
  123.  
  124. #define NUMTOOLTYPES 17
  125.  
  126. char *ToolTypeIDs[NUMTOOLTYPES] =
  127.  {"CX_PRIORITY","CX_POPUP","CX_POPKEY","BLANKKEY",
  128.   "TIMEOUT","CLIENTTIMEOUT",
  129.   "DISPLAY","CYCLE","AIM",
  130.   "WASP","BEES","SPEED","TIGHTNESS",
  131.   "MOUSEBLANKMETHOD","VELOCITY","JOYSTICK","FINALTIMEOUT"};
  132.  
  133. /*
  134.  
  135.    MUI stuff
  136.  
  137. */
  138.  
  139. /* Defines for the Guide-Node-entries */
  140. #define GUIDE_FILE         "ASwarm.guide"
  141. #define NODE_MAIN_MAIN     "EDIT"
  142.  
  143. #define NODE_MAIN_HIDE     "HIDE"
  144. #define NODE_MAIN_BLANK    "BLANK"
  145. #define NODE_MAIN_QUIT     "QUIT"
  146.  
  147. #define NODE_COMM_MAIN     "COMM"
  148. #define NODE_COMM_TIMEOUT  "TIME"
  149. #define NODE_COMM_POPKEY   "POPKEY"
  150. #define NODE_COMM_CLTIME   "CLIENT"
  151. #define NODE_COMM_BLANKKEY "BLANKKEY"
  152. #define NODE_COMM_FITIME   "FINAL"
  153. #define NODE_COMM_JOYSTICK "JOYSTICK"
  154.  
  155. #define NODE_SWARM_MAIN  "OPTIONS"
  156. #define NODE_SWARM_SPEED "SPEED"
  157. #define NODE_SWARM_WASPS "WASPS"
  158. #define NODE_SWARM_BEES  "BEES"
  159. #define NODE_SWARM_VELO  "VELO"
  160. #define NODE_SWARM_TIGHT "TIGHT"
  161. #define NODE_SWARM_COLOR "COLOR"
  162. #define NODE_SWARM_AIM   "AIM"
  163.  
  164. #define NODE_DISPLAY_MAIN     "DISPLAY"
  165. #define NODE_DISPLAY_LIST     "SCREEN"
  166. #define NODE_DISPLAY_MOUSE    "MOUSE"
  167.  
  168. APTR AP_ASwarm,WI_Config;
  169. APTR ST_Time,ST_Pop,ST_Client,ST_Blank,ST_Final;
  170. APTR CY_Speed,CY_Mouse;
  171. APTR SL_Wasps,SL_Bees,SL_Velo,SL_Tight;
  172. APTR CM_Cycle,CM_Aim,CM_JoyStick;
  173. APTR LV_Modes;
  174.  
  175. #define ID_OPEN_WINDOW    1L
  176. #define ID_CLOSE_WINDOW   2L
  177. #define ID_BLANK          3L
  178.  
  179. #define ID_TIMEOUT       10L
  180. #define ID_POPKEY        11L
  181. #define ID_CLIENTTIMEOUT 12L
  182. #define ID_BLANKKEY      13L
  183. #define ID_FINALTIMEOUT  14L
  184. #define ID_JOYSTICK      15L
  185.  
  186. #define ID_SPEED         20L
  187. #define ID_MOUSE         21L
  188. #define ID_WASPS         22L
  189. #define ID_BEES          23L
  190. #define ID_VELOCITY      24L
  191. #define ID_TIGHTNESS     25L
  192. #define ID_CYCLE         26L
  193. #define ID_AIM           27L
  194.  
  195. #define ID_MODES         30L
  196.  
  197. #define ID_LOAD_CONFIG   40L
  198. #define ID_SAVE_CONFIG   41L
  199. #define ID_ABOUT         42L
  200. #define ID_DEFAULTS      43L
  201.  
  202. char *CE_Speed[5],*CE_SpeedPreDef[] =
  203.  {
  204.   "Slow Motion","Very Slow","Slow",
  205.   "Normal","Fast","Very Fast","Incredible"
  206.  };
  207. char *CE_MouseBlank[] = {"Hardware","Window",NULL};
  208.  
  209. struct NewMenu NM_Config[] =
  210.  {NM_TITLE,"Project",NULL,0,0L,NULL,
  211.   NM_ITEM,"Load Config","L",0,0L,(APTR)ID_LOAD_CONFIG,
  212.   NM_ITEM,"Save Config","S",0,0L,(APTR)ID_SAVE_CONFIG,
  213.   NM_ITEM,NM_BARLABEL,NULL,0,0L,NULL,
  214.   NM_ITEM,"About ...",NULL,0,0L,(APTR)ID_ABOUT,
  215.   NM_ITEM,NM_BARLABEL,NULL,0,0L,NULL,
  216.   NM_ITEM,"Hide","H",0,0L,(APTR)ID_CLOSE_WINDOW,
  217.   NM_ITEM,"Quit","Q",0,0L,(APTR)MUIV_Application_ReturnID_Quit,
  218.   NM_TITLE,"Edit",NULL,0,0L,NULL,
  219.   NM_ITEM,"Reset To Defaults","D",0,0L,(APTR)ID_DEFAULTS,
  220.   NM_END,NULL,NULL,0,0L,NULL};
  221.  
  222. /*
  223.  
  224.    Definitions for our Commodity
  225.  
  226. */
  227.  
  228. CxObj *Broker,*PopKeyFilter,*BlankKeyFilter;
  229. struct MsgPort *CxPort;
  230. LONG CxPri,CxPopUp;
  231.  
  232.  
  233. UBYTE PopKey[128],BlankKey[128];
  234. LONG JoyStick;
  235.  
  236. #define EVENT_OPEN_WINDOW 4711L /* What is that number for, Tron ? */
  237. #define EVENT_BLANK       4712L
  238.  
  239. #define DEF_CX_PRI 0L
  240. #define DEF_POPKEY   "CONTROL ALT s"     /* Hot Key for the Edit Window */
  241. #define DEF_BLANKKEY "CONTROL ALT b"     /* Hot Key for immediate Blank */
  242.  
  243. LONG TimeLeft,InitTimeLeft,TimeOut,ClientTimeOut,FinalTimeOut;
  244.  
  245. #define MAX_TIMEOUT        3600L
  246. #define MAX_CLIENT_TIMEOUT 60L
  247. #define MAX_FINAL_TIMEOUT  3600L
  248.  
  249. #define DEF_TIMEOUT        60L
  250. #define DEF_CLIENT_TIMEOUT 5L
  251. #define DEF_FINAL_TIMEOUT  0L
  252.  
  253. #define SERVER_PRI 5L                 /* Don't change this, saves live */
  254. #define CLIENT_PRI -40L
  255.  
  256. /*
  257.  
  258.    Definitions for our Blanker Screen
  259.  
  260. */
  261.  
  262. CHIP(UWORD) EmptyPointer[] = {0,0,0,0}; /* Dummy Pointer when using the
  263.                                            One-Pixel-Window-Trick */
  264.  
  265. struct ModeNode
  266.  {
  267.   struct Node mn_Node;
  268.   UWORD mn_Index;
  269.   ULONG mn_DisplayID;
  270.   char mn_Name[DISPLAYNAMELEN];
  271.  };
  272.  
  273. struct List *ModeList;
  274. struct ModeNode *DisplayMode;
  275.  
  276. #define FindMode(l,n) ((struct ModeNode *)FindName(l,n))
  277.  
  278. #define DEF_MODE      HIRES
  279. #define DEF_MODE_NAME "HighRes"
  280.  
  281. /* Mini and Maximum definitions for possible parameters */
  282.  
  283. #define MAX_SPEED     4L
  284. #define MAX_WASPS     10L
  285. #define MAX_BEES      500L
  286. #define MAX_TIGHTNESS 10L
  287. #define MAX_VEL       15L
  288.  
  289. #define DEF_SPEED     4L
  290. #define DEF_WASPS     2L
  291. #define DEF_BEES      25L
  292. #define DEF_TIGHTNESS 5L
  293. #define DEF_VEL       5L
  294.  
  295. char *Template = /* extra extra extra long :-) */
  296.  "CX_PRIORITY/N/K,CX_POPKEY/K,CX_POPUP/S,BLANKKEY/K,SECONDS=TIMEOUT/N/K,"
  297.  "CLIENTTIMEOUT/N/K,DISPLAY/K,CYCLE/S,AIM/S,WASPS/N/K,BEES/N/K,SPEED/N/K,"
  298.  "TIGHTNESS/N/K,MOUSEBLANKMETHOD/K,VELOCITY/N/K,JOYSTICK/S,FINALTIMEOUT/N/K";
  299.  
  300. /*
  301.  
  302.     Definitions for Server/Client Communication
  303.  
  304. */
  305.  
  306. BYTE bsp_TimeOut,bsp_InputSig,bsp_ClientSig;
  307. struct Task *BlankerServerProcess;
  308.  
  309. #define MASK(n) (1L<<(n))
  310.  
  311. struct BlankerClientMsg
  312.  {
  313.   struct Message bcm_Message;
  314.   struct Screen *bcm_Screen;
  315.   LONG bcm_Status;
  316.   ULONG bcm_SigMask;
  317.   LONG bcm_Wasps,bcm_Bees,bcm_Speed,bcm_Tightness,bcm_Velocity;
  318.   LONG bcm_Cycle,bcm_AimMode,bcm_MouseBlank,bcm_FinalTimeOut;
  319.  } BlankerClientMsg;
  320.  
  321. /*
  322.  
  323.    Definitions or Swarm Movement
  324.  
  325. */
  326.  
  327. #define BEEACC  3
  328. #define BEEVELOC 2
  329. #define WASPACC 5
  330. #define WASPVELOC 5
  331. #define BORDER  20
  332. #define WASPVEL (WASPVELOC+Velocity)
  333. #define BEEVEL  (BEEVELOC+Velocity)
  334.  
  335. #define BEE_PEN  1
  336. #define WASP_PEN 2
  337.  
  338. #define BEE_COL_NUM 33
  339.  
  340. UWORD BeeColors[BEE_COL_NUM] = /* Color Cycling Table */
  341.  {0x000F,0x000F,0x004F,0x008F,0x00BF,0x00FF,0x00FB,0x00F7,0x00F3,0x00F0,0x04F0,
  342.   0x08F0,0x09F0,0x0AF0,0x0BF0,0x0CF0,0x0DF0,0x0EF0,0x0FF0,0x0FE0,0x0FD0,0x0FC0,
  343.   0x0FB0,0x0F90,0x0F80,0x0F70,0x0F60,0x0F50,0x0F40,0x0F30,0x0F20,0x0F10,0x0F00};
  344.  
  345. #define RAND(m) (Random(m)-(m)/2)
  346.  
  347. LONG RandN,RandF,RandI;
  348.  
  349. UWORD SwarmColors[4] = {0x0000,0x0000,0x0FFF,0x0000};
  350. LONG NumWasps,NumBees,Speed,Tightness;
  351. LONG Cycle,AimMode,MouseBlank,Velocity;
  352.  
  353. struct SwarmStruct /* structure for a swarm, including the wasp */
  354.  {
  355.   WORD ss_Width;   /* Width and */
  356.   WORD ss_Height;  /* Height of the used Screen, probably useful for
  357.                       future versions of ASwarm :) */
  358.   WORD ss_NumWasps;/* total number of the Wasps */
  359.   WORD *ss_WX[4];  /* The Wasps x-Position*/  /* WX[3] is used for Velocity */
  360.   WORD *ss_WY[4];  /* Y-Position */
  361.   WORD *ss_NB;     /* No. of Bees following this Wasp */
  362.   WORD ss_NumBees; /* Total (!) number of Bees */
  363.   WORD ss_BeeAcc;  /* Acceleration of the Bees */
  364.   WORD *ss_X[4];   /* The Bees X-Position */  /* X[3] used for Velocity */
  365.   WORD *ss_Y[4];   /* Y-Position */
  366.   WORD *ss_MW;     /* The aimed Wasp */
  367.  };
  368.  
  369. /* Ill's strange Macros for easy access to the above structure */
  370.  
  371. #define BXVel(I)   (SP->ss_X[3][I])
  372. #define BYVel(I)   (SP->ss_Y[3][I])
  373. #define BeeX(P,I)  (SP->ss_X[P][I])
  374. #define BeeY(P,I)  (SP->ss_Y[P][I])
  375. #define MyWasp(I)  (SP->ss_MW[I])
  376.  
  377. #define WaXVel(I)  (SP->ss_WX[3][I])
  378. #define WaYVel(I)  (SP->ss_WY[3][I])
  379. #define WaspX(P,I) (SP->ss_WX[P][I])
  380. #define WaspY(P,I) (SP->ss_WY[P][I])
  381.  
  382. /*
  383.  
  384.     The following functions are taken from my resource tracker library for
  385.     SAS/C. I normally use to link the programs with this library, but to make
  386.     it possible for other people to compile ASwarm II I included the required
  387.     source codes.
  388.  
  389.     - Tron -
  390.  
  391. */
  392.  
  393. struct ToolNode
  394.  {
  395.   struct ToolNode *Next;
  396.   void *Tool;
  397.   void (*RemProc)(void *,LONG); /* requires stack arguments !!! */
  398.   LONG Size;
  399.  } *ToolList;
  400.  
  401. REGARGS(void) RemTool(void *Tool)
  402.  
  403. {
  404.  struct ToolNode **Ptr,*ToolNode;
  405.  
  406.  Ptr=&ToolList;
  407.  while (ToolNode=*Ptr)
  408.   if (ToolNode->Tool==Tool)
  409.    {
  410.     *Ptr=ToolNode->Next;
  411.  
  412.     ToolNode->RemProc(ToolNode->Tool,ToolNode->Size);
  413.     FreeVec (ToolNode);
  414.  
  415.     return; /* This one was missing in ASwarm II V1.0-V1.1 and in
  416.                ASwarm III :-) */
  417.    }
  418.   else Ptr=&ToolNode->Next;
  419. }
  420.  
  421. void RemoveAll(void)
  422.  
  423. {
  424.  while (ToolList) RemTool (ToolList->Tool);
  425. }
  426.  
  427. REGARGS(void) AddTool(void *NewTool,void *ProcPtr,LONG NewSize)
  428.  
  429. {
  430.  struct ToolNode *Ptr;
  431.  void (*NewRemProc)(void *,LONG);
  432.  static BOOL First=TRUE;
  433.  
  434.  NewRemProc=(void (*)(void *,LONG))ProcPtr;
  435.  if (NewTool==NULL) exit (10);
  436.  
  437.  if (First)
  438.   {
  439.    First=FALSE;
  440.    if (atexit(RemoveAll))
  441.     {
  442.      NewRemProc (NewTool,NewSize);
  443.      exit (20);
  444.     }
  445.   }
  446.  
  447.  if ((Ptr=AllocVec(sizeof(struct ToolNode),0L))==NULL)
  448.   {
  449.    NewRemProc (NewTool,NewSize);
  450.    exit (20);
  451.   }
  452.  Ptr->Next=ToolList;
  453.  Ptr->Tool=NewTool;
  454.  Ptr->RemProc=NewRemProc;
  455.  Ptr->Size=NewSize;
  456.  ToolList=Ptr;
  457. }
  458.  
  459. /*
  460.  
  461.    Some useful functions
  462.  
  463. */
  464.  
  465. void MUI_Dispose(APTR Object)
  466.  
  467. {
  468.  MUI_DisposeObject (Object);
  469. }
  470.  
  471. void MUI_DisplayBeep(APTR WI_Any)
  472.  
  473. {
  474.  struct Window *Window;
  475.  
  476.  Window=NULL;
  477.  get (WI_Any,MUIA_Window_Window,&Window);
  478.  if (Window) DisplayBeep (Window->WScreen);
  479. }
  480.  
  481. void DeleteMsgPortSafely(struct MsgPort *AnyPort)
  482.  
  483. {
  484.  struct Message *AnyMsg;
  485.  
  486.  while (AnyMsg=GetMsg(AnyPort)) ReplyMsg (AnyMsg);
  487.  DeleteMsgPort (AnyPort);
  488. }
  489.  
  490. LONG RDArgsLong(LONG Param,LONG Default,LONG Min,LONG Max)
  491.  
  492. {
  493.  LONG *Ptr;
  494.  
  495.  if ((Ptr=(LONG *)Param)==NULL) return Default;
  496.  
  497.  if ((*Ptr<Min)||(*Ptr>Max)) return Default;
  498.  else return *Ptr;
  499. }
  500.  
  501. UWORD PutChar[2] = {0x16C0,0x4E75};
  502.  
  503. /* dirty hack to avoid assembler part :-)
  504.  
  505.    16C0: move.b d0,(a3)+
  506.    4E75: rts
  507. */
  508.  
  509. void SPrintF(char *Buffer,char *FormatString,...)
  510.  
  511. {
  512.  RawDoFmt (FormatString,(APTR)((LONG *)&FormatString+1L),
  513.            (void *)PutChar,Buffer);
  514. }
  515.  
  516. /*
  517.  
  518.    Functions for Handling the List of the avaible Graphics Modes
  519.  
  520. */
  521.  
  522. void DeleteModeList(struct List *ModeList)
  523.  
  524. {
  525.  struct ModeNode *ModeNode;
  526.  
  527.  while (ModeNode=(struct ModeNode *)RemHead(ModeList)) FreeVec (ModeNode);
  528.  
  529.  FreeVec (ModeList);
  530. }
  531.  
  532. struct List *CreateModeList(void)
  533.  
  534. {
  535.  struct List *ModeList;
  536.  UWORD Num;
  537.  ULONG DisplayID;
  538.  struct DimensionInfo DimInfo;
  539.  struct NameInfo NameInfo;
  540.  struct ModeNode *ModeNode;
  541.  
  542.  if (ModeList=AllocVec(sizeof(struct List),MEMF_PUBLIC)) NewList (ModeList);
  543.  else return NULL;
  544.  
  545.  Num=0;
  546.  DisplayID=INVALID_ID;
  547.  while ((DisplayID=NextDisplayInfo(DisplayID))!=INVALID_ID)
  548.   if ((DisplayID&MONITOR_ID_MASK)&&(ModeNotAvailable(DisplayID)==0L))
  549.    if (GetDisplayInfoData(NULL,(UBYTE *)&DimInfo,sizeof(struct DimensionInfo),
  550.                           DTAG_DIMS,DisplayID))
  551.     if (DimInfo.MaxDepth>1)
  552.      if (GetDisplayInfoData(NULL,(UBYTE *)&NameInfo,sizeof(struct NameInfo),
  553.                             DTAG_NAME,DisplayID))
  554.       if (ModeNode=AllocVec(sizeof(struct ModeNode),MEMF_PUBLIC))
  555.        {
  556.         (void)strcpy(ModeNode->mn_Node.ln_Name=ModeNode->mn_Name,
  557.                      NameInfo.Name);
  558.         ModeNode->mn_Index=Num++;
  559.         ModeNode->mn_DisplayID=DisplayID;
  560.         AddTail (ModeList,&ModeNode->mn_Node);
  561.        }
  562.  
  563.  if (ModeList->lh_Head->ln_Succ==NULL)
  564.   if (ModeNode=AllocVec(sizeof(struct ModeNode),MEMF_PUBLIC))
  565.    {
  566.     (void)strcpy(ModeNode->mn_Node.ln_Name=ModeNode->mn_Name,DEF_MODE_NAME);
  567.     ModeNode->mn_Index=Num;
  568.     ModeNode->mn_DisplayID=DEF_MODE;
  569.     AddTail (ModeList,&ModeNode->mn_Node);
  570.    }
  571.   else
  572.    {
  573.     FreeVec (ModeList);
  574.     return NULL;
  575.    }
  576.  
  577.  return ModeList;
  578. }
  579.  
  580. REGARGS(struct ModeNode *) GetDefaultMode(struct List *ModeList)
  581.  
  582. {
  583.  struct NameInfo NameInfo;
  584.  struct ModeNode *ModeNode;
  585.  
  586.  if (GetDisplayInfoData(NULL,(UBYTE *)&NameInfo,sizeof(struct NameInfo),
  587.                         DTAG_NAME,DEF_MODE))
  588.   if (ModeNode=FindMode(ModeList,NameInfo.Name)) return ModeNode;
  589.  
  590.  return (struct ModeNode *)ModeList->lh_Head;
  591. }
  592.  
  593. REGARGS(struct ModeNode *) GetIndexMode(struct List *ModeList,UWORD Index)
  594.  
  595. {
  596.  struct ModeNode *ModeNode;
  597.  
  598.  ModeNode=(struct ModeNode *)ModeList->lh_Head;
  599.  while (ModeNode->mn_Node.ln_Succ)
  600.   if (ModeNode->mn_Index==Index) return ModeNode;
  601.   else ModeNode=(struct ModeNode *)ModeNode->mn_Node.ln_Succ;
  602.  
  603.  return (struct ModeNode *)ModeList->lh_Head;
  604. }
  605.  
  606. /*
  607.  
  608.    "icon.library" Stuff
  609.  
  610. */
  611.  
  612. REGARGS(char *) YesNo(LONG Flag)
  613.  
  614. {
  615.  return Flag?"YES":"NO";
  616. }
  617.  
  618. REGARGS(char *) ToolTypeString(struct DiskObject *DiskObject,char *ID,
  619.                                char *Default)
  620.  
  621. {
  622.  char *String;
  623.  
  624.  if (DiskObject==NULL) return Default;
  625.  
  626.  if (String=FindToolType(DiskObject->do_ToolTypes,ID)) return String;
  627.  else return Default;
  628. }
  629.  
  630. REGARGS(LONG) ToolTypeBoolean(struct DiskObject *DiskObject,char *ID,
  631.                               LONG Default)
  632.  
  633. {
  634.  if (Default) return (stricmp(ToolTypeString(DiskObject,ID,""),
  635.                               YesNo(FALSE))!=0);
  636.  else return (stricmp(ToolTypeString(DiskObject,ID,""),YesNo(TRUE))==0);
  637. }
  638.  
  639. /* should be: REGARGS(LONG) ... but DICE 2.07.54 doesn't like that. */
  640.  
  641. LONG ToolTypeLong(struct DiskObject *DiskObject,char *ID,LONG Default,
  642.                   LONG Min,LONG Max)
  643.  
  644. {
  645.  char *String;
  646.  
  647.  if (DiskObject==NULL) return Default;
  648.  
  649.  if (String=FindToolType(DiskObject->do_ToolTypes,ID))
  650.   {
  651.    LONG Value;
  652.  
  653.    Value=atol(String);
  654.    if ((Value<Min)||(Value>Max)) return Default;
  655.    else return Value;
  656.   }
  657.  else return Default;
  658. }
  659.  
  660. REGARGS(void) LoadConfig(char *Name)
  661.  
  662. {
  663.  struct DiskObject *DiskObject;
  664.  
  665.  if (Name) DiskObject=GetDiskObject(Name);
  666.  else DiskObject=NULL;
  667.  
  668.  CxPri=ToolTypeLong(DiskObject,ToolTypeIDs[0],0L,-128L,127L);
  669.  CxPopUp=ToolTypeBoolean(DiskObject,ToolTypeIDs[1],TRUE);
  670.  (void)strcpy(PopKey,ToolTypeString(DiskObject,ToolTypeIDs[2],DEF_POPKEY));
  671.  (void)strcpy(BlankKey,ToolTypeString(DiskObject,ToolTypeIDs[3],DEF_BLANKKEY));
  672.  
  673.  /* get Time Out, Client Time Out and Display mode */
  674.  
  675.  if ((TimeOut=ToolTypeLong(DiskObject,"SECONDS",0L,1L,MAX_TIMEOUT))==0L)
  676.   TimeOut=ToolTypeLong(DiskObject,ToolTypeIDs[4],DEF_TIMEOUT,1L,MAX_TIMEOUT);
  677.  
  678.  ClientTimeOut=ToolTypeLong(DiskObject,ToolTypeIDs[5],
  679.                             DEF_CLIENT_TIMEOUT,1L,MAX_CLIENT_TIMEOUT);
  680.  FinalTimeOut=ToolTypeLong(DiskObject,ToolTypeIDs[16],
  681.                            DEF_FINAL_TIMEOUT,1L,MAX_FINAL_TIMEOUT);
  682.  
  683.  if ((DisplayMode=FindMode(ModeList,ToolTypeString(DiskObject,ToolTypeIDs[6],
  684.                                                    "")))==NULL)
  685.   DisplayMode=GetDefaultMode(ModeList);
  686.  
  687.  /* get Parameters for Graphics */
  688.  
  689.  Speed=ToolTypeLong(DiskObject,ToolTypeIDs[11],DEF_SPEED,1L,MAX_SPEED);
  690.  if (stricmp(ToolTypeString(DiskObject,ToolTypeIDs[13],""),
  691.              CE_MouseBlank[1])) MouseBlank=0L;
  692.  else MouseBlank=1L;
  693.  
  694.  NumWasps=ToolTypeLong(DiskObject,ToolTypeIDs[9],DEF_WASPS,1L,MAX_WASPS);
  695.  NumBees=ToolTypeLong(DiskObject,ToolTypeIDs[10],DEF_BEES,1L,MAX_BEES);
  696.  Tightness=ToolTypeLong(DiskObject,ToolTypeIDs[12],DEF_TIGHTNESS,1L,
  697.                         MAX_TIGHTNESS);
  698.  Velocity=ToolTypeLong(DiskObject,ToolTypeIDs[14],DEF_VEL,1L,MAX_VEL);
  699.  
  700.  Cycle=ToolTypeBoolean(DiskObject,ToolTypeIDs[7],FALSE);
  701.  AimMode=ToolTypeBoolean(DiskObject,ToolTypeIDs[8],FALSE);
  702.  JoyStick=ToolTypeBoolean(DiskObject,ToolTypeIDs[15],FALSE);
  703.  
  704.  if (WI_Config)
  705.   {
  706.    set (ST_Time,MUIA_String_Integer,TimeOut);
  707.    set (ST_Pop,MUIA_String_Contents,PopKey);
  708.    set (ST_Client,MUIA_String_Integer,ClientTimeOut);
  709.    set (ST_Blank,MUIA_String_Contents,BlankKey);
  710.    set (ST_Final,MUIA_String_Integer,FinalTimeOut);
  711.  
  712.    set (LV_Modes,MUIA_List_Active,DisplayMode->mn_Index);
  713.  
  714.    set (CY_Speed,MUIA_Cycle_Active,Speed-1L);
  715.    set (CY_Mouse,MUIA_Cycle_Active,MouseBlank);
  716.  
  717.    set (SL_Wasps,MUIA_Slider_Level,NumWasps);
  718.    set (SL_Bees,MUIA_Slider_Level,NumBees);
  719.    set (SL_Tight,MUIA_Slider_Level,Tightness);
  720.    set (SL_Velo,MUIA_Slider_Level,Velocity);
  721.  
  722.    set (CM_Cycle,MUIA_Selected,Cycle);
  723.    set (CM_Aim,MUIA_Selected,AimMode);
  724.    set (CM_JoyStick,MUIA_Selected,JoyStick);
  725.   }
  726.  
  727.  if (DiskObject) FreeDiskObject (DiskObject);
  728. }
  729.  
  730. REGARGS(void) SaveConfig(char *Name)
  731.  
  732. {
  733.  struct DiskObject *DiskObject;
  734.  ULONG Index;
  735.  char **NewToolTypes,**NextEntry,**OldToolTypes;
  736.  
  737.  if ((DiskObject=GetDiskObjectNew(Name))==NULL)
  738.   {
  739.    MUI_DisplayBeep (WI_Config);
  740.    return;
  741.   }
  742.  
  743.  Index=0L;
  744.  OldToolTypes=DiskObject->do_ToolTypes;
  745.  while (OldToolTypes[Index]) Index++;
  746.  Index+=NUMTOOLTYPES+1L;
  747.  
  748.  if ((NewToolTypes=(char **)AllocVec(Index*4L+NUMTOOLTYPES*48L,
  749.                                      MEMF_PUBLIC|MEMF_CLEAR))==NULL)
  750.   {
  751.    FreeDiskObject (DiskObject);
  752.    return;
  753.   }
  754.  NextEntry=NewToolTypes;
  755.  
  756.  SPrintF (*NextEntry++=(char *)&NewToolTypes[Index],"%s=%ld",ToolTypeIDs[0],CxPri);
  757.  SPrintF (*NextEntry++=NewToolTypes[0]+48L,"%s=NO",ToolTypeIDs[1]);
  758.  SPrintF (*NextEntry++=NewToolTypes[1]+48L,"%s=%s",ToolTypeIDs[2],PopKey);
  759.  SPrintF (*NextEntry++=NewToolTypes[2]+48L,"%s=%s",ToolTypeIDs[3],BlankKey);
  760.  SPrintF (*NextEntry++=NewToolTypes[3]+48L,"%s=%ld",ToolTypeIDs[4],TimeOut);
  761.  SPrintF (*NextEntry++=NewToolTypes[4]+48L,"%s=%ld",ToolTypeIDs[5],
  762.           ClientTimeOut);
  763.  SPrintF (*NextEntry++=NewToolTypes[5]+48L,"%s=%s",ToolTypeIDs[6],
  764.           DisplayMode->mn_Name);
  765.  SPrintF (*NextEntry++=NewToolTypes[6]+48L,"%s=%s",ToolTypeIDs[7],
  766.           YesNo(Cycle));
  767.  SPrintF (*NextEntry++=NewToolTypes[7]+48L,"%s=%s",ToolTypeIDs[8],
  768.           YesNo(AimMode));
  769.  SPrintF (*NextEntry++=NewToolTypes[8]+48L,"%s=%ld",ToolTypeIDs[9],NumWasps);
  770.  SPrintF (*NextEntry++=NewToolTypes[9]+48L,"%s=%ld",ToolTypeIDs[10],NumBees);
  771.  SPrintF (*NextEntry++=NewToolTypes[10]+48L,"%s=%ld",ToolTypeIDs[11],Speed);
  772.  SPrintF (*NextEntry++=NewToolTypes[11]+48L,"%s=%ld",ToolTypeIDs[12],Tightness);
  773.  SPrintF (*NextEntry++=NewToolTypes[12]+48L,"%s=%s",ToolTypeIDs[13],
  774.           CE_MouseBlank[MouseBlank]);
  775.  SPrintF (*NextEntry++=NewToolTypes[13]+48L,"%s=%ld",ToolTypeIDs[14],Velocity);
  776.  SPrintF (*NextEntry++=NewToolTypes[14]+48L,"%s=%s",ToolTypeIDs[15],YesNo(JoyStick));
  777.  SPrintF (*NextEntry++=NewToolTypes[15]+48L,"%s=%ld",ToolTypeIDs[16],FinalTimeOut);
  778.  
  779.  Index=0L;
  780.  while (OldToolTypes[Index])
  781.   {
  782.    char *Ptr,*Asgn;
  783.  
  784.    if (Ptr=(char *)AllocVec(strlen(OldToolTypes[Index])+1L,0L))
  785.     {
  786.      if (Asgn=strchr(strcpy(Ptr,OldToolTypes[Index]),'=')) *Asgn='\0';
  787.      if (FindToolType(NewToolTypes,Ptr)==NULL) *NextEntry++=OldToolTypes[Index];
  788.      FreeVec (Ptr);
  789.     }
  790.    Index++;
  791.   }
  792.  
  793.  DiskObject->do_ToolTypes=NewToolTypes;
  794.  if (!PutDiskObject(Name,DiskObject)) MUI_DisplayBeep (WI_Config);
  795.  (void)PutDiskObject(Name,DiskObject);
  796.  DiskObject->do_ToolTypes=OldToolTypes;
  797.  
  798.  FreeVec (NewToolTypes);
  799.  FreeDiskObject (DiskObject);
  800. }
  801.  
  802. /*
  803.  
  804.    Our "InputHandler"
  805.  
  806. */
  807.  
  808. #define BIT(w,b) (((w)>>(b))&1)
  809.  
  810. VOID_GETA4 BlankerAction(CxMsg *CxMsg,CxObj *CO)
  811.  
  812. {
  813.  struct InputEvent *IE;
  814.  
  815.  if (JoyStick)
  816.   if (BIT(custom.joy1dat,1)||(BIT(custom.joy1dat,1)^BIT(custom.joy1dat,0))||
  817.       BIT(custom.joy1dat,9)||(BIT(custom.joy1dat,9)^BIT(custom.joy1dat,8))||
  818.       ((ciaa.ciapra&128)==0))
  819.    {
  820.     Signal (BlankerServerProcess,1L<<bsp_InputSig);
  821.     TimeLeft=InitTimeLeft;
  822.    }
  823.  
  824.  IE=(struct InputEvent *)CxMsgData(CxMsg);
  825.  if (IE->ie_Class==IECLASS_TIMER)
  826.   {
  827.    if (TimeLeft)
  828.     {
  829.      TimeLeft--;
  830.      if (TimeLeft==0L) Signal (BlankerServerProcess,1L<<bsp_TimeOut);
  831.     }
  832.   }
  833.  else
  834.   {
  835.    Signal (BlankerServerProcess,1L<<bsp_InputSig);
  836.    TimeLeft=InitTimeLeft;
  837.   }
  838. }
  839.  
  840. /*
  841.  
  842.    Functions for Handling the Configuration Window
  843.  
  844. */
  845.  
  846. LONG GetNum(APTR ST_Object,LONG *Data,LONG Min,LONG Max)
  847.  
  848. {
  849.  LONG NewData;
  850.  
  851.  NewData=*Data;
  852.  get (ST_Object,MUIA_String_Integer,&NewData);
  853.  if ((NewData<Min)||(NewData>Max))
  854.   {
  855.    set (ST_Object,MUIA_String_Integer,*Data);
  856.    return FALSE;
  857.   }
  858.  else
  859.   {
  860.    *Data=NewData;
  861.    return TRUE;
  862.   }
  863. }
  864.  
  865. ASM(LONG) ModeDispFunc(REG(a0) struct Hook *Hook,
  866.                        REG(a2) char **Array,
  867.                        REG(a1) struct ModeNode *ModeNode)
  868.  
  869. {
  870.  *Array=ModeNode->mn_Node.ln_Name;
  871.  return 0L;
  872. }
  873.  
  874. struct Hook HK_Mode = {NULL,NULL,(void *)ModeDispFunc,NULL,NULL};
  875.  
  876. void CloseConfigWindow(void)
  877.  
  878. {
  879.  if (WI_Config)
  880.   {
  881.    set (WI_Config,MUIA_Window_Open,FALSE);
  882.  
  883.    DoMethod (AP_ASwarm,OM_REMMEMBER,WI_Config);
  884.    MUI_DisposeObject (WI_Config);
  885.  
  886.    WI_Config=NULL;
  887.   }
  888. }
  889.  
  890. /* New Makros for KeyLabels with Guide-Nodes */
  891.  
  892. REGARGS(APTR) NodeKeyLabelF(char *Label,char HiChar,char *Node)
  893.  
  894. {
  895.  return TextObject,
  896.          MUIA_Text_PreParse,"\33r",
  897.          MUIA_Text_Contents,Label,
  898.          MUIA_Weight,0,
  899.          MUIA_InnerLeft,0,
  900.          MUIA_InnerRight,0,
  901.          MUIA_Text_HiChar,HiChar,
  902.          MUIA_HelpNode,Node,
  903.         End;
  904. }
  905.  
  906. REGARGS(APTR) NodeKeyLabel1F(char *Label,char HiChar,char *Node)
  907.  
  908. {
  909.  return TextObject,
  910.          MUIA_Text_PreParse,"\33r",
  911.          MUIA_Text_Contents,Label,
  912.          MUIA_Weight,0,
  913.          MUIA_InnerLeft,0,
  914.          MUIA_InnerRight,0,
  915.          MUIA_Text_HiChar,HiChar,
  916.          ButtonFrame,
  917.          MUIA_FramePhantomHoriz,TRUE,
  918.          MUIA_HelpNode,Node,
  919.         End;
  920. }
  921.  
  922. REGARGS(APTR) NodeKeyLabel2F(char *Label,char HiChar,char *Node)
  923.  
  924. {
  925.  return TextObject,
  926.          MUIA_Text_PreParse,"\33r",
  927.          MUIA_Text_Contents,Label,
  928.          MUIA_Weight,0,
  929.          MUIA_InnerLeft,0,
  930.          MUIA_InnerRight,0,
  931.          MUIA_Text_HiChar,HiChar,
  932.          StringFrame,
  933.          MUIA_FramePhantomHoriz,TRUE,
  934.          MUIA_HelpNode,Node,
  935.         End;
  936. }
  937.  
  938. REGARGS(APTR) NodeKeyButtonF(char *Name,char Key,char *Node)
  939.  
  940. {
  941.  return TextObject,
  942.          ButtonFrame,
  943.          MUIA_Text_Contents,Name,
  944.          MUIA_Text_PreParse,"\33c",
  945.          MUIA_Text_HiChar,Key,
  946.          MUIA_ControlChar,Key,
  947.          MUIA_InputMode,MUIV_InputMode_RelVerify,
  948.          MUIA_Background,MUII_ButtonBack,
  949.          MUIA_HelpNode,Node,
  950.         End;
  951. }
  952.  
  953. /* should be: REGARGS(APTR) ... but DICE 2.07.54 doesn't like that. */
  954.  
  955. APTR NodeKeySliderF(LONG Min,LONG Max,LONG Level,char Key,char *Node)
  956.  
  957. {
  958.  return SliderObject,
  959.          MUIA_Slider_Min,Min,
  960.          MUIA_Slider_Max,Max,
  961.          MUIA_Slider_Level,Level,
  962.          MUIA_ControlChar,Key,
  963.          MUIA_HelpNode,Node,
  964.         End;
  965. }
  966.  
  967. REGARGS(APTR) NodeKeyCheckMarkF(LONG Selected,char Control,char *Node)
  968.  
  969. {
  970.  return ImageObject,
  971.          ImageButtonFrame,
  972.          MUIA_InputMode,MUIV_InputMode_Toggle,
  973.          MUIA_Image_Spec,MUII_CheckMark,
  974.          MUIA_Image_FreeVert,TRUE,
  975.          MUIA_Selected,Selected,
  976.          MUIA_Background,MUII_ButtonBack,
  977.          MUIA_ShowSelState,FALSE,
  978.          MUIA_ControlChar,Control,
  979.          MUIA_HelpNode,Node,
  980.         End;
  981. }
  982.  
  983. void OpenConfigWindow(void)
  984.  
  985. {
  986.  ULONG Index;
  987.  APTR BT_Hide,BT_Blank,BT_Quit;
  988.  
  989.  if (WI_Config)
  990.   {
  991.    DoMethod (WI_Config,MUIM_Window_ToFront);
  992.    set (WI_Config,MUIA_Window_Open,TRUE);
  993.  
  994.    return;
  995.   }
  996.  
  997.  if (SysBase->AttnFlags&AFF_68020)
  998.   if (SysBase->AttnFlags&AFF_68030)
  999.    if (SysBase->AttnFlags&AFF_68040) Index=3L;
  1000.    else Index=2L;
  1001.   else Index=1L;
  1002.  else Index=0L;
  1003.  (void)memcpy(&CE_Speed[0],&CE_SpeedPreDef[Index],4L*sizeof(char *));
  1004.  CE_Speed[4]=NULL;
  1005.  
  1006.  if (!WBStarted)
  1007.   {
  1008.    NM_Config[1].nm_Flags|=NM_ITEMDISABLED;
  1009.    NM_Config[2].nm_Flags|=NM_ITEMDISABLED;
  1010.   }
  1011.  
  1012.  if (WI_Config=WindowObject,
  1013.                 MUIA_Window_Title,"ASwarm II V2.0",
  1014.                 MUIA_Window_ID,"CONFIG",
  1015.                 MUIA_Window_Menu,NM_Config,
  1016.                 MUIA_HelpNode, NODE_MAIN_MAIN,
  1017.                 WindowContents,VGroup,
  1018.                  Child,ColGroup(4),GroupFrameT("Commodity Options"),
  1019.                   MUIA_HelpNode,NODE_COMM_MAIN,
  1020.                   Child,NodeKeyLabel2F("Timeout",'t',NODE_COMM_TIMEOUT),
  1021.                   Child,ST_Time=StringObject,
  1022.                    StringFrame,
  1023.                    MUIA_ControlChar,'t',
  1024.                    MUIA_String_Integer,TimeOut,
  1025.                    MUIA_String_Accept,"0123456789",
  1026.                    MUIA_HorizWeight,25,
  1027.                    MUIA_HelpNode,NODE_COMM_TIMEOUT,
  1028.                   End,
  1029.  
  1030.                   Child,NodeKeyLabel2F("Pop Key",'p',NODE_COMM_POPKEY),
  1031.                   Child,ST_Pop=StringObject,
  1032.                    StringFrame,
  1033.                    MUIA_String_Contents,PopKey,
  1034.                    MUIA_String_MaxLen,128L,
  1035.                    MUIA_ControlChar,'p',
  1036.                    MUIA_HelpNode,NODE_COMM_POPKEY,
  1037.                   End,
  1038.  
  1039.                   Child,NodeKeyLabel2F("Client Timeout",'l',NODE_COMM_CLTIME),
  1040.                   Child,ST_Client=StringObject,
  1041.                    StringFrame,
  1042.                    MUIA_ControlChar,'l',
  1043.                    MUIA_String_Integer,ClientTimeOut,
  1044.                    MUIA_String_Accept,"0123456789",
  1045.                    MUIA_HorizWeight,25,
  1046.                    MUIA_HelpNode,NODE_COMM_CLTIME,
  1047.                   End,
  1048.  
  1049.                   Child,NodeKeyLabel2F("Blank Key",'k',NODE_COMM_BLANKKEY),
  1050.                   Child,ST_Blank=StringObject,
  1051.                    StringFrame,
  1052.                    MUIA_String_Contents,BlankKey,
  1053.                    MUIA_String_MaxLen,128L,
  1054.                    MUIA_ControlChar,'k',
  1055.                    MUIA_HelpNode,NODE_COMM_BLANKKEY,
  1056.                   End,
  1057.  
  1058.                   Child,NodeKeyLabel2F("Final Timeout",'f',NODE_COMM_FITIME),
  1059.                   Child,ST_Final=StringObject,
  1060.                    StringFrame,
  1061.                    MUIA_ControlChar,'f',
  1062.                    MUIA_String_Integer,FinalTimeOut,
  1063.                    MUIA_String_Accept,"0123456789",
  1064.                    MUIA_HorizWeight,25,
  1065.                    MUIA_HelpNode,NODE_COMM_FITIME,
  1066.                   End,
  1067.  
  1068.                   Child,NodeKeyLabel1F("JoyStick",'j',NODE_COMM_JOYSTICK),
  1069.                   Child,HGroup,
  1070.                    Child,CM_JoyStick=NodeKeyCheckMarkF(JoyStick,'j',NODE_COMM_JOYSTICK),
  1071.                    Child,RectangleObject,End,
  1072.                    MUIA_HelpNode,NODE_COMM_JOYSTICK,
  1073.                   End,
  1074.                  End,
  1075.                  Child,HGroup,
  1076.                   Child,VGroup,GroupFrameT("Swarm Options"),
  1077.                   MUIA_HelpNode, NODE_SWARM_MAIN,
  1078.                    Child,ColGroup(2),
  1079.                     Child,NodeKeyLabel1F("Speed",'s',NODE_SWARM_SPEED),
  1080.                     Child,CY_Speed=CycleObject,
  1081.                      MUIA_Cycle_Active,Speed-1L,
  1082.                      MUIA_Cycle_Entries,CE_Speed,
  1083.                      MUIA_ControlChar,'s',
  1084.                      MUIA_HelpNode, NODE_SWARM_SPEED,
  1085.                     End,
  1086.  
  1087.                     Child,NodeKeyLabelF("Wasps",'w',NODE_SWARM_WASPS),
  1088.                     Child,SL_Wasps=NodeKeySliderF(1L,MAX_WASPS,NumWasps,'w',NODE_SWARM_WASPS),
  1089.  
  1090.                     Child,NodeKeyLabelF("Bees",'e',NODE_SWARM_BEES),
  1091.                     Child,SL_Bees=NodeKeySliderF(1L,MAX_BEES,NumBees,'e',NODE_SWARM_BEES),
  1092.  
  1093.                     Child,NodeKeyLabelF("Velocity",'v',NODE_SWARM_VELO),
  1094.                     Child,SL_Velo=NodeKeySliderF(1L,MAX_VEL,Velocity,'v',NODE_SWARM_VELO),
  1095.  
  1096.                     Child,NodeKeyLabelF("Tightness",'i',NODE_SWARM_TIGHT),
  1097.                     Child,SL_Tight=NodeKeySliderF(1L,MAX_TIGHTNESS,Tightness,'i',NODE_SWARM_TIGHT),
  1098.  
  1099.                     Child,NodeKeyLabel1F("Color Cycling",'c',NODE_SWARM_COLOR),
  1100.                     Child,CM_Cycle=NodeKeyCheckMarkF(Cycle,'c',NODE_SWARM_COLOR),
  1101.  
  1102.                     Child,NodeKeyLabel1F("Aim",'a',NODE_SWARM_AIM),
  1103.                     Child,CM_Aim=NodeKeyCheckMarkF(AimMode,'a',NODE_SWARM_AIM),
  1104.                    End,
  1105.                    Child,RectangleObject,End,
  1106.                   End,
  1107.                   Child,VGroup,GroupFrameT("Display Options"),MUIA_HelpNode,NODE_DISPLAY_MAIN,
  1108.                    Child,LV_Modes=ListviewObject,
  1109.                     MUIA_Listview_List,ListObject,
  1110.                      MUIA_List_DisplayHook,&HK_Mode,
  1111.                      MUIA_List_AdjustWidth,TRUE,
  1112.                      MUIA_HelpNode,NODE_DISPLAY_LIST,
  1113.                      InputListFrame,
  1114.                     End,
  1115.                    End,
  1116.  
  1117.                    Child,HGroup,
  1118.                     Child,NodeKeyLabel1F("Mouse Blank",'m',NODE_DISPLAY_MOUSE),
  1119.                     Child,CY_Mouse=CycleObject,
  1120.                      MUIA_Cycle_Active,MouseBlank,
  1121.                      MUIA_Cycle_Entries,CE_MouseBlank,
  1122.                      MUIA_ControlChar,'m',
  1123.                      MUIA_HelpNode, NODE_DISPLAY_MOUSE,
  1124.                     End,
  1125.  
  1126.                    End,
  1127.                   End,
  1128.                  End,
  1129.                  Child,HGroup,
  1130.                   Child,BT_Hide=NodeKeyButtonF("Hide",'h',NODE_MAIN_HIDE),
  1131.                   Child,BT_Blank=NodeKeyButtonF("Blank",'b',NODE_MAIN_BLANK),
  1132.                   Child,BT_Quit=NodeKeyButtonF("Quit",'q',NODE_MAIN_QUIT),
  1133.                  End,
  1134.                 End,
  1135.                End)
  1136.  
  1137.   /* Have you seen this? No f*cking macros for GadTools needed to calculate
  1138.      the size and position of gadgets */
  1139.  
  1140.   {
  1141.    struct ModeNode *ModeNode;
  1142.  
  1143.    DoMethod (AP_ASwarm,OM_ADDMEMBER,WI_Config);
  1144.  
  1145.    DoMethod (WI_Config,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,
  1146.              AP_ASwarm,2,MUIM_Application_ReturnID,ID_CLOSE_WINDOW);
  1147.    DoMethod (ST_Time,MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,
  1148.              AP_ASwarm,2,MUIM_Application_ReturnID,ID_TIMEOUT);
  1149.    DoMethod (ST_Pop,MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,
  1150.              AP_ASwarm,2,MUIM_Application_ReturnID,ID_POPKEY);
  1151.    DoMethod (ST_Client,MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,
  1152.              AP_ASwarm,2,MUIM_Application_ReturnID,ID_CLIENTTIMEOUT);
  1153.    DoMethod (ST_Blank,MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,
  1154.              AP_ASwarm,2,MUIM_Application_ReturnID,ID_BLANKKEY);
  1155.    DoMethod (ST_Final,MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,
  1156.              AP_ASwarm,2,MUIM_Application_ReturnID,ID_FINALTIMEOUT);
  1157.    DoMethod (CM_JoyStick,MUIM_Notify,MUIA_Selected,MUIV_EveryTime,
  1158.              AP_ASwarm,2,MUIM_Application_ReturnID,ID_JOYSTICK);
  1159.    DoMethod (CY_Speed,MUIM_Notify,MUIA_Cycle_Active,MUIV_EveryTime,
  1160.              AP_ASwarm,2,MUIM_Application_ReturnID,ID_SPEED);
  1161.    DoMethod (SL_Wasps,MUIM_Notify,MUIA_Slider_Level,MUIV_EveryTime,
  1162.              AP_ASwarm,2,MUIM_Application_ReturnID,ID_WASPS);
  1163.    DoMethod (SL_Bees,MUIM_Notify,MUIA_Slider_Level,MUIV_EveryTime,
  1164.              AP_ASwarm,2,MUIM_Application_ReturnID,ID_BEES);
  1165.    DoMethod (SL_Velo,MUIM_Notify,MUIA_Slider_Level,MUIV_EveryTime,
  1166.              AP_ASwarm,2,MUIM_Application_ReturnID,ID_VELOCITY);
  1167.    DoMethod (SL_Tight,MUIM_Notify,MUIA_Slider_Level,MUIV_EveryTime,
  1168.              AP_ASwarm,2,MUIM_Application_ReturnID,ID_TIGHTNESS);
  1169.    DoMethod (CM_Cycle,MUIM_Notify,MUIA_Selected,MUIV_EveryTime,
  1170.              AP_ASwarm,2,MUIM_Application_ReturnID,ID_CYCLE);
  1171.    DoMethod (CM_Aim,MUIM_Notify,MUIA_Selected,MUIV_EveryTime,
  1172.              AP_ASwarm,2,MUIM_Application_ReturnID,ID_AIM);
  1173.    DoMethod (LV_Modes,MUIM_Notify,MUIA_List_Active,MUIV_EveryTime,
  1174.              AP_ASwarm,2,MUIM_Application_ReturnID,ID_MODES);
  1175.    DoMethod (CY_Mouse,MUIM_Notify,MUIA_Cycle_Active,MUIV_EveryTime,
  1176.              AP_ASwarm,2,MUIM_Application_ReturnID,ID_MOUSE);
  1177.    DoMethod (BT_Hide,MUIM_Notify,MUIA_Pressed,FALSE,
  1178.              AP_ASwarm,2,MUIM_Application_ReturnID,ID_CLOSE_WINDOW);
  1179.    DoMethod (BT_Blank,MUIM_Notify,MUIA_Pressed,FALSE,
  1180.              AP_ASwarm,2,MUIM_Application_ReturnID,ID_BLANK);
  1181.    DoMethod (BT_Quit,MUIM_Notify,MUIA_Pressed,FALSE,
  1182.              AP_ASwarm,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);
  1183.  
  1184.    DoMethod (WI_Config,MUIM_Window_SetCycleChain,
  1185.              ST_Time,ST_Pop,ST_Client,ST_Blank,ST_Final,CM_JoyStick,
  1186.              CY_Speed,SL_Wasps,SL_Bees,SL_Velo,SL_Tight,CM_Cycle,CM_Aim,
  1187.              LV_Modes,CY_Mouse,
  1188.              BT_Hide,BT_Blank,BT_Quit,NULL);
  1189.  
  1190.    ModeNode=(struct ModeNode *)ModeList->lh_Head;
  1191.    while (ModeNode->mn_Node.ln_Succ)
  1192.     {
  1193.      DoMethod (LV_Modes,MUIM_List_Insert,&ModeNode,1L,MUIV_List_Insert_Bottom);
  1194.      ModeNode=(struct ModeNode *)ModeNode->mn_Node.ln_Succ;
  1195.     }
  1196.  
  1197.    set (WI_Config,MUIA_Window_Open,TRUE);
  1198.  
  1199.    set (LV_Modes,MUIA_List_Active,DisplayMode->mn_Index);
  1200.   }
  1201.  
  1202.  DoMethod (WI_Config,MUIM_Window_ScreenToFront);
  1203.  DoMethod (WI_Config,MUIM_Window_ToFront);
  1204.  
  1205.  set (WI_Config,MUIA_Window_Open,TRUE);
  1206.  
  1207. }
  1208.  
  1209. void About(void)
  1210.  
  1211. {
  1212.  (void)MUI_Request(AP_ASwarm,WI_Config,0L, "About","*Ok",
  1213.                    "\33cASwarm II V2.0 - The Original One\n"
  1214.                    "(c) 1992-1994 by Markus Illenseer and Matthias Scheler\n"
  1215.                    "\33cThis program is freely distributable.\n\n"
  1216.                    "\33cThis is a MUI Application.",TAG_END);
  1217. }
  1218.  
  1219. /*
  1220.  
  1221.    Function to handle the Commodity Stuff
  1222.  
  1223. */
  1224.  
  1225. ASM(void) CxDispatcher(REG(a0) struct Hook *Hook,
  1226.                        REG(a2) APTR AP_Object,
  1227.                        REG(a1) CxMsg *CxMsg)
  1228.  
  1229. {
  1230.  ULONG MsgType,MsgID;
  1231.  
  1232.  MsgType=CxMsgType(CxMsg);
  1233.  MsgID=CxMsgID(CxMsg);
  1234.  
  1235.  switch (MsgType)
  1236.   {
  1237.    case CXM_IEVENT:
  1238.     if (MsgID==EVENT_BLANK) DoMethod (AP_Object,MUIM_Application_ReturnID,ID_BLANK);
  1239.     else DoMethod (AP_Object,MUIM_Application_ReturnID,ID_OPEN_WINDOW);
  1240.     break;
  1241.    case CXM_COMMAND:
  1242.     switch (MsgID)
  1243.      {
  1244.       case CXCMD_UNIQUE:
  1245.        DoMethod (AP_Object,MUIM_Application_ReturnID,ID_OPEN_WINDOW);
  1246.      }
  1247.   }
  1248. }
  1249.  
  1250. struct Hook HK_Broker = {NULL,NULL,(void *)CxDispatcher,NULL,NULL};
  1251.  
  1252. REGARGS(CxObj *) InstallHotKey(CxObj *Filter,char *Describ,LONG Event,
  1253.                                char *Default)
  1254.  
  1255. {
  1256.  if (Filter)
  1257.   {
  1258.    RemoveCxObj (Filter);
  1259.    DeleteCxObj (Filter);
  1260.   }
  1261.  
  1262.  if (Filter=HotKey(Describ,CxPort,Event))
  1263.   if (CxObjError(Filter)==0L)
  1264.    {
  1265.     AttachCxObj (Broker,Filter);
  1266.     return Filter;
  1267.    }
  1268.   else DeleteCxObj (Filter);
  1269.  
  1270.  if (Filter=HotKey(Default,CxPort,Event))
  1271.   if (CxObjError(Filter)==0L)
  1272.    {
  1273.     AttachCxObj (Broker,Filter);
  1274.     (void)strcpy(Describ,Default);
  1275.     return Filter;
  1276.    }
  1277.   else DeleteCxObj (Filter);
  1278.  
  1279.  (void)strcpy(Describ,"<NONE>");
  1280.  return NULL;
  1281. }
  1282.  
  1283. /*
  1284.  
  1285.    Hooks for ARexx Port
  1286.  
  1287. */
  1288.  
  1289. ASM(LONG) RxEnable(REG(a0) struct Hook *Hook,
  1290.                    REG(a2) APTR AP_Object,
  1291.                    REG(a1) LONG *Array)
  1292.  
  1293. {
  1294.  (void)ActivateCxObj(Broker,TRUE);
  1295.  
  1296.  return 0L;
  1297. }
  1298.  
  1299. struct Hook HK_RxEnable = {NULL,NULL,(void *)RxEnable,NULL,NULL};
  1300.  
  1301. ASM(LONG) RxDisable(REG(a0) struct Hook *Hook,
  1302.                     REG(a2) APTR AP_Object,
  1303.                     REG(a1) LONG *Array)
  1304.  
  1305. {
  1306.  (void)ActivateCxObj(Broker,FALSE);
  1307.  Signal (BlankerServerProcess,1L<<bsp_InputSig);
  1308.  
  1309.  return 0L;
  1310. }
  1311.  
  1312. struct Hook HK_RxDisable = {NULL,NULL,(void *)RxDisable,NULL,NULL};
  1313.  
  1314. struct MUI_Command ASwarmRexxCommands[] =
  1315.  {
  1316.   {"openwindow",MC_TEMPLATE_ID,ID_OPEN_WINDOW,NULL},
  1317.   {"closewindow",MC_TEMPLATE_ID,ID_CLOSE_WINDOW,NULL},
  1318.   {"enable",NULL,0L,&HK_RxEnable},
  1319.   {"disable",NULL,0L,&HK_RxDisable},
  1320.   {"blank",MC_TEMPLATE_ID,ID_BLANK,NULL},
  1321.   {NULL,NULL,NULL,NULL}
  1322.  };
  1323.  
  1324.  
  1325. /*
  1326.  
  1327.    Functions fore Creating/Deleting the Client Process
  1328.  
  1329. */
  1330.  
  1331. void DeleteBlankerClient(struct MsgPort *BlankerClientPort,
  1332.                          struct BlankerClientMsg *BlankerClientMsg)
  1333.  
  1334. {
  1335.  Forbid();
  1336.  PutMsg (BlankerClientPort,(struct Message *)BlankerClientMsg);
  1337.  (void)SetTaskPri(BlankerClientPort->mp_SigTask,SERVER_PRI+1L);
  1338.  Permit();
  1339.  
  1340.  (void)WaitPort(BlankerClientMsg->bcm_Message.mn_ReplyPort);
  1341.  (void)GetMsg(BlankerClientMsg->bcm_Message.mn_ReplyPort);
  1342. }
  1343.  
  1344. REGARGS(struct MsgPort *) CreateBlankerClient(void *CodePtr,
  1345.                                      struct BlankerClientMsg *BlankerClientMsg)
  1346.  
  1347. {
  1348.  struct Process *BlankerClientProcess;
  1349.  
  1350.  if (BlankerClientProcess=CreateNewProcTags(NP_Entry,CodePtr,
  1351.                                             NP_Name,"BlankerClient",
  1352.                                             NP_StackSize,4000L,TAG_DONE))
  1353.   {
  1354.    PutMsg (&BlankerClientProcess->pr_MsgPort,
  1355.            (struct Message *)BlankerClientMsg);
  1356.  
  1357.    (void)WaitPort(BlankerClientMsg->bcm_Message.mn_ReplyPort);
  1358.    (void)GetMsg(BlankerClientMsg->bcm_Message.mn_ReplyPort);
  1359.  
  1360.    (void)SetTaskPri((struct Task *)BlankerClientProcess,CLIENT_PRI);
  1361.  
  1362.    if (BlankerClientMsg->bcm_Status) return &BlankerClientProcess->pr_MsgPort;
  1363.   }
  1364.  return NULL;
  1365. }
  1366.  
  1367. /*
  1368.  
  1369.    Open a Screen with the supplied DisplayID
  1370.  
  1371. */
  1372.  
  1373. REGARGS(void) SpritesOff(struct Screen *BlankerScreen)
  1374.  
  1375. {
  1376.  ULONG Index;
  1377.  
  1378.  if (!MouseBlank)
  1379.   {
  1380.    OFF_SPRITE /* switch sprites off */
  1381.    for (Index=0L; Index<8L; Index++) custom.spr[Index].ctl=0;
  1382.   }
  1383.  else /* reactivate our window to show our null mouse pointer */
  1384.   if (BlankerScreen->FirstWindow) ActivateWindow (BlankerScreen->FirstWindow);
  1385. }
  1386.  
  1387. REGARGS(struct Screen *) CreateScreen(struct List *ModeList,struct ModeNode *ModeNode)
  1388.  
  1389. {
  1390.  struct Screen *Screen;
  1391.  
  1392.  if (Screen=OpenScreenTags(NULL,
  1393.                            SA_Depth,2,
  1394.                            SA_Title,"ASwarm II",
  1395.                            SA_DisplayID,ModeNode->mn_DisplayID,
  1396.                            SA_Quiet,TRUE,TAG_DONE))
  1397.   {
  1398.    SetRGB4 (&Screen->ViewPort,0,0,0,0);
  1399.    SetRast (&Screen->RastPort,0);
  1400.  
  1401.    SpritesOff (Screen);
  1402.   }
  1403.  return Screen;
  1404. }
  1405.  
  1406. /*
  1407.  
  1408.    Functions for Creating/Drawing/Removing the Swarms
  1409.  
  1410. */
  1411.  
  1412. void InitRandom(void)
  1413.  
  1414. {
  1415.  ULONG Time[2];
  1416.  
  1417.  CurrentTime (&Time[0],&Time[1]);
  1418.  RandN=(LONG)Time[0];
  1419.  if (Time[1]<1000L)
  1420.   {
  1421.    RandF=4*Time[1]+1;
  1422.    RandI=2*Time[1]+1;
  1423.   }
  1424.  else
  1425.   {
  1426.    RandF=4*(Time[1]/1000L)+1;
  1427.    RandI=2*(Time[1]/1000L)+1;
  1428.   }
  1429. }
  1430.  
  1431. REGARGS(WORD) Random(WORD Max)
  1432.  
  1433. {
  1434.  RandN=RandF*RandN+RandI;
  1435.  if (RandN<0L) RandN=-RandN;
  1436.  
  1437.  return (WORD)(RandN%Max);
  1438. }
  1439.  
  1440. BYTE SquareRootTab[256] = /* The mighty 256 Bytes eater :-) */
  1441.  {0,1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,
  1442.   4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,
  1443.   5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,
  1444.   6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  1445.   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
  1446.   8,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
  1447.   9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,
  1448.   10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,
  1449.   11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
  1450.   12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
  1451.   12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,
  1452.   13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
  1453.   13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14,
  1454.   14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
  1455.   14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
  1456.   15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15};
  1457.  
  1458.  
  1459. REGARGS(LONG) FastSQRT(LONG x) /* *Grin* Nice idea, Tron */
  1460.  
  1461. {
  1462.  LONG sr;
  1463.  
  1464.  sr=1L;
  1465.  while (x>255L)
  1466.   {
  1467.    x/=4L;
  1468.    sr*=2L;
  1469.   }
  1470.  return sr*(LONG)SquareRootTab[x];
  1471. }
  1472.  
  1473. REGARGS(ULONG) SwarmSize(LONG NumWaps,LONG NumBees)
  1474.  
  1475. {
  1476.  return sizeof(struct SwarmStruct)+sizeof(WORD)*((ULONG)NumWaps*9L+
  1477.                                    (ULONG)NumBees*9L);
  1478. }
  1479.  
  1480. /* should be: REGARGS(...) ... but DICE 2.07.54 doesn't like that. */
  1481.  
  1482. struct SwarmStruct *CreateSwarms(struct Screen *SwarmScreen,
  1483.                                  LONG NumWasps,LONG NumBees,
  1484.                                  LONG Speed,LONG Tightness)
  1485.  
  1486. /* allocate Memory and initialize the Swarm(s) */
  1487.  
  1488. {
  1489.  LONG Index;
  1490.  struct SwarmStruct *SP;
  1491.  WORD *Ptr;
  1492.  
  1493.  if ((SP=AllocVec(SwarmSize(NumWasps,NumBees),0L))==NULL) return NULL;
  1494.  
  1495.  SP->ss_NumWasps=NumWasps;
  1496.  SP->ss_NumBees=NumBees;
  1497.  SP->ss_Width=SwarmScreen->Width;    /* Will probably be changed in a */
  1498.  SP->ss_Height=SwarmScreen->Height;  /* future version of ASwarm */
  1499.  SP->ss_BeeAcc=(Tightness*BEEACC)/MAX_SPEED+1;
  1500.  
  1501.  Ptr=(WORD *)&SP[1];
  1502.  for (Index=0L; Index<4L; Index++)
  1503.   {
  1504.    SP->ss_WX[Index]=Ptr;
  1505.    Ptr+=NumWasps;
  1506.    SP->ss_WY[Index]=Ptr;
  1507.    Ptr+=NumWasps;
  1508.    SP->ss_X[Index]=Ptr;
  1509.    Ptr+=NumBees;
  1510.    SP->ss_Y[Index]=Ptr;
  1511.    Ptr+=NumBees;
  1512.   }
  1513.  SP->ss_NB=Ptr;
  1514.  SP->ss_MW=Ptr+NumWasps;
  1515.  
  1516.  /* Wasps */
  1517.  for (Index=0L; Index<NumWasps; Index++)
  1518.   {
  1519.    WaspX(1,Index)=WaspX(0,Index)=BORDER+Random(SP->ss_Width-2*BORDER);
  1520.    WaspY(1,Index)=WaspY(0,Index)=BORDER+Random(SP->ss_Height-2*BORDER);
  1521.    WaXVel(Index)=RAND(WASPACC);
  1522.    WaYVel(Index)=RAND(WASPACC);
  1523.    SP->ss_NB[Index]=0;
  1524.   }
  1525.  
  1526.  /* Bees */
  1527.  for (Index=0L; Index<SP->ss_NumBees; Index++)
  1528.   {
  1529.    BeeX(1,Index)=BeeX(0,Index)=BORDER+Random(SP->ss_Width-2*BORDER);
  1530.    BeeY(1,Index)=BeeY(0,Index)=BORDER+Random(SP->ss_Height-2*BORDER);
  1531.    BXVel(Index)=RAND(SP->ss_BeeAcc);
  1532.    BYVel(Index)=RAND(SP->ss_BeeAcc);
  1533.    SP->ss_NB[MyWasp(Index)=Index%SP->ss_NumWasps]++;
  1534.   }
  1535.  
  1536.  return SP;
  1537. }
  1538.  
  1539. /* move Swarms and redraw it */
  1540.  
  1541. REGARGS(void) DrawSwarms(struct RastPort *RP,struct SwarmStruct *SP,
  1542.                          LONG AimMode,LONG Velocity)
  1543.  
  1544. {
  1545.  LONG Index;
  1546.  
  1547.  /* Wasps */
  1548.  
  1549.  for (Index=0L; Index<SP->ss_NumWasps; Index++)
  1550.   {
  1551.    WaspX(2,Index)=WaspX(1,Index);
  1552.    WaspX(1,Index)=WaspX(0,Index);
  1553.    WaspY(2,Index)=WaspY(1,Index);
  1554.    WaspY(1,Index)=WaspY(0,Index);
  1555.  
  1556.    WaXVel(Index)+=RAND(WASPACC);
  1557.    WaYVel(Index)+=RAND(WASPACC);
  1558.  
  1559.    if (WaXVel(Index)>WASPVEL) WaXVel(Index)=WASPVEL;
  1560.    if (WaXVel(Index)<-WASPVEL) WaXVel(Index)=-WASPVEL;
  1561.    if (WaYVel(Index)>WASPVEL) WaYVel(Index)=WASPVEL;
  1562.    if (WaYVel(Index)<-WASPVEL) WaYVel(Index)=-WASPVEL;
  1563.  
  1564.    WaspX(0,Index)=WaspX(1,Index)+WaXVel(Index);
  1565.    WaspY(0,Index)=WaspY(1,Index)+WaYVel(Index);
  1566.  
  1567.    /* Bounce check for Wasps */
  1568.  
  1569.    if ((WaspX(0,Index)<BORDER)||(WaspX(0,Index)>SP->ss_Width-BORDER-1))
  1570.     {
  1571.      WaXVel(Index)=-WaXVel(Index);
  1572. /*
  1573.      if (WaspX(0,Index)<BORDER) WaspX(0,Index)=BORDER;
  1574.      else WaspX(0,Index)=SP->ss_Width-BORDER-1;
  1575. */
  1576.      WaspX(0,Index)+=WaXVel(Index);
  1577.     }
  1578.    if ((WaspY(0,Index)<BORDER)||(WaspY(0,Index)>SP->ss_Height-BORDER-1))
  1579.     {
  1580.      WaYVel(Index)=-WaYVel(Index);
  1581. /*
  1582.      if (WaspY(0,Index)<BORDER) WaspY(0,Index)=BORDER;
  1583.      else WaspY(0,Index)=SP->ss_Height-BORDER-1;
  1584. */
  1585.      WaspY(0,Index)+=WaYVel(Index);
  1586.     }
  1587.   }
  1588.  
  1589.  /* Bees */
  1590.  
  1591.  for (Index=0L; Index<SP->ss_NumBees; Index++)
  1592.   {
  1593.    WORD DX,DY,ChkIndex;
  1594.    LONG Distance,NewDistance;
  1595.  
  1596.    BeeX(2,Index)=BeeX(1,Index);
  1597.    BeeX(1,Index)=BeeX(0,Index);
  1598.    BeeY(2,Index)=BeeY(1,Index);
  1599.    BeeY(1,Index)=BeeY(0,Index);
  1600.  
  1601.    DX=WaspX(1,MyWasp(Index))-BeeX(1,Index);
  1602.    DY=WaspY(1,MyWasp(Index))-BeeY(1,Index);
  1603.    Distance=FastSQRT(DX*DX+DY*DY);
  1604.    if (Distance==0L) Distance=1L;
  1605.  
  1606.    if (AimMode) /* Look out for the nearest wasp if Aim-Mode is on */
  1607.     for (ChkIndex=0; ChkIndex<=SP->ss_NumWasps; ChkIndex++)
  1608.      if (ChkIndex!=MyWasp(Index))
  1609.       {
  1610.        LONG NewDX,NewDY;
  1611.  
  1612.        NewDX=WaspX(1,ChkIndex)-BeeX(1,Index);
  1613.        NewDY=WaspY(1,ChkIndex)-BeeY(1,Index);
  1614.        NewDistance=FastSQRT(NewDX*NewDX+NewDY*NewDY);
  1615.        if (Distance>NewDistance)
  1616.         {
  1617.          DX=NewDX;
  1618.          DY=NewDY;
  1619.          if (NewDistance==0L) Distance=1L;
  1620.          else Distance=NewDistance;
  1621.          SP->ss_NB[MyWasp(Index)]--;
  1622.          SP->ss_NB[MyWasp(Index)=ChkIndex]++; /* Mark a nearer Wasp */
  1623.         }
  1624.       }
  1625.  
  1626.    BXVel(Index)+=(DX*SP->ss_BeeAcc)/Distance+RAND(3);
  1627.    BYVel(Index)+=(DY*SP->ss_BeeAcc)/Distance+RAND(3);
  1628.  
  1629.    if (BXVel(Index)>BEEVEL)  BXVel(Index)=BEEVEL;
  1630.    if (BXVel(Index)<-BEEVEL) BXVel(Index)=-BEEVEL;
  1631.    if (BYVel(Index)>BEEVEL)  BYVel(Index)=BEEVEL;
  1632.    if (BYVel(Index)<-BEEVEL) BYVel(Index)=-BEEVEL;
  1633.  
  1634.    BeeX(0,Index)=BeeX(1,Index)+BXVel(Index);
  1635.    BeeY(0,Index)=BeeY(1,Index)+BYVel(Index);
  1636.  
  1637.   /* Bounce check for Bees */
  1638.  
  1639.    if ((BeeX(0,Index)<BORDER)||(BeeX(0,Index)>(SP->ss_Width-BORDER-1)))
  1640.     {
  1641.      BXVel(Index)=-BXVel(Index);
  1642. /*
  1643.      BeeX(0,Index)=BeeX(1,Index)+BXVel(Index);
  1644. */
  1645.      BeeX(0,Index)+=BXVel(Index);
  1646.     }
  1647.    if ((BeeY(0,Index)<BORDER)||(BeeY(0,Index)>(SP->ss_Height-BORDER-1)))
  1648.     {
  1649.      BYVel(Index)=-BYVel(Index);
  1650. /*
  1651.      BeeY(0,Index)=BeeY(1,Index)+BYVel(Index);
  1652. */
  1653.      BeeY(0,Index)+=BYVel(Index);
  1654.     }
  1655.   }
  1656.  
  1657.  
  1658.  /* Move our insects */
  1659.  
  1660.  for (Index=0L; Index<SP->ss_NumWasps; Index++)   /* Wasps */
  1661.   {
  1662.    SetAPen (RP,0);
  1663.    Move (RP,WaspX(2,Index),WaspY(2,Index));
  1664.    Draw (RP,WaspX(1,Index),WaspY(1,Index));
  1665.  
  1666.    if(WaspX(0,Index)<0 || WaspX(0,Index)>SP->ss_Width ||
  1667.       WaspY(0,Index)<0 || WaspY(0,Index)>SP->ss_Height) goto DoNotDraw;
  1668.  
  1669.  
  1670.    SetAPen (RP,WASP_PEN);
  1671.    Draw (RP,WaspX(0,Index),WaspY(0,Index));
  1672.  
  1673. DoNotDraw:
  1674.    ;
  1675.   }
  1676.  
  1677.  for (Index=0L; Index<SP->ss_NumBees; Index++)   /* Bees  */
  1678.   {
  1679.    SetAPen (RP,0);
  1680.    Move (RP,BeeX(2,Index),BeeY(2,Index));
  1681.    Draw (RP,BeeX(1,Index),BeeY(1,Index));
  1682.  
  1683.    if(BeeX(0,Index)<0 || BeeX(0,Index)>SP->ss_Width || 
  1684.       BeeY(0,Index)<0 || BeeY(0,Index)>SP->ss_Height) goto DoNotDraw2;
  1685.  
  1686.    SetAPen (RP,BEE_PEN);
  1687.    Draw (RP,BeeX(0,Index),BeeY(0,Index));
  1688.  
  1689. DoNotDraw2:
  1690.    ;
  1691.  
  1692.   }
  1693. }
  1694.  
  1695. /*
  1696.  
  1697.    This is the Client Process's Main Loop
  1698.  
  1699. */
  1700.  
  1701. VOID_GETA4 ASwarmClientProcess(void)
  1702.  
  1703. {
  1704.  struct BlankerClientMsg *BlankerClientMsg;
  1705.  struct MsgPort *BlankerClientPort;
  1706.  struct Task *BlankerServerTask;
  1707.  ULONG BlankerServerSigMask,Seconds,Micros,EndTime;
  1708.  struct Screen *SwarmScreen;
  1709.  LONG NumWasps,NumBees,Speed,Cycle,AimMode,Count,Tightness;
  1710.  struct SwarmStruct *Swarms;
  1711.  WORD Color,DColor;
  1712.  
  1713.  /* wait for Server's initial Message */
  1714.  
  1715.  BlankerClientPort=FINDPROCPORT;
  1716.  (void)WaitPort(BlankerClientPort);
  1717.  BlankerClientMsg=(struct BlankerClientMsg *)GetMsg(BlankerClientPort);
  1718.  
  1719.  BlankerServerTask=BlankerClientMsg->bcm_Message.mn_ReplyPort->mp_SigTask;
  1720.  BlankerServerSigMask=BlankerClientMsg->bcm_SigMask;
  1721.  
  1722.  NumWasps=BlankerClientMsg->bcm_Wasps;
  1723.  NumBees=BlankerClientMsg->bcm_Bees;
  1724.  SwarmScreen=BlankerClientMsg->bcm_Screen;
  1725.  Speed=BlankerClientMsg->bcm_Speed;
  1726.  Cycle=BlankerClientMsg->bcm_Cycle;
  1727.  AimMode=BlankerClientMsg->bcm_AimMode;
  1728.  Tightness=BlankerClientMsg->bcm_Tightness;
  1729.  Velocity=BlankerClientMsg->bcm_Velocity;
  1730.  
  1731.  if (BlankerClientMsg->bcm_FinalTimeOut)
  1732.   {
  1733.    CurrentTime (&Seconds,&Micros);
  1734.    EndTime=Seconds+BlankerClientMsg->bcm_FinalTimeOut;
  1735.   }
  1736.  else EndTime=0L;
  1737.  
  1738.  /* init pseudo random number generator */
  1739.  
  1740.  InitRandom();
  1741.  
  1742.  /* initialize requested Number of Swarms */
  1743.  
  1744.  if ((Swarms=CreateSwarms(SwarmScreen,NumWasps,NumBees,Speed,Tightness))==NULL)
  1745.   {
  1746.    BlankerClientMsg->bcm_Status=FALSE;
  1747.    Forbid();
  1748.    ReplyMsg ((struct Message *)BlankerClientMsg);
  1749.    return;
  1750.   }
  1751.  BlankerClientMsg->bcm_Status=TRUE;
  1752.  ReplyMsg ((struct Message *)BlankerClientMsg);
  1753.  
  1754.  Color=BEE_COL_NUM-1;
  1755.  DColor=Cycle?1:0;
  1756.  Count=Speed;
  1757.  
  1758.  while ((BlankerClientMsg=(struct BlankerClientMsg *)
  1759.                            GetMsg(BlankerClientPort))==NULL)
  1760.   {
  1761.    /* Color Cycling */
  1762.  
  1763.    SwarmColors[BEE_PEN]=BeeColors[Color];
  1764.    LoadRGB4 (&SwarmScreen->ViewPort,SwarmColors,4);
  1765.    Color+=DColor;
  1766.    if ((Color==-1)||(Color==BEE_COL_NUM))
  1767.     {
  1768.      DColor=-DColor;
  1769.      Color+=2*DColor;
  1770.     }
  1771.  
  1772.    /* Synchronisation */
  1773.  
  1774.    SpritesOff (SwarmScreen);
  1775.    WaitTOF();
  1776.    if (Count<MAX_SPEED)
  1777.     {
  1778.      Count++;
  1779.      continue;
  1780.     }
  1781.    Count=Speed;
  1782.  
  1783.    /* Move the Swarm(s) */
  1784.  
  1785.    DrawSwarms (&SwarmScreen->RastPort,Swarms,AimMode,Velocity);
  1786.    if (IntuitionBase->FirstScreen!=SwarmScreen)
  1787.     {
  1788.      ScreenToFront (SwarmScreen);
  1789.      SpritesOff (SwarmScreen);
  1790.     }
  1791.    Signal (BlankerServerTask,BlankerServerSigMask);
  1792.  
  1793.    if (EndTime)
  1794.     {
  1795.      CurrentTime (&Seconds,&Micros);
  1796.      if (Seconds>=EndTime) /* final timeout reached, turn screen black */
  1797.       {
  1798.        SetRGB4 (&SwarmScreen->ViewPort,BEE_PEN,0,0,0);
  1799.        SetRGB4 (&SwarmScreen->ViewPort,WASP_PEN,0,0,0);
  1800.        (void)WaitPort(BlankerClientPort);
  1801.       }
  1802.     }
  1803.   }
  1804.  FreeVec (Swarms);
  1805.  
  1806.  /* We are requested to finish, so we do. */
  1807.  
  1808.  Forbid();
  1809.  ReplyMsg ((struct Message *)BlankerClientMsg);
  1810. }
  1811.  
  1812. /*
  1813.  
  1814.    The Main Loop
  1815.  
  1816. */
  1817.  
  1818. void main(LONG argc,UBYTE **argv)
  1819.  
  1820. {
  1821.  CxObj *ObjectList;
  1822.  struct Screen *BlankerScreen=NULL;
  1823.  struct Window *BlankerWindow=NULL;
  1824.  struct MsgPort *BlankerClientPort=NULL;
  1825.  struct DiskObject *DiskObject;
  1826.  
  1827.  /* open our Libraries */
  1828.  
  1829.  AddTool (GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",37L),
  1830.           CloseLibrary,0L);
  1831.  AddTool (IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",
  1832.           37L),CloseLibrary,0L);
  1833.  AddTool (CxBase=OpenLibrary("commodities.library",37L),CloseLibrary,0L);
  1834.  AddTool (IconBase=OpenLibrary(ICONNAME,37L),CloseLibrary,0L);
  1835.  AddTool (MUIMasterBase=OpenLibrary(MUIMASTER_NAME,MUIMASTER_VMIN),CloseLibrary,0L);
  1836.  
  1837.  /* create our MUI application object */
  1838.  
  1839.  if (DiskObject=GetDiskObject("PROGDIR:ASwarm")) AddTool (DiskObject,FreeDiskObject,0L);
  1840.  
  1841.  AP_ASwarm=ApplicationObject,
  1842.             MUIA_Application_Title,"ASwarm II",
  1843.             MUIA_Application_Version,Version,
  1844.             MUIA_Application_Copyright,
  1845.              "Copyright ⌐ 1992-1994, Markus Illenseer & Matthias Scheler",
  1846.             MUIA_Application_Author,"Markus Illenseer & Matthias Scheler",
  1847.             MUIA_Application_Description,"Screen Blanker based on XSwarm",
  1848.             MUIA_Application_Base,"ASwarm",
  1849.             MUIA_Application_SingleTask,TRUE,
  1850.             MUIA_Application_DiskObject,DiskObject,
  1851.             MUIA_Application_BrokerHook,&HK_Broker,
  1852.             MUIA_Application_BrokerPri,CxPri,
  1853.             MUIA_Application_Commands,ASwarmRexxCommands,
  1854.             MUIA_HelpFile,GUIDE_FILE,
  1855.            End;
  1856.  
  1857.  if (AP_ASwarm==NULL) exit (10L);
  1858.  AddTool (AP_ASwarm,MUI_Dispose,0L);
  1859.  
  1860.  /* create List of Graphics Modes */
  1861.  
  1862.  AddTool (ModeList=CreateModeList(),DeleteModeList,0L);
  1863.  
  1864.  /* get some Signals */
  1865.  
  1866.  BlankerServerProcess=SysBase->ThisTask;
  1867.  if ((bsp_TimeOut=AllocSignal(-1L))==-1) exit (10);
  1868.  AddTool ((void *)bsp_TimeOut,FreeSignal,0L);
  1869.  if ((bsp_InputSig=AllocSignal(-1L))==-1) exit (10);
  1870.  AddTool ((void *)bsp_InputSig,FreeSignal,0L);
  1871.  if ((bsp_ClientSig=AllocSignal(-1L))==-1) exit (10);
  1872.  AddTool ((void *)bsp_ClientSig,FreeSignal,0L);
  1873.  
  1874.  /* Were we started from Workbench or from CLI ? */
  1875.  
  1876.  if (WBStarted=(argc==0L))
  1877.   {
  1878.    /* Workbench: load Config from DiskObject */
  1879.    struct WBStartup *WBenchMsg;
  1880.  
  1881.    WBenchMsg=(struct WBStartup *)argv;
  1882.    LoadConfig (WBenchMsg->sm_NumArgs?WBenchMsg->sm_ArgList->wa_Name:NULL);
  1883.   }
  1884.  else
  1885.   {
  1886.    struct RDArgs *RDArgs;
  1887.    LONG Array[17];
  1888.  
  1889.    (void)memset(Array,'\0',sizeof(Array));
  1890.    if (RDArgs=ReadArgs(Template,Array,NULL))
  1891.     {
  1892.      AddTool (RDArgs,FreeArgs,0L);
  1893.  
  1894.      CxPri=RDArgsLong(Array[0],0L,-128L,127L);
  1895.      (void)strcpy(PopKey,Array[1]?(char *)Array[1]:DEF_POPKEY);
  1896.      CxPopUp=Array[2];
  1897.      (void)strcpy(BlankKey,Array[3]?(char *)Array[3]:DEF_BLANKKEY);
  1898.  
  1899.      /* get Time Out, Client Time Out and Display mode */
  1900.  
  1901.      TimeOut=RDArgsLong(Array[4],DEF_TIMEOUT,1L,MAX_TIMEOUT);
  1902.      ClientTimeOut=RDArgsLong(Array[5],DEF_CLIENT_TIMEOUT,1L,
  1903.                    MAX_CLIENT_TIMEOUT);
  1904.      if ((DisplayMode=FindMode(ModeList,Array[6]?(char *)Array[6]:""))==NULL)
  1905.       DisplayMode=GetDefaultMode(ModeList);
  1906.  
  1907.  
  1908.      /* get Parameters for Graphics */
  1909.  
  1910.      Cycle=Array[7];
  1911.      AimMode=Array[8];
  1912.      JoyStick=Array[15];
  1913.  
  1914.      NumWasps=RDArgsLong(Array[9],DEF_WASPS,1L,MAX_WASPS);
  1915.      NumBees=RDArgsLong(Array[10],DEF_BEES,1L,MAX_BEES);
  1916.      Speed=RDArgsLong(Array[11],DEF_SPEED,1L,MAX_SPEED);
  1917.      Tightness=RDArgsLong(Array[12],DEF_TIGHTNESS,1L,MAX_TIGHTNESS);
  1918.      if (stricmp(Array[13]?(char *)Array[13]:"",CE_MouseBlank[1]))
  1919.       MouseBlank=0L;
  1920.      else MouseBlank=1L;
  1921.      Velocity=RDArgsLong(Array[14],DEF_VEL,1L,MAX_VEL);
  1922.      FinalTimeOut=RDArgsLong(Array[16],DEF_FINAL_TIMEOUT,0L,MAX_FINAL_TIMEOUT);
  1923.     }
  1924.    else
  1925.     {
  1926.      PrintFault (IoErr(),"ASwarm");
  1927.      exit (10);
  1928.     }
  1929.   }
  1930.  
  1931.  /* get our Broker from MUI */
  1932.  
  1933.  Broker=NULL;
  1934.  get (AP_ASwarm,MUIA_Application_Broker,&Broker);
  1935.  if (Broker==NULL) exit (10);
  1936.  
  1937.  CxPort=NULL;
  1938.  get (AP_ASwarm,MUIA_Application_BrokerPort,&CxPort);
  1939.  if (CxPort==NULL) exit (10);
  1940.  
  1941.  /* install our Hot Keys */
  1942.  
  1943.  PopKeyFilter=InstallHotKey(NULL,PopKey,EVENT_OPEN_WINDOW,DEF_POPKEY);
  1944.  BlankKeyFilter=InstallHotKey(NULL,BlankKey,EVENT_BLANK,DEF_BLANKKEY);
  1945.  
  1946.  /* install our "InputHandler" */
  1947.  
  1948.  TimeLeft=InitTimeLeft=TimeOut*10L;
  1949.  ObjectList=CxCustom(BlankerAction,0L);
  1950.  AttachCxObj (Broker,ObjectList);
  1951.  if (CxObjError(ObjectList)) exit (10);
  1952.  
  1953.  (void)ActivateCxObj(Broker,TRUE);
  1954.  
  1955.  /* open Window on startup if not forbidden */
  1956.  
  1957.  if (CxPopUp) OpenConfigWindow();
  1958.  
  1959.  /* increase our Priority */
  1960.  
  1961.  AddTool (BlankerServerProcess,SetTaskPri,
  1962.           (LONG)SetTaskPri(BlankerServerProcess,SERVER_PRI));
  1963.  
  1964.  /* start the Loop */
  1965.  
  1966.  FOREVER
  1967.   {
  1968.    ULONG Signal,Mask;
  1969.  
  1970.    /* handle MUI events */
  1971.  
  1972.    do
  1973.     {
  1974.      char *Ptr;
  1975.      struct WBStartup *WBenchMsg;
  1976.  
  1977.      switch (DoMethod(AP_ASwarm,MUIM_Application_Input,&Signal))
  1978.       {
  1979.        case MUIV_Application_ReturnID_Quit:
  1980.         exit (0);
  1981.        case ID_OPEN_WINDOW:
  1982.         OpenConfigWindow();
  1983.         break;
  1984.        case ID_CLOSE_WINDOW:
  1985.         CloseConfigWindow();
  1986.         break;
  1987.        case ID_BLANK:
  1988.         TimeLeft=InitTimeLeft=2L;
  1989.         break;
  1990.  
  1991.        case ID_TIMEOUT:
  1992.         if (GetNum(ST_Time,&TimeOut,1L,MAX_TIMEOUT)) TimeLeft=InitTimeLeft=10L*TimeOut;
  1993.         break;
  1994.        case ID_POPKEY:
  1995.         Ptr=NULL;
  1996.         get (ST_Pop,MUIA_String_Contents,&Ptr);
  1997.         if (Ptr)
  1998.          {
  1999.           (void)strcpy(PopKey,Ptr);
  2000.           PopKeyFilter=InstallHotKey(PopKeyFilter,PopKey,
  2001.                                      EVENT_OPEN_WINDOW,DEF_POPKEY);
  2002.           set (ST_Pop,MUIA_String_Contents,PopKey);
  2003.          }
  2004.         break;
  2005.        case ID_CLIENTTIMEOUT:
  2006.         (void)GetNum(ST_Client,&ClientTimeOut,1L,MAX_CLIENT_TIMEOUT);
  2007.         break;
  2008.        case ID_BLANKKEY:
  2009.         Ptr=NULL;
  2010.         get (ST_Blank,MUIA_String_Contents,&Ptr);
  2011.         if (Ptr)
  2012.          {
  2013.           (void)strcpy(BlankKey,Ptr);
  2014.           BlankKeyFilter=InstallHotKey(BlankKeyFilter,BlankKey,
  2015.                                        EVENT_BLANK,DEF_BLANKKEY);
  2016.           set (ST_Blank,MUIA_String_Contents,BlankKey);
  2017.          }
  2018.         break;
  2019.        case ID_FINALTIMEOUT:
  2020.         (void)GetNum(ST_Final,&FinalTimeOut,0L,MAX_FINAL_TIMEOUT);
  2021.         break;
  2022.        case ID_JOYSTICK:
  2023.         get (CM_JoyStick,MUIA_Selected,&JoyStick);
  2024.         break;
  2025.  
  2026.        case ID_SPEED:
  2027.         Speed--;
  2028.         get (CY_Speed,MUIA_Cycle_Active,&Speed);
  2029.         Speed++;
  2030.         break;        
  2031.        case ID_MOUSE:
  2032.         get (CY_Mouse,MUIA_Cycle_Active,&MouseBlank);
  2033.         break;        
  2034.        case ID_WASPS:
  2035.         get (SL_Wasps,MUIA_Slider_Level,&NumWasps);
  2036.         break;        
  2037.        case ID_BEES:
  2038.         get (SL_Bees,MUIA_Slider_Level,&NumBees);
  2039.         break;        
  2040.        case ID_VELOCITY:
  2041.         get (SL_Velo,MUIA_Slider_Level,&Velocity);
  2042.         break;        
  2043.        case ID_TIGHTNESS:
  2044.         get (SL_Tight,MUIA_Slider_Level,&Tightness);
  2045.         break;        
  2046.        case ID_CYCLE:
  2047.         get (CM_Cycle,MUIA_Selected,&Cycle);
  2048.         break;
  2049.        case ID_AIM:
  2050.         get (CM_Aim,MUIA_Selected,&AimMode);
  2051.         break;
  2052.  
  2053.        case ID_MODES:
  2054.         {
  2055.          struct ModeNode *NewMode;
  2056.  
  2057.          NewMode=NULL;
  2058.          DoMethod (LV_Modes,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&NewMode);
  2059.          if (NewMode) DisplayMode=NewMode;
  2060.          break;
  2061.         }
  2062.  
  2063.        case ID_LOAD_CONFIG:
  2064.         WBenchMsg=(struct WBStartup *)argv;
  2065.         LoadConfig (WBenchMsg->sm_NumArgs?WBenchMsg->sm_ArgList->wa_Name:NULL);
  2066.         PopKeyFilter=InstallHotKey(PopKeyFilter,PopKey,EVENT_OPEN_WINDOW,
  2067.                                    DEF_POPKEY);
  2068.         BlankKeyFilter=InstallHotKey(BlankKeyFilter,BlankKey,EVENT_BLANK,
  2069.                                      DEF_BLANKKEY);
  2070.         break;
  2071.        case ID_SAVE_CONFIG:
  2072.         WBenchMsg=(struct WBStartup *)argv;
  2073.         if (WBenchMsg->sm_NumArgs) SaveConfig(WBenchMsg->sm_ArgList->wa_Name);
  2074.         break;
  2075.        case ID_ABOUT:
  2076.         About();
  2077.         break;
  2078.        case ID_DEFAULTS:
  2079.         LoadConfig (NULL);
  2080.         PopKeyFilter=InstallHotKey(PopKeyFilter,PopKey,EVENT_OPEN_WINDOW,
  2081.                                    DEF_POPKEY);
  2082.         BlankKeyFilter=InstallHotKey(BlankKeyFilter,BlankKey,EVENT_BLANK,
  2083.                                      DEF_BLANKKEY);
  2084.       }
  2085.     }
  2086.    while (Signal==0L);
  2087.  
  2088.    /* wait */
  2089.  
  2090.    Mask=Wait(MASK(bsp_TimeOut)|MASK(bsp_InputSig)|MASK(bsp_ClientSig)|SIGBREAKF_CTRL_C|Signal);
  2091.  
  2092.    /* check for <CTRL>-C */
  2093.  
  2094.    if (Mask&SIGBREAKF_CTRL_C) exit (0);
  2095.  
  2096.    /* Input detected, unblank if necessary */
  2097.  
  2098.    if (Mask&MASK(bsp_InputSig))
  2099.     {
  2100.      if (BlankerScreen)
  2101.       {
  2102.        if (BlankerClientPort) RemTool (BlankerClientPort);
  2103.        if (BlankerWindow) RemTool (BlankerWindow);
  2104.        RemTool (BlankerScreen);
  2105.        BlankerScreen=NULL;
  2106.        InitTimeLeft=TimeOut*10L;
  2107.        ON_SPRITE
  2108.       }
  2109.      TimeLeft=InitTimeLeft;
  2110.     }
  2111.  
  2112.    /* client has confirmed that it is still alive */
  2113.  
  2114.    if (Mask&MASK(bsp_ClientSig)) TimeLeft=InitTimeLeft;
  2115.  
  2116.    /* time run out */
  2117.  
  2118.    if (TimeLeft==0L)
  2119.     if (BlankerScreen)
  2120.      {
  2121.       /* Client Time Out reached, turn entire screen black */
  2122.       SetRGB4 (&BlankerScreen->ViewPort,BEE_PEN,0,0,0);
  2123.       SetRGB4 (&BlankerScreen->ViewPort,WASP_PEN,0,0,0);
  2124.  
  2125.       /* check again after one second to keep screen in front */
  2126.       TimeLeft=10L;
  2127.       if (IntuitionBase->FirstScreen!=BlankerScreen) ScreenToFront (BlankerScreen);
  2128.       SpritesOff (BlankerScreen);
  2129.      }
  2130.     else
  2131.      {
  2132.       AddTool (BlankerScreen=CreateScreen(ModeList,DisplayMode),
  2133.                CloseScreen,0L);
  2134.       if (MouseBlank)
  2135.        if (BlankerWindow=OpenWindowTags(NULL,
  2136.                                         WA_Width,1,
  2137.                                         WA_Height,1,
  2138.                                         WA_CustomScreen,BlankerScreen,
  2139.                                         WA_Flags,WFLG_ACTIVATE|WFLG_RMBTRAP|
  2140.                                          WFLG_BORDERLESS|WFLG_SIMPLE_REFRESH,
  2141.                                         TAG_DONE))
  2142.         {
  2143.          AddTool (BlankerWindow,CloseWindow,0L);
  2144.          SetPointer (BlankerWindow,EmptyPointer,1L,1L,0L,0L);
  2145.         }
  2146.        else
  2147.         {
  2148.          MouseBlank=0L;
  2149.          if (WI_Config) set (CY_Mouse,MUIA_Cycle_Active,MouseBlank);
  2150.         }
  2151.       else BlankerWindow=NULL;
  2152.  
  2153.       BlankerClientMsg.bcm_Message.mn_Node.ln_Type=NT_MESSAGE;
  2154.       BlankerClientMsg.bcm_Message.mn_Node.ln_Pri=0;
  2155.       BlankerClientMsg.bcm_Message.mn_Length=sizeof(struct BlankerClientMsg);
  2156.       BlankerClientMsg.bcm_Message.mn_ReplyPort=FINDPROCPORT;
  2157.  
  2158.       BlankerClientMsg.bcm_Screen=BlankerScreen;
  2159.       BlankerClientMsg.bcm_SigMask=1L<<bsp_ClientSig;
  2160.       BlankerClientMsg.bcm_Wasps=NumWasps;
  2161.       BlankerClientMsg.bcm_Bees=NumBees;
  2162.       BlankerClientMsg.bcm_Speed=Speed;
  2163.       BlankerClientMsg.bcm_Cycle=Cycle;
  2164.       BlankerClientMsg.bcm_AimMode=AimMode;
  2165.       BlankerClientMsg.bcm_Tightness=Tightness;
  2166.       BlankerClientMsg.bcm_Velocity=Velocity;
  2167.       BlankerClientMsg.bcm_FinalTimeOut=FinalTimeOut;
  2168.       /* try to start Client */
  2169.       if (BlankerClientPort=CreateBlankerClient(ASwarmClientProcess,
  2170.                                                 &BlankerClientMsg))
  2171.        {
  2172.         TimeLeft=InitTimeLeft=10L*ClientTimeOut;
  2173.         AddTool (BlankerClientPort,DeleteBlankerClient,
  2174.                  (LONG)&BlankerClientMsg);
  2175.        }
  2176.      }
  2177.   }
  2178. }
  2179.