home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d5xx / d597 / gold.lha / GoLD / GoLD.c < prev    next >
C/C++ Source or Header  |  1992-02-01  |  29KB  |  1,403 lines

  1. /***************************************************************************
  2.  *                                                                         *
  3.  * 'Game of Life - Duo' - a "Game of Life" for 2 kinds of cells            *
  4.  *                                                                         *
  5.  ***************************************************************************
  6.  *                                                                         *
  7.  * Created by                                                              *
  8.  *              Andreas Neubacher                                          *
  9.  *                                                                         *
  10.  *              Hausleitnerweg 26                                          *
  11.  *              4020 Linz                                                  *
  12.  *              Austria                                                    *
  13.  *                                                                         *
  14.  *              E-mail: aneubach@risc.uni-linz.ac.at (Internet)            *
  15.  *                       k318577@alijku11            (Bitnet)              *
  16.  *                                                                         *
  17.  ***************************************************************************
  18.  *                                                                         *
  19.  *  Copyright notice:                                                      *
  20.  *  I don't claim any copyright and put this code into the public domain.  *
  21.  *                                                                         *
  22.  ***************************************************************************
  23.  *                                                                         *
  24.  * 92-01-23  AN : Finished release version                                 *
  25.  *                                                                         *
  26.  ***************************************************************************/
  27.  
  28. #include <exec/types.h>
  29. #include <exec/memory.h>
  30. #include <intuition/intuition.h>
  31. #include "functions.h"
  32.  
  33. #ifdef _DCC
  34. void wbmain() { main(); }   /* DICE needs this for Workbench startup. */
  35. #endif
  36.  
  37.  
  38. extern void SetCell(struct BitMap*,short,short,short),
  39.             ScanAgar(char*,char*,char*,short,short,short),
  40.             ChangeAgar(struct BitMap*,char*,char*,short,short,short,short),
  41.             DisplayAgar(struct BitMap*,char*,short,short,short,short),
  42.             CountCells(char*,short*,short*,unsigned short);
  43.  
  44.  
  45. #define XSIZE   162   /* No. of columns + 2 */
  46. #define YSIZE   62    /* No. of rows + 2    */
  47.  
  48. #define AGARLE  0     /* Coordinates of the left upper corner */
  49. #define AGARTE  25    /* of the 'Agar' output area.           */
  50.  
  51. #define MAXCELL 3     /* No. of cell types (dead, red, blue) */
  52. #define MAXVAL  16    /* 8 * (MAXCELL-1)                     */
  53.  
  54. #define NULLCODE  1   /* Code for dead cells               */
  55. #define P1CODE    0   /* Code for Strain 1 cells           */
  56. #define P2CODE    2   /* Code for Strain 2 cells           */
  57. #define NOCODE    3   /* Code for 'cell remains unchanges' */
  58.  
  59. #define NULLPEN   0             /* Color for dead cells     */
  60. #define P1PEN     2             /* Color for Strain 1 cells */
  61. #define P2PEN     1             /* Color for Strain 2 cells */
  62. #define GRIDPEN   MAXCELL       /* Color for grid           */
  63. #define FGPEN     MAXCELL + 1L  /* Textcolor                */
  64.  
  65.  
  66. /***************************************************************************
  67.  *
  68.  * MENUS
  69.  *
  70.  ***************************************************************************/
  71.  
  72. #define EDITITEMWID 100 + COMMWIDTH
  73. #define PITEMWID    60
  74.  
  75. struct IntuiText ClearText = {
  76.   0,0,JAM1,
  77.   8,1,
  78.   NULL,
  79.   "Clear Agar",
  80.   NULL
  81. };
  82.  
  83. struct MenuItem ClearItem = {
  84.   NULL,
  85.   0,10,EDITITEMWID,10,
  86.   ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ,
  87.   0,
  88.   (APTR)&ClearText,
  89.   NULL,
  90.   'c',
  91.   NULL,0
  92. };
  93.  
  94. struct IntuiText UndoText = {
  95.   0,0,JAM1,
  96.   8,1,
  97.   NULL,
  98.   "Undo",
  99.   NULL
  100. };
  101.  
  102. struct MenuItem UndoItem = {
  103.   &ClearItem,
  104.   0,0,EDITITEMWID,10,
  105.   ITEMTEXT | ITEMENABLED | HIGHCOMP | COMMSEQ,
  106.   0,
  107.   (APTR)&UndoText,
  108.   NULL,
  109.   'u',
  110.   NULL,0
  111. };
  112.  
  113. struct Menu EditMenu = {
  114.   NULL,
  115.   75,0,40,0,
  116.   MENUENABLED,
  117.   "Edit",
  118.   &UndoItem
  119. };
  120.  
  121. struct IntuiText QuitText = {
  122.   0,0,JAM1,
  123.   8,1,
  124.   NULL,
  125.   "Quit",
  126.   NULL
  127. };
  128.  
  129. struct MenuItem QuitItem = {
  130.   NULL,
  131.   0,36,PITEMWID,10,
  132.   ITEMTEXT | ITEMENABLED | HIGHCOMP,
  133.   0,
  134.   (APTR)&QuitText,
  135.   NULL,0,NULL,0
  136. };
  137.  
  138. struct IntuiText ResetText = {
  139.   0,0,JAM1,
  140.   8,1,
  141.   NULL,
  142.   "Reset",
  143.   NULL
  144. };
  145.  
  146. struct MenuItem ResetItem = {
  147.   &QuitItem,
  148.   0,24,PITEMWID,10,
  149.   ITEMTEXT | ITEMENABLED | HIGHCOMP,
  150.   0,
  151.   (APTR)&ResetText,
  152.   NULL,0,NULL,0
  153. };
  154.  
  155. struct IntuiText RulesText = {
  156.   0,0,JAM1,
  157.   8,1,
  158.   NULL,
  159.   "Rules",
  160.   NULL
  161. };
  162.  
  163. struct MenuItem RulesItem = {
  164.   &ResetItem,
  165.   0,12,PITEMWID,10,
  166.   ITEMTEXT | ITEMENABLED | HIGHCOMP,
  167.   0,
  168.   (APTR)&RulesText,
  169.   NULL,0,NULL,0
  170. };
  171.  
  172. struct IntuiText AboutText = {
  173.   0,0,JAM1,
  174.   8,1,
  175.   NULL,
  176.   "About",
  177.   NULL
  178. };
  179.  
  180. struct MenuItem AboutItem = {
  181.   &RulesItem,
  182.   0,0,PITEMWID,10,
  183.   ITEMTEXT | ITEMENABLED | HIGHCOMP,
  184.   0,
  185.   (APTR)&AboutText,
  186.   NULL,0,NULL,0
  187. };
  188.  
  189. struct Menu ProjectMenu = {
  190.   &EditMenu,
  191.   0,0,PITEMWID,0,
  192.   MENUENABLED,
  193.   "Project",
  194.   &AboutItem
  195. };
  196.  
  197.  
  198. /***************************************************************************
  199.  *
  200.  * GADGETS
  201.  *
  202.  ***************************************************************************/
  203.  
  204. #define P1ID    1
  205. #define P2ID    2
  206. #define GROWID  3
  207. #define AGARID  4
  208. #define CS1ID   8
  209. #define CS2ID   9
  210. #define GS1ID   10
  211. #define GS2ID   11
  212. #define ROKID   12
  213. #define RCANID  13
  214. #define UOKID   14
  215. #define UCANID  15
  216. #define AOKID   16
  217. #define UX0ID   32
  218.  
  219. short PnXY[] = { 0,0, 67,0, 67,11, 0,11, 0,0 };
  220.  
  221. struct Border PnBorder = {
  222.   -1,-1,
  223.   0,0,JAM1,
  224.   5,PnXY,
  225.   NULL
  226. };
  227.  
  228. struct Border P2Border = {
  229.   -1,-1,
  230.   P2PEN,0,JAM1,
  231.   5,PnXY,
  232.   NULL
  233. };
  234.  
  235. struct IntuiText P2Text = {
  236.   P2PEN,0,JAM2,
  237.   1,1,
  238.   NULL,
  239.   "Strain 2",
  240.   NULL
  241. };
  242.  
  243. struct Gadget P2Gadget = {
  244.   NULL,
  245.   520,13,66,10,
  246.   GADGHIMAGE,
  247.   TOGGLESELECT | RELVERIFY,
  248.   BOOLGADGET,
  249.   (APTR)&PnBorder,
  250.   (APTR)&P2Border,
  251.   &P2Text,
  252.   0,NULL,
  253.   P2ID,
  254.   NULL
  255. };
  256.  
  257. struct Border P1Border = {
  258.   -1,-1,
  259.   P1PEN,0,JAM1,
  260.   5,PnXY,
  261.   NULL
  262. };
  263.  
  264. struct IntuiText P1Text = {
  265.   P1PEN,0,JAM2,
  266.   1,1,
  267.   NULL,
  268.   "Strain 1",
  269.   NULL
  270. };
  271.  
  272. struct Gadget P1Gadget = {
  273.   &P2Gadget,
  274.   55,13,66,10,
  275.   GADGHIMAGE | SELECTED,
  276.   TOGGLESELECT | RELVERIFY,
  277.   BOOLGADGET,
  278.   (APTR)&PnBorder,
  279.   (APTR)&P1Border,
  280.   &P1Text,
  281.   0,NULL,
  282.   P1ID,
  283.   NULL
  284. };
  285.  
  286. short GrowXY[] =
  287.  { 0,0, 35,0, 35,11, 0,11, 0,0 };
  288.  
  289. struct Border GrowBorder = {
  290.   -1,-1,
  291.   FGPEN,0,JAM1,
  292.   5,GrowXY,
  293.   NULL
  294. };
  295.  
  296. struct IntuiText GrowText = {
  297.   FGPEN,0,JAM2,
  298.   1,1,
  299.   NULL,
  300.   "Grow",
  301.   NULL
  302. };
  303.  
  304. struct Gadget GrowGadget = {
  305.   &P1Gadget,
  306.   302,30,34,10,
  307.   GADGHCOMP,
  308.   GADGIMMEDIATE | RELVERIFY,
  309.   BOOLGADGET,
  310.   (APTR)&GrowBorder,
  311.   NULL,
  312.   &GrowText,
  313.   0,NULL,
  314.   GROWID,
  315.   NULL
  316. };
  317.  
  318. struct Gadget AgarGadget = {
  319.   &GrowGadget,
  320.   4 * AGARLE,3 * AGARTE,
  321.   4 * XSIZE - 9,3 * YSIZE - 7,
  322.   GADGHNONE,
  323.   GADGIMMEDIATE | RELVERIFY,
  324.   BOOLGADGET,
  325.   NULL,NULL,NULL,0,NULL,
  326.   AGARID,
  327.   NULL
  328. };
  329.  
  330. SHORT RReqGXY[] = { 0,0, 51,0, 51,11, 0,11, 0,0 };
  331.  
  332. struct Border RReqGBorder = {
  333.   -2,-2,
  334.   GRIDPEN,0,JAM1,
  335.   5,RReqGXY,
  336.   NULL
  337. };
  338.  
  339. char CS1Buffer[7] = { '0',0 };
  340.  
  341. struct StringInfo CS1SInfo = {
  342.   CS1Buffer,
  343.   NULL,
  344.   0,7,0,
  345.   0,0,0,0,0,NULL,0L,NULL
  346. };
  347.  
  348. struct Gadget CS1Gadget = {
  349.   NULL,
  350.   146,30,50,10,
  351.   GADGHCOMP,
  352.   RELVERIFY | LONGINT,
  353.   STRGADGET | REQGADGET,
  354.   (APTR)&RReqGBorder,
  355.   NULL,NULL,0L,
  356.   (APTR)&CS1SInfo,
  357.   CS1ID,
  358.   NULL
  359. };
  360.  
  361. char CS2Buffer[7] = { '0',0 };
  362.  
  363. struct StringInfo CS2SInfo = {
  364.   CS2Buffer,
  365.   NULL,
  366.   0,7,0,
  367.   0,0,0,0,0,NULL,0L,NULL
  368. };
  369.  
  370. struct Gadget CS2Gadget = {
  371.   &CS1Gadget,
  372.   218,30,50,10,
  373.   GADGHCOMP,
  374.   RELVERIFY | LONGINT,
  375.   STRGADGET | REQGADGET,
  376.   (APTR)&RReqGBorder,
  377.   NULL,NULL,0L,
  378.   (APTR)&CS2SInfo,
  379.   CS2ID,
  380.   NULL
  381. };
  382.  
  383. char GS1Buffer[7] = { '0',0 };
  384.  
  385. struct StringInfo GS1SInfo = {
  386.   GS1Buffer,
  387.   NULL,
  388.   0,7,0,
  389.   0,0,0,0,0,NULL,0L,NULL
  390. };
  391.  
  392. struct Gadget GS1Gadget = {
  393.   &CS2Gadget,
  394.   146,44,50,10,
  395.   GADGHCOMP,
  396.   RELVERIFY | LONGINT,
  397.   STRGADGET | REQGADGET,
  398.   (APTR)&RReqGBorder,
  399.   NULL,NULL,0L,
  400.   (APTR)&GS1SInfo,
  401.   GS1ID,
  402.   NULL
  403. };
  404.  
  405. char GS2Buffer[7] = { '0',0 };
  406.  
  407. struct StringInfo GS2SInfo = {
  408.   GS2Buffer,
  409.   NULL,
  410.   0,7,0,
  411.   0,0,0,0,0,NULL,0L,NULL
  412. };
  413.  
  414. struct Gadget GS2Gadget = {
  415.   &GS1Gadget,
  416.   218,44,50,10,
  417.   GADGHCOMP,
  418.   RELVERIFY | LONGINT,
  419.   STRGADGET | REQGADGET,
  420.   (APTR)&RReqGBorder,
  421.   NULL,NULL,0L,
  422.   (APTR)&GS2SInfo,
  423.   GS2ID,
  424.   NULL
  425. };
  426.  
  427. struct IntuiText ROKText = {
  428.   GRIDPEN,0,JAM1,
  429.   0,0,
  430.   NULL,
  431.   "  OK  ",
  432.   NULL
  433. };
  434.  
  435. struct Gadget ROKGadget = {
  436.   &GS2Gadget,
  437.   45,65,48,8,
  438.   GADGHCOMP,
  439.   RELVERIFY | ENDGADGET,
  440.   BOOLGADGET | REQGADGET,
  441.   (APTR)&RReqGBorder,
  442.   NULL,
  443.   &ROKText,
  444.   0L,NULL,
  445.   ROKID,
  446.   NULL
  447. };
  448.  
  449. struct IntuiText RCanText = {
  450.   GRIDPEN,0,JAM1,
  451.   0,0,
  452.   NULL,
  453.   "CANCEL",
  454.   NULL
  455. };
  456.  
  457. struct Gadget RCanGadget = {
  458.   &ROKGadget,
  459.   185,65,48,8,
  460.   GADGHCOMP,
  461.   RELVERIFY | ENDGADGET,
  462.   BOOLGADGET | REQGADGET,
  463.   (APTR)&RReqGBorder,
  464.   NULL,
  465.   &RCanText,
  466.   0L,NULL,
  467.   RCANID,
  468.   NULL
  469. };
  470.  
  471. SHORT UXXY[] = { 0,0, 15,8, 15,0, 0,8, 0,0 };
  472.  
  473. struct Border BlackXBorder = {
  474.   0,0,
  475.   0,0,JAM1,
  476.   5,UXXY,
  477.   NULL
  478. };
  479.  
  480. struct Border P1XBorder = {
  481.   0,0,
  482.   P1PEN,0,JAM1,
  483.   5,UXXY,
  484.   NULL
  485. };
  486.  
  487. struct Border P2XBorder = {
  488.   0,0,
  489.   P2PEN,0,JAM1,
  490.   5,UXXY,
  491.   NULL
  492. };
  493.  
  494. struct Gadget UXGadget[MAXCELL][MAXVAL+1] = { {
  495.   NULL,
  496.   6,26,15,9,
  497.   GADGHCOMP,
  498.   RELVERIFY,
  499.   BOOLGADGET | REQGADGET,
  500.   (APTR)&BlackXBorder,
  501.   NULL,NULL,0L,NULL,
  502.   UX0ID,
  503.   NULL
  504. } };
  505.  
  506. struct Gadget UOKGadget = {
  507.   UXGadget,
  508.   45,65,48,8,
  509.   GADGHCOMP,
  510.   RELVERIFY | ENDGADGET,
  511.   BOOLGADGET | REQGADGET,
  512.   (APTR)&RReqGBorder,
  513.   NULL,
  514.   &ROKText,
  515.   0L,NULL,
  516.   UOKID,
  517.   NULL
  518. };
  519.  
  520. struct Gadget UCanGadget = {
  521.   &UOKGadget,
  522.   185,65,48,8,
  523.   GADGHCOMP,
  524.   RELVERIFY | ENDGADGET,
  525.   BOOLGADGET | REQGADGET,
  526.   (APTR)&RReqGBorder,
  527.   NULL,
  528.   &RCanText,
  529.   0L,NULL,
  530.   UCANID,
  531.   NULL
  532. };
  533.  
  534. SHORT AOKGXY[] = { 0,0, 51,0, 51,11, 0,11, 0,0 };
  535.  
  536. struct Border AOKGBorder = {
  537.   -2,-2,
  538.   P2PEN,0,JAM1,
  539.   5,AOKGXY,
  540.   NULL
  541. };
  542.  
  543. struct IntuiText AOKText = {
  544.   P1PEN,0,JAM1,
  545.   0,0,
  546.   NULL,
  547.   "Great!",
  548.   NULL
  549. };
  550.  
  551. struct Gadget AOKGadget = {
  552.   NULL,
  553.   100,76,48,8,
  554.   GADGHCOMP,
  555.   RELVERIFY | ENDGADGET,
  556.   BOOLGADGET | REQGADGET,
  557.   (APTR)&AOKGBorder,
  558.   NULL,
  559.   &AOKText,
  560.   0L,NULL,
  561.   AOKID,
  562.   NULL
  563. };
  564.  
  565. /***************************************************************************
  566.  *
  567.  * REQUESTERS
  568.  *
  569.  ***************************************************************************/
  570.  
  571. #define RREQWID 280
  572. #define RREQHEI 78
  573.  
  574. SHORT RReqXY[] = { 1,13, RREQWID-2,13, RREQWID-2,RREQHEI-2, 1,RREQHEI-2,
  575.   1,1, RREQWID-2,1, RREQWID-2,13 };
  576.  
  577. struct Border RReqBorder = {
  578.   0,0,
  579.   0,0,JAM1,
  580.   7,RReqXY,
  581.   NULL
  582. };
  583.  
  584. struct IntuiText RReqText1 = {
  585.   P1PEN,0,JAM1,
  586.   138,18,
  587.   NULL,
  588.   "Strain 1",
  589.   NULL
  590. };
  591.  
  592. struct IntuiText RReqText2 = {
  593.   P2PEN,0,JAM1,
  594.   210,18,
  595.   NULL,
  596.   "Strain 2",
  597.   &RReqText1
  598. };
  599.  
  600. struct IntuiText RReqText3 = {
  601.   GRIDPEN,0,JAM1,
  602.   6,4,
  603.   NULL,
  604.   "Reset initial values",
  605.   &RReqText2
  606. };
  607.  
  608. struct IntuiText RReqText4 = {
  609.   GRIDPEN,0,JAM1,
  610.   10,30,
  611.   NULL,
  612.   "Cells in Freezer",
  613.   &RReqText3
  614. };
  615.  
  616. struct IntuiText RReqText5 = {
  617.   GRIDPEN,0,JAM1,
  618.   6,44,
  619.   NULL,
  620.   "Growth in Freezer",
  621.   &RReqText4
  622. };
  623.  
  624. struct Requester ResetReq = {
  625.   NULL,
  626.   180,121,RREQWID,RREQHEI,
  627.   0,0,
  628.   &RCanGadget,
  629.   &RReqBorder,
  630.   &RReqText5,
  631.   0,FGPEN,
  632.   NULL,{0},NULL,NULL,{0}
  633. };
  634.  
  635. #define UREQWID 284
  636. #define UREQHEI 78
  637.  
  638. SHORT UReqXY2[] = { 0,0, 273,0, 273,10, 0,10, 0,0 };
  639.  
  640. struct Border UReqBorder4 = {
  641.   5,49,
  642.   P2PEN,0,JAM1,
  643.   5,UReqXY2,
  644.   NULL
  645. };
  646.  
  647. struct Border UReqBorder3 = {
  648.   5,37,
  649.   0,0,JAM1,
  650.   5,UReqXY2,
  651.   &UReqBorder4
  652. };
  653.  
  654. struct Border UReqBorder2 = {
  655.   5,25,
  656.   P1PEN,0,JAM1,
  657.   5,UReqXY2,
  658.   &UReqBorder3
  659. };
  660.  
  661. SHORT UReqXY1[] = { 1,13, UREQWID-2,13, UREQWID-2,UREQHEI-2, 1,UREQHEI-2,
  662.   1,1, UREQWID-2,1, UREQWID-2,13 };
  663.  
  664. struct Border UReqBorder1 = {
  665.   0,0,
  666.   0,0,JAM1,
  667.   7,UReqXY1,
  668.   &UReqBorder2
  669. };
  670.  
  671. struct IntuiText UReqText4 = {
  672.   P2PEN,0,JAM1,
  673.   150,16,
  674.   NULL,
  675.   "+1+2+3+4+5+6+7+8",
  676.   NULL
  677. };
  678.  
  679. struct IntuiText UReqText3 = {
  680.   GRIDPEN,0,JAM1,
  681.   134,16,
  682.   NULL,
  683.   "±0",
  684.   &UReqText4
  685. };
  686.  
  687. struct IntuiText UReqText2 = {
  688.   P1PEN,0,JAM1,
  689.   6,16,
  690.   NULL,
  691.   "-8-7-6-5-4-3-2-1",
  692.   &UReqText3
  693. };
  694.  
  695. struct IntuiText UReqText1 = {
  696.   GRIDPEN,0,JAM1,
  697.   6,4,
  698.   NULL,
  699.   "Define rules",
  700.   &UReqText2
  701. };
  702.  
  703. struct Requester RulesReq = {
  704.   NULL,
  705.   180,121,UREQWID,UREQHEI,
  706.   0,0,
  707.   &UCanGadget,
  708.   &UReqBorder1,
  709.   &UReqText1,
  710.   0,FGPEN,
  711.   NULL,{0},NULL,NULL,{0}
  712. };
  713.  
  714. #define AREQWID   158L
  715. #define AREQHEI   90L
  716.  
  717. SHORT AReqXY[] = { 0,0, AREQWID-5,0, AREQWID-5,AREQHEI-3, 0,AREQHEI-3, 0,0 };
  718.  
  719. struct Border AReqBorder = {
  720.   2,1,
  721.   P2PEN,0,JAM1,
  722.   5,AReqXY,
  723.   NULL
  724. };
  725.  
  726. struct IntuiText AReqText1 = {
  727.   P1PEN,0,JAM1,
  728.   6,4,
  729.   NULL,
  730.   "GAME OF LIFE - DUO",
  731.   NULL
  732. };
  733.  
  734. struct IntuiText AReqText2 = {
  735.   P1PEN,0,JAM1,
  736.   6,20,
  737.   NULL,
  738.   "(C)reated 1992 by",
  739.   &AReqText1
  740. };
  741.  
  742. struct IntuiText AReqText3 = {
  743.   P1PEN,0,JAM1,
  744.   6,34,
  745.   NULL,
  746.   "Andreas Neubacher",
  747.   &AReqText2
  748. };
  749.  
  750. struct IntuiText AReqText4 = {
  751.   P1PEN,0,JAM1,
  752.   6,48,
  753.   NULL,
  754.   "Hausleitnerweg 26",
  755.   &AReqText3
  756. };
  757.  
  758. struct IntuiText AReqText5 = {
  759.   P1PEN,0,JAM1,
  760.   6,58,
  761.   NULL,
  762.   "4020 Linz",
  763.   &AReqText4
  764. };
  765.  
  766. struct IntuiText AReqText6 = {
  767.   P1PEN,0,JAM1,
  768.   6,68,
  769.   NULL,
  770.   "Austria",
  771.   &AReqText5
  772. };
  773.  
  774. struct Requester AboutReq = {
  775.   NULL,
  776.   244,81,AREQWID,AREQHEI,
  777.   0,0,
  778.   &AOKGadget,
  779.   &AReqBorder,
  780.   &AReqText6,
  781.   0,FGPEN,
  782.   NULL,{0},NULL,NULL,{0}
  783. };
  784.  
  785. /***************************************************************************
  786.  *
  787.  * POINTER
  788.  *
  789.  ***************************************************************************/
  790.  
  791. #define PTRWIDTH    9L
  792. #define PTRHEIGHT   8L
  793. #define PTRXOFFSET  -5L
  794. #define PTRYOFFSET  -4L
  795.  
  796. USHORT PointerData[] = {
  797.   0x0000,0x0000,
  798.   0x8080,0x0000,
  799.   0x4100,0x0000,
  800.   0x2200,0x0000,
  801.   0x0000,0x0000,
  802.   0x0000,0x0000,
  803.   0x2200,0x0000,
  804.   0x4100,0x0000,
  805.   0x8080,0x0000,
  806.   0x0000,0x0000
  807. };
  808.  
  809. /***************************************************************************
  810.  *
  811.  * SCREEN UND WINDOW
  812.  *
  813.  ***************************************************************************/
  814.  
  815. #define SCRWID  642L
  816. #define SCRHEI  254L
  817.  
  818. struct NewScreen ns = {
  819.   0,0,
  820.   SCRWID,SCRHEI,
  821.   3,
  822.   0,FGPEN,
  823.   HIRES,CUSTOMSCREEN,
  824.   0,0,0,0
  825. };
  826.  
  827. struct NewWindow nw = {
  828.   0,0,
  829.   SCRWID,SCRHEI,
  830.   0,FGPEN,
  831.   GADGETDOWN | GADGETUP | MENUPICK | MENUVERIFY | MOUSEBUTTONS,
  832.   SMART_REFRESH | NOCAREREFRESH | BACKDROP | BORDERLESS | ACTIVATE,
  833.   &AgarGadget,
  834.   0,0,0,0,0,0,SCRWID,SCRHEI,
  835.   CUSTOMSCREEN
  836. };
  837.  
  838. /***************************************************************************
  839.  *
  840.  * Main routine
  841.  *
  842.  ***************************************************************************/
  843.  
  844. char AgarMem[2][YSIZE][XSIZE];  /* Agar, Undo Agar */
  845. char (*Agar)[XSIZE];            /* Current Agar    */
  846. short AgarNum;                  /* Index of current Agar (0,1) */
  847. char AuxAgar[YSIZE][XSIZE];     /* Auxiliary Agar */
  848.  
  849. char NewCT[MAXCELL][MAXVAL+1];        /* Backup for 'CellTrans'          */
  850. char CellTrans[MAXCELL][MAXVAL+1] = { /* Table for transformation rules  */
  851.   1,1,1,1,1,3,3,1,1,1,1,1,1,1,1,1,1,
  852.   3,3,3,3,3,0,3,3,3,3,3,2,3,3,3,3,3,
  853.   1,1,1,1,1,1,1,1,1,1,3,3,1,1,1,1,1
  854. };
  855.  
  856. struct StrainData {
  857.   short LCells;       /* No. of cells of this Strain on the Agar */
  858.   short SCells;       /* No. of cells in freezer                 */
  859.   short GRate;        /* Growth of cells in freezer              */
  860.   short ox,oy;        /* Left upper corner of output area        */
  861.   short CellCode;     /* Code of this Strain                     */
  862.   short CellPen;      /* Color of this Strain                    */
  863. } pd[2];
  864.  
  865. struct StrainData *actp;  /* Pointer to active Strain */
  866.  
  867. struct IntuitionBase *IntuitionBase;
  868. struct GfxBase *GfxBase;
  869.  
  870. struct Screen *sc;
  871. struct Window *wd;
  872. struct RastPort *rp;
  873. struct BitMap *bm;
  874. USHORT *PointerCMem;
  875.  
  876. main()
  877.  
  878. {
  879.   void ProcessMenu(),ProcessGadgetUp(),ProcessGadgetDown(),ProcessRMB();
  880.   void ClearAgar(),SumOut(),CleanUp();
  881.   APTR XBorder();
  882.  
  883.   struct IntuiMessage *Msg;
  884.   USHORT MClass,MCode;
  885.   APTR   MAddress;
  886.   struct ViewPort *vp;
  887.   short  i,j,c;
  888.  
  889.  
  890. /***
  891.  *
  892.  * OPEN LIBRARIES, SCREEN AND WINDOW; INITIALISE GRAPHICS
  893.  *
  894.  ***/
  895.  
  896.   IntuitionBase = GfxBase = sc = wd = PointerCMem = NULL;
  897.  
  898.   if (! (GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0L)))
  899.     CleanUp(NULL);
  900.   if (! (IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0L)))
  901.     CleanUp(NULL);
  902.  
  903.   if (!(sc = OpenScreen(&ns))) CleanUp("GoLD: Couldn't open screen!");
  904.   nw.Screen = sc;
  905.   if (!(wd = OpenWindow(&nw))) CleanUp("GoLD: Couldn't open window!");
  906.   ShowTitle(sc,FALSE);
  907.  
  908.   vp = &(sc->ViewPort);
  909.   rp = wd->RPort;
  910.   bm = rp->BitMap;
  911.  
  912.   SetRGB4(vp,0L,0L,0L,0L);
  913.   SetRGB4(vp,1L,15L,0L,0L);
  914.   SetRGB4(vp,2L,0L,7L,15L);
  915.   SetRGB4(vp,(long)MAXCELL,3L,3L,3L);
  916.   SetRGB4(vp,(long)FGPEN,12L,12L,12L);
  917.   SetRGB4(vp,5L,0L,0L,15L);
  918.   SetRGB4(vp,6L,8L,0L,0L);
  919.   SetRGB4(vp,7L,15L,15L,15L);
  920.   SetRGB4(vp,16L,0L,15L,0L);
  921.  
  922.   if (!(PointerCMem = (USHORT *)AllocMem((long)sizeof(PointerData),MEMF_CHIP)))
  923.     CleanUp("GoLD: No ChipMem for pointer!\n");
  924.   for (i=0;i<2*PTRHEIGHT+4;i++)
  925.     PointerCMem[i] = PointerData[i];
  926.   SetPointer(wd,PointerCMem,PTRHEIGHT,PTRWIDTH,PTRXOFFSET,PTRYOFFSET);
  927.  
  928.   SetMenuStrip(wd,&ProjectMenu);
  929.  
  930.   SetAPen(rp,(long)GRIDPEN);
  931.   RectFill(rp,0L,74L,SCRWID-1L,SCRHEI-1L);
  932.   SetAPen(rp,(long)FGPEN);
  933.  
  934. /***
  935.  *
  936.  * INITIALISE GADGETS IN 'UXGadget'
  937.  *
  938.  ***/
  939.  
  940.   c = UX0ID;
  941.   for (i=0;i<MAXCELL;i++)
  942.     for (j=0;j<=MAXVAL;j++) {
  943.       UXGadget[i][j] = UXGadget[0][0];
  944.       UXGadget[i][j].GadgetID = c;
  945.       c++;
  946.       UXGadget[i][j].LeftEdge += (j * 16);
  947.       UXGadget[i][j].TopEdge += (i * 12);
  948.       UXGadget[i][j].GadgetRender = XBorder(CellTrans,i,j);
  949.       if (j == MAXVAL)
  950.         if (i == MAXCELL-1) UXGadget[i][j].NextGadget = NULL;
  951.         else                UXGadget[i][j].NextGadget = &(UXGadget[i+1][0]);
  952.       else
  953.         UXGadget[i][j].NextGadget = &(UXGadget[i][j+1]);
  954.     }
  955.  
  956. /***
  957.  *
  958.  * INITIALISE PLAYER/STRAIN DATA
  959.  *
  960.  ***/
  961.  
  962.   actp = &(pd[1]);
  963.   actp->LCells = 0;
  964.   actp->SCells = 100;
  965.   actp->GRate = 0;
  966.   actp->ox = 458;
  967.   actp->oy = 40;
  968.   actp->CellCode = P2CODE;
  969.   actp->CellPen = P2PEN;
  970.  
  971.   Move(rp,(long)actp->ox,(long)actp->oy);
  972.   Text(rp,"   Cells on Agar:",17L);
  973.   Move(rp,(long)actp->ox,(long)(actp->oy+15));
  974.   Text(rp,"Cells in Freezer:",17L);
  975.  
  976.   actp = &(pd[0]);
  977.   actp->LCells = 0;
  978.   actp->SCells = 100;
  979.   actp->GRate = 0;
  980.   actp->ox = 4;
  981.   actp->oy = 40;
  982.   actp->CellCode = P1CODE;
  983.   actp->CellPen = P1PEN;
  984.  
  985.   Move(rp,(long)actp->ox,(long)actp->oy);
  986.   Text(rp,"   Cells on Agar:",17L);
  987.   Move(rp,(long)actp->ox,(long)(actp->oy+15));
  988.   Text(rp,"Cells in Freezer:",17L);
  989.  
  990.   ClearAgar(AgarMem[0]);
  991.   ClearAgar(AgarMem[1]);
  992.   ClearAgar(AuxAgar);
  993.  
  994.   Agar = AgarMem[0];
  995.   AgarNum = 0;
  996.  
  997. /***
  998.  *
  999.  * MAIN LOOP
  1000.  *
  1001.  ***/
  1002.  
  1003.   SumOut(&(pd[0]));
  1004.   SumOut(&(pd[1]));
  1005.   DisplayAgar(bm,Agar,XSIZE,YSIZE,AGARLE,AGARTE);
  1006.  
  1007.   Request(&AboutReq,wd);
  1008.  
  1009.   for (;;) {
  1010.     Wait(1L << wd->UserPort->mp_SigBit);
  1011.     while (Msg = (struct IntuiMessage *)GetMsg(wd->UserPort)) {
  1012.       MClass = Msg->Class;
  1013.       MCode = Msg->Code;
  1014.       MAddress = Msg->IAddress;
  1015.       if (MClass != MENUVERIFY) ReplyMsg(Msg);
  1016.       switch (MClass) {
  1017.         case MENUVERIFY:
  1018.           if (MCode == MENUHOT) ProcessRMB(Msg);
  1019.           else                  ReplyMsg(Msg);
  1020.           break;
  1021.         case MENUPICK:
  1022.           ProcessMenu(MCode);
  1023.           break;
  1024.         case GADGETUP:
  1025.           ProcessGadgetUp(MAddress);
  1026.           break;
  1027.         case GADGETDOWN:
  1028.           ProcessGadgetDown(MAddress);
  1029.           break;
  1030.         case MOUSEBUTTONS:
  1031.           break;
  1032.         default:
  1033.           CleanUp("GoLD: Unknown message!");
  1034.       }
  1035.     }
  1036.   }
  1037. }
  1038.  
  1039.  
  1040. /***************************************************************************
  1041.  *
  1042.  * SUBROUTINES
  1043.  *
  1044.  ***************************************************************************/
  1045.  
  1046. APTR XBorder(a,i,j)   /* Returns a pointer to the 'XBorder'-structure */
  1047.                       /* for 'a[i][j]'.                               */
  1048.   char a[MAXCELL][MAXVAL+1];
  1049.   short i,j;
  1050.  
  1051. {
  1052.   switch (a[i][j]) {
  1053.     case P1CODE:
  1054.       return(&P1XBorder);
  1055.     case NULLCODE:
  1056.       return(&BlackXBorder);
  1057.     case P2CODE:
  1058.       return(&P2XBorder);
  1059.     case NOCODE:
  1060.       if (i == P1CODE)        return(&P1XBorder);
  1061.       else if (i == NULLCODE) return(&BlackXBorder);
  1062.       else if (i == P2CODE)   return(&P2XBorder);
  1063.     default:
  1064.       return(NULL);
  1065.   }
  1066. }
  1067.  
  1068.  
  1069. APTR NextXBorder(a,i,j)   /* Toggles 'a[i][j]' and returns a pointer to the */
  1070.                           /* the 'XBorder'-structure for 'a[i][j]'.         */
  1071.   char a[MAXCELL][MAXVAL+1];
  1072.   short i,j;
  1073.  
  1074. {
  1075.   switch (a[i][j]) {
  1076.     case P1CODE:
  1077.       if (i == NULLCODE) a[i][j] = NOCODE;
  1078.       else               a[i][j] = NULLCODE;
  1079.       return(&BlackXBorder);
  1080.     case NULLCODE:
  1081.       if (i == P2CODE) a[i][j] = NOCODE;
  1082.       else             a[i][j] = P2CODE;
  1083.       return(&P2XBorder);
  1084.     case P2CODE:
  1085.       if (i == P1CODE) a[i][j] = NOCODE;
  1086.       else             a[i][j] = P1CODE;
  1087.       return(&P1XBorder);
  1088.     case NOCODE:
  1089.       switch (i) {
  1090.         case P1CODE:
  1091.           a[i][j] = NULLCODE;
  1092.           return(&BlackXBorder);
  1093.         case NULLCODE:
  1094.           a[i][j] = P2CODE;
  1095.           return(&P2XBorder);
  1096.         case P2CODE:
  1097.           a[i][j] = P1CODE;
  1098.           return(&P1XBorder);
  1099.       }
  1100.     default:
  1101.       return(NULL);
  1102.   }
  1103. }
  1104.  
  1105.  
  1106. char TxtBuf[6];
  1107.  
  1108. void SumOut(pptr)   /* Prints the values for "Cells on Agar" and "Cells */
  1109.                     /* in Freezer".                                     */
  1110.   register struct StrainData *pptr;
  1111.  
  1112. {
  1113.   SetDrMd(rp,JAM2);
  1114.   SetAPen(rp,(long)pptr->CellPen);
  1115.   Move(rp,(long)(pptr->ox+138),(long)pptr->oy);
  1116.   sprintf(TxtBuf,"%5d",pptr->LCells);
  1117.   Text(rp,TxtBuf,5L);
  1118.   Move(rp,(long)(pptr->ox+138),(long)(pptr->oy+15));
  1119.   sprintf(TxtBuf,"%5d",pptr->SCells);
  1120.   Text(rp,TxtBuf,5L);
  1121.   SetAPen(rp,(long)FGPEN);
  1122. }
  1123.  
  1124.  
  1125. void ClearAgar(a)     /* Sets all cells in the Agar to type 'dead'. */
  1126.  
  1127.   register char *a;
  1128.  
  1129. {
  1130.   register USHORT i;
  1131.  
  1132.   for (i=XSIZE*YSIZE;i!=0;i--,a++)
  1133.     *a = NULLCODE;
  1134. }
  1135.  
  1136.  
  1137. void SaveAgar()       /* Copies the current Agar to the Undo Agar. */
  1138.  
  1139. {
  1140.   register char *a,*aa;
  1141.   register USHORT i;
  1142.  
  1143.   a = Agar;
  1144.   AgarNum = 1 - AgarNum;
  1145.   Agar = AgarMem[AgarNum];
  1146.   aa = Agar;
  1147.   for (i=XSIZE*YSIZE;i!=0;i--,a++,aa++)
  1148.     *aa = *a;
  1149. }
  1150.  
  1151.  
  1152. void ProcessMenu(mnum)    /* Does exactly that. */
  1153.  
  1154.   USHORT mnum;
  1155.  
  1156. {
  1157.   register short i,j;
  1158.  
  1159.   if (mnum != MENUNULL) switch (MENUNUM(mnum)) {
  1160.     case 0:                                             /* 'Project'-Menu */
  1161.       switch (ITEMNUM(mnum)) {
  1162.         case 0:                                             /* About */
  1163.           if (!Request(&AboutReq,wd)) DisplayBeep(sc);
  1164.           break;
  1165.         case 1:                                             /* Rules */
  1166.           for (i=0;i<MAXCELL;i++)
  1167.             for (j=0;j<=MAXVAL;j++) {
  1168.               NewCT[i][j] = CellTrans[i][j];
  1169.               UXGadget[i][j].GadgetRender = XBorder(NewCT,i,j);
  1170.              }
  1171.           SetAPen(rp,(long)FGPEN);
  1172.           SetDrMd(rp,JAM1);
  1173.           if (!Request(&RulesReq,wd)) DisplayBeep(sc);
  1174.           break;
  1175.         case 2:                                             /* Reset */
  1176.           SetAPen(rp,(long)FGPEN);
  1177.           SetDrMd(rp,JAM1);
  1178.           if (!Request(&ResetReq,wd)) DisplayBeep(sc);
  1179.           break;
  1180.         case 3:                                             /* Quit */
  1181.           CleanUp(NULL);
  1182.           break;
  1183.       }
  1184.       break;
  1185.     case 1:                                             /* 'Edit'-Menu */
  1186.       switch (ITEMNUM(mnum)) {
  1187.         case 0:                                             /* Undo */
  1188.           AgarNum = 1 - AgarNum;
  1189.           Agar = AgarMem[AgarNum];
  1190.           CountCells(Agar,&(pd[0].LCells),&(pd[1].LCells),XSIZE*YSIZE-1);
  1191.           SumOut(&(pd[0]));
  1192.           SumOut(&(pd[1]));
  1193.           DisplayAgar(bm,Agar,XSIZE,YSIZE,AGARLE,AGARTE);
  1194.           break;
  1195.         case 1:                                             /* Clear Agar */
  1196.           pd[0].SCells += pd[0].LCells;
  1197.           pd[1].SCells += pd[1].LCells;
  1198.           pd[0].LCells = pd[1].LCells = 0;
  1199.           SumOut(&(pd[0]));
  1200.           SumOut(&(pd[1]));
  1201.           AgarNum = 1 - AgarNum;
  1202.           Agar = AgarMem[AgarNum];
  1203.           ClearAgar(Agar);
  1204.           DisplayAgar(bm,Agar,XSIZE,YSIZE,AGARLE,AGARTE);
  1205.           break;
  1206.       }
  1207.       break;
  1208.   }
  1209. }
  1210.  
  1211.  
  1212. void ProcessGadgetUp(gptr)    /* Gadget clicked */
  1213.  
  1214.   struct Gadget *gptr;
  1215.  
  1216. {
  1217.   short i,j,id;
  1218.  
  1219.   switch (gptr->GadgetID) {
  1220.     case P1ID:                            /* 'Strain 1'-Gadget */
  1221.       if (gptr->Flags & SELECTED) actp = &(pd[0]);
  1222.       else                        actp = &(pd[1]);
  1223.       P2Gadget.Flags ^= SELECTED;
  1224.       RefreshGadgets(&P2Gadget,wd,NULL);
  1225.       return;
  1226.     case P2ID:                            /* 'Strain 2'-Gadget */
  1227.       if (gptr->Flags & SELECTED) actp = &(pd[1]);
  1228.       else                        actp = &(pd[0]);
  1229.       P1Gadget.Flags ^= SELECTED;
  1230.       RefreshGadgets(&P1Gadget,wd,NULL);
  1231.       return;
  1232.     case ROKID:                           /* 'OK' in 'Reset'-Req */
  1233.       pd[0].LCells = pd[1].LCells = 0;
  1234.       pd[0].SCells = CS1SInfo.LongInt;
  1235.       pd[1].SCells = CS2SInfo.LongInt;
  1236.       pd[0].GRate = GS1SInfo.LongInt;
  1237.       pd[1].GRate = GS2SInfo.LongInt;
  1238.       SumOut(&(pd[0]));
  1239.       SumOut(&(pd[1]));
  1240.       ClearAgar(AgarMem[0]);
  1241.       ClearAgar(AgarMem[1]);
  1242.       DisplayAgar(bm,Agar,XSIZE,YSIZE,AGARLE,AGARTE);
  1243.       return;
  1244.     case RCANID:                          /* 'CANCEL' in 'Reset'-Requester */
  1245.       return;
  1246.     case UOKID:                           /* 'OK' in 'Rules'-Requester */
  1247.       for (i=0;i<MAXCELL;i++)
  1248.         for (j=0;j<=MAXVAL;j++)
  1249.           CellTrans[i][j] = NewCT[i][j];
  1250.       return;
  1251.     case UCANID:                          /* 'CANCEL' in 'Rules'-Requester */
  1252.       return;
  1253.     case AOKID:                           /* 'OK' in 'About'-Requester */
  1254.       return;
  1255.     default:                              /* an 'X' in 'Rules'-Requester */
  1256.       id = gptr->GadgetID - UX0ID;
  1257.       if (id >= 0) {
  1258.         i = id / (MAXVAL+1);
  1259.         j = id % (MAXVAL+1);
  1260.         UXGadget[i][j].GadgetRender = NextXBorder(NewCT,i,j);
  1261.        }
  1262.       RefreshGadgets(gptr,wd,&RulesReq);
  1263.       return;
  1264.   }
  1265. }
  1266.  
  1267.  
  1268. void ProcessGadgetDown(gptr)    /* Gadget pressed (and held?) */
  1269.  
  1270.   struct Gadget *gptr;
  1271.  
  1272. {
  1273.   register struct IntuiMessage *Msg;
  1274.   ULONG IDCMPFlags;
  1275.   register short i,j;
  1276.  
  1277.   SaveAgar();
  1278.  
  1279.   switch (gptr->GadgetID) {
  1280.     case GROWID:                                      /* 'Grow'-Gadget */
  1281.       for (;;) {
  1282.         ScanAgar(Agar,AuxAgar,CellTrans,XSIZE,YSIZE,MAXVAL+1);
  1283.         ChangeAgar(bm,Agar,AuxAgar,XSIZE,YSIZE,AGARLE,AGARTE);
  1284.  
  1285.         pd[0].SCells += pd[0].GRate;
  1286.         pd[1].SCells += pd[1].GRate;
  1287.         CountCells(Agar,&(pd[0].LCells),&(pd[1].LCells),XSIZE*YSIZE-1);
  1288.         SumOut(&(pd[0]));
  1289.         SumOut(&(pd[1]));
  1290.  
  1291.         if (Msg = (struct IntuiMessage *)GetMsg(wd->UserPort)) {
  1292.           i = Msg->Class;
  1293.           j = Msg->Code;
  1294.           ReplyMsg(Msg);
  1295.           if ((i == GADGETUP) || (j == SELECTUP)) break;
  1296.         }
  1297.       }
  1298.       break;
  1299.     case AGARID:                                      /* Agar */
  1300.       for (;;) {
  1301.         i = wd->MouseY/3 - AGARTE + 1;
  1302.         j = wd->MouseX/4 - AGARLE + 1;
  1303.         if ((i > 0) && (i < YSIZE-1) && (j > 0) && (j < XSIZE-1))
  1304.           if ((Agar[i][j] == 1) && (actp->SCells != 0)) {
  1305.             Agar[i][j] = actp->CellCode;
  1306.             actp->LCells ++;
  1307.             actp->SCells --;
  1308.             SetCell(bm,j+AGARLE-1,i+AGARTE-1,actp->CellPen);
  1309.             SumOut(actp);
  1310.           }
  1311.  
  1312.         if (Msg = (struct IntuiMessage *)GetMsg(wd->UserPort)) {
  1313.           i = Msg->Class;
  1314.           j = Msg->Code;
  1315.           ReplyMsg(Msg);
  1316.           if ((i == GADGETUP) || (j == SELECTUP)) break;
  1317.         }
  1318.       }
  1319.       break;
  1320.   }
  1321.  
  1322.   return;
  1323. }
  1324.  
  1325.  
  1326. void ProcessRMB(msg)        /* Right mouse button */
  1327.  
  1328.   struct IntuiMessage *msg;
  1329.  
  1330. {
  1331.   register struct IntuiMessage *Msg;
  1332.   ULONG IDCMPFlags;
  1333.   register short i,j;
  1334.  
  1335.   i = wd->MouseY/3 - AGARTE + 1;
  1336.   j = wd->MouseX/4 - AGARLE + 1;
  1337.   if ((i < 1) || (i > YSIZE-2) || (j < 1) || (j > XSIZE-2)) {
  1338.     ReplyMsg(msg);
  1339.     return;
  1340.   }
  1341.  
  1342.   SaveAgar();
  1343.  
  1344.   msg->Code = MENUCANCEL;
  1345.   ReplyMsg(msg);
  1346.  
  1347.   for (;;) {
  1348.     i = wd->MouseY/3 - AGARTE + 1;
  1349.     j = wd->MouseX/4 - AGARLE + 1;
  1350.     if ((i > 0) && (i < YSIZE-1) && (j > 0) && (j < XSIZE-1))
  1351.       if (Agar[i][j] == actp->CellCode) {
  1352.         Agar[i][j] = 1;
  1353.         actp->LCells --;
  1354.         actp->SCells ++;
  1355.         SetCell(bm,j+AGARLE-1,i+AGARTE-1,NULLPEN);
  1356.         SumOut(actp);
  1357.       }
  1358.  
  1359.     if (Msg = (struct IntuiMessage *)GetMsg(wd->UserPort)) {
  1360.       j = Msg->Code;
  1361.       ReplyMsg(Msg);
  1362.       if (j == MENUUP) break;
  1363.     }
  1364.   }
  1365.   return;
  1366. }
  1367.  
  1368.  
  1369. #define ERRLEN  70
  1370.  
  1371. char ErrorString[ERRLEN];
  1372.  
  1373. void CleanUp(txt)
  1374.  
  1375.   char *txt;
  1376.  
  1377. {
  1378.   short i;
  1379.  
  1380.   if (PointerCMem) {
  1381.     ClearPointer(wd);
  1382.     FreeMem(PointerCMem,(long)sizeof(PointerData));
  1383.   }
  1384.   if (wd) {
  1385.     ClearMenuStrip(wd);
  1386.     CloseWindow(wd);
  1387.   }
  1388.   if (sc) CloseScreen(sc);
  1389.   if (IntuitionBase) CloseLibrary(IntuitionBase);
  1390.   if (GfxBase) CloseLibrary(GfxBase);
  1391.  
  1392.   if (txt != NULL) {
  1393.     for(i=3;(i < ERRLEN-2) && (txt[i-3] != 0);i++)
  1394.       ErrorString[i] = txt[i-3];
  1395.     *((short *)ErrorString) = 308 - 4*i;
  1396.     ErrorString[2] = 15;
  1397.     ErrorString[i] = ErrorString[i+1] = 0;
  1398.     DisplayAlert(RECOVERY_ALERT,ErrorString,30L);
  1399.   }
  1400.  
  1401.   exit(0L);
  1402. }
  1403.