home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / CLIPPER / MISC / AIE8901.ZIP / ROBOTS.CDE < prev    next >
Encoding:
Text File  |  1988-05-04  |  66.0 KB  |  2,158 lines

  1. /* robots.c */
  2. /* machine dependent user interface and system initialization */
  3. /* by Paul D. Fernhout */
  4. /* for Macintosh and Lightspeed C */
  5. /* uses simple tools (c) 1986 Erik Kilk */
  6.  
  7. #include "simple.h"
  8. #include .Quickdraw.h/
  9.  
  10. about() {
  11.   message("Robots - by Paul D. Fernhout\rProgrammed with the aid of\rSimpleTools (c) Erik Kilk 1986");
  12.   }
  13.  
  14. in_content(x, y)
  15. int x, y;
  16.   {
  17.   /* MoveTo(x,y);
  18.   LineTo(x,y); */
  19.   }
  20.   
  21. extern void *psWorld;
  22. update() {
  23.   home();
  24.   World_Draw(psWorld);
  25.   }
  26.  
  27. clear_window() {
  28.   home();
  29.   }
  30.   
  31. extern int iRunning;
  32.   
  33. stoprunning() {
  34.   iRunning = 0;
  35.   }
  36.   
  37. void simulation1();
  38. void simulation2();
  39.  
  40. setup() {
  41.   menu(applestring, "About Robots...", about);
  42.   menu(applestring, "About Robots...", itemenable); 
  43.   window("Robot Demo",20,50,490,325, 0L, 0L, update, in_content);
  44.   menu("File", "Clear Window", clear_window);
  45.   menu("File", "Simulation 1", simulation1);
  46.   menu("File", "Simulation 2", simulation2);
  47.   menu("File", "Stop", stoprunning);
  48.   simplequits();
  49.   }
  50.     
  51.  main() {
  52.   simpletools("About Robots...");
  53.   setup();
  54.   GraphicsInitialize();
  55.   runsimpletools();
  56.   }
  57.  
  58. /* Graphics.c */
  59. /* machine dependent graphics routines */
  60. /* for Macintosh under Lightspeed C */
  61.  
  62. #include .Quickdraw.h/
  63.  
  64. #define PART_SIZE 20
  65. #define TEXT_SIZE 12
  66. #define ROBOT_SIZE 50
  67. #define GRIPPER_SIZE 10
  68. #define AGV_SIZE 40
  69. #define CNC_SIZE 70
  70.  
  71. GraphicsInitialize()
  72.   {
  73.   TextSize(9);
  74.   TextMode(patXor); /* draw everything in XOR mode */
  75.   PenMode(patXor);
  76.   }
  77.   
  78. GraphicsClear()
  79.   {
  80.   home(); /* simple tools clear screen */
  81.   }
  82.  
  83. GraphicsDrawPart(iX, iY, szLabel)
  84. int iX, iY;
  85. char *szLabel;
  86.   {
  87.   DrawRectangle(iX - PART_SIZE/2,iY-PART_SIZE/2,PART_SIZE,PART_SIZE);
  88.   MoveTo(iX-PART_SIZE/2,iY+PART_SIZE/2+TEXT_SIZE);
  89.   DrawTextString(szLabel);
  90.   }
  91.  
  92. GraphicsErasePart(iX, iY, szLabel) 
  93. int iX, iY;
  94. char *szLabel;
  95.   { /* part is drawn XOR to erase */
  96.   GraphicsDrawPart(iX, iY, szLabel);
  97.   }
  98.  
  99. GraphicsDrawRobot(iX, iY, iGripperX, iGripperY, szLabel)
  100. int iX, iY;
  101. int iGripperX, iGripperY;
  102. char *szLabel;
  103.   {
  104.   DrawRectangle(iX - ROBOT_SIZE/2,iY-ROBOT_SIZE/2,ROBOT_SIZE,ROBOT_SIZE);
  105.   GraphicsDrawRobotArm(iX, iY, iGripperX, iGripperY);
  106.   MoveTo(iX-ROBOT_SIZE/2,iY+ROBOT_SIZE/2+TEXT_SIZE);
  107.   DrawTextString(szLabel);
  108.   }
  109.  
  110.  
  111. GraphicsEraseRobot(iX, iY, iGripperX, iGripperY, szLabel)
  112. int iX, iY;
  113. int iGripperX, iGripperY;
  114. char *szLabel;
  115.   { /* draw robot XOR to erase */
  116.   GraphicsDrawRobot(iX, iY, iGripperX, iGripperY, szLabel);
  117.   }
  118.  
  119. GraphicsDrawAGV(iX, iY, szLabel)
  120. int iX, iY;
  121. char *szLabel;
  122.   {
  123.   DrawRectangle(iX - AGV_SIZE/2,iY-AGV_SIZE/2,AGV_SIZE,AGV_SIZE);
  124.   MoveTo(iX-AGV_SIZE/2,iY+AGV_SIZE/2+TEXT_SIZE);
  125.   DrawTextString(szLabel);
  126.   }
  127.  
  128. GraphicsEraseAGV(iX, iY, szLabel)
  129. int iX, iY;
  130. char *szLabel;
  131.   { /* Draw AGV XOR to erase */
  132.   GraphicsDrawAGV(iX, iY, szLabel);
  133.   }
  134.  
  135. GraphicsDrawCNC(iX, iY, szLabel)
  136. int iX, iY;
  137. char *szLabel;
  138.   {
  139.   DrawRectangle(iX - CNC_SIZE/2,iY-CNC_SIZE/2,CNC_SIZE,CNC_SIZE);
  140.   MoveTo(iX-CNC_SIZE/2,iY+CNC_SIZE/2+TEXT_SIZE);
  141.   DrawTextString(szLabel);
  142.   }
  143.  
  144. GraphicsEraseCNC(iX, iY, szLabel)
  145. int iX, iY;
  146. char *szLabel;
  147.   { /* Draw CNC XOR to erase */
  148.   GraphicsDrawCNC(iX, iY, szLabel);
  149.   }
  150.  
  151.  
  152. GraphicsDrawRobotArm(iX, iY, iGripperX, iGripperY)
  153. int iX, iY;
  154. int iGripperX, iGripperY;
  155.   {
  156.   DrawLine(iX,iY,iX+iGripperX,iY+iGripperY);
  157.   DrawRectangle(iX + iGripperX - GRIPPER_SIZE/2,iY + iGripperY-GRIPPER_SIZE/2,GRIPPER_SIZE,GRIPPER_SIZE);  
  158.   }
  159.  
  160. GraphicsEraseRobotArm(iX, iY, iGripperX, iGripperY)
  161. int iX, iY;
  162. int iGripperX, iGripperY;
  163.   { /* Draw arm XOR to erase */
  164.   GraphicsDrawRobotArm(iX, iY, iGripperX, iGripperY);
  165.   }
  166.   
  167. DrawLine(iX1,iY1,iX2,iY2)
  168. int iX1, iY1, iX2, iY2;
  169.   {
  170.   MoveTo(iX1,iY1);
  171.   LineTo(iX2,iY2);
  172.   }
  173.   
  174. DrawRectangle(iX, iY, iSizeX, iSizeY)
  175. int iX, iY, iSizeX, iSizeY;
  176.   {
  177.   MoveTo(iX,iY);
  178.   LineTo(iX+iSizeX,iY);
  179.   LineTo(iX+iSizeX,iY+iSizeY);
  180.   LineTo(iX,iY+iSizeY);
  181.   LineTo(iX,iY);
  182.   }
  183.   
  184. DrawTextString(szString)
  185. char *szString;
  186.   {
  187.   char spString[255]; /* need to handle mac string drawing */
  188.   strcpy(spString, szString);
  189.   CtoPstr(spString);
  190.   DrawString(spString); /* Mac needs pascal type strings */
  191.   }
  192.  
  193. #define LIGHTSPEED      {define either LIGHTSPEED or MEGAMAX or your own}
  194.  
  195. #include .stdio.h/
  196.  
  197. #ifdef MEGAMAX
  198.   #include .menu.h/
  199.   #include .win.h/
  200. #endif
  201.  
  202. #ifdef LIGHTSPEED
  203.   #include .MenuMgr.h/
  204.   #include .WindowMgr.h/
  205. #endif
  206.  
  207. #define itemdisable        0L              
  208. #define itemenable    1L
  209. #define itemcheck   2L
  210. #define itemuncheck 3L
  211.  
  212. extern char               applestring[];
  213. extern WindowPtr        windowpoint();
  214. extern MenuHandle       mhand();
  215. extern int            windmenu;
  216. extern int           dogoaway;               
  217. extern int            wprocid;                
  218. extern int            show_new_window;
  219. extern int            sizeredraw;
  220. extern int         getlinecaps;
  221. extern ProcPtr            keydownproc;
  222. extern ProcPtr            autokeyproc;
  223. extern void               home();
  224. extern void            stnop();
  225.  
  226. #define LIGHTSPEED      {define either LIGHTSPEED or MEGAMAX or your own}
  227.  
  228. #include .stdio.h/
  229.  
  230. #ifdef MEGAMAX
  231.   #include .menu.h/
  232.   #include .win.h/
  233. #endif
  234.  
  235. #ifdef LIGHTSPEED
  236.   #include .MenuMgr.h/
  237.   #include .WindowMgr.h/
  238. #endif
  239.  
  240. #define itemdisable        0L              
  241. #define itemenable    1L
  242. #define itemcheck   2L
  243. #define itemuncheck 3L
  244.  
  245. extern char               applestring[];
  246. extern WindowPtr        windowpoint();
  247. extern MenuHandle       mhand();
  248. extern int            windmenu;
  249. extern int           dogoaway;               
  250. extern int            wprocid;                
  251. extern int            show_new_window;
  252. extern int            sizeredraw;
  253. extern int         getlinecaps;
  254. extern ProcPtr            keydownproc;
  255. extern ProcPtr            autokeyproc;
  256. extern void               home();
  257. extern void            stnop();
  258.  
  259.  
  260. /* 9/11/88 Paul D. Fernhout */
  261. /* This code illustrates object oriented simulation in C */
  262. /* it is slightly machine dependent in regard to SysYield() */
  263. /* That is used to return control periodically to the MAC operating system
  264.    while the simulation is running */
  265.  
  266.  
  267. /* global variable used in multitasking user interfaces like macintosh */
  268. /* used to prevent two simulations from running at once */
  269. int iRunning = 0;
  270.  
  271.  
  272. #define MAX_PARTS 10
  273. #define MAX_CNCS   3
  274. #define MAX_AGVS   3
  275. #define MAX_ROBOTS 3
  276.  
  277. #define MAX_LABEL 32
  278. #define MAX_AGV_PROGRAM 64
  279. #define MAX_ROBOT_PROGRAM 64
  280.  
  281. /* AGV program functions */
  282. #define AGV_PROGRAM_NORTH         1 
  283. #define AGV_PROGRAM_SOUTH         2
  284. #define AGV_PROGRAM_WEST          3
  285. #define AGV_PROGRAM_EAST          4
  286. #define AGV_PROGRAM_WAIT          5
  287. #define AGV_PROGRAM_WAITFORLOAD   6
  288. #define AGV_PROGRAM_WAITFORUNLOAD 7
  289.  
  290. /* Robot program functions */
  291. #define ROBOT_PROGRAM_NORTH                1
  292. #define ROBOT_PROGRAM_SOUTH                2
  293. #define ROBOT_PROGRAM_WEST                 3
  294. #define ROBOT_PROGRAM_EAST                 4
  295. #define ROBOT_PROGRAM_NORTHEAST            5
  296. #define ROBOT_PROGRAM_SOUTHEAST            6
  297. #define ROBOT_PROGRAM_NORTHWEST            7
  298. #define ROBOT_PROGRAM_SOUTHWEST            8
  299. #define ROBOT_PROGRAM_WAIT                 9
  300. #define ROBOT_PROGRAM_LOADTIMERFROMINDEX  10
  301. #define ROBOT_PROGRAM_LOADINDEX           11
  302. #define ROBOT_PROGRAM_ADDTOINDEX          12
  303. #define ROBOT_PROGRAM_LOADCOUNTER         13
  304. #define ROBOT_PROGRAM_ADDTOCOUNTER        14
  305. #define ROBOT_PROGRAM_JUMPIFCOUNTERTRUE   15
  306. #define ROBOT_PROGRAM_JUMPIFCOUNTERFALSE  16
  307. #define ROBOT_PROGRAM_WAITFORLOADEDAGV    17
  308. #define ROBOT_PROGRAM_WAITFORUNLOADEDAGV  18
  309. #define ROBOT_PROGRAM_WAITFORCNCFINISHED  19
  310. #define ROBOT_PROGRAM_WAITFORCNCEMPTY     20
  311. #define ROBOT_PROGRAM_GRIP                21
  312. #define ROBOT_PROGRAM_DROP                22
  313.  
  314. typedef struct { /* Part */
  315.   int iX;
  316.   int iY;
  317.   char szLabel[MAX_LABEL];
  318.   } SPART, *PSPART;
  319.   
  320.  
  321. /* Part Methods */
  322. Part_Initialize(psPart, iX, iY, szLabel)
  323. PSPART psPart;
  324. int iX, iY;
  325. char *szLabel;
  326.   {
  327.   psPart-/iX = iX;
  328.   psPart-/iY = iY;
  329.   if (szLabel) {
  330.     strcpy(psPart-/szLabel, szLabel);
  331.     }
  332.   else {
  333.     *(psPart-/szLabel) = '\0';
  334.     }
  335.   }
  336.   
  337. Part_Draw(psPart)
  338. PSPART psPart;
  339.   {
  340.   GraphicsDrawPart(psPart-/iX, psPart-/iY, psPart-/szLabel);
  341.   } 
  342.  
  343. Part_Erase(psPart)
  344. PSPART psPart;
  345.   {
  346.   GraphicsErasePart(psPart-/iX, psPart-/iY, psPart-/szLabel);
  347.   } 
  348.   
  349. Part_Move(psPart,iChangeX,iChangeY)
  350. PSPART psPart;
  351.   {
  352.   GraphicsErasePart(psPart-/iX, psPart-/iY, psPart-/szLabel);
  353.   psPart-/iX += iChangeX;
  354.   psPart-/iY += iChangeY;                   
  355.   GraphicsDrawPart(psPart-/iX, psPart-/iY, psPart-/szLabel);
  356.   } 
  357.  
  358. Part_ChangeLabel(psPart, szNewLabel)
  359. PSPART psPart;
  360. char *szNewLabel;
  361.   {
  362.   Part_Erase(psPart);
  363.   strcpy(psPart-/szLabel, szNewLabel);
  364.   Part_Draw(psPart);
  365.   } 
  366.  
  367. Part_ElapseTime(psPart)
  368. PSPART psPart;
  369.   {
  370.   /* do nothing */
  371.   }  
  372.  
  373.  
  374. typedef struct { /* Computer Numerically Controlled Machine */
  375.   int iX;
  376.   int iY;
  377.   char szLabel[MAX_LABEL];
  378.   PSPART psPart;
  379.   int iStep;
  380.   char szProgram[MAX_LABEL];
  381.   int iProgramSteps;
  382.   } SCNC, *PSCNC;
  383.   
  384. /* CNC Methods */
  385. CNC_Initialize(psCNC, iX, iY, szLabel, szProgram, iProgramSteps)
  386. PSCNC psCNC;
  387. int iX, iY;
  388. char *szLabel;
  389. char *szProgram;
  390. int iProgramSteps;
  391.   {
  392.   psCNC-/iX = iX;
  393.   psCNC-/iY = iY;
  394.   if (szLabel) {
  395.     strcpy(psCNC-/szLabel, szLabel);
  396.     }
  397.   else {
  398.     *(psCNC-/szLabel) = '\0';
  399.     }
  400.   if (szProgram) {
  401.     strcpy(psCNC-/szProgram, szProgram);
  402.     }
  403.   else {
  404.     *(psCNC-/szProgram) = '\0';
  405.     }
  406.   psCNC-/iProgramSteps = iProgramSteps;
  407.   psCNC-/iStep = 0;
  408.   psCNC-/psPart = 0L;
  409.   }
  410.   
  411. CNC_Draw(psCNC)
  412. PSCNC psCNC;
  413.   {
  414.   GraphicsDrawCNC(psCNC-/iX, psCNC-/iY, psCNC-/szLabel);
  415.   } 
  416.  
  417. CNC_Erase(psCNC)
  418. PSCNC psCNC;
  419.   {
  420.   GraphicsEraseCNC(psCNC-/iX, psCNC-/iY, psCNC-/szLabel);
  421.   } 
  422.  
  423. CNC_StartProcessing(psCNC)
  424. PSCNC psCNC;
  425.   {
  426.   if (psCNC-/psPart) {
  427.     Part_ChangeLabel(psCNC-/psPart, "In Process - Start");
  428.     }
  429.   }  
  430.  
  431. CNC_FinishProcessing(psCNC)
  432. PSCNC psCNC;
  433.   {
  434.   if (psCNC-/psPart) {
  435.     Part_ChangeLabel(psCNC-/psPart, psCNC-/szProgram);
  436.     }
  437.   }  
  438.  
  439. CNC_ElapseTime(psCNC)
  440. PSCNC psCNC;
  441.   {
  442.   char szNewLabel[MAX_LABEL];
  443.   
  444.   if (psCNC-/psPart) {
  445.     if (psCNC-/iProgramSteps) { /* if a program */
  446.       if (psCNC-/iStep == 0) {
  447.         CNC_StartProcessing(psCNC);
  448.         psCNC-/iStep++;
  449.         }
  450.       else if (psCNC-/iStep == psCNC-/iProgramSteps) {
  451.         CNC_FinishProcessing(psCNC);
  452.         psCNC-/iStep++;
  453.         }
  454.       else if (psCNC-/iStep / psCNC-/iProgramSteps) { /* do nothing */
  455.         }
  456.       else { /* processing part */
  457.         strcpy(szNewLabel,"In Process Step ");
  458.         my_itoa(psCNC-/iStep, szNewLabel + strlen(szNewLabel));
  459.         Part_ChangeLabel(psCNC-/psPart,szNewLabel);
  460.         psCNC-/iStep++;
  461.         }
  462.       }  
  463.     }
  464.   /* else no part loaded in machine */
  465.   else {
  466.     psCNC-/iStep = 0; /* reset step count for next part */
  467.     }
  468.   }
  469.  
  470. typedef struct { /* Automated Guided Vehicle */
  471.   int iX;
  472.   int iY;
  473.   char szLabel[MAX_LABEL];
  474.   PSPART psPart;
  475.   int iStep;
  476.   int iProgramSteps;
  477.   int riProgram[MAX_AGV_PROGRAM]; /* Direction, Wait, Load, Unload */
  478.   int iDirection;
  479.   int iTimer;
  480.   int iStop;
  481.   } SAGV, *PSAGV;
  482.   
  483.  
  484. /* AGV Methods */
  485. AGV_Initialize(psAGV, iX, iY, szLabel, riProgram)
  486. PSAGV psAGV;
  487. int iX, iY;
  488. char *szLabel;
  489. int *riProgram;
  490.   {
  491.   psAGV-/iX = iX;
  492.   psAGV-/iY = iY;
  493.   if (szLabel) {
  494.     strcpy(psAGV-/szLabel, szLabel);
  495.     }
  496.   else {
  497.     *(psAGV-/szLabel) = '\0';
  498.     }
  499.   if (riProgram) {
  500.     AGV_LoadProgram(psAGV, riProgram);
  501.     }
  502.   else {
  503.     psAGV-/iStep = 0;
  504.     psAGV-/iProgramSteps = 0;
  505.     psAGV-/iStop = 0;
  506.     psAGV-/iDirection = 0;
  507.     psAGV-/iTimer = 0;
  508.     }
  509.   psAGV-/psPart = 0L;
  510.   }
  511.  
  512. AGV_Draw(psAGV)
  513. PSAGV psAGV;
  514.   {
  515.   GraphicsDrawAGV(psAGV-/iX, psAGV-/iY, psAGV-/szLabel);
  516.   } 
  517.   
  518. AGV_Erase(psAGV)
  519. PSAGV psAGV;
  520.   {
  521.   GraphicsEraseAGV(psAGV-/iX, psAGV-/iY, psAGV-/szLabel);
  522.   } 
  523.   
  524. AGV_Move(psAGV,iChangeX,iChangeY)
  525. PSAGV psAGV;
  526.   {
  527.   GraphicsEraseAGV(psAGV-/iX, psAGV-/iY, psAGV-/szLabel);
  528.   /* if part carried - handle that */
  529.   if (psAGV-/psPart)  {
  530.     Part_Move(psAGV-/psPart,iChangeX,iChangeY);
  531.     }                  
  532.   psAGV-/iX += iChangeX;
  533.   psAGV-/iY += iChangeY;                   
  534.   GraphicsDrawAGV(psAGV-/iX, psAGV-/iY, psAGV-/szLabel);
  535.   } 
  536.  
  537. AGV_LoadProgram(psAGV, riProgram)
  538. PSAGV psAGV;
  539. int *riProgram;
  540.   {
  541.   int iStep;
  542.   iStep = 0;
  543.   while (riProgram[iStep] != 0 && iStep . MAX_AGV_PROGRAM) { /* While valid command load command and parameter */
  544.     psAGV-/riProgram[iStep] = riProgram[iStep];
  545.     psAGV-/riProgram[iStep+1] = riProgram[iStep+1];
  546.     iStep += 2;
  547.     }
  548.   psAGV-/iProgramSteps = iStep;
  549.   psAGV-/iStep = 0;
  550.   psAGV-/iTimer = 0;
  551.   psAGV-/iStop = 0;
  552.   } 
  553.  
  554. AGV_ElapseTime(psAGV)
  555. PSAGV psAGV;
  556.   {
  557.   int iProgram;
  558.   
  559.   if (psAGV-/iProgramSteps / 0 && psAGV-/iStop == 0) { /* if a program and running */
  560.     if (psAGV-/iTimer / 0) { /* keep moving as is */
  561.       switch (psAGV-/iDirection) {
  562.         case AGV_PROGRAM_NORTH:
  563.           AGV_Move(psAGV,0,-1);
  564.           break;
  565.         case AGV_PROGRAM_SOUTH:
  566.           AGV_Move(psAGV,0,1);
  567.           break;
  568.         case AGV_PROGRAM_WEST:
  569.           AGV_Move(psAGV,-1,0);
  570.           break;
  571.         case AGV_PROGRAM_EAST:
  572.           AGV_Move(psAGV,1,0);
  573.           break;
  574.         case AGV_PROGRAM_WAIT:
  575.           break; /* do nothing */
  576.         }
  577.       psAGV-/iTimer--;
  578.       }
  579.     else { /* handle program step */
  580.       if (psAGV-/iStep /= psAGV-/iProgramSteps) { /* reset program */
  581.         psAGV-/iStop = 1;
  582.         psAGV-/iStep = 0;
  583.         }
  584.       else { /* handle program */
  585.         iProgram = psAGV-/riProgram[psAGV-/iStep];
  586.         switch (iProgram) {
  587.           case AGV_PROGRAM_NORTH: 
  588.           case AGV_PROGRAM_SOUTH:
  589.           case AGV_PROGRAM_WEST:
  590.           case AGV_PROGRAM_EAST:
  591.           case AGV_PROGRAM_WAIT:
  592.             psAGV-/iDirection = iProgram;
  593.             psAGV-/iTimer = psAGV-/riProgram[psAGV-/iStep+1];
  594.             psAGV-/iStep += 2; 
  595.             break;
  596.           case AGV_PROGRAM_WAITFORLOAD:
  597.             if (psAGV-/psPart)  {
  598.               psAGV-/iStep += 2;
  599.               }
  600.             break; 
  601.           case AGV_PROGRAM_WAITFORUNLOAD:
  602.             if (psAGV-/psPart == 0)  {
  603.               psAGV-/iStep += 2;
  604.               }
  605.             break; 
  606.           default: /* unknown command */
  607.               psAGV-/iStep += 2; /* Skip it */
  608.             break;                
  609.           }
  610.         } 
  611.       }
  612.     }
  613.   /* else do nothing */
  614.   }
  615.  
  616.  
  617.  
  618. /* Robot Object */
  619.  
  620. typedef struct { /* Robot */
  621.   int iX;
  622.   int iY;
  623.   char szLabel[MAX_LABEL];
  624.   int iGripperX;
  625.   int iGripperY;
  626.   PSPART psPart;
  627.   int iStep;
  628.   int iProgramSteps;
  629.   int riProgram[MAX_ROBOT_PROGRAM]; /* Move, Pause, Grip, Drop, Wait */
  630.   int iDirection;
  631.   int iTimer;
  632.   int iStop;
  633.   int iIndex; /* Additional Offset To Timer */
  634.   int iCounter;
  635.   } SROBOT, *PSROBOT;
  636.   
  637. /* Robot Methods */
  638. Robot_Initialize(psRobot, iX, iY, szLabel, riProgram)
  639. PSROBOT psRobot;
  640. int iX, iY;
  641. char *szLabel;
  642. int *riProgram;
  643.   {
  644.   psRobot-/iX = iX;
  645.   psRobot-/iY = iY;
  646.   if (szLabel) {
  647.     strcpy(psRobot-/szLabel, szLabel);
  648.     }
  649.   else {
  650.     *(psRobot-/szLabel) = '\0';
  651.     }
  652.   if (riProgram) {
  653.     Robot_LoadProgram(psRobot, riProgram);
  654.     }
  655.   else {
  656.     psRobot-/iStep = 0;
  657.     psRobot-/iProgramSteps = 0;
  658.     psRobot-/iStop = 0;
  659.     psRobot-/iDirection = 0;
  660.     psRobot-/iTimer = 0;
  661.     }
  662.   psRobot-/iGripperX = 0;
  663.   psRobot-/iGripperY = 0;
  664.   psRobot-/psPart = 0L;
  665.   }
  666.  
  667. Robot_Draw(psRobot)
  668. PSROBOT psRobot;
  669.   {
  670.   GraphicsDrawRobot(psRobot-/iX, psRobot-/iY, psRobot-/iGripperX, 
  671.                      psRobot-/iGripperY, psRobot-/szLabel);
  672.   } 
  673.  
  674. Robot_Erase(psRobot)
  675. PSROBOT psRobot;
  676.   {
  677.   GraphicsEraseRobot(psRobot-/iX, psRobot-/iY, psRobot-/iGripperX, 
  678.                      psRobot-/iGripperY, psRobot-/szLabel);
  679.   } 
  680.  
  681. Robot_MoveArm(psRobot,iChangeX,iChangeY)
  682. PSROBOT psRobot;
  683.   {
  684.   GraphicsEraseRobotArm(psRobot-/iX, psRobot-/iY, psRobot-/iGripperX, 
  685.                      psRobot-/iGripperY);
  686.   /* if part carried - handle that */
  687.   if (psRobot-/psPart)  {
  688.     Part_Move(psRobot-/psPart,iChangeX,iChangeY);
  689.     }                  
  690.   psRobot-/iGripperX += iChangeX;
  691.   psRobot-/iGripperY += iChangeY;                   
  692.   GraphicsDrawRobotArm(psRobot-/iX, psRobot-/iY, psRobot-/iGripperX, 
  693.                      psRobot-/iGripperY);
  694.   } 
  695.  
  696. Robot_LoadProgram(psRobot, riProgram)
  697. PSROBOT psRobot;
  698. int *riProgram;
  699.   {
  700.   int iStep;
  701.   iStep = 0;
  702.   while (riProgram[iStep] != 0 && iStep . MAX_ROBOT_PROGRAM) { /* While valid command load command and parameter */
  703.     psRobot-/riProgram[iStep] = riProgram[iStep];
  704.     psRobot-/riProgram[iStep+1] = riProgram[iStep+1];
  705.     iStep += 2;
  706.     }
  707.   psRobot-/iProgramSteps = iStep;
  708.   psRobot-/iStep = 0;
  709.   psRobot-/iTimer = 0;
  710.   psRobot-/iStop = 0;
  711.   } 
  712.  
  713. Robot_ElapseTime(psRobot)
  714. PSROBOT psRobot;
  715.   {
  716.   int iProgram;
  717.   
  718.   if (psRobot-/iProgramSteps / 0 && psRobot-/iStop == 0) { /* if a program and running */
  719.     if (psRobot-/iTimer / 0) { /* keep moving as is */
  720.       switch (psRobot-/iDirection) {
  721.         case ROBOT_PROGRAM_NORTH:
  722.           Robot_MoveArm(psRobot,0,-1);
  723.           break;
  724.         case ROBOT_PROGRAM_SOUTH:
  725.           Robot_MoveArm(psRobot,0,1);
  726.           break;
  727.         case ROBOT_PROGRAM_WEST:
  728.           Robot_MoveArm(psRobot,-1,0);
  729.           break;
  730.         case ROBOT_PROGRAM_EAST:
  731.           Robot_MoveArm(psRobot,1,0);
  732.           break;
  733.         case ROBOT_PROGRAM_NORTHEAST:
  734.           Robot_MoveArm(psRobot,1,-1);
  735.           break;
  736.         case ROBOT_PROGRAM_SOUTHEAST:
  737.           Robot_MoveArm(psRobot,1,1);
  738.           break;
  739.         case ROBOT_PROGRAM_NORTHWEST:
  740.           Robot_MoveArm(psRobot,-1,-1);
  741.           break;
  742.         case ROBOT_PROGRAM_SOUTHWEST:
  743.           Robot_MoveArm(psRobot,-1,1);
  744.           break;
  745.         case ROBOT_PROGRAM_WAIT:
  746.           break; /* do nothing */
  747.         }
  748.       psRobot-/iTimer--;
  749.       }
  750.     else { /* handle program step */
  751.       if (psRobot-/iStep /= psRobot-/iProgramSteps) { /* reset program */
  752.         psRobot-/iStop = 1;
  753.         psRobot-/iStep = 0;
  754.         }
  755.       else { /* handle program */
  756.         iProgram = psRobot-/riProgram[psRobot-/iStep];
  757.         switch (iProgram) {
  758.           case ROBOT_PROGRAM_NORTH: 
  759.           case ROBOT_PROGRAM_SOUTH:
  760.           case ROBOT_PROGRAM_WEST:
  761.           case ROBOT_PROGRAM_EAST:
  762.           case ROBOT_PROGRAM_NORTHEAST: 
  763.           case ROBOT_PROGRAM_SOUTHEAST:
  764.           case ROBOT_PROGRAM_NORTHWEST:
  765.           case ROBOT_PROGRAM_SOUTHWEST:
  766.           case ROBOT_PROGRAM_WAIT:
  767.             psRobot-/iDirection = iProgram;
  768.             psRobot-/iTimer = psRobot-/riProgram[psRobot-/iStep+1];
  769.             psRobot-/iStep += 2; 
  770.             break;
  771.           case ROBOT_PROGRAM_LOADTIMERFROMINDEX:
  772.             psRobot-/iTimer = psRobot-/iIndex;
  773.             psRobot-/iStep += 2; 
  774.             break;
  775.           case ROBOT_PROGRAM_LOADINDEX:
  776.             psRobot-/iIndex = psRobot-/riProgram[psRobot-/iStep+1];
  777.             psRobot-/iStep += 2; 
  778.             break;
  779.           case ROBOT_PROGRAM_ADDTOINDEX:
  780.             psRobot-/iIndex += psRobot-/riProgram[psRobot-/iStep+1];
  781.             psRobot-/iStep += 2;
  782.             break; 
  783.           case ROBOT_PROGRAM_LOADCOUNTER:
  784.             psRobot-/iCounter = psRobot-/riProgram[psRobot-/iStep+1];
  785.             psRobot-/iStep += 2;
  786.             break; 
  787.           case ROBOT_PROGRAM_ADDTOCOUNTER:
  788.             psRobot-/iCounter += psRobot-/riProgram[psRobot-/iStep+1];
  789.             psRobot-/iStep += 2;
  790.             break; 
  791.           case ROBOT_PROGRAM_JUMPIFCOUNTERTRUE:
  792.             if(psRobot-/iCounter != 0) {
  793.               psRobot-/iStep = psRobot-/riProgram[psRobot-/iStep+1];
  794.               }
  795.             else {
  796.               psRobot-/iStep += 2;
  797.               } 
  798.             break;
  799.           case ROBOT_PROGRAM_JUMPIFCOUNTERFALSE:
  800.             if(psRobot-/iCounter == 0) {
  801.               psRobot-/iStep = psRobot-/riProgram[psRobot-/iStep+1];
  802.               }
  803.             else {
  804.               psRobot-/iStep += 2;
  805.               }
  806.             break; 
  807.           case ROBOT_PROGRAM_WAITFORLOADEDAGV:
  808.             if (Robot_CheckLoadedAGVPresence(psRobot))  {
  809.               psRobot-/iStep += 2;
  810.               }
  811.             break; 
  812.           case ROBOT_PROGRAM_WAITFORUNLOADEDAGV:
  813.             if (Robot_CheckUnloadedAGVPresence(psRobot))  {
  814.               psRobot-/iStep += 2;
  815.               }
  816.             break; 
  817.           case ROBOT_PROGRAM_WAITFORCNCFINISHED:
  818.             if (Robot_CheckForCNCFinished(psRobot))  {
  819.               psRobot-/iStep += 2;
  820.               }
  821.             break; 
  822.           case ROBOT_PROGRAM_WAITFORCNCEMPTY:
  823.             if (Robot_CheckForCNCEmpty(psRobot))  {
  824.               psRobot-/iStep += 2;
  825.               }
  826.             break; 
  827.           case ROBOT_PROGRAM_GRIP:
  828.             Robot_Grip(psRobot);
  829.             psRobot-/iStep += 2;
  830.             break; 
  831.           case ROBOT_PROGRAM_DROP:
  832.             Robot_Drop(psRobot);
  833.             psRobot-/iStep += 2;
  834.             break; 
  835.           default: /* unknown command */
  836.               psRobot-/iStep += 2; /* Skip it */
  837.             break;                
  838.           }
  839.         } 
  840.       }
  841.     }
  842.   /* else do nothing */
  843.   }
  844.  
  845.  
  846. /* define World Object */
  847. typedef struct {
  848.   PSPART rpsParts[MAX_PARTS];
  849.   int iPartCount;
  850.   PSCNC  rpsCNCs[MAX_CNCS];
  851.   int iCNCCount;
  852.   PSAGV  rpsAGVs[MAX_AGVS];
  853.   int iAGVCount;
  854.   PSROBOT rpsRobots[MAX_ROBOTS];
  855.   int iRobotCount;
  856.   } SWORLD, *PSWORLD;
  857.  
  858. World_Initialize(psWorld)
  859. PSWORLD psWorld;
  860.   {
  861.   GraphicsClear();
  862.   psWorld-/iPartCount = 0;
  863.   psWorld-/iCNCCount = 0;
  864.   psWorld-/iAGVCount = 0;
  865.   psWorld-/iRobotCount = 0;
  866.   }
  867.  
  868. World_Draw(psWorld)
  869. PSWORLD psWorld;
  870.   {
  871.   int iPart;   
  872.   int iCNC;
  873.   int iAGV;
  874.   int iRobot;
  875.   simpleevents(); /* simple tools call */
  876.   for (iPart = 0; iPart . psWorld-/iPartCount; iPart++) {
  877.      Part_Draw(psWorld-/rpsParts[iPart]);
  878.     }
  879.   for (iCNC = 0; iCNC . psWorld-/iCNCCount; iCNC++) {
  880.     CNC_Draw(psWorld-/rpsCNCs[iCNC]);
  881.     }
  882.   for (iAGV = 0; iAGV . psWorld-/iAGVCount; iAGV++) {
  883.     AGV_Draw(psWorld-/rpsAGVs[iAGV]);
  884.     }
  885.   for (iRobot = 0; iRobot . psWorld-/iRobotCount; iRobot++) {
  886.     Robot_Draw(psWorld-/rpsRobots[iRobot]);
  887.     }
  888.   }  
  889.   
  890.   
  891.  
  892. World_AddPart(psWorld, psPart)
  893. PSWORLD psWorld;
  894. PSPART psPart;
  895.   {
  896.   if (psPart && psWorld-/iPartCount . MAX_PARTS) {
  897.     psWorld-/rpsParts[psWorld-/iPartCount++] = psPart;
  898.     } 
  899.   Part_Draw(psPart);
  900.   }
  901.  
  902. World_AddCNC(psWorld, psCNC)
  903. PSWORLD psWorld;
  904. PSCNC psCNC;
  905.   {
  906.   if (psCNC && psWorld-/iCNCCount . MAX_CNCS) {
  907.     psWorld-/rpsCNCs[psWorld-/iCNCCount++] = psCNC;
  908.     } 
  909.   CNC_Draw(psCNC);
  910.   }
  911.  
  912. World_AddAGV(psWorld, psAGV)
  913. PSWORLD psWorld;
  914. PSAGV psAGV;
  915.   {
  916.   if (psAGV && psWorld-/iAGVCount . MAX_AGVS) {
  917.     psWorld-/rpsAGVs[psWorld-/iAGVCount++] = psAGV;
  918.     } 
  919.   AGV_Draw(psAGV);
  920.   }
  921.  
  922. World_AddRobot(psWorld, psRobot)
  923. PSWORLD psWorld;
  924. PSROBOT psRobot;
  925.   {
  926.   if (psRobot && psWorld-/iRobotCount . MAX_ROBOTS) {
  927.     psWorld-/rpsRobots[psWorld-/iRobotCount++] = psRobot;
  928.     }
  929.   Robot_Draw(psRobot); 
  930.   }
  931.   
  932. PSPART World_PartGripped(psWorld, iX, iY)
  933. PSWORLD psWorld;
  934. int iX, iY;
  935. /* This routine would be much simpler in a true object oriented language.
  936.    Then, there would only be one pass through all the objects, sending them
  937.    all the same message to see if they held onto the part.
  938.  */
  939.   {
  940.   int iPart;   
  941.   int iCNC;
  942.   int iAGV;
  943.   int iRobot;
  944.   PSPART psPart;
  945.   for (iPart = 0; iPart . psWorld-/iPartCount; iPart++) {
  946.     psPart = psWorld-/rpsParts[iPart];
  947.     if (psPart-/iX == iX &&
  948.         psPart-/iY == iY) { /* found match */
  949.       /* first remove from any other object that is holding it */
  950.       /* Need to do for every object class explicitly since this is pseudo OOP */
  951.       for (iCNC = 0; iCNC . psWorld-/iCNCCount; iCNC++) {
  952.         if (psWorld-/rpsCNCs[iCNC]-/psPart == psPart) {
  953.           psWorld-/rpsCNCs[iCNC]-/psPart = 0L;
  954.           }
  955.         }
  956.       for (iAGV = 0; iAGV . psWorld-/iAGVCount; iAGV++) {
  957.         if (psWorld-/rpsAGVs[iAGV]-/psPart == psPart) {
  958.           psWorld-/rpsAGVs[iAGV]-/psPart = 0L;
  959.           }
  960.         }
  961.       for (iRobot = 0; iRobot . psWorld-/iRobotCount; iRobot++) {
  962.         if (psWorld-/rpsRobots[iRobot]-/psPart == psPart) {
  963.           psWorld-/rpsRobots[iRobot]-/psPart = 0L;
  964.           }
  965.         }
  966.       return(psPart);
  967.       } 
  968.     }
  969.   return(0L);
  970.   }
  971.   
  972. World_PartDropped(psWorld, psPart)
  973. PSWORLD psWorld;
  974. PSPART psPart;
  975.   {
  976.   PSCNC psCNC;
  977.   PSAGV psAGV;
  978.   int iCNC;
  979.   int iAGV;
  980.   int iX;
  981.   int iY;
  982.   iX = psPart-/iX;
  983.   iY = psPart-/iY;
  984.   /* for CNCs and AGVs, need to see if part dropped on it */
  985.   /* This would be easier in a true OOPS */
  986.   for (iCNC = 0; iCNC . psWorld-/iCNCCount; iCNC++) {
  987.     psCNC = psWorld-/rpsCNCs[iCNC];
  988.     if (psCNC-/iX == iX && psCNC-/iY == iY) {
  989.       psCNC-/psPart = psPart;
  990.       return;
  991.       }
  992.     }
  993.   for (iAGV = 0; iAGV . psWorld-/iAGVCount; iAGV++) {
  994.     psAGV = psWorld-/rpsAGVs[iAGV];
  995.     if (psAGV-/iX == iX && psAGV-/iY == iY) {
  996.       psAGV-/psPart = psPart;
  997.       return;
  998.       } 
  999.     } 
  1000.   }
  1001.  
  1002. World_CheckLoadedAGVPresence(psWorld, iX, iY)
  1003. PSWORLD psWorld;
  1004. int iX, iY;
  1005.   {
  1006.   PSAGV psAGV;
  1007.   int iAGV;
  1008.  
  1009.   for (iAGV = 0; iAGV . psWorld-/iAGVCount; iAGV++) {
  1010.     psAGV = psWorld-/rpsAGVs[iAGV];
  1011.     if (psAGV-/iX == iX && psAGV-/iY == iY && psAGV-/psPart) {
  1012.       return(1);
  1013.       } 
  1014.     } 
  1015.   return(0);
  1016.   }
  1017.  
  1018. World_CheckUnloadedAGVPresence(psWorld, iX, iY)
  1019. PSWORLD psWorld;
  1020. int iX, iY;
  1021.   {
  1022.   PSAGV psAGV;
  1023.   int iAGV;
  1024.  
  1025.   for (iAGV = 0; iAGV . psWorld-/iAGVCount; iAGV++) {
  1026.     psAGV = psWorld-/rpsAGVs[iAGV];
  1027.     if (psAGV-/iX == iX && psAGV-/iY == iY && psAGV-/psPart == 0) {
  1028.       return(1);
  1029.       } 
  1030.     } 
  1031.   return(0);
  1032.   }
  1033.   
  1034. World_CheckForCNCFinished(psWorld, iX, iY)
  1035. PSWORLD psWorld;
  1036. int iX, iY;
  1037.   {
  1038.   PSCNC psCNC;
  1039.   int iCNC;
  1040.  
  1041.   for (iCNC = 0; iCNC . psWorld-/iCNCCount; iCNC++) {
  1042.     psCNC = psWorld-/rpsCNCs[iCNC];
  1043.     if (psCNC-/iX == iX && psCNC-/iY == iY) {
  1044.       return(psCNC-/iStep / psCNC-/iProgramSteps);
  1045.       } 
  1046.     } 
  1047.   return(0);
  1048.   }
  1049.  
  1050. World_CheckForCNCEmpty(psWorld, iX, iY)
  1051. PSWORLD psWorld;
  1052. int iX, iY;
  1053.   {
  1054.   PSCNC psCNC;
  1055.   int iCNC;
  1056.  
  1057.   for (iCNC = 0; iCNC . psWorld-/iCNCCount; iCNC++) {
  1058.     psCNC = psWorld-/rpsCNCs[iCNC];
  1059.     if (psCNC-/iX == iX && psCNC-/iY == iY) {
  1060.       return(psCNC-/psPart == 0);
  1061.       } 
  1062.     } 
  1063.   return(0);
  1064.   }
  1065.  
  1066. World_ElapseTime(psWorld)
  1067. PSWORLD psWorld;
  1068.   {
  1069.   int iPart;   
  1070.   int iCNC;
  1071.   int iAGV;
  1072.   int iRobot;
  1073.   simpleevents(); /* simple tools call */
  1074.   for (iPart = 0; iPart . psWorld-/iPartCount; iPart++) {
  1075.      Part_ElapseTime(psWorld-/rpsParts[iPart]);
  1076.     }
  1077.   for (iCNC = 0; iCNC . psWorld-/iCNCCount; iCNC++) {
  1078.     CNC_ElapseTime(psWorld-/rpsCNCs[iCNC]);
  1079.     }
  1080.   for (iAGV = 0; iAGV . psWorld-/iAGVCount; iAGV++) {
  1081.     AGV_ElapseTime(psWorld-/rpsAGVs[iAGV]);
  1082.     }
  1083.   for (iRobot = 0; iRobot . psWorld-/iRobotCount; iRobot++) {
  1084.     Robot_ElapseTime(psWorld-/rpsRobots[iRobot]);
  1085.     }
  1086.   }  
  1087.   
  1088. /* variables defining world */
  1089. SWORLD sWorld;
  1090. PSWORLD psWorld = &sWorld;
  1091.  
  1092. World_ElapseTimeAmount(psWorld, iAmount)
  1093. PSWORLD psWorld;
  1094. int iAmount;
  1095.   {
  1096.   for (;iAmount / 0; iAmount--) {
  1097.     if (iRunning == 0) return; /* break out of routine in multitasking system */
  1098.     World_ElapseTime(psWorld);
  1099.     }
  1100.   }
  1101.  
  1102. /* Robot routines that interact with the world object */
  1103.  
  1104. Robot_CheckLoadedAGVPresence(psRobot) /* check if AGV is below gripper */
  1105. PSROBOT psRobot;
  1106.   {
  1107.   return(World_CheckLoadedAGVPresence(psWorld, 
  1108.     psRobot-/iX + psRobot-/iGripperX, psRobot-/iY + psRobot-/iGripperY));
  1109.   }
  1110.  
  1111. Robot_CheckUnloadedAGVPresence(psRobot) /* check if AGV is below gripper */
  1112. PSROBOT psRobot;
  1113.   {
  1114.   return(World_CheckUnloadedAGVPresence(psWorld, 
  1115.     psRobot-/iX + psRobot-/iGripperX, psRobot-/iY + psRobot-/iGripperY));
  1116.   }
  1117.  
  1118. Robot_CheckForCNCFinished(psRobot) /* check if finished CNC below gripper */
  1119. PSROBOT psRobot;
  1120.   {
  1121.   return(World_CheckForCNCFinished(psWorld,
  1122.     psRobot-/iX + psRobot-/iGripperX, psRobot-/iY + psRobot-/iGripperY));
  1123.   }
  1124.  
  1125. Robot_CheckForCNCEmpty(psRobot) /* check if finished CNC below gripper */
  1126. PSROBOT psRobot;
  1127.   {
  1128.   return(World_CheckForCNCEmpty(psWorld,
  1129.     psRobot-/iX + psRobot-/iGripperX, psRobot-/iY + psRobot-/iGripperY));
  1130.   }
  1131.  
  1132. Robot_Grip(psRobot)
  1133. PSROBOT psRobot; 
  1134.   {
  1135.   psRobot-/psPart = World_PartGripped(psWorld, 
  1136.        psRobot-/iX + psRobot-/iGripperX, psRobot-/iY + psRobot-/iGripperY);
  1137.   }
  1138.  
  1139. Robot_Drop(psRobot)
  1140. PSROBOT psRobot; 
  1141.   {
  1142.   PSPART psPart;
  1143.   psPart = psRobot-/psPart;
  1144.   psRobot-/psPart = 0L; 
  1145.   World_PartDropped(psWorld, psPart);
  1146.   }
  1147.  
  1148.  
  1149. /* Simulation Code */
  1150.  
  1151. int riRobotProgram1[] = {
  1152.   ROBOT_PROGRAM_WEST,       50,
  1153.   ROBOT_PROGRAM_WAITFORLOADEDAGV,  0,
  1154.   ROBOT_PROGRAM_GRIP,        0,
  1155.   ROBOT_PROGRAM_SOUTHEAST, 100,
  1156.   ROBOT_PROGRAM_DROP,        0,
  1157.   ROBOT_PROGRAM_NORTH,     100,
  1158.   ROBOT_PROGRAM_WEST,       50,
  1159.   ROBOT_PROGRAM_SOUTHEAST,  50,
  1160.   ROBOT_PROGRAM_SOUTH,      50,
  1161.   ROBOT_PROGRAM_WAITFORCNCFINISHED,  0,
  1162.   ROBOT_PROGRAM_GRIP,        0,
  1163.   ROBOT_PROGRAM_NORTHWEST, 100,
  1164.   ROBOT_PROGRAM_WAITFORUNLOADEDAGV,  0,
  1165.   ROBOT_PROGRAM_DROP,        0,
  1166.   ROBOT_PROGRAM_EAST,       50,
  1167.   0, 0
  1168.   };
  1169.  
  1170. int riAGVProgram1[] = {
  1171.   AGV_PROGRAM_SOUTH,        50,
  1172.   AGV_PROGRAM_WAITFORUNLOAD, 0,
  1173.   AGV_PROGRAM_NORTH, 200,
  1174.   AGV_PROGRAM_WAIT,  200,
  1175.   AGV_PROGRAM_SOUTH, 200,
  1176.   AGV_PROGRAM_WAITFORLOAD, 0,
  1177.   AGV_PROGRAM_SOUTH, 200,
  1178.   0, 0
  1179.   };
  1180.  
  1181.  
  1182. simulation1() {
  1183.   SPART sPart;
  1184.   PSPART psPart;
  1185.   SROBOT sRobot;
  1186.   PSROBOT psRobot;
  1187.   SAGV sAGV;
  1188.   PSAGV psAGV;
  1189.   SCNC sCNC;
  1190.   PSCNC psCNC;
  1191.   
  1192.   if (iRunning) return;
  1193.   iRunning = 1;
  1194.   
  1195.   psPart = &sPart;
  1196.   psRobot = &sRobot;
  1197.   psAGV = &sAGV;
  1198.   psCNC = &sCNC;
  1199.   
  1200.   World_Initialize(psWorld);
  1201.   
  1202.   Part_Initialize(psPart, 50, 50, "Raw");
  1203.   World_AddPart(psWorld,psPart);
  1204.   
  1205.   Robot_Initialize(psRobot, 100, 100, "Robot One", riRobotProgram1);
  1206.   World_AddRobot(psWorld,psRobot);
  1207.  
  1208.   AGV_Initialize(psAGV, 50, 50, "AGV One", riAGVProgram1);
  1209.   psAGV-/psPart = psPart; /* needed for simulation as part starts on AGV */
  1210.   World_AddAGV(psWorld,psAGV);
  1211.  
  1212.   CNC_Initialize(psCNC, 150, 200, "CNC One", "Vase", 300);
  1213.   World_AddCNC(psWorld,psCNC);
  1214.  
  1215.   World_ElapseTimeAmount(psWorld,1500);
  1216.   iRunning = 0;
  1217.   }
  1218.  
  1219.  
  1220. int riRobotProgram2[] = {
  1221.   ROBOT_PROGRAM_LOADINDEX,   0,
  1222.   ROBOT_PROGRAM_LOADCOUNTER, 6,
  1223.   ROBOT_PROGRAM_NORTH,      50,
  1224.   ROBOT_PROGRAM_EAST,        0,
  1225.   ROBOT_PROGRAM_LOADTIMERFROMINDEX, 0,
  1226.   ROBOT_PROGRAM_GRIP,        0,
  1227.   ROBOT_PROGRAM_WEST,        0,
  1228.   ROBOT_PROGRAM_LOADTIMERFROMINDEX, 0,
  1229.   ROBOT_PROGRAM_SOUTH,     150,
  1230.   ROBOT_PROGRAM_WAITFORCNCEMPTY, 0,
  1231.   ROBOT_PROGRAM_DROP,        0,
  1232.   ROBOT_PROGRAM_NORTH,     100,
  1233.   ROBOT_PROGRAM_ADDTOCOUNTER, -1,
  1234.   ROBOT_PROGRAM_JUMPIFCOUNTERFALSE, 44,
  1235.   ROBOT_PROGRAM_NORTH,      50,
  1236.   ROBOT_PROGRAM_EAST,        0,
  1237.   ROBOT_PROGRAM_LOADTIMERFROMINDEX, 0,
  1238.   ROBOT_PROGRAM_ADDTOINDEX, 30,
  1239.   ROBOT_PROGRAM_EAST,       30,
  1240.   ROBOT_PROGRAM_JUMPIFCOUNTERTRUE, 10,
  1241.   ROBOT_PROGRAM_WEST,        0,
  1242.   0, 0
  1243.   };
  1244.  
  1245. int riRobotProgram3[] = {
  1246.   ROBOT_PROGRAM_LOADINDEX,   0,
  1247.   ROBOT_PROGRAM_LOADCOUNTER, 6,
  1248.   ROBOT_PROGRAM_WEST,      100,
  1249.   ROBOT_PROGRAM_WAITFORCNCFINISHED, 0,
  1250.   ROBOT_PROGRAM_GRIP,        0,
  1251.   ROBOT_PROGRAM_EAST,      150,
  1252.   ROBOT_PROGRAM_LOADTIMERFROMINDEX, 0,
  1253.   ROBOT_PROGRAM_DROP,        0,
  1254.   ROBOT_PROGRAM_WEST,        0,
  1255.   ROBOT_PROGRAM_LOADTIMERFROMINDEX, 0,
  1256.   ROBOT_PROGRAM_WEST,        50,
  1257.   ROBOT_PROGRAM_ADDTOCOUNTER, -1,
  1258.   ROBOT_PROGRAM_ADDTOINDEX, 50,
  1259.   ROBOT_PROGRAM_JUMPIFCOUNTERTRUE, 4,
  1260.   0, 0
  1261.   };
  1262.  
  1263.   
  1264. simulation2() {
  1265.   SPART sPart1, sPart2, sPart3, sPart4, sPart5, sPart6;
  1266.   SROBOT sRobot1, sRobot2, sRobot3;
  1267.   SAGV sAGV1, sAGV2;
  1268.   SCNC sCNC1, sCNC2;
  1269.  
  1270.   if (iRunning) return;
  1271.   iRunning = 1;
  1272.   
  1273.   World_Initialize(psWorld);
  1274.   
  1275.   Part_Initialize(&sPart1, 50, 50, "Raw");
  1276.   World_AddPart(psWorld,&sPart1);
  1277.   Part_Initialize(&sPart2, 80, 50, "Raw");
  1278.   World_AddPart(psWorld,&sPart2);
  1279.   Part_Initialize(&sPart3, 110, 50, "Raw");
  1280.   World_AddPart(psWorld,&sPart3);
  1281.   Part_Initialize(&sPart4, 140, 50, "Raw");
  1282.   World_AddPart(psWorld,&sPart4);
  1283.   Part_Initialize(&sPart5, 170, 50, "Raw");
  1284.   World_AddPart(psWorld,&sPart5);
  1285.   Part_Initialize(&sPart6, 200, 50, "Raw");
  1286.   World_AddPart(psWorld,&sPart6);
  1287.   
  1288.   Robot_Initialize(&sRobot1, 50, 100, "Robot One", riRobotProgram2);
  1289.   World_AddRobot(psWorld,&sRobot1);
  1290.  
  1291.   Robot_Initialize(&sRobot2, 150, 200, "Robot Two", riRobotProgram3);
  1292.   World_AddRobot(psWorld,&sRobot2);
  1293.  
  1294.   CNC_Initialize(&sCNC1, 50, 200, "CNC One", "Vase", 60);
  1295.   World_AddCNC(psWorld,&sCNC1);
  1296.  
  1297.   World_ElapseTimeAmount(psWorld,4000);
  1298.   
  1299.   iRunning = 0;
  1300.   }
  1301.   
  1302.  
  1303. my_itoa(iNumber, szString)
  1304. int iNumber;
  1305. char *szString;
  1306.   {
  1307.   int iDigit;
  1308.   char szNumber[MAX_LABEL+1];
  1309.   szNumber[MAX_LABEL] = '\0'; 
  1310.   for (iDigit = 1; iNumber / 0; iDigit++) {
  1311.     szNumber[MAX_LABEL - iDigit] = '0' + (iNumber % 10);
  1312.     iNumber /= 10; 
  1313.     }
  1314.   strcat(szString, szNumber+MAX_LABEL-iDigit+1);
  1315.   }
  1316.  
  1317.  
  1318. /*
  1319.         Title   : SimpleTools2.c
  1320.       Author  : Erik Kilk  Copyright 1985, 1987
  1321.      Dates   : June 7, 1985, June 3, 1986, November 8, 1986
  1322.                   November 28, 1986, April 17, 1987, April 21, 1987.
  1323.   
  1324.       SimpleTools is a collection of routines to aid programming
  1325.     simple "Macintosh looking" programs.  SimpleTools initializes
  1326.  the toolbox, monitors & acts upon events, and provides generic
  1327.         i/o routines for your application.  You initialize your program
  1328.        by letting SimpleTools know what windows and menus you want along
  1329.      with what functions SimpleTools should call when they are
  1330.      selected.
  1331.      
  1332.       The purpose of SimpleTools is to encourage you to program those
  1333.        simple programs or to pilot larger programs which you may not
  1334.  do due to the enormous effort required to use the Macintosh
  1335.    toolbox.  My goal was to study Inside Macintosh once to
  1336.        Create SimpleTools and then be able to forget most of the usages
  1337.       of the Toolbox routines.  Instead of thumbing through hundreds of
  1338.      pages of Inside Macintosh just to get something up and running,
  1339.        one need only remember a dozen generic calls.
  1340.  
  1341.        SimpleTools is very powerful, yet also very simple to use.  One
  1342.        can get a program up and running with desk accessories, windows,
  1343.       and menus in only a few minutes.  Advance features of SimpleTools
  1344.      allow you to retrieve enough information from SimpleTools to call
  1345.      any of the toolbox routines manually if need be.  
  1346.     
  1347.       
  1348. =========================================================================
  1349.  
  1350.  You may use, study, copy, and freely distribute SimpleTools if:
  1351.                1)  You mention "Programmed with the aid of SimpleTools
  1352.                    (c) Erik Kilk 1986" in your About... window of all
  1353.                     programs distributed free, share, or marketted.
  1354.            2)  You register by sending $20 or more to:
  1355.                    Erik Kilk
  1356.                      834 Hudis St
  1357.                         Rohnert Park, CA  94928
  1358.                        (707) 794-2424 weekday afternoons
  1359.                  to encourage me to maintain and improve SimpleTools.
  1360.                   
  1361. ==/       For a diskette including the most recent version of SimpleTools, 
  1362.      several detailed examples of using SimpleTools, and a MacWrite file
  1363.    describing SimpleTools and its use in more detail, send me a
  1364.   diskette with enough stamps to mail it back to you.  Make sure you
  1365.     have registered as stated above.
  1366.               
  1367.       This is 128k, MFS, HFS, old ROM, new ROM, Mac+, & TMON compatible.
  1368.     This file compiles and executes with Megamax 3.0 beta and
  1369.      LightSpeed 2.1.  Adjust the definition in simple.h for your
  1370.    compiler.  When porting to other compilers, pay particular
  1371.     attention to where the Lightspeed and Megamax code is specified
  1372.        since these places are the likely problem areas.
  1373.       
  1374.       LIGHTSPEED NOTE:
  1375.       
  1376.       Drag SimpleTools out of the main segment in your project window.
  1377.       You do this by dragging it below the dotted horizontal Line in the
  1378.     project window.
  1379.        
  1380.       SimpleTools requires the MacTraps library and stringsasm.c or
  1381.  strings.c.  If you load the unix library, your project will be
  1382.         larger than needed (unless you need unix for your own program.)
  1383.        
  1384.       MEGAMAX NOTE:
  1385.  
  1386.       Use Megamax's convert utility to convert all Mac names to all
  1387.  lower case.  If you send me suggestions and/or new code for
  1388.    SimpleTools, please convert back to mixed case first.
  1389.  
  1390. =========================================================================
  1391.    
  1392.       SimpleTools provides the following functions for your application
  1393.      to call.  Note that your application need not call any Toolbox
  1394.         routines directly.  The entire C program (including the standard
  1395.       desk accessory support):
  1396.       
  1397.                       main ()
  1398.                        {
  1399.                              simpletools ("Skel");
  1400.                          simplequits ();
  1401.                                runsimpletools ();
  1402.                     }
  1403.                      
  1404.       will execute as a Macintosh program, terminating upon the user
  1405.         selecting Quit.  SimpleTools includes:
  1406.         
  1407.               simpletools ()          - init Toolbox and SimpleTools
  1408.                 simplequits ()          - add Transfer & Quit menus
  1409.            simpleevents ()         - process next Mac event
  1410.               runsimpletools ()       - continuously process events
  1411.          
  1412.               menu ("File","New",new) - install a menu
  1413.               window ("My Window",..) - install a window
  1414.                                     
  1415.               run (function)          - install a periodic function
  1416.          stop (function)         - remove a periodic function
  1417.           
  1418.               havenewrom ()           - test for new 128k ROM
  1419.                withwindow("My Window") - set output to a window
  1420.               
  1421.               stgotoxy (x, y)         - set pen to text position x, y
  1422.                home ()                 - clear window, set pen to home
  1423.                getline (deflt, dest)   - with TE editing, get a Line
  1424.          prompt (question, dest) - with dialog box & TE, get a Line
  1425.             message (string)        - with dialog box, print a string
  1426.              getfile ("TEXT", name)  - with list, select a filename
  1427.                 putfile (orig, name)    - with list, select a filename
  1428.                 
  1429.       
  1430.       A complete Macintosh Style application (including windowing and 
  1431.       menus) is given in the following trivial example...
  1432.    
  1433.               #include .simple.h/
  1434.            
  1435.               char name[50];
  1436.                 
  1437.               got_beep()              
  1438.               {
  1439.                      SysBeep (10);
  1440.          }
  1441.              
  1442.               got_getname()
  1443.          {
  1444.                      char newname[50];
  1445.                      *newname = 0;
  1446.                  if (prompt ("What is your name?", newname)) {
  1447.                          strcpy (name, newname);
  1448.                                withwindow ("My Window");
  1449.                              home();
  1450.                                update();
  1451.                      }
  1452.              }
  1453.              
  1454.               in_content(x, y)
  1455.               int x, y;
  1456.              {
  1457.                      MoveTo (x, y); LineTo (x, y);
  1458.          }
  1459.              
  1460.               update()
  1461.               {
  1462.                      char outstring[100];
  1463.                   stgotoxy (1, 5);
  1464.                       sprintf (outstring,"Hello, %s", name);
  1465.                         #ifndef MEGAMAX
  1466.                          CtoPstr (outstring);
  1467.                         #endif
  1468.                         DrawString (outstring);
  1469.                }
  1470.              
  1471.               main ()
  1472.                {
  1473.                      simpletools ("Sample Program");
  1474.                        simplequits ();
  1475.                        menu ("Commands", "Beep", got_beep);
  1476.                   menu ("Commands", "Get Name", got_getname);
  1477.                    strcpy (name, "World");
  1478.                        window ("My Window",0,0,0,0,0L,0L,update,
  1479.                              in_content);
  1480.                   runsimpletools ();
  1481.             }
  1482.              
  1483. =========================================================================
  1484.  
  1485.  ROUTINES YOUR APPLICATION MAY CALL:
  1486.    
  1487.       
  1488.       simpleevents ()
  1489.        
  1490.       To be called repeatedly by your program's main routine.  In
  1491.    most SimpleTools programs, your main routine will initialize
  1492.   and install SimpleTools followed by an loop such as:
  1493.   
  1494.               for (;;) simpleevents();
  1495.               
  1496.       This routine handles all window changes, menu requests, and
  1497.    other Macintosh events.  There is also a routine called with
  1498.   runsimpletools() which does not return.  It simply performs the
  1499.        above loop.  Program exit is accomplished by assigning an
  1500.      exiting routine to a menu, usually this is File/Quit.
  1501.          
  1502.       
  1503.       simpletools (about_string)
  1504.     char *about_string;
  1505.    
  1506.       To be called once at the very beginning of your main routine.
  1507.  This routine initializes all the Macintosh software managers
  1508.   and installs the basic Apple, File, and Edit menus.  The 
  1509.      about_string is the name of the menu Item to appear first under
  1510.        the Apple menu.
  1511.        
  1512.       
  1513.       simplequits ()
  1514.         
  1515.       Installs a simple File/Quit and File/Transfer menu.  You only
  1516.  want to installs these if no application dependent processing
  1517.  must be done when the user selects Quit or Transfer.
  1518.   
  1519.       
  1520.       menu (name, Item, routine)
  1521.     char    *name;
  1522.         char    *Item;
  1523.         ProcPtr routine;
  1524.       
  1525.       To be called when a new menu is to be installed on the menu bar
  1526.        or when the characteristics of that menu are to be modified.
  1527.   Name is the name of the menu to appear on the menu bar.  Item
  1528.  is the name of the Item to appear under the menu name.  Routine
  1529.        is the name of the routine to be executed when the stated menu/Item
  1530.    has been selected.  The characteristics of the menu may be changed
  1531.     by passing one of the constants itemdisable, itemenable, itemcheck,
  1532.    or itemuncheck in place of the routine.
  1533.        
  1534.       
  1535.       window (name, xtop, ytop, xbot, ybot, act, deact, update, content)
  1536.     char    *name;
  1537.         int     xtop, ytop;
  1538.    int     xbot, ybot;
  1539.    ProcPtr act, deact, update, content;
  1540.   
  1541.       To be called when a new window is to be installed on the screen
  1542.        or when the characteristics of that window are to be modified.
  1543.         Name is the name of the window.  Xtop, ytop, xbot, and ybot are
  1544.        the initial coordinates of the new window.  Act is the name of
  1545.         the procedure to execute when the window becomes the top or
  1546.    active window.  Deact is the name of the procedure to execute when
  1547.     the window ceases being the top window and deactivates.  Update
  1548.        is the name of the procedure called when the Macintosh needs to
  1549.        redraw the window's contents.  Content is the name of the procedure
  1550.    called when the mouse is pressed within the window.  The procedure
  1551.     specified as content will be passed an x and y integer value
  1552.   representing the local mouse coordinates.
  1553.      
  1554.       
  1555.       withwindow (name)
  1556.      char *name;
  1557.    
  1558.       To be called when you want to select which window will receive
  1559.         output and drawings.  In most cases, SimpleTools will select the
  1560.       appropriate window before calling your specified act, deact,
  1561.   update, or content procedures.  Use this at other times.
  1562.       
  1563.       
  1564.       run (routine)
  1565.  ProcPtr routine;
  1566.       
  1567.       To be called when you want a routine to be continuously executed
  1568.       once each time simpleevents() is called.  Small, quickly running
  1569.       routines should be used so as not to Delay the next event
  1570.      processing.  Pseudo multiprocessing with each routine running in
  1571.       its own window can be accomplished by making sure a run routine
  1572.        uses withwindow() to direct its output to the proper window.
  1573.   
  1574.       
  1575.       stop (routine)
  1576.         ProcPtr routine;
  1577.       
  1578.       To be called when you want to remove a previously run() routine
  1579.        from the list of routines to run.  50 routines can fit into the
  1580.        run list.
  1581.      
  1582.       
  1583.       home ()
  1584.        
  1585.       Clears the current window and positions the pen such that any
  1586.  following text will appear in the upper left corner of the
  1587.     window.
  1588.        
  1589.       
  1590.       stgotoxy (column, row)
  1591.         int column, row;
  1592.       
  1593.       Positions the pen in the current window so that the next text
  1594.  output will appear in text row and column.  This is compatible
  1595.         with some old text only terminals.  stgotoxy (1, 1) positions the
  1596.      pen in the upper left corner.  Any negative coordinate leaves
  1597.  that axis of the pen where it currently is.
  1598.    
  1599.       
  1600.       getline (default, destination)
  1601.         char *default;
  1602.         char *destination;
  1603.     
  1604.       Calling this routine begins a "modal" mode where the user is
  1605.   required to enter a Line of text.  This would be similar to
  1606.    using scanf() on "non-Mac", text-only terminals.  This routine
  1607.         uses the Macintoshes built in Text-Edit routines allowing the
  1608.  user to edit his Line until .RETURN/ is pressed.  The flashing
  1609.         bar Cursor is positioned at the current pen location.  The 
  1610.    resulting string is placed into destination.  Default contains
  1611.         the initial value to be displayed on the screen.  You may use
  1612.  the null string "" for default.
  1613.        
  1614.       
  1615.       prompt (question, answer)
  1616.      char *question;
  1617.        char *answer;
  1618.  
  1619.       This routine places a small 3-lined Macintosh Style dialog window
  1620.      prompting the user with question and getting the answer in a
  1621.   boxed Text-Edit area.  Two buttons are displayed to terminate the
  1622.      user entry.  If Cancel is clicked upon, FALSE is returned.  If
  1623.         okay is clicked upon, TRUE is returned.  Answer must be set to
  1624.         a default value, "" is okay.
  1625.   
  1626.       
  1627.       message (message)
  1628.      char *message;
  1629.         
  1630.       This routine is similar to prompt except no textual response is
  1631.        asked from the user.  This is like an Alert dialog.  Just like
  1632.         prompt, TRUE or FALSE is returned depending upon which Button the
  1633.      user presses.
  1634.  
  1635.       
  1636.       getfile (file_type, reply)
  1637.     char *file_type;
  1638.       char *replay;
  1639.  
  1640.       This routine places the standard Macintosh SFGetFile() window
  1641.  up with a list of files of file_type.  Once the user selects a
  1642.         file, the answer is returned in the string reply.  Also, and
  1643.   very important for HFS, the working volume/folder is set so that
  1644.       any subsequent open() with reply as the file name will open the
  1645.        correct selected file.  The open() should be done before someone
  1646.       has a chance to change the working volume.  This routine will 
  1647.         return FALSE if the user selects the CANCEL Button.
  1648.    
  1649.       
  1650.       putfile (origname, reply)
  1651.      char *origname;
  1652.        char *reply;
  1653.   
  1654.       This routine is like getfile, except the standard putfile window
  1655.       is displayed with origname as the default name to save a file as.
  1656.      The actual name selected by the user is returned in reply.  As
  1657.         getfile, the working volume/folder is set properly for the next
  1658.        open() call.
  1659.  
  1660. =========================================================================
  1661.  
  1662.    THE FOLLOWING IS THE FILE simple.h.  YOU SHOULD COPY THIS PORTION
  1663.      INTO A NEW FILE NAMED simple.h SO YOU CAN #include IT INTO YOUR
  1664.        SOURCE FILES.
  1665.  
  1666. =========================================================================
  1667.  
  1668. #define LIGHTSPEED       {define either LIGHTSPEED or MEGAMAX or your own}
  1669.  
  1670. #include .stdio.h/
  1671.  
  1672. #ifdef MEGAMAX
  1673.   #include .menu.h/
  1674.   #include .win.h/
  1675. #endif
  1676.  
  1677. #ifdef LIGHTSPEED
  1678.   #include .MenuMgr.h/
  1679.   #include .WindowMgr.h/
  1680. #endif
  1681.  
  1682. #define itemdisable        0L              
  1683. #define itemenable    1L
  1684. #define itemcheck   2L
  1685. #define itemuncheck 3L
  1686.  
  1687. extern char               applestring[];
  1688. extern WindowPtr        windowpoint();
  1689. extern MenuHandle       mhand();
  1690. extern int            windmenu;
  1691. extern int           dogoaway;               
  1692. extern int            wprocid;                
  1693. extern int            show_new_window;
  1694. extern int            sizeredraw;
  1695. extern int         getlinecaps;
  1696. extern ProcPtr            keydownproc;
  1697. extern ProcPtr            autokeyproc;
  1698. extern void               home();
  1699. extern void            stnop();
  1700. =========================================================================
  1701.  
  1702.          Here begins SimpleTools.c
  1703.              _________________________
  1704. */
  1705.  
  1706. #include "simple.h"                    /* define compiler in here      */
  1707.  
  1708. #ifdef MEGAMAX                                                    
  1709.         overlay "simpletools"         /* compiler dependent           */
  1710.  
  1711.   #include .mem.h/
  1712.       #include .qd.h/
  1713.        #include .qdvars.h/
  1714.    #include .misc.h/
  1715.      #include .event.h/
  1716.     #include .res.h/
  1717.       #include .win.h/
  1718.       #include .dialog.h/
  1719.    #include .menu.h/
  1720.      #include .string.h/
  1721.    #include .stdio.h/
  1722.     #include .pack.h/
  1723.      #include .te.h/
  1724.        #include .toolbox.h/
  1725.   
  1726.       #define  ZZ     &
  1727. #else
  1728.       #include .MemoryMgr.h/
  1729.         #include .Quicke .te.h/
  1730.        #include .toolbox.h/
  1731.   
  1732.       #define  ZZ     &
  1733. #else
  1734.       #include .MemoryMgr.h/
  1735.         #include .Quickdraw.h/
  1736.         #include .EventMgr.h/
  1737.  #include .ResourceMgr.h/
  1738.       #include .WindowMgr.h/
  1739.         #include .TextEdit.h/
  1740.  #include .DialogMgr.h/
  1741.         #include .MenuMgr.h/
  1742.   #include .strings.h/
  1743.   #include .stdio.h/
  1744.     #include .PackageMgr.h/
  1745.        #include .ToolboxUtil.h/
  1746.       #include .StdFilePkg.h/
  1747.        #include .pascal.h/
  1748.    
  1749.       #define  ZZ     
  1750. #endif
  1751.  
  1752. #define TRUE (-1)           /* local definitions                    */
  1753. #define FALSE 0
  1754. #define maxsruns 50                /* procedure table size                 */
  1755. #define MESSN 30            /* array size for message dialog items  */
  1756. #define QUESN 40            /* array size for prompt dialog items   */
  1757. #define ROM85   0x28E               /* new rom stuff                        */
  1758. #define NEWROM  0x7FFF
  1759. #define inzoomout 8
  1760. #define inzoomin  7
  1761. #define zoomproc  8
  1762.  
  1763. typedef struct {                   /* structure for an Item        */
  1764.     char            itemname[40];
  1765.  int             itemno;         /* Item number within menu      */
  1766.     int             menuId;         /* menu id                      */
  1767.     MenuHandle      menuhand;       /* Item's menu's Handle                                 */
  1768.     ProcPtr         menurun;        /* procedure to run             */
  1769.     Ptr             next;           /* pointer to the next Item     */
  1770. } itemdatum;
  1771.  
  1772. typedef struct {                    /* structure for a menu         */
  1773.     char            menuname[20];   /* to allow reference by name   */
  1774.     int             menuId;         /* menu id                      */
  1775.     MenuHandle      menuhand;       /* menu Handle to reference menu*/
  1776.     itemdatum       **itemlist;     /* pointer to the list of items */
  1777.     Ptr             next;           /* pointer to the next menu     */
  1778. } menudatum;
  1779.  
  1780. typedef struct {                    /* structure for a window       */
  1781.     char            windname[80];   /* window's name and reference  */
  1782.     WindowPtr       wptr;           /* window's pointer reference   */
  1783.     ProcPtr wact;                   /* the activate procedure       */
  1784.     ProcPtr wdeact;                 /* the deactivate procedure     */
  1785.     ProcPtr wupdate;                /* the update procedure         */
  1786.     ProcPtr wcontent;               /* the content procedure        */
  1787.     Ptr             next;           /* pointer to the next window   */
  1788. } winddatum;
  1789.  
  1790. #ifdef LIGHTSPEED
  1791.   pascal Boolean         *TrackBox() = 0xA83B; 
  1792.   pascal void           *ZoomWindow() = 0xA83A;
  1793. #endif
  1794.  
  1795. WindowPtr windowpoint();
  1796.  
  1797. /* Local variables */
  1798.  
  1799. menudatum       **simplemenus;          /* Handle to menu data          */
  1800. char                accname[80];            /* desk accessory name to open  */
  1801. Rect                dragrect, sizerect;     /* limits for moving windows    */
  1802. Rect                swholescreen;
  1803. winddatum        **simplewinds;          /* Handle to window data        */
  1804. int         firstwind;              /* if no windows have been made */
  1805. ProcPtr     simpleruns[maxsruns];   /* list of procedures to run    */
  1806. WindowPtr   debugw;                 /* window pointer for debugging */
  1807. int         snewrom;
  1808. int           getlinecaps = FALSE;
  1809.  
  1810. /************************************************************************/
  1811. /* GLOBAL USER MODIFIABLE VARIABLES                                         */
  1812. /* These are variables that you can declare extern so that you can use      */
  1813. /* them to change the SimpleTools defaults                          */
  1814. /************************************************************************/
  1815.  
  1816. /* wprocid = type of window to Create on next window() call           */
  1817. /* For LightSpeed C, use a lower case d and upper case P for                */
  1818. /*  DocumentProc.  Megamax conversion program does this wrong.      */
  1819.  
  1820. int               wprocid = documentProc; 
  1821.  
  1822. /* dogoaway = is the next created window to have a go-away box              */
  1823.  
  1824. int               dogoaway = TRUE;        
  1825.  
  1826. /* keydownproc = the procedure to be called when keyDown is detected        */
  1827. /* autokeyproc = the procedure to be called when autoKey is detected        */
  1828. /* BOTH OF THESE ARE PASSED THE EVENTRECORD SO THE KEY CAN BE FOUND */
  1829.  
  1830. ProcPtr   keydownproc,
  1831.                   autokeyproc;            
  1832.               
  1833. /* applestring = a string containing the Apple for menu reference     */
  1834.  
  1835. char              applestring[2] 
  1836.                = {'\024', '\0'};       
  1837.  
  1838. /* windmenu = does the next window created get a choice under the
  1839.               window menu (so a closed window can be brought back        */
  1840.               
  1841. int                 windmenu = TRUE;        
  1842.  
  1843. /* sizeredraw = is the window's content area erased and made
  1844.                 updateable upon being resized                         */
  1845.                 
  1846. int               sizeredraw = FALSE;     
  1847.  
  1848. /* show_new_window = does the created window get displayed right away
  1849.              on the screen, if not, then it is hidden                */
  1850.             
  1851. int           show_new_window = TRUE;
  1852.  
  1853.  
  1854. /******************************************************************/
  1855. /* Dialog lists.  These were calculated by using the new resource */
  1856. /* editor to make a template for a dialog and then using fedit to */
  1857. /* list the hex listing of the Item list for the dialog.   */
  1858. /******************************************************************/
  1859.  
  1860. int messd[MESSN] = {2,0,0,0x38,0xf1,0x4c,0x12d,0x402,0x4f4b,0,0,5,5,
  1861.             0x36,0x12d,0x800,0,0,0x38,0xac,0x4c,0xe8,0x406,
  1862.                0x4361,0x6e63,0x656c};
  1863. int quesd[QUESN] = {3,0,0,0x21,0xf0,0x35,0x12c,0x402,0x4f4b,0,0,8,8,
  1864.           0x28,0xe8,0x800,0,0,0x2b,8,0x4b,0xe8,0x1000,0,0,
  1865.               8,0xf0,0x1c,0x12c,0x406,0x4361,0x6e63,0x656c};
  1866.                 
  1867.               
  1868. /* Local procedure */
  1869.  
  1870. void stnop()                         /* a no op procedure for defaults */
  1871. {
  1872. }
  1873.  
  1874. char *ptoc(s)
  1875. char *s;
  1876. {
  1877.       #ifndef MEGAMAX
  1878.                return (PtoCstr(s));
  1879.   #else
  1880.          return (s);
  1881.    #endif
  1882. }
  1883.  
  1884. char *ctop(s)
  1885. char *s;
  1886. {
  1887.        #ifndef MEGAMAX
  1888.                return (CtoPstr(s));
  1889.   #else
  1890.          return (s);
  1891.    #endif
  1892. }
  1893.  
  1894. /* Given a menu name, find our data structure for it.  Return a Handle
  1895.    to this structure.  This is a local procedure for SimpleTools use.
  1896. */
  1897.  
  1898. /* local procedure */
  1899.  
  1900. menudatum **getourmenuhandle (name)
  1901. char *name;                             /* name of menu bar menu */
  1902. {
  1903.         menudatum **here, **temp;       /* hand to menu structure*/
  1904.    here = simplemenus;
  1905.  
  1906.  /* find the menu name or the end of out menu list */
  1907.   HLock (here);
  1908.  while (strcmp(name,(**here).menuname) && (**here).next )  {
  1909.            temp = here;
  1910.           here = (menudatum **)(**here).next;
  1911.            HUnlock (temp);
  1912.                HLock (here);
  1913.  }
  1914.              
  1915.       /* see if we found it or just the end of the list */
  1916.   if (!strcmp(name,(**here).menuname)) {
  1917.                 HUnlock (here);
  1918.                return (here);
  1919.         } else {
  1920.               HUnlock (here);
  1921.                return ((menudatum **)0L);              
  1922.       }
  1923. }
  1924.  
  1925. /* This takes a Handle to our personal Item record and either a 
  1926.    procedure name or a modifier code.  If it got a procedure name,
  1927.    it sets it to the Item's procedure to run when the Item is chosen.
  1928.    If it got a modifier code, it changes the state of the menu's Item
  1929.    to checked, unchecked, enabled, or disabled.  It especially keeps 
  1930.    track of the standard Edit menu items so we can restore them after
  1931.    a desk accessory is finished.
  1932. */
  1933.  
  1934. /* Local procedure */
  1935.  
  1936. setitems ( items, routine)   /* set a menu Item's routine or display */
  1937. itemdatum   **items;        /* if items is neg, then whole menu     */
  1938. ProcPtr     routine;
  1939. {
  1940.    int                     inumber;
  1941.       MenuHandle              mhand;
  1942.         
  1943.       /* check to see if a procedure pointer was given to us */
  1944.      if ( (((long)items)/0L) && (routine / (ProcPtr)0x1000L)) {  
  1945.                                           /* good procedure value */
  1946.             (**items).menurun = routine;
  1947.           return;
  1948.        }
  1949.      
  1950.       /* Calculate which Item number we are going to modify */
  1951.       if ( (long)items . 0L) {                /* the whole menu       */
  1952.             mhand = (MenuHandle) (0L - (long)items);
  1953.               inumber = 0;
  1954.   } else {                                /* just one Item        */
  1955.             mhand = (**items).menuhand;
  1956.            inumber = (**items).itemno;
  1957.    }
  1958.  
  1959.    /* If a NULL procedure pointer, then set to a no_op routine */
  1960.         if ( (inumber / 0) && ((**items).menurun == (ProcPtr)0L) )
  1961.             (**items).menurun = (ProcPtr) stnop;
  1962.  
  1963.         /* Now change the state of a menu Item */
  1964.      switch ((int)routine) {
  1965.                case itemdisable: 
  1966.                     DisableItem(mhand,inumber); break;
  1967.             case itemenable:
  1968.                       EnableItem(mhand, inumber); break;
  1969.             case itemcheck:
  1970.                        CheckItem(mhand, inumber, TRUE); break;
  1971.                case itemuncheck:
  1972.                      CheckItem(mhand, inumber, FALSE); break;
  1973.       }
  1974.      if (inumber == 0) DrawMenuBar();  /* if main menu was changed   */
  1975.     
  1976. }
  1977.  
  1978. /* This routine is called by the simpletools() initial routine.  It gets
  1979.    the pointer list of menus started, loads the desk accessories into
  1980.    the Apple menu, and loads up some standard menu entries.  The reason
  1981.    menu File has a New entry, and none others, is because as this code
  1982.    currently stands, a menu must have at least one Item.  And since we
  1983.    want File before Edit, I had to make an entry.  The most commonly used
  1984.    Item under File is Quit.  But we like quit to be at the end of the list.
  1985.    So, since New is usually always first when it is used, that the one
  1986.    chosen to start File.  
  1987. */
  1988.  
  1989. /* Local procedure */
  1990.  
  1991. initsmenus(about)                   /* init simpletools' menus */
  1992. char *about;
  1993. {
  1994.         itemdatum **items;
  1995.  
  1996.   simplemenus = (menudatum **) NewHandle ( (long)sizeof(menudatum));
  1997.     HLock (simplemenus);
  1998.  
  1999.         strcpy ( (**simplemenus).menuname, applestring);
  2000.       (**simplemenus).menuId = 1;
  2001.    (**simplemenus).next = (Ptr) 0L;
  2002.       ctop ((**simplemenus).menuname);
  2003.       (**simplemenus).menuhand = NewMenu (1, (**simplemenus).menuname);
  2004.      ptoc ((**simplemenus).menuname);
  2005.       HUnlock ((**simplemenus).menuhand);
  2006.  
  2007.  (**simplemenus).itemlist = (itemdatum **)NewHandle ( 
  2008.                  (long)sizeof(itemdatum));
  2009.      items = (itemdatum **) (**simplemenus).itemlist;
  2010.       HLock (items);
  2011.  
  2012.      strcpy ((**items).itemname, about);
  2013.    (**items).itemno = 1;
  2014.  (**items).menuId = 1;
  2015.  (**items).menuhand = (**simplemenus).menuhand;
  2016.         (**items).menurun = (ProcPtr) stnop;
  2017.   (**items).next = 0L;
  2018.   HUnlock (items);
  2019.  
  2020.     ctop (about);
  2021.  AppendMenu ((**simplemenus).menuhand, about);
  2022.  ptoc (about);
  2023.  DisableItem ((**simplemenus).menuhand, 1);
  2024.     menu (applestring, "-", (ProcPtr) itemdisable);
  2025.        #ifdef MEGAMAX
  2026.           AddResMenu ((**simplemenus).menuhand, "DRVR");
  2027.       #else
  2028.    AddResMenu ((**simplemenus).menuhand, 'DRVR');
  2029.       #endif
  2030.         InsertMenu ((**simplemenus).menuhand, 0);
  2031.      HUnlock (simplemenus);
  2032.  
  2033.       menu ("File", "New", (ProcPtr)itemdisable);
  2034.    menu ("Edit", "Undo", stnop);
  2035.  menu ("Edit", "-", (ProcPtr)itemdisable);
  2036.      menu ("Edit", "Cut/X", stnop);
  2037.         menu ("Edit", "Copy/C", stnop);
  2038.        menu ("Edit", "Paste/V", stnop);
  2039.       menu ("Edit", "Clear", stnop);
  2040. }
  2041.  
  2042. /* Local procedure */
  2043.  
  2044. #ifndef LIGHTSPEED
  2045. gottrans () 
  2046. {
  2047.   char prog[80];
  2048.   char *argv[3];
  2049.   if ( getfile("APPL", prog) ) {
  2050.     argv[1] = NULL;
  2051.     execv (prog, argv);
  2052.   }
  2053. }
  2054. #endif
  2055.  
  2056. /* Local procedure */
  2057.  
  2058. gotquit ()
  2059. {
  2060.   ExitToShell();
  2061. }
  2062.  
  2063. /* This routine is for the Windows menu Item.  The Windows menu is
  2064.    set up when new windows are added.  It is used to bring forward and
  2065.    bring into view windows that may be under other windows or have been
  2066.    sent hiding by a click on their close box.
  2067. */
  2068.  
  2069. /* Local procedure */
  2070.  
  2071. showawindow(name)                    /* show the named window        */
  2072. char *name;
  2073. {
  2074.     WindowPtr foo;
  2075.         foo = windowpoint(name);        /* get its window pointer       */
  2076.     if ( foo ) {
  2077.           ShowWindow(foo);        /* show it on the screen        */
  2078.             SetPort (foo);          /* set further output to it */
  2079.                 if ( foo != FrontWindow())      /* if it isn't active,  */
  2080.                     SelectWindow (foo);     /* activate it          */
  2081.     }
  2082. }
  2083.  
  2084. /* Local procedure */
  2085.  
  2086. winddatum **wdatum(windpt)             /* return Handle to window data */
  2087. WindowPtr windpt;
  2088. {
  2089.       winddatum **wind, **temp;
  2090.  
  2091.    if (firstwind) return ((winddatum **) 0L);
  2092.     wind = simplewinds;
  2093.    HLock (wind);
  2094.  
  2095.        while ( ((**wind).wptr != windpt) && (**wind).next) {
  2096.          temp = wind;
  2097.           wind = (winddatum **) (**wind).next;
  2098.           HUnlock (temp);
  2099.                HLock (wind);
  2100.  }
  2101.  
  2102.    if ( (**wind).wptr == windpt) {
  2103.                HUnlock (wind);
  2104.                return (wind);
  2105.         } else {
  2106.               HUnlock (wind);
  2107.                return ((winddatum **) 0L);     /* zero if not found */
  2108.        }
  2109. }
  2110.   
  2111. /* Local procedure */
  2112.  
  2113. runruns(event)                       /* run all the installed run procedures */
  2114. EventRecord *event;         /* returns number of routines run       */
  2115. {
  2116.  int i=0;
  2117.       WindowPtr saveport;
  2118.    GetPort (&saveport);
  2119.   while ( simpleruns[i] )
  2120.                (*(simpleruns[i++])) (event);
  2121.  SetPort (saveport);
  2122.    return(i);
  2123. }
  2124.  
  2125. /* Local procedure */
  2126.  
  2127. stdialog( question, answer, type)  /* a general dialog displayer      */
  2128. char *question;
  2129. char *answer;
  2130. int  type;                  /* type:  1=prompt, 2=message           */
  2131. {
  2132.  DialogPtr dialog;       /* dialog reference                     */
  2133.     Handle Item, items;     /* handles for the dialog items         */
  2134.     Rect screen, box;       /* rectangles for dialog/items          */
  2135.     int dtype, hit, canc;   /* Item type and which was hit          */
  2136.     char tempanswer[255];   /* address where answer is              */
  2137.  
  2138.   items = NewHandle (512L);/* get memory for items list           */
  2139.     HLock (items);          /* lock it down                         */
  2140.     if (type == 1)
  2141.                 BlockMove (quesd, *items, (long) QUESN * 2L); 
  2142.         else
  2143.           BlockMove (messd, *items, (long) MESSN * 2L);
  2144.  SetRect (&screen, 103, 50, 409, 137);           
  2145.       
  2146.       /* For LIGHTSPEED, use a lower case d and upper case B and P    */
  2147.     /* for DBoxProc.  Megamax conversion utility does this wrong.   */
  2148.     
  2149.       dialog = NewDialog (0L, &screen, "", 0, dBoxProc, -1L, 0, 0L, items);
  2150.  GetDItem (dialog, 2, &dtype, &Item, &box);
  2151.     ctop (question);        
  2152.       SetIText (Item, question);              /* set Item#2 text      */
  2153.     ptoc (question);
  2154.       if (type == 1) {                        /* set default answer   */
  2155.             GetDItem (dialog, 3, &dtype, &Item, &box);
  2156.             ctop (answer);
  2157.                 SetIText (Item, answer);
  2158.