home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 032.lha / doc / misc / intuition.d < prev    next >
Text File  |  1987-05-16  |  22KB  |  740 lines

  1. #include:exec/miscellaneous.g
  2. #include:exec/memory.g
  3. #include:exec/tasks.g
  4. #include:exec/ports.g
  5. #include:intuition/miscellaneous.g
  6. #include:intuition/screen.g
  7. #include:intuition/window.g
  8. #include:intuition/intuiText.g
  9. #include:intuition/image.g
  10. #include:intuition/intuiMessage.g
  11. #include:intuition/menu.g
  12. #include:graphics/gfx.g
  13. #include:graphics/rastport.g
  14. #include:graphics/gels.g
  15. #include:graphics/clip.g
  16.  
  17. /*
  18.  * Sample Draco program showing simple use of Intuition and Graphics on the
  19.  * Amiga. The parameters below can't really be changed, because of the things
  20.  * that depend on them indirectly, like the initial window position, the
  21.  * size of the image and Bob pictures, etc.
  22.  */
  23.  
  24. uint
  25.     BIT_PLANES = 2,
  26.     SCREEN_WIDTH = 320,
  27.     SCREEN_HEIGHT = 200;
  28.  
  29. IntuiText_t
  30.     MODEL1 = IntuiText_t(0, 1, 0x0, 0, 1, nil, nil, nil),
  31.     MODEL2 = IntuiText_t(1, 0, 0x0, 0, 1, nil, nil, nil);
  32.  
  33. *Screen_t Screen;
  34. *Window_t Window;
  35. *Menu_t MainMenu, AnimationMenu;
  36. IntuiText_t It11, It12, It13, It21, It22, It23, It24, It25,
  37.         It111, It112, It221, It222,
  38.         ItA1, ItA2, ItA3;
  39.  
  40. /*
  41.  * setupMenus -
  42.  *    Create the two menu strips the program uses.
  43.  *    Note that I'm cheating a bit by modifying the constant menu displays
  44.  *    and relying on them all being different (and thus not made into a
  45.  *    common one by the compiler). This commoning is why the IntuiText
  46.  *    structures are global variables - they are all the same, but I need
  47.  *    to put a different text pointer into each one.
  48.  */
  49.  
  50. proc setupMenus()void:
  51.     *MenuItem_t mi11, mi12, mi13, mi21, mi22, mi23, mi24, mi25,
  52.         mi111, mi112, mi221, mi222,
  53.         miA1, miA2, miA3;
  54.     *Menu_t m1, m2;
  55.  
  56.     /* first, set up the main menu */
  57.  
  58.     mi25 := &MenuItem_t(
  59.         nil, 0, 36, 49, 9,
  60.         ITEMTEXT | ITEMENABLED | HIGHCOMP,
  61.         0x0, (nil), (nil), ' ', nil, 0);
  62.     It25 := MODEL1;
  63.     It25.it_IText := "Fill";
  64.     mi25*.mi_ItemFill.miIt := &It25;
  65.     mi24 := &MenuItem_t(
  66.         nil, 0, 27, 49, 9,
  67.         ITEMTEXT | ITEMENABLED | HIGHCOMP,
  68.         0x0, (nil), (nil), ' ', nil, 0);
  69.     It24 := MODEL1;
  70.     It24.it_IText := "Lines";
  71.     mi24*.mi_ItemFill.miIt := &It24;
  72.     mi24*.mi_NextItem := mi25;
  73.     mi23 := &MenuItem_t(
  74.         nil, 0, 18, 49, 9,
  75.         ITEMTEXT | ITEMENABLED | HIGHCOMP,
  76.         0x0, (nil), (nil), ' ', nil, 0);
  77.     It23 := MODEL1;
  78.     It23.it_IText := "Pixels";
  79.     mi23*.mi_ItemFill.miIt := &It23;
  80.     mi23*.mi_NextItem := mi24;
  81.     mi222 := &MenuItem_t(
  82.         nil, 40, 9, 66, 9,
  83.         ITEMTEXT | ITEMENABLED | HIGHCOMP,
  84.         0x0, (nil), (nil), ' ', nil, 0);
  85.     It222 := MODEL1;
  86.     It222.it_IText := "good-bye";
  87.     mi222*.mi_ItemFill.miIt := &It222;
  88.     mi221 := &MenuItem_t(
  89.         nil, 40, 0, 66, 9,
  90.         ITEMTEXT | ITEMENABLED | HIGHCOMP,
  91.         0x0, (nil), (nil), ' ', nil, 0);
  92.     It221 := MODEL1;
  93.     It221.it_IText := "hello";
  94.     mi221*.mi_ItemFill.miIt := &It221;
  95.     mi221*.mi_NextItem := mi222;
  96.     mi22 := &MenuItem_t(
  97.         nil, 0, 9, 49, 9,
  98.         ITEMTEXT | ITEMENABLED | HIGHCOMP,
  99.         0x0, (nil), (nil), ' ', nil, 0);
  100.     It22 := MODEL1;
  101.     It22.it_IText := "Text";
  102.     mi22*.mi_ItemFill.miIt := &It22;
  103.     mi22*.mi_NextItem := mi23;
  104.     mi22*.mi_SubItem := mi221;
  105.     mi21 := &MenuItem_t(
  106.         nil, 0, 0, 49, 9,
  107.         ITEMTEXT | ITEMENABLED | HIGHCOMP,
  108.         0x0, (nil), (nil), ' ', nil, 0);
  109.     It21 := MODEL1;
  110.     It21.it_IText := "Image";
  111.     mi21*.mi_ItemFill.miIt := &It21;
  112.     mi21*.mi_NextItem := mi22;
  113.     m2 := &Menu_t(nil, 64, 0, 50, 10, MENUENABLED, nil, nil, 0, 0, 0, 0);
  114.     m2*.m_MenuName := "Things";
  115.     m2*.m_FirstItem := mi21;
  116.     mi13 := &MenuItem_t(
  117.         nil, 0, 18, 74, 9,
  118.         ITEMTEXT | ITEMENABLED | HIGHCOMP,
  119.         0x0, (nil), (nil), ' ', nil, 0);
  120.     It13 := MODEL1;
  121.     It13.it_IText := "Quit";
  122.     mi13*.mi_ItemFill.miIt := &It13;
  123.     mi12 := &MenuItem_t(
  124.         nil, 0, 9, 74, 9,
  125.         ITEMTEXT | ITEMENABLED | HIGHCOMP,
  126.         0x0, (nil), (nil), ' ', nil, 0);
  127.     It12 := MODEL1;
  128.     It12.it_IText := "Bounce";
  129.     mi12*.mi_ItemFill.miIt := &It12;
  130.     mi12*.mi_NextItem := mi13;
  131.     mi112 := &MenuItem_t(
  132.         nil, 72, 9, 50, 9,
  133.         ITEMTEXT | ITEMENABLED | HIGHCOMP,
  134.         0x0, (nil), (nil), ' ', nil, 0);
  135.     It112 := MODEL1;
  136.     It112.it_IText := "screen";
  137.     mi112*.mi_ItemFill.miIt := &It112;
  138.     mi111 := &MenuItem_t(
  139.         nil, 72, 0, 50, 9,
  140.         ITEMTEXT | ITEMENABLED | HIGHCOMP,
  141.         0x0, (nil), (nil), ' ', nil, 0);
  142.     It111 := MODEL1;
  143.     It111.it_IText := "window";
  144.     mi111*.mi_ItemFill.miIt := &It111;
  145.     mi111*.mi_NextItem := mi112;
  146.     mi11 := &MenuItem_t(
  147.         nil, 0, 0, 74, 9,
  148.         ITEMTEXT | ITEMENABLED | HIGHCOMP,
  149.         0x0, (nil), (nil), ' ', nil, 0);
  150.     It11 := MODEL1;
  151.     It11.it_IText := "Animation";
  152.     mi11*.mi_ItemFill.miIt := &It11;
  153.     mi11*.mi_NextItem := mi12;
  154.     mi11*.mi_SubItem := mi111;
  155.     m1 := &Menu_t(nil, 0, 0, 58, 10, MENUENABLED, nil, nil, 0, 0, 0, 0);
  156.     m1*.m_MenuName := "Project";
  157.     m1*.m_FirstItem := mi11;
  158.     m1*.m_NextMenu := m2;
  159.     MainMenu := m1;
  160.  
  161.     /* now, set up the alternate menu used during animation */
  162.  
  163.     miA3 := &MenuItem_t(
  164.         nil, 0, 18, 50, 9,
  165.         ITEMTEXT | ITEMENABLED | HIGHCOMP,
  166.         0x0, (nil), (nil), ' ', nil, 0);
  167.     ItA3 := MODEL1;
  168.     ItA3.it_IText := "Quit";
  169.     miA3*.mi_ItemFill.miIt := &ItA3;
  170.     miA2 := &MenuItem_t(
  171.         nil, 0, 9, 50, 9,
  172.         ITEMTEXT | ITEMENABLED | HIGHCOMP,
  173.         0x0, (nil), (nil), ' ', nil, 0);
  174.     ItA2 := MODEL1;
  175.     ItA2.it_IText := "Slower";
  176.     miA2*.mi_ItemFill.miIt := &ItA2;
  177.     miA2*.mi_NextItem := miA3;
  178.     miA1 := &MenuItem_t(
  179.         nil, 0, 0, 50, 9,
  180.         ITEMTEXT | ITEMENABLED | HIGHCOMP,
  181.         0x0, (nil), (nil), ' ', nil, 0);
  182.     ItA1 := MODEL1;
  183.     ItA1.it_IText := "Faster";
  184.     miA1*.mi_ItemFill.miIt := &ItA1;
  185.     miA1*.mi_NextItem := miA2;
  186.     m1 := &Menu_t(nil, 0, 0, 66, 10, MENUENABLED, nil, nil, 0, 0, 0, 0);
  187.     m1*.m_MenuName := "Controls";
  188.     m1*.m_FirstItem := miA1;
  189.     AnimationMenu := m1;
  190.  
  191. corp;
  192.  
  193. /*
  194.  * doAnimation -
  195.  *    Do a little animation, just to show how its done. Waiting for the
  196.  *    top of the frame each cycle is kind of slow, but even slower is the
  197.  *    INTUITICKS signals (supposedly about 10 per second). The proper way
  198.  *    is to set up a timer interrupt which repeats and sends us a signal
  199.  *    every now and then.
  200.  */
  201.  
  202. proc doAnimation(*RastPort_t rp)void:
  203.     uint BOB_WIDTH = 32, BOB_HEIGHT = 32;
  204.     /* we make these types so we can use constant displays */
  205.     type
  206.     bobMask_t = [BOB_HEIGHT * BOB_WIDTH / 32]ulong,
  207.     bobImage_t = [2] bobMask_t;
  208.     GelsInfo_t gelsInfo;
  209.     VSprite_t headVSprite, tailVSprite, myVSprite;
  210.     Bob_t myBob;
  211.     *bobImage_t bobImage;
  212.     *bobMask_t bobMask;
  213.     *ViewPort_t viewPort;
  214.     *IntuiMessage_t im;
  215.     *MenuItem_t mi;
  216.     ulong class;
  217.     uint which, speed, width, height;
  218.     bool quit, leftToRight, topToBottom, moved, switched;
  219.  
  220.     /* I hate all these 'pretend's but I don't see an alternative - I don't
  221.        want to add a whole bunch of Amiga specific stuff to the language. */
  222.  
  223.     bobImage := pretend(AllocMem(sizeof(bobImage_t), MEMF_CHIP), *bobImage_t);
  224.     bobMask := pretend(AllocMem(sizeof(bobMask_t), MEMF_CHIP), *bobMask_t);
  225.     myBob.b_SaveBuffer :=
  226.     pretend(AllocMem(sizeof(bobImage_t), MEMF_CHIP), *uint);
  227.     myVSprite.vs_BorderLine :=
  228.     pretend(AllocMem(BOB_WIDTH / 8, MEMF_CHIP), *uint);
  229.     if bobImage ~= nil and bobMask ~= nil and myBob.b_SaveBuffer ~= nil and
  230.         myVSprite.vs_BorderLine ~= nil then
  231.  
  232.     /* I could have used array assignment here, but they insist in the
  233.        manuals that 'CopyMem' is real fast, so I'll use it (as if it
  234.        mattered! */
  235.  
  236.     CopyMem(pretend(&bobImage_t(
  237.            (0b11111111111111111111111111111111,
  238.         0b01111111111111111111111111111110,
  239.         0b00111111111111111111111111111100,
  240.         0b00011111111111111111111111111000,
  241.         0b00001111111111111111111111110000,
  242.         0b10000111111111111111111111100001,
  243.         0b11000011111111111111111111000011,
  244.         0b11100001111111111111111110000111,
  245.         0b11110000111111111111111100001111,
  246.         0b11111000011111111111111000011111,
  247.         0b11111100001111111111110000111111,
  248.         0b01111110000000000000000001111110,
  249.         0b00111111000000000000000011111100,
  250.         0b00011111100000000000000111111000,
  251.         0b00001111110000000000001111110000,
  252.         0b10000111111000000000011111100001,
  253.         0b11000011111000000000011111000011,
  254.         0b11100001111000000000011110000111,
  255.         0b11110000111000000000011100001111,
  256.         0b11111000011000000000011000011111,
  257.         0b11111100001000000000010000111111,
  258.         0b01111110000111111111100001111110,
  259.         0b00111111000011111111000011111100,
  260.         0b00011111100001111110000111111000,
  261.         0b00001111110000111100001111110000,
  262.         0b10000111111000011000011111100001,
  263.         0b11000011111100000000111111000011,
  264.         0b11100001111110000001111110000111,
  265.         0b11110000111111000011111100001111,
  266.         0b11111000011111100111111000011111,
  267.         0b11111100001111111111110000111111,
  268.         0b01111110000111111111100001111110),
  269.  
  270.            (0b01111110000111111111100001111110,
  271.         0b11111100001111111111110000111111,
  272.         0b11111000011111100111111000011111,
  273.         0b11110000111111000011111100001111,
  274.         0b11100001111110000001111110000111,
  275.         0b11000011111100000000111111000011,
  276.         0b10000111111000011000011111100001,
  277.         0b00001111110000111100001111110000,
  278.         0b00011111100001111110000111111000,
  279.         0b00111111000011111111000011111100,
  280.         0b01111110000111111111100001111110,
  281.         0b11111100001000000000010000111111,
  282.         0b11111000011000000000011000011111,
  283.         0b11110000111000000000011100001111,
  284.         0b11100001111000000000011110000111,
  285.         0b11000011111000000000011111000011,
  286.         0b10000111111000000000011111100001,
  287.         0b00001111110000000000001111110000,
  288.         0b00011111100000000000000111111000,
  289.         0b00111111000000000000000011111100,
  290.         0b01111110000000000000000001111110,
  291.         0b11111100001111111111110000111111,
  292.         0b11111000011111111111111000011111,
  293.         0b11110000111111111111111100001111,
  294.         0b11100001111111111111111110000111,
  295.         0b11000011111111111111111111000011,
  296.         0b10000111111111111111111111100001,
  297.         0b00001111111111111111111111110000,
  298.         0b00011111111111111111111111111000,
  299.         0b00111111111111111111111111111100,
  300.         0b01111111111111111111111111111110,
  301.         0b11111111111111111111111111111111)),
  302.         *byte),
  303.         pretend(bobImage, *byte),
  304.         sizeof(bobImage_t));
  305.  
  306.     /* I set up vs_CollMask and vs_BorderLine so I can just call
  307.        'InitMasks', even though I'm not doing any collision detection,
  308.        which is what those are for */
  309.  
  310.     myBob.b_BobVSprite := &myVSprite;
  311.     myBob.b_ImageShadow := pretend(&bobMask*[0], *uint);
  312.     myBob.b_Flags := 0;
  313.     myBob.b_Before := nil;
  314.     myBob.b_After := nil;
  315.     myBob.b_DBuffer := nil;
  316.     myVSprite.vs_VSBob := &myBob;
  317.     myVSprite.vs_Height := BOB_HEIGHT;
  318.     myVSprite.vs_Width := BOB_WIDTH / 16;
  319.     myVSprite.vs_Depth := BIT_PLANES;
  320.     myVSprite.vs_ImageData := pretend(&bobImage*[0][0], *uint);
  321.     myVSprite.vs_CollMask := pretend(&bobMask*[0], *uint);
  322.     myVSprite.vs_PlanePick := 0x3;
  323.     myVSprite.vs_PlaneOnOff := 0x0;
  324.     myVSprite.vs_Flags := SAVEBACK | OVERLAY;
  325.     myVSprite.vs_NextVSprite := nil;
  326.     myVSprite.vs_PrevVSprite := nil;
  327.     myVSprite.vs_Y := 0;
  328.     myVSprite.vs_X := 0;
  329.     InitMasks(&myVSprite);
  330.  
  331.     viewPort := ViewPortAddress(Window);
  332.     gelsInfo.gi_nextLine := nil;
  333.     gelsInfo.gi_lastColor := nil;
  334.     gelsInfo.gi_collHandler := nil;
  335.     InitGels(&headVSprite, &tailVSprite, &gelsInfo);
  336.     /* Note this absolutely vital assignment. It's not mentioned in the
  337.        chapter on animation, but is in the one on creating views and
  338.        viewports */
  339.     rp*.rp_GelsInfo := &gelsInfo;
  340.     AddBob(&myBob, rp);
  341.  
  342.     leftToRight := true;
  343.     topToBottom := true;
  344.     speed := 1;
  345.     SetMenuStrip(Window, AnimationMenu);
  346.     ModifyIDCMP(Window, MENUPICK | CLOSEWINDOW | INTUITICKS);
  347.     quit := false;
  348.     while not quit do
  349.         pretend(Wait(1 << Window*.w_UserPort*.mp_SigBit), void);
  350.         moved := false;
  351.         while
  352.         im:= pretend(GetMsg(Window*.w_UserPort), *IntuiMessage_t);
  353.         im ~= nil
  354.         do
  355.         /* Again, as per the manual, we save what we need from the
  356.            message and reply to it right away, thus freeing up the
  357.            space it occupied */
  358.         class := im*.im_Class;
  359.         which := im*.im_Code;
  360.         ReplyMsg(pretend(im, *Message_t));
  361.         case class
  362.         incase CLOSEWINDOW:
  363.             /* Note that here, as well as in the main menu processing,
  364.                I call ClearMenuStrip and continue with the inner
  365.                menu event handling loop. This ensures that I won't
  366.                lose a message which arrives after the quit message
  367.                but before the system has actually removed the menu */
  368.             quit := true;
  369.             ClearMenuStrip(Window);
  370.         incase MENUPICK:
  371.             while which ~= MENUNULL do
  372.             mi := ItemAddress(AnimationMenu, which);
  373.             case MENUNUM(which)
  374.             incase 0:
  375.                 /* Controls */
  376.                 case ITEMNUM(which)
  377.                 incase 0:
  378.                 /* Faster */
  379.                 speed := speed * 2;
  380.                 /* Sigh; there doesn't seem to be a Layer
  381.                    attached to the screen's RastPort */
  382.                 width :=
  383.                     if rp*.rp_Layer = nil then
  384.                     SCREEN_WIDTH - BOB_WIDTH
  385.                     else
  386.                     rp*.rp_Layer*.l_bounds.r_MaxX -
  387.                     rp*.rp_Layer*.l_bounds.r_MinX -
  388.                     BOB_WIDTH + 1
  389.                     fi;
  390.                 if speed >= width then
  391.                     speed := width - 1;
  392.                 fi;
  393.                 incase 1:
  394.                 /* Slower */
  395.                 speed := speed / 2;
  396.                 if speed = 0 then
  397.                     speed := 1;
  398.                 fi;
  399.                 incase 2:
  400.                 /* Quit */
  401.                 quit := true;
  402.                 ClearMenuStrip(Window);
  403.                 default:
  404.                 /* shouldn't get this */
  405.                 esac;
  406.             default:
  407.                 /* shouldn't get this */
  408.             esac;
  409.             which := mi*.mi_NextSelect;
  410.             od;
  411.         incase INTUITICKS:
  412.             /* clock has ticked - move the Bob */
  413.             if rp*.rp_Layer = nil then
  414.             width := SCREEN_WIDTH - BOB_WIDTH;
  415.             height := SCREEN_HEIGHT - BOB_HEIGHT;
  416.             else
  417.             width := rp*.rp_Layer*.l_bounds.r_MaxX -
  418.                  rp*.rp_Layer*.l_bounds.r_MinX - BOB_WIDTH + 1;
  419.             height := rp*.rp_Layer*.l_bounds.r_MaxY -
  420.                   rp*.rp_Layer*.l_bounds.r_MinY - BOB_HEIGHT+1;
  421.             fi;
  422.             switched := false;
  423.             if leftToRight then
  424.             myVSprite.vs_X := myVSprite.vs_X + speed;
  425.             if myVSprite.vs_X > width then
  426.                 myVSprite.vs_X := width;
  427.                 leftToRight := false;
  428.                 switched := true;
  429.             fi;
  430.             else
  431.             if myVSprite.vs_X < speed then
  432.                 myVSprite.vs_X := 0;
  433.                 leftToRight := true;
  434.                 switched := true;
  435.             else
  436.                 myVSprite.vs_X := myVSprite.vs_X - speed;
  437.             fi;
  438.             fi;
  439.             if switched then
  440.             if topToBottom then
  441.                 myVSprite.vs_Y := myVSprite.vs_Y + 1;
  442.                 if myVSprite.vs_Y = height then
  443.                 topToBottom := false;
  444.                 fi;
  445.             else
  446.                 myVSprite.vs_Y := myVSprite.vs_Y - 1;
  447.                 if myVSprite.vs_Y = 0 then
  448.                 topToBottom := true;
  449.                 fi;
  450.             fi;
  451.             fi;
  452.             moved := true;
  453.         default:
  454.             /* shouldn't get this */
  455.         esac;
  456.         od;
  457.         /* Following the advice given in the manual, this is separated
  458.            out so that I don't get behind in message handling */
  459.         if moved then
  460.         SortGList(rp);
  461.         WaitTOF();
  462.         DrawGList(rp, viewPort);
  463.         fi;
  464.     od;
  465.     RemBob(&myBob, rp);
  466.     SortGList(rp);
  467.     DrawGList(rp, viewPort);
  468.     ModifyIDCMP(Window, CLOSEWINDOW | MENUPICK);
  469.     SetMenuStrip(Window, MainMenu);
  470.     fi;
  471.     if myVSprite.vs_BorderLine ~= nil then
  472.     FreeMem(pretend(myVSprite.vs_BorderLine, *byte), BOB_WIDTH / 8);
  473.     fi;
  474.     if myBob.b_SaveBuffer ~= nil then
  475.     FreeMem(pretend(myBob.b_SaveBuffer, *byte), sizeof(bobImage_t));
  476.     fi;
  477.     if bobMask ~= nil then
  478.     FreeMem(pretend(bobMask, *byte), sizeof(bobMask_t));
  479.     fi;
  480.     if bobImage ~= nil then
  481.     FreeMem(pretend(bobImage, *byte), sizeof(bobImage_t));
  482.     fi;
  483. corp;
  484.  
  485. /*
  486.  * doit -
  487.  *    After everything is set up, loop, handling menu selections and any
  488.  *    other IDCMP messages (only CLOSEWINDOW enabled)
  489.  */
  490.  
  491. proc doit()void:
  492.     uint IMAGE_WIDTH = 32, IMAGE_HEIGHT = 32;
  493.     type squareImage_t = [IMAGE_WIDTH * IMAGE_HEIGHT / 32]ulong;
  494.     IntuiText_t it;
  495.     *Image_t i;
  496.     *IntuiMessage_t im;
  497.     *MenuItem_t mi;
  498.     ulong n;
  499.     ulong class;
  500.     uint which;
  501.     bool quit;
  502.  
  503.     SetMenuStrip(Window, MainMenu);
  504.     quit := false;
  505.     while not quit do
  506.     pretend(Wait(1 << Window*.w_UserPort*.mp_SigBit), void);
  507.     while
  508.         im:= pretend(GetMsg(Window*.w_UserPort), *IntuiMessage_t);
  509.         im ~= nil
  510.     do
  511.         class := im*.im_Class;
  512.         which := im*.im_Code;
  513.         ReplyMsg(pretend(im, *Message_t));
  514.         case class
  515.         incase CLOSEWINDOW:
  516.         quit := true;
  517.         ClearMenuStrip(Window);
  518.         incase MENUPICK:
  519.         while which ~= MENUNULL do
  520.             mi := ItemAddress(MainMenu, which);
  521.             case MENUNUM(which)
  522.             incase 0:
  523.             /* Project */
  524.             case ITEMNUM(which)
  525.             incase 0:
  526.                 /* Animation */
  527.                 case SUBNUM(which)
  528.                 incase 0:
  529.                 /* window */
  530.                 doAnimation(Window*.w_RPort);
  531.                 incase 1:
  532.                 /* screen */
  533.                 doAnimation(&Screen*.sc_RastPort);
  534.                 default:
  535.                 /* shouldn't get this */
  536.                 esac;
  537.             incase 1:
  538.                 /* Bounce */
  539.                 for n from 1 upto SCREEN_HEIGHT - 10 do
  540.                 MoveScreen(Screen, 0, 1);
  541.                 WaitTOF();
  542.                 od;
  543.                 for n from 1 upto SCREEN_HEIGHT - 10 do
  544.                 MoveScreen(Screen, 0, -1);
  545.                 WaitTOF();
  546.                 od;
  547.             incase 2:
  548.                 /* Quit */
  549.                 quit := true;
  550.                 ClearMenuStrip(Window);
  551.             default:
  552.                 /* shouldn't get this */
  553.             esac;
  554.             incase 1:
  555.             /* Things */
  556.             case ITEMNUM(which)
  557.             incase 0:
  558.                 /* Image */
  559.                 i :=
  560.                 &Image_t(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT,
  561.                      BIT_PLANES, nil, 0x2, 0x1, nil);
  562.                 i*.i_ImageData :=
  563.                 pretend(AllocMem(sizeof(squareImage_t),
  564.                      MEMF_CHIP), *uint);
  565.                 if i*.i_ImageData ~= nil then
  566.                 CopyMem(pretend(&squareImage_t(
  567.                     0b10000000000000000000000000000001,
  568.                     0b11100000000000000000000000000111,
  569.                     0b11111000000000000000000000011111,
  570.                     0b11111110000000000000000001111111,
  571.                     0b00111111100000000000000111111100,
  572.                     0b00001111111000000000011111110000,
  573.                     0b00000011111110000001111111000000,
  574.                     0b00000000111111100111111100000000,
  575.                     0b00000000001111111111110000000000,
  576.                     0b00000000000011111111000000000000,
  577.                     0b00000000000000111100000000000000,
  578.                     0b00000000000000000000000000000000,
  579.                     0b00000000000000000000000000000000,
  580.                     0b00110011001100110011001100110011,
  581.                     0b01100110011001100110011001100110,
  582.                     0b11001100110011001100110011001100,
  583.                     0b01100110011001100110011001100110,
  584.                     0b00110011001100110011001100110011,
  585.                     0b00000000000000000000000000000000,
  586.                     0b00000000000000000000000000000000,
  587.                     0b01111111111111111111111111111110,
  588.                     0b00011111111111111111111111111000,
  589.                     0b00000111111111111111111111100000,
  590.                     0b00000001111111111111111110000000,
  591.                     0b00000000011111111111111000000000,
  592.                     0b00000000000111111111100000000000,
  593.                     0b00000000000001111110000000000000,
  594.                     0b00000000000000011000000000000000,
  595.                     0b00000000000000000000000000000000,
  596.                     0b00000000000000000000000000000000,
  597.                     0b11111111111111111111111111111111,
  598.                     0b11111111111111111111111111111111),
  599.                     *byte),
  600.                     pretend(i*.i_ImageData, *byte),
  601.                     sizeof(squareImage_t));
  602.                 DrawImage(Window*.w_RPort, i, 50, 30);
  603.                 FreeMem(pretend(i*.i_ImageData, *byte),
  604.                     sizeof(squareImage_t));
  605.                 fi;
  606.             incase 1:
  607.                 /* Text */
  608.                 case SUBNUM(which)
  609.                 incase 0:
  610.                 /* hello */
  611.                 it := MODEL2;
  612.                 it.it_IText := "hello";
  613.                 PrintIText(Window*.w_RPort, &it, 25, 15);
  614.                 incase 1:
  615.                 /* good-bye */
  616.                 it := MODEL2;
  617.                 it.it_IText := "good-bye";
  618.                 PrintIText(Window*.w_RPort, &it, 25, 65);
  619.                 default:
  620.                 /* shouldn't get this */
  621.                 esac;
  622.             incase 2:
  623.                 /* Pixels */
  624.                 for n from 0 upto 16 do
  625.                 SetAPen(Window*.w_RPort, n % 3 + 1);
  626.                 pretend(
  627.                     WritePixel(Window*.w_RPort, n * n, n * 10),
  628.                     void);
  629.                 od;
  630.                 SetAPen(Window*.w_RPort, 1);
  631.             incase 3:
  632.                 /* Lines */
  633.                 for n from 0 upto 18 do
  634.                 SetAPen(Window*.w_RPort, n % 3 + 1);
  635.                 Move(Window*.w_RPort, 12, 12);
  636.                 Draw(Window*.w_RPort, 300, 12 + 10 * n);
  637.                 od;
  638.                 SetAPen(Window*.w_RPort, 1);
  639.             incase 4:
  640.                 /* Fill */
  641.                 SetAPen(Window*.w_RPort, 2);
  642.                 SetBPen(Window*.w_RPort, 3);
  643.                 RectFill(Window*.w_RPort, 20, 100, 300, 180);
  644.             default:
  645.                 /* shouldn't get this */
  646.             esac;
  647.             default:
  648.             /* shouldn't get this */
  649.             esac;
  650.             which := mi*.mi_NextSelect;
  651.         od;
  652.         default:
  653.         /* shouldn't get this */
  654.         esac;
  655.     od;
  656.     od;
  657. corp;
  658.  
  659. proc main()void:
  660.     type
  661.     pointer_t = [22]uint,
  662.     pattern_t = [2]uint;
  663.     *NewScreen_t ns;
  664.     *NewWindow_t nw;
  665.     *uint pointer, pattern;
  666.  
  667.     /* The C technique of calling a cleanup routine on any failure, and having
  668.        it free everything up via checking global variables, could have been
  669.        used here, but I didn't nest TOO deep did I? (Also, given that Draco
  670.        doesn't initialize global variables to anything, it would have
  671.        required assignments to everything at the beginning.) */
  672.  
  673.     if OpenIntuitionLibrary(0) ~= nil then
  674.     if OpenExecLibrary(0) ~= nil then
  675.         if OpenGraphicsLibrary(0) ~= nil then
  676.         ns := &NewScreen_t(
  677.             0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, BIT_PLANES,
  678.             0, 1, 0x0, CUSTOMSCREEN, nil, nil, nil, nil);
  679.         ns*.ns_DefaultTitle := "My Test Screen";
  680.         Screen := OpenScreen(ns);
  681.         if Screen ~= nil then
  682.             nw := &NewWindow_t(
  683.             100, 50, 200, 100, FREEPEN, FREEPEN,
  684.             CLOSEWINDOW | MENUPICK,
  685.             SMART_REFRESH | ACTIVATE | WINDOWSIZING | SIZEBRIGHT |
  686.                 WINDOWDEPTH | WINDOWCLOSE | WINDOWDRAG |
  687.                 NOCAREREFRESH,
  688.             nil, nil, nil, nil, nil, 40, 33, /* room for Bob */
  689.             SCREEN_WIDTH, SCREEN_HEIGHT, CUSTOMSCREEN);
  690.             nw*.nw_Title := "My Test Window";
  691.             nw*.nw_Screen := Screen;
  692.             Window := OpenWindow(nw);
  693.             if Window ~= nil then
  694.             pointer := pretend(
  695.                 AllocMem(sizeof(pointer_t), MEMF_CHIP), *uint);
  696.             if pointer ~= nil then
  697.                 CopyMem(pretend(&pointer_t(
  698.                     0x0000, 0x0000,
  699.                     0xc180, 0x4100,
  700.                     0x6380, 0xa280,
  701.                     0x3700, 0x5500,
  702.                     0x1600, 0x2200,
  703.                     0x0000, 0x0000,
  704.                     0x1600, 0x2200,
  705.                     0x2300, 0x5500,
  706.                     0x4180, 0xa280,
  707.                     0x8080, 0x4100,
  708.                     0x0000, 0x0000), *byte),
  709.                     pretend(pointer, *byte),
  710.                     sizeof(pointer_t));
  711.                 SetPointer(Window, pointer, 9, 9, -5, -4);
  712.                 pattern := pretend(
  713.                 AllocMem(sizeof(pattern_t), MEMF_CHIP), *uint);
  714.                 if pattern ~= nil then
  715.                 CopyMem(pretend(&pattern_t(
  716.                         0xaaaa,
  717.                         0x5555), *byte),
  718.                     pretend(pattern, *byte),
  719.                     sizeof(pattern_t));
  720.                 SetAfPt(Window*.w_RPort, pattern, 1);
  721.                 setupMenus();
  722.                 doit();
  723.                 FreeMem(pretend(pattern, *byte),
  724.                     sizeof(pattern_t));
  725.                 fi;
  726.                 FreeMem(pretend(pointer, *byte),
  727.                     sizeof(pointer_t));
  728.             fi;
  729.             CloseWindow(Window);
  730.             fi;
  731.             CloseScreen(Screen);
  732.         fi;
  733.         CloseGraphicsLibrary();
  734.         fi;
  735.         CloseExecLibrary();
  736.     fi;
  737.     CloseIntuitionLibrary();
  738.     fi;
  739. corp;
  740.