home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / Misc / TRSICAT.LZX / CATS_CD2_TRSI / Reference_Library / lib_examples / lines.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-21  |  11.6 KB  |  404 lines

  1. ;/* lines.c - Execute me to compile me with SAS C 5.10
  2. LC -b1 -cfistq -v -y -j73 lines.c
  3. Blink FROM LIB:c.o,lines.o TO lines LIBRARY LIB:LC.lib,LIB:Amiga.lib
  4. quit
  5. **
  6. ** This example shows how to implement a superbitmap, and uses a host of
  7. ** Intuition facilities.  Further reading of other Intuition and graphics
  8. ** chapters may be required for a complete understanding of this example.
  9. **
  10. ** lines.c -- implements a superbitmap with scroll gadgets
  11. ** This program requires V37, as it uses calls to OpenWindowTags(),
  12. ** LockPubScreen().
  13. */
  14.  
  15.  
  16. /* Enforces use of new prefixed Intuition flag names */
  17. #define INTUI_V36_NAMES_ONLY
  18.  
  19. #include <exec/types.h>
  20. #include <exec/memory.h>
  21. #include <intuition/intuition.h>
  22.  
  23. #include <clib/exec_protos.h>
  24. #include <clib/layers_protos.h>
  25. #include <clib/graphics_protos.h>
  26. #include <clib/intuition_protos.h>
  27.  
  28. /* Random number function in amiga.lib (see amiga.lib.doc) */
  29. UWORD RangeRand( unsigned long maxValue );
  30.  
  31. #ifdef LATTICE
  32. int CXBRK(void)    { return(0); }  /* Disable Lattice CTRL/C handling */
  33. int chkabort(void) { return(0); }  /* really */
  34. #endif
  35.  
  36. #define WIDTH_SUPER     (800)
  37. #define HEIGHT_SUPER    (600)
  38.  
  39. #define UP_DOWN_GADGET    (0)
  40. #define LEFT_RIGHT_GADGET (1)
  41. #define NO_GADGET         (2)
  42.  
  43. #define MAXPROPVAL (0xFFFFL)
  44.  
  45. #define GADGETID(x) (((struct Gadget *)(msg->IAddress))->GadgetID)
  46.  
  47. #define LAYERXOFFSET(x) (x->RPort->Layer->Scroll_X)
  48. #define LAYERYOFFSET(x) (x->RPort->Layer->Scroll_Y)
  49.  
  50. /* A string with this format will be found by the version command
  51. ** supplied by Commodore.  This will allow users to give version
  52. ** numbers with error reports.
  53. */
  54. UBYTE vers[] = "$VER: lines 37.2";
  55.  
  56. struct Library *GfxBase;
  57. struct Library *IntuitionBase;
  58. struct Library *LayersBase;
  59.  
  60. struct Window      *Win = NULL;          /* window pointer */
  61. struct PropInfo     BotGadInfo = {0};
  62. struct Image        BotGadImage = {0};
  63. struct Gadget       BotGad = {0};
  64. struct PropInfo     SideGadInfo = {0};
  65. struct Image        SideGadImage = {0};
  66. struct Gadget       SideGad = {0};
  67.  
  68.  
  69. /* Prototypes for our functions */
  70. VOID initBorderProps(struct Screen *myscreen);
  71. VOID doNewSize(void);
  72. VOID doDrawStuff(void);
  73. VOID doMsgLoop(void);
  74. VOID superWindow(struct Screen *myscreen);
  75.  
  76.  
  77. /*
  78. ** main
  79. ** Open all required libraries and get a pointer to the default public screen.
  80. ** Cleanup when done or on error.
  81. */
  82. VOID main(int argc, char **argv)
  83. {
  84. struct Screen *myscreen;
  85.  
  86. /* open all of the required libraries for the program.
  87. **
  88. ** require version 37 of the Intuition library.
  89. */
  90.  
  91. if (IntuitionBase = OpenLibrary("intuition.library",37L))
  92.     {
  93.     if (GfxBase = OpenLibrary("graphics.library",33L))
  94.         {
  95.         if (LayersBase = OpenLibrary("layers.library",33L))
  96.             {
  97.             /* LockPubScreen()/UnlockPubScreen is only available under V36
  98.             ** and later... Use GetScreenData() under V34 systems to get a
  99.             ** copy of the screen structure...
  100.             */
  101.             if (NULL != (myscreen = LockPubScreen(NULL)))
  102.                 {
  103.                 superWindow(myscreen);
  104.                 UnlockPubScreen(NULL,myscreen);
  105.                 }
  106.             CloseLibrary(LayersBase);
  107.             }
  108.         CloseLibrary(GfxBase);
  109.         }
  110.     CloseLibrary(IntuitionBase);
  111.     }
  112. }
  113.  
  114.  
  115. /*
  116. ** Create, initialize and process the super bitmap window.
  117. ** Cleanup if any error.
  118. */
  119. VOID superWindow(struct Screen *myscreen)
  120. {
  121. struct BitMap *bigBitMap;
  122. WORD planeNum;
  123. WORD allocatedBitMaps;
  124.  
  125. /* set-up the border prop gadgets for the OpenWindow() call. */
  126. initBorderProps(myscreen);
  127.  
  128. /* The code relies on the allocation of the BitMap structure with
  129. ** the MEMF_CLEAR flag.  This allows the assumption that all of the
  130. ** bitmap pointers are NULL, except those successfully allocated
  131. ** by the program.
  132. */
  133. if (bigBitMap = AllocMem(sizeof(struct BitMap), MEMF_PUBLIC | MEMF_CLEAR))
  134.     {
  135.     InitBitMap(bigBitMap, myscreen->BitMap.Depth, WIDTH_SUPER, HEIGHT_SUPER);
  136.  
  137.     allocatedBitMaps = TRUE;
  138.     for (planeNum = 0;
  139.          (planeNum < myscreen->BitMap.Depth) && (allocatedBitMaps == TRUE);
  140.              planeNum++)
  141.         {
  142.         bigBitMap->Planes[planeNum] = AllocRaster(WIDTH_SUPER, HEIGHT_SUPER);
  143.         if (NULL == bigBitMap->Planes[planeNum])
  144.             allocatedBitMaps = FALSE;
  145.         }
  146.  
  147.     /* Only open the window if the bitplanes were successfully
  148.     ** allocated.  Fail silently if they were not.
  149.     */
  150.     if (TRUE == allocatedBitMaps)
  151.         {
  152.         /* OpenWindowTags() and OpenWindowTagList() are only available
  153.         ** when the library version is at least V36.  Under earlier
  154.         ** versions of Intuition, use OpenWindow() with a NewWindow
  155.         ** structure.
  156.         */
  157.         if (NULL != (Win = OpenWindowTags(NULL,
  158.                 WA_Width,  150,
  159.                 WA_Height, 4 * (myscreen->WBorTop + myscreen->Font->ta_YSize + 1),
  160.                 WA_MaxWidth,  WIDTH_SUPER,
  161.                 WA_MaxHeight, HEIGHT_SUPER,
  162.                 WA_IDCMP, IDCMP_GADGETUP | IDCMP_GADGETDOWN |
  163.                     IDCMP_NEWSIZE | IDCMP_INTUITICKS | IDCMP_CLOSEWINDOW,
  164.                 WA_Flags, WFLG_SIZEGADGET | WFLG_SIZEBRIGHT | WFLG_SIZEBBOTTOM |
  165.                     WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET |
  166.                     WFLG_SUPER_BITMAP | WFLG_GIMMEZEROZERO | WFLG_NOCAREREFRESH,
  167.                 WA_Gadgets, &(SideGad),
  168.                 WA_Title, &vers[6], /* take title from version string */
  169.                 WA_PubScreen, myscreen,
  170.                 WA_SuperBitMap, bigBitMap,
  171.                 TAG_DONE)))
  172.             {
  173.             /* set-up the window display */
  174.             SetRast(Win->RPort,0); /* clear the bitplanes */
  175.             SetDrMd(Win->RPort,JAM1);
  176.  
  177.         doNewSize();    /* adjust props to represent portion visible */
  178.             doDrawStuff();
  179.  
  180.             /* process the window, return on IDCMP_CLOSEWINDOW */
  181.             doMsgLoop();
  182.  
  183.             CloseWindow(Win);
  184.             }
  185.         }
  186.  
  187.     for (planeNum = 0; planeNum < myscreen->BitMap.Depth; planeNum++)
  188.         {
  189.         /* free only the bitplanes actually allocated... */
  190.         if (NULL != bigBitMap->Planes[planeNum])
  191.             FreeRaster(bigBitMap->Planes[planeNum], WIDTH_SUPER, HEIGHT_SUPER);
  192.         }
  193.     FreeMem(bigBitMap,sizeof(struct BitMap));
  194.     }
  195. }
  196.  
  197. /*
  198. ** Set-up the prop gadgets--initialize them to values that fit
  199. ** into the window border.  The height of the prop gadget on the side
  200. ** of the window takes the height of the title bar into account in its
  201. ** set-up. note the initialization assumes a fixed size "sizing" gadget.
  202. **
  203. ** Note also, that the size of the sizing gadget is dependent on the
  204. ** screen resolution.  The numbers given here are only valid if the
  205. ** screen is NOT lo-res.  These values must be re-worked slightly
  206. ** for lo-res screens.
  207. **
  208. ** The PROPNEWLOOK flag is ignored by 1.3.
  209. */
  210. VOID initBorderProps(struct Screen *myscreen)
  211. {
  212. /* initializes the two prop gadgets.
  213. **
  214. ** Note where the PROPNEWLOOK flag goes.  Adding this flag requires
  215. ** no extra storage, but tells the system that our program is
  216. ** expecting the new-look prop gadgets under 2.0.
  217. */
  218. BotGadInfo.Flags     = AUTOKNOB | FREEHORIZ | PROPNEWLOOK;
  219. BotGadInfo.HorizPot  = 0;
  220. BotGadInfo.VertPot   = 0;
  221. BotGadInfo.HorizBody = -1;
  222. BotGadInfo.VertBody  = -1;
  223.  
  224. BotGad.LeftEdge     = 3;
  225. BotGad.TopEdge      = -7;
  226. BotGad.Width        = -23;
  227. BotGad.Height       = 6;
  228.  
  229. BotGad.Flags        = GFLG_RELBOTTOM | GFLG_RELWIDTH;
  230. BotGad.Activation   = GACT_RELVERIFY | GACT_IMMEDIATE | GACT_BOTTOMBORDER;
  231. BotGad.GadgetType   = GTYP_PROPGADGET | GTYP_GZZGADGET;
  232. BotGad.GadgetRender = (APTR)&(BotGadImage);
  233. BotGad.SpecialInfo  = (APTR)&(BotGadInfo);
  234. BotGad.GadgetID     = LEFT_RIGHT_GADGET;
  235.  
  236. SideGadInfo.Flags     = AUTOKNOB | FREEVERT | PROPNEWLOOK;
  237. SideGadInfo.HorizPot  = 0;
  238. SideGadInfo.VertPot   = 0;
  239. SideGadInfo.HorizBody = -1;
  240. SideGadInfo.VertBody  = -1;
  241.  
  242. /* NOTE the TopEdge adjustment for the border and the font for V36.
  243. */
  244. SideGad.LeftEdge   = -14;
  245. SideGad.TopEdge    = myscreen->WBorTop + myscreen->Font->ta_YSize + 2;
  246. SideGad.Width      = 12;
  247. SideGad.Height     = -SideGad.TopEdge - 11;
  248.  
  249. SideGad.Flags        = GFLG_RELRIGHT | GFLG_RELHEIGHT;
  250. SideGad.Activation   = GACT_RELVERIFY | GACT_IMMEDIATE | GACT_RIGHTBORDER;
  251. SideGad.GadgetType   = GTYP_PROPGADGET | GTYP_GZZGADGET;
  252. SideGad.GadgetRender = (APTR)&(SideGadImage);
  253. SideGad.SpecialInfo  = (APTR)&(SideGadInfo);
  254. SideGad.GadgetID     = UP_DOWN_GADGET;
  255. SideGad.NextGadget   = &(BotGad);
  256. }
  257.  
  258.  
  259. /*
  260. ** This function does all the work of drawing the lines
  261. */
  262. VOID doDrawStuff()
  263. {
  264. WORD x1,y1,x2,y2;
  265. WORD pen,ncolors,deltx,delty;
  266.  
  267. ncolors = 1 << Win->WScreen->BitMap.Depth;
  268. deltx = RangeRand(6)+2;
  269. delty = RangeRand(6)+2;
  270.  
  271. pen = RangeRand(ncolors-1) + 1;
  272. SetAPen(Win->RPort,pen);
  273. for(x1=0, y1=0, x2=WIDTH_SUPER-1, y2=HEIGHT_SUPER-1;
  274.     x1 < WIDTH_SUPER;
  275.         x1 += deltx, x2 -= deltx)
  276.     {
  277.     Move(Win->RPort,x1,y1);
  278.     Draw(Win->RPort,x2,y2);
  279.     }
  280.  
  281. pen = RangeRand(ncolors-1) + 1;
  282. SetAPen(Win->RPort,pen);
  283. for(x1=0, y1=0, x2=WIDTH_SUPER-1, y2=HEIGHT_SUPER-1;
  284.     y1 < HEIGHT_SUPER;
  285.         y1 += delty, y2 -= delty)
  286.     {
  287.     Move(Win->RPort,x1,y1);
  288.     Draw(Win->RPort,x2,y2);
  289.     }
  290. }
  291.  
  292. /*
  293. ** This function provides a simple interface to ScrollLayer
  294. */
  295. VOID slideBitMap(WORD Dx,WORD Dy)
  296. {
  297. ScrollLayer(0,Win->RPort->Layer,Dx,Dy);
  298. }
  299.  
  300. /*
  301. ** Update the prop gadgets and bitmap positioning when the size changes.
  302. */
  303. VOID doNewSize()
  304. {
  305. ULONG tmp;
  306.  
  307. tmp = LAYERXOFFSET(Win) + Win->GZZWidth;
  308. if (tmp >= WIDTH_SUPER)
  309.     slideBitMap(WIDTH_SUPER-tmp,0);
  310.  
  311. NewModifyProp(&(BotGad),Win,NULL,AUTOKNOB | FREEHORIZ,
  312.     ((LAYERXOFFSET(Win) * MAXPROPVAL) /
  313.         (WIDTH_SUPER - Win->GZZWidth)),
  314.     NULL,
  315.     ((Win->GZZWidth * MAXPROPVAL) / WIDTH_SUPER),
  316.     MAXPROPVAL,
  317.     1);
  318.  
  319. tmp = LAYERYOFFSET(Win) + Win->GZZHeight;
  320. if (tmp >= HEIGHT_SUPER)
  321.     slideBitMap(0,HEIGHT_SUPER-tmp);
  322.  
  323. NewModifyProp(&(SideGad),Win,NULL,AUTOKNOB | FREEVERT,
  324.     NULL,
  325.     ((LAYERYOFFSET(Win) * MAXPROPVAL) /
  326.         (HEIGHT_SUPER - Win->GZZHeight)),
  327.     MAXPROPVAL,
  328.     ((Win->GZZHeight * MAXPROPVAL) / HEIGHT_SUPER),
  329.     1);
  330. }
  331.  
  332. /*
  333. ** Process the currently selected gadget.
  334. ** This is called from IDCMP_INTUITICKS and when the gadget is released
  335. ** IDCMP_GADGETUP.
  336. */
  337. VOID checkGadget(UWORD gadgetID)
  338. {
  339. ULONG tmp;
  340. WORD dX = 0;
  341. WORD dY = 0;
  342.  
  343. switch (gadgetID)
  344.     {
  345.     case UP_DOWN_GADGET:
  346.         tmp = HEIGHT_SUPER - Win->GZZHeight;
  347.         tmp = tmp * SideGadInfo.VertPot;
  348.         tmp = tmp / MAXPROPVAL;
  349.         dY = tmp - LAYERYOFFSET(Win);
  350.         break;
  351.     case LEFT_RIGHT_GADGET:
  352.         tmp = WIDTH_SUPER - Win->GZZWidth;
  353.         tmp = tmp * BotGadInfo.HorizPot;
  354.         tmp = tmp / MAXPROPVAL;
  355.         dX = tmp - LAYERXOFFSET(Win);
  356.         break;
  357.     }
  358. if (dX || dY)
  359.     slideBitMap(dX,dY);
  360. }
  361.  
  362. /*
  363. ** Main message loop for the window.
  364. */
  365. VOID doMsgLoop()
  366. {
  367. struct IntuiMessage *msg;
  368. WORD flag = TRUE;
  369. UWORD currentGadget = NO_GADGET;
  370.  
  371. while (flag)
  372.     {
  373.     /* Whenever you want to wait on just one message port */
  374.     /* you can use WaitPort(). WaitPort() doesn't require */
  375.     /* the setting of a signal bit. The only argument it  */
  376.     /* requires is the pointer to the window's UserPort   */
  377.     WaitPort(Win->UserPort);
  378.     while (msg = (struct IntuiMessage *)GetMsg(Win->UserPort))
  379.         {
  380.         switch (msg->Class)
  381.             {
  382.             case IDCMP_CLOSEWINDOW:
  383.                 flag = FALSE;
  384.                 break;
  385.             case IDCMP_NEWSIZE:
  386.                 doNewSize();
  387.             doDrawStuff();
  388.                 break;
  389.             case IDCMP_GADGETDOWN:
  390.                 currentGadget = GADGETID(msg);
  391.                 break;
  392.             case IDCMP_GADGETUP:
  393.                 checkGadget(currentGadget);
  394.                 currentGadget = NO_GADGET;
  395.                 break;
  396.             case IDCMP_INTUITICKS:
  397.                 checkGadget(currentGadget);
  398.                 break;
  399.             }
  400.         ReplyMsg((struct Message *)msg);
  401.         }
  402.     }
  403. }
  404.