home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / NDK / NDK_1.3 / Read-Me1.3 / Workbench1.3 / Ieee.Examples / Ffuz.c next >
Encoding:
C/C++ Source or Header  |  1988-02-11  |  13.5 KB  |  593 lines

  1. /***********************************************************************
  2. *
  3. *            More Fuzzy Numbers on the Amiga
  4. *
  5. *       This Fuz shows a way to use direct calls to the IEEEDP math
  6. *    functions. This way people without the Manx mi.lib & mi32.lib
  7. *    files can compile this mess (just wait 'till you see the assembler
  8. *    version...) and get some fuzzy idea of how to use the MC68881 on
  9. *    Microbotics' Multi-Function Module.
  10. *       Fuz works off of three input variable - rot or rotation factor,
  11. *    vx and vy which are the X & Y vectors. The values that give the
  12. *    best results are floating point numbers of course. Use a value of
  13. *    .1 or less for rot, vy generally likes bigger #'s like 599.9893,
  14. *    and vx can be anything including 0 up to the 9 character limit on
  15. *    the input buffer. - when it's started it'll plot the default values
  16. *    I put in, and takes 20 seconds (roughly) to draw. I chose these
  17. *    values because they're a good example of the type of numerical
  18. *    input you should try. It's a toy. Play with it.
  19. *
  20. *        To compile FFuz.c with Manx, you need to link in two extra
  21. *    libraries, midb.lib and midt.lib that I hacked together for use with
  22. *     Manx. They stand for mathieeedoubbas.lib and mathieeedoubtrans.lib 
  23. *    respectively, which I've gotten damned tired of typing, so if you see
  24. *     midb or midt somewhere in my code, that's what they mean. I'm glad
  25. *    there's a 30 character filename size limit, 'cause gawd knows what
  26. *    weird library or function names that Dale Luck will come up with,
  27. *    you know? I mean, have you ever looked at the function names in the
  28. *    Layers library? I rest my case.
  29. *        Anyway, here's the Manx makefile for FFuz.c
  30.  
  31. CFLAGS    =    +fi +L -S
  32. OBJ    =    FFuz.o
  33.  
  34. ffuz:        $(OBJ)
  35.         ln -o FFuz $(OBJ) -lmidb -lmidt -lmi32 -lc32
  36.  
  37. *            author: David Milligan, for MicroBotics 
  38. *
  39. * FFuz source code is presented courtesy of MicroBotics, Inc., Richardson, TX.
  40. * FFuz is copyright 1987, MicroBotics, Inc. and David Milligan.
  41. * All rights reserved.
  42. ****************************************************************************/
  43.  
  44. #include <exec/types.h>
  45. #include <intuition/intuition.h>
  46. #include "devices/timer.h"
  47. #include <math.h>
  48. #include <stdio.h>
  49.  
  50. #define INTUITION    0x00000001
  51. #define GRAPHICS    0x00000002
  52. #define SCREEN        0x00000004
  53. #define WINDOW        0x00000008
  54. #define MIDB        0x00000010
  55. #define MIDT        0x00000020
  56. #define    NW_IDCMP    MOUSEBUTTONS|GADGETDOWN|GADGETUP|CLOSEWINDOW
  57. #define    NW_FLAGS    BORDERLESS|BACKDROP|ACTIVATE|WINDOWCLOSE
  58.  
  59. #ifndef TRUE
  60. #define TRUE 1
  61. #define FALSE 0
  62. #endif
  63.  
  64. #define CX    320
  65. #define CY    200
  66. #define XTWEAK    170
  67. #define YTWEAK    140
  68.  
  69. /*
  70.  * Gadget definitions
  71.  */
  72. #define ROT    1
  73. #define VX    2
  74. #define VY    3
  75. #define WHOA    4
  76. #define GO    5
  77. #define NUMGADS 5
  78. #define BOOLAFLAGS    RELVERIFY|GADGIMMEDIATE
  79. #define STRAFLAGS    RELVERIFY|GADGIMMEDIATE|STRINGCENTER
  80. #define GADL_EDGE    5
  81. #define GADT_EDGE    30
  82.  
  83. struct  GfxBase       *GfxBase;
  84. struct  IntuitionBase *IntuitionBase;
  85. struct  RastPort      *rp;
  86. struct  ViewPort      *vp;
  87. struct    Window    *w;
  88. struct    Screen    *screen;
  89. struct    IntuiMessage    *message;
  90.  
  91. UBYTE rotbuf[10] =    ".02";    /* This set of values draws a nice display */
  92. UBYTE vxbuf[10] =    "199";
  93. UBYTE vybuf[10] =    "192";
  94. char timebuf[25];
  95.  
  96. /*#define USE_COMPILER*/
  97. #ifdef USE_COMPILER
  98. #define    Add(x,y)    ((x)+(y))
  99. #define    Mul(x,y)    ((x)*(y))
  100. #define    Div(x,y)    ((x)/(y))
  101. #define    Sub(x,y)    ((x)-(y))
  102. #define Flt(x)    (x)
  103. #define Fix(x) (x)
  104. #define Sin sin
  105. #define Cos cos
  106. #define Abs fabs
  107. double    sin(),cos(),fabs();
  108. #else
  109. #define Add  IEEEDPAdd        /* We re-define the Double-Precision math */
  110. #define Mul IEEEDPMul        /* functions to a tolerable length.      */
  111. #define Div IEEEDPDiv
  112. double Add();        /* We want to make sure that we get a double value */
  113. double Mul();        /* returned from all the IEEEDP functions.....*/
  114. double Div();
  115. #define Flt IEEEDPFlt
  116. #define Fix IEEEDPFix
  117. double Flt();
  118.         /* Everything EXCEPT IEEDPFix() - this function is */
  119.         /* what turns the IEEEDP values into usable integer */
  120.         /* values. This hung me up for an embarassing amount */
  121.         /* of time whilst beating on the IEEEDP stuff. It must */
  122.         /* be declared as   int IEEEDPFix()   */
  123. int Fix();
  124. #define Sin IEEEDPSin
  125. #define Cos IEEEDPCos
  126. #define Abs IEEEDPAbs
  127. double Sin();
  128. double Cos();
  129. double Abs();
  130. #endif
  131.  
  132. #ifndef GREENHILLS
  133. long MathIeeeDoubBasBase;
  134. long MathIeeeDoubTransBase;
  135. #endif
  136.  
  137. double atof();
  138.  
  139. /*
  140.  *    color values
  141.  *        pen #      0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
  142.  */
  143. USHORT red[] =        { 0, 13,11,12,13,13,14,15, 8, 4, 0, 0, 0, 0, 0, 4 };
  144. USHORT green[] =    { 0,  2, 3, 4, 5, 7, 9,13,11, 9, 6, 4, 2, 0, 5,10 };
  145. USHORT blue[] =        { 0,  2, 2, 2, 2, 1, 1, 0, 0, 0, 2, 7,10,14,15,15 };
  146.  
  147. struct TextAttr Topfont =
  148.     {
  149.     "topaz.font", TOPAZ_SIXTY,
  150.     FSF_EXTENDED | FSF_ITALIC | FSF_BOLD,
  151.     FPF_ROMFONT | FPF_PROPORTIONAL
  152.     };
  153. struct TextAttr Toyfont =
  154.     {
  155.     "topaz.font", TOPAZ_EIGHTY,
  156.     FSF_EXTENDED,
  157.     FPF_ROMFONT | FPF_PROPORTIONAL
  158.     };
  159. /*
  160.  *    border line vectors
  161.  */
  162. USHORT gadvecs2[] =    { 0,0,58,0,58,10,0,10,0,0 };
  163. USHORT gadvecs3[] =    { 0,0,84,0,84,12,0,12,0,0 };
  164. USHORT timervec[] =    {0,0,176,0,176,11,0,11,0,0};
  165.  
  166. struct IntuiText timer_text = { 7,0,JAM2,20,380, &Toyfont, &timebuf, NULL };
  167. struct Border timer_brdr = { 5,377, 1,0,JAM2, 5, timervec, NULL };
  168.  
  169. struct Border gad_brdr[NUMGADS] = 
  170. {
  171.     { -2,-3, 15,0,JAM1, 5, gadvecs3, NULL },
  172.     { -2,-3, 13,0,JAM1, 5, gadvecs3, NULL },
  173.     { -2,-3, 11,0,JAM1, 5, gadvecs3, NULL },
  174.     { -2,-1,  5,0,JAM1, 5, gadvecs2, NULL },
  175.     { -2,-1, 10,0,JAM1, 5, gadvecs2, NULL }
  176. };
  177.  
  178. struct IntuiText gad_txt[NUMGADS] =
  179. {
  180.     { 7,0,JAM2,    28,-12, &Toyfont, "rot", NULL },
  181.     { 7,0,JAM2,    34,-12, &Toyfont, "vx", NULL },
  182.     { 7,0,JAM2,    34,-12, &Toyfont, "vy", NULL },
  183.     { 7,4,JAM2,    1,   0, &Topfont, "Whoa!", NULL },
  184.     { 7,9,JAM2,    1,   0, &Topfont, "Start", NULL }
  185. };
  186.  
  187. struct StringInfo gad_info[NUMGADS-2] =
  188.     { rotbuf,  NULL, 0, 10, 0, 0,0,0,2,1, 0, NULL, NULL },
  189.     { vxbuf,   NULL, 0, 10, 0, 0,0,0,2,1, 0, NULL, NULL },
  190.     { vybuf,   NULL, 0, 10, 0, 0,0,0,2,1, 0, NULL, NULL }
  191. };
  192.  
  193. struct Gadget toy_gad[NUMGADS] = 
  194. {
  195.     {        /*    rotation string gadget    */
  196.     NULL,
  197.     GADL_EDGE,GADT_EDGE,
  198.     80,10,
  199.     GADGHCOMP,STRAFLAGS,STRGADGET,
  200.     (APTR)&gad_brdr[0],NULL, &gad_txt[0],
  201.     0, (APTR)&gad_info[0],
  202.     ROT, NULL
  203.     },
  204.     {        /*    x-vector input gadget    */
  205.     &toy_gad[0],
  206.     GADL_EDGE,GADT_EDGE+25,
  207.     80,10,
  208.     GADGHCOMP,STRAFLAGS,STRGADGET,
  209.     (APTR)&gad_brdr[1],NULL, &gad_txt[1],
  210.     0, (APTR)&gad_info[1],
  211.     VX, NULL
  212.     },
  213.     {        /*    y-vector input gadget    */
  214.     &toy_gad[1],
  215.     GADL_EDGE,GADT_EDGE+50,
  216.     80,10,
  217.     GADGHCOMP,STRAFLAGS,STRGADGET,
  218.     (APTR)&gad_brdr[2],NULL, &gad_txt[2],
  219.     0, (APTR)&gad_info[2],
  220.     VY, NULL
  221.     },
  222.     {        /*    stop button    */
  223.     &toy_gad[2],
  224.     GADL_EDGE+11,GADT_EDGE+65,
  225.     58,9,
  226.     GADGHCOMP, BOOLAFLAGS, BOOLGADGET,
  227.     (APTR)&gad_brdr[3],NULL, &gad_txt[3],
  228.     0, NULL,
  229.     WHOA, NULL
  230.     },
  231.     {        /*    start button     */
  232.     &toy_gad[3],
  233.     GADL_EDGE+11,GADT_EDGE+80,
  234.     58,9, 
  235.     GADGHCOMP, BOOLAFLAGS, BOOLGADGET, 
  236.     (APTR)&gad_brdr[4],NULL, &gad_txt[4],
  237.     0, NULL, 
  238.     GO, NULL
  239.     }
  240. };
  241.  
  242. struct NewScreen ns =
  243.     {
  244.     0, 0, 640, 400,
  245.     4, 0, 0,
  246.     HIRES|LACE, CUSTOMSCREEN,
  247.     &Toyfont,NULL, NULL
  248.     };
  249.  
  250. struct NewWindow nw =
  251.     {
  252.     0, 12, 640, 388, 7, 0,
  253.     NW_IDCMP,
  254.     NW_FLAGS,
  255.     &toy_gad[4], NULL,
  256.     "               MicroBotics' Fuzzy Number Plotter, by Dmil",
  257.     NULL, NULL, 0, 0, 0, 0, CUSTOMSCREEN
  258.     };
  259.  
  260. struct timeval t1;
  261. struct timeval t2;
  262.  
  263. extern struct MsgPort *CreatePort();
  264. extern struct IORequest *CreateExtIO();
  265.  
  266.  
  267. unsigned int mask = 0;
  268. BOOL idling;
  269.     /* A variable for everything I could think of, and a couple more */
  270.     /* just in case it wasn't confusing enough.    */
  271. int from_wb,col,cnt,nx,ny,n;
  272. double rot,vx,vy,inc,deginc,degvx,degvy,absvx,absvy,xtweak,ytweak;
  273. double PI,DEG,sintemp,sintempvx,costemp,costempvy,vnx,vny,n1,n2;
  274.  
  275. /************************************************
  276.  *         Main Program             *
  277.  ************************************************/
  278. main(argc)
  279. int argc;
  280. {
  281.     ULONG  class;
  282.     USHORT code;
  283.     register struct Gadget *gad;
  284.     register int gadgid;
  285.     
  286.     col = 1;
  287.     inc = nx = ny = cnt = 0;
  288.  
  289.     if(argc)        /* started from CLI or Workbench? */
  290.       from_wb = 0;
  291.     else
  292.       from_wb = -1;
  293.  
  294.     std_open();    /* open all the librarys, screens, etc. */
  295.  
  296.     xtweak = Flt(XTWEAK);
  297.     ytweak = Flt(YTWEAK);
  298.  
  299.             /* This could've be #defined , but I did that */
  300.             /* in the last program. Tempting fate... */
  301.     PI = 3.14159265358979323846;
  302.     n = 80;
  303.     n1 = Flt(n);
  304.     DEG = Div(PI,n1);
  305.  
  306.     rot = atof(rotbuf); /* use default values for initial plot */
  307.     vx = atof(vxbuf);
  308.     vy = atof(vybuf);
  309.     SetBPen(rp, 0);
  310.     SetAPen(rp,col);
  311.     Move(rp,CX,CY+YTWEAK);
  312.     idling = FALSE;
  313.  
  314.     GetSysTime(&t1);
  315.  
  316. /************************************************
  317.  *         Main Fuzzy Area            *
  318.  ************************************************/
  319.  
  320. FOREVER 
  321.   {
  322.     if((message = (struct IntuiMessage *)GetMsg(w->UserPort)) != NULL)
  323.     {
  324.     class = message->Class;
  325.     code  = message->Code;
  326.     gad = message->IAddress;
  327.     ReplyMsg(message);
  328.        switch (class)
  329.         {
  330.              case CLOSEWINDOW:
  331.         stage_left();        /* Anyone remember Snagglepuss? */
  332.         break;
  333.          case GADGETDOWN:
  334.          case GADGETUP:
  335.         gadgid = gad->GadgetID;
  336.         if(class == GADGETUP)
  337.            switch (gadgid)
  338.          {
  339.             case WHOA:
  340.                ny = YTWEAK;
  341.                GetSysTime(&t2);
  342.                showetime();
  343.                break;
  344.             case GO:
  345.                rot = atof(rotbuf);
  346.                vx = atof(vxbuf);
  347.                vy = atof(vybuf);
  348.                SetRast(rp,0);
  349.                RefreshWindowFrame(w);
  350.                col = 1;
  351.                SetAPen(rp,col);
  352.                Move(rp,CX,CY+YTWEAK);
  353.                inc =0;
  354.                cnt = 0;
  355.                ny = 0;
  356.                GetSysTime(&t1);
  357.                idling = FALSE;
  358.                break;
  359.  
  360.             default:
  361.               break;
  362.             }
  363.        default:
  364.         break;
  365.         }
  366.  
  367.     }
  368.     do_fuzzer();
  369.   }
  370.  stage_left();    /* main exit */
  371. }    /* end of main */
  372.  
  373.  
  374.     /*
  375.      * Here we are, all set to bang out fuzzy numbers & draw them in
  376.      * loud, garish colors. In interlace too, so that all you out 
  377.      * there without long persistance monitors (I've got one) get the
  378.      * added eyestrain of flickering teensy dots.
  379.      *  I've broken the math functions into individual calls stored
  380.      * in lots of variables to avoid extremely long lines of code.
  381.      * You may not like this approach. Bummer. I do.
  382.      */
  383. do_fuzzer()
  384. {
  385.        if(ny < YTWEAK)
  386.     {
  387.     inc = Add(inc,rot);
  388.  
  389.     deginc = Mul(inc,DEG);
  390.     sintemp = Sin(deginc);
  391.     costemp = Cos(deginc);
  392.     degvy = Mul(deginc,vy);
  393.     costempvy = Cos(degvy);
  394.     absvy = Abs(costempvy);
  395.     vny = Mul(costemp,absvy);
  396.     if(vx == 0)
  397.       {
  398.        nx = Fix(Mul(sintemp,xtweak));
  399.       } else {    
  400.      degvx = Mul(deginc,vx);
  401.      sintempvx = Sin(degvx);
  402.      absvx = Abs(sintempvx);
  403.      vnx = Mul(sintemp,absvx);
  404.     nx = Fix(Mul(vnx,xtweak));
  405.      }
  406.     ny = Fix(Mul(vny,ytweak));
  407.     cnt ++;
  408.     if(cnt >141)
  409.      {
  410.       cnt = 0;
  411.       col++;
  412.       if(col == 15) col = 1;
  413.       SetAPen(rp,col);
  414.      }
  415.     Draw(rp,nx+CX,ny+CY);
  416.          if(ny >= YTWEAK && !idling)
  417.         {
  418.         GetSysTime(&t2);
  419.          showetime();
  420.         }
  421.     }
  422. }
  423.  
  424. std_open()
  425. {
  426.     register int i;
  427.  
  428.     if(!(IntuitionBase = (struct IntuitionBase *)
  429.             OpenLibrary("intuition.library", 0)))
  430.         errexit(" Can't open Intuition");
  431.  
  432.     mask |= INTUITION;
  433.  
  434.     if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0)))
  435.         errexit(" Can't open Gfx lib");
  436.  
  437.     mask |= GRAPHICS;
  438.  
  439. #ifndef GREENHILLS
  440.  
  441.     if(!(MathIeeeDoubBasBase = OpenLibrary("mathieeedoubbas.library",0)))
  442.         errexit(" no basic ieee library\n");
  443. #endif
  444.  
  445.     mask |= MIDB;
  446.  
  447. #ifndef GREENHILLS
  448.     if(!(MathIeeeDoubTransBase = OpenLibrary("mathieeedoubtrans.library",0)))
  449.         errexit(" no transcendental ieee library\n");
  450. #endif
  451.  
  452.     mask |= MIDT;
  453.  
  454.     if(!(screen = (struct Screen *)OpenScreen(&ns))) 
  455.         errexit(" Can't open the screen");
  456.  
  457.     mask |= SCREEN;
  458.  
  459.     nw.Screen = screen;
  460.  
  461.     ShowTitle(screen,FALSE);    /* turn off the screen title bar */
  462.     vp = &screen->ViewPort;
  463.         
  464. /*
  465.  * install some loud garish color
  466.  */
  467.     for(i = 0; i < 16; i++)
  468.         SetRGB4(vp,i,red[i],green[i],blue[i]);
  469.  
  470.     if(!(w = (struct Window *)OpenWindow(&nw)))
  471.         errexit(" Can't open the window");
  472.  
  473.     mask |= WINDOW;
  474.  
  475.     rp = w->RPort;
  476. }
  477.  
  478. errexit(str)
  479. register UBYTE *str;
  480. {
  481.     if(!from_wb)        /* started from CLI, so it's safe to */
  482.       printf("%s\n",str);    /* printf the error message    */
  483.  
  484.     stage_left();
  485. }
  486.  
  487. stage_left()
  488. {
  489. /*
  490.  *    use the masked flag bits to close what we opened
  491.  */
  492.  
  493.     if (mask & WINDOW)
  494.         CloseWindow(w);
  495.     if (mask & SCREEN)
  496.         CloseScreen(screen);
  497. #ifndef GREENHILLS
  498.     if (mask & MIDT)
  499.         CloseLibrary(MathIeeeDoubTransBase);
  500.     if (mask & MIDB)
  501.         CloseLibrary(MathIeeeDoubBasBase);
  502. #endif
  503.     if (mask & GRAPHICS)
  504.         CloseLibrary(GfxBase);
  505.     if (mask & INTUITION)
  506.         CloseLibrary(IntuitionBase);
  507.     exit();
  508. }
  509.  
  510. showetime()
  511. {
  512.     if(!idling)
  513.        sprintf(timebuf,"%ld.%ld seconds"
  514.         ,t2.tv_secs-t1.tv_secs,t1.tv_micro-t2.tv_micro);
  515.        DrawBorder(rp,&timer_brdr,0L,0L);
  516.        PrintIText(rp,&timer_text,0L,0L);
  517.        idling = TRUE;
  518. }
  519.  
  520. struct timerequest *PrepareTimer(precision)
  521. SHORT precision;
  522. {
  523.  
  524.     int error;
  525.     SHORT whichunit;
  526.  
  527.     struct MsgPort *timerport;
  528.     struct timerequest *timermsg;
  529.     
  530.         timerport = CreatePort(0,0);
  531.         if (timerport == NULL) 
  532.         return(NULL);    /* Error during CreatePort */
  533.  
  534.     timermsg = (struct timerequest *)CreateExtIO(
  535.                     timerport,sizeof(struct timerequest));
  536.     if (timermsg == NULL)
  537.         {
  538.         DeletePort(timerport);
  539.         return(NULL);    /* Error during CreateExtIO */
  540.         }
  541.     
  542.     if(precision)    /* if true, use precision timer  ( under 1 second ) */
  543.         whichunit = UNIT_MICROHZ;
  544.     else
  545.         whichunit = UNIT_VBLANK;
  546.  
  547.     error = OpenDevice(TIMERNAME, whichunit, timermsg, 0);
  548.     if (error != 0)
  549.         {
  550.         DeleteExtIO(timermsg,sizeof(struct timerequest));
  551.         DeletePort(timerport);
  552.         return(NULL);    /* Error during OpenDevice */
  553.         }
  554.     return(timermsg);
  555. }
  556.  
  557. int
  558. GetSysTime(tv)
  559. struct timeval *tv;
  560. {
  561.     struct timerequest *tr;
  562.     tr = PrepareTimer(TRUE);    /* MUST use Precise timer for this */
  563.     if(tr == 0) return(-1);        /* non zero return says error */
  564.  
  565.     tr->tr_node.io_Command = TR_GETSYSTIME;
  566.     DoIO( tr );
  567.  
  568.     tv->tv_secs = tr->tr_time.tv_secs;
  569.     tv->tv_micro = tr->tr_time.tv_micro;
  570.  
  571.     DeleteTimer(tr);
  572.     return(0);
  573.  
  574. }
  575.  
  576. int
  577. DeleteTimer(tr)
  578. struct timerequest *tr;
  579. {
  580.     struct MsgPort *tp;
  581.  
  582.     tp = tr->tr_node.io_Message.mn_ReplyPort;
  583.     if(tr != 0)
  584.     {
  585.         CloseDevice(tr);
  586.         DeleteExtIO(tr,sizeof(struct timerequest));
  587.     }
  588.     if(tp != 0)
  589.         DeletePort(tp);
  590.     return(0);        
  591. }
  592.