home *** CD-ROM | disk | FTP | other *** search
/ Current Shareware 1994 January / SHAR194.ISO / graphuti / polyops.zip / POLY_IN.C < prev    next >
Text File  |  1991-08-27  |  23KB  |  757 lines

  1.  
  2. /* Input routines for polyops.c */
  3.  
  4. #include <stdio.h>
  5. #include <graphics.h>
  6. #include <ctype.h>
  7. #include <alloc.h>
  8. #include <math.h>
  9. #include <string.h>
  10. #include <conio.h>
  11. #include <dos.h>
  12. #include <stdarg.h>
  13.  
  14. #define MAXPTS   100    /* maximum size of ANY polygon used, not just input */
  15. #define MAXX     640    /* greater than any permissible x-coordinate */
  16. #define MAXCOMPS  20    /* maximum number of output polygons allowed */
  17. #define MAXCHOICE 12    /* menu choices */
  18.  
  19. #define ESC       27
  20. #define PLUS      43
  21. #define MINUS     45
  22. #define INS      -82
  23. #define DEL      -83
  24. #define UP       -72
  25. #define DN       -80
  26. #define LEFT     -75
  27. #define RIGHT    -77
  28. #define HOME     -71
  29. #define END      -79
  30. #define PGUP     -73
  31. #define PGDN     -81
  32. #define SHFT_HOME 55
  33.  
  34. #define MIN(a,b)  (a) < (b) ? (a) : (b)
  35. #define MAX(a,b)  (a) > (b) ? (a) : (b)
  36. #define CLIP(x,a,b) MIN(MAX((x),(a)),(b))        /*  assumes a <= b  */
  37.  
  38. typedef struct {double x; double y;} point;
  39. typedef struct {point first; point second;} segment;
  40. typedef struct {int nverts; double x[MAXPTS]; double y[MAXPTS];} polygon;
  41. typedef struct {point v; int class; int next;} ventry; /* for vertex rings */
  42. typedef struct {point p1; point p2; int del;} fentry;  /* for frags list */
  43.  
  44. /* function prototypes */
  45. void
  46. check(int),
  47. clrmark(void),
  48. clearline(int,int),
  49. display(void),
  50. gprintf(int, int, int, char *,...),
  51. initialize(void),
  52. mark(void),
  53. move_to(int,int),
  54. msgcursor(void),
  55. msgotoxy(int,int),
  56. mshbounds(int,int),
  57. mshidecur(void),
  58. msmotion(int *,int *),
  59. mspage(int),
  60. msshowcur(void),
  61. msstatus(int *,int *,int *),
  62. msvbounds(int,int),
  63. pause(void);
  64.  
  65. int
  66. getint(int,char *),
  67. get_poly(void),
  68. load_data(char *),
  69. msinit(void),
  70. msrelease(int),
  71. prompt(int,int,int,char *msg),
  72. sx(double),
  73. sy(double);
  74.  
  75. double
  76. wx(int),
  77. wy(int);
  78.  
  79. extern int
  80.   getdouble(int,char *),
  81.   getkey(void);
  82.  
  83. extern int normcolr;
  84. extern double vd[];
  85. int vi[10];
  86.  
  87. /* variables and constants for graphics interface --------------------- */
  88. int xc,yc;                        /* coordinates of CP */
  89. int delta = 10;                   /* initial increment for moving CP */
  90. int colr;                         /* graph color */
  91. int colr1 = 0;                    /* background color for message line */
  92. int colr2 = 14;                   /* text color for prompts */
  93. int colr3 = 10;                   /* text color for display of coordinates */
  94. int bkcolor = 0;                  /* general background color, for erasures */
  95. int np;                           /* number of points currently marked */
  96. int mx[MAXPTS], my[MAXPTS];       /* coordinates of marked points */
  97. void *block1, *block2;            /* marked point indicators */
  98. void *cross;                      /* CP indicator */
  99. int x0=10,y0=329;                 /* home pos for cursor */
  100. int xdec=1, ydec=1;               /* precision values for display of CP */
  101. int sxmax,symax;                  /* maximum/minimum screen coordinates */
  102. int xb,yb;                        /* for graphics prompts */
  103. int graphics_init;                /* flag for graphics initialization */
  104. double xscale,yscale,xscale1,yscale1;  /* scaling constants */
  105. int mouse;                       /* mouse driver loaded flag */
  106. int stat;                        /* mouse button status */
  107. /* ----------------------------------------------------------------------- */
  108.  
  109. int mode;                          /* graphics mode used */
  110. extern polygon A,B;                /* input polygons */
  111. extern int oper;                   /* intersection, union, A-B, B-A */
  112. char filename[32], fname[13];
  113.  
  114. int ax1[MAXPTS],ay1[MAXPTS];        /* screen vertices of A */
  115. int ax2[MAXPTS],ay2[MAXPTS];        /* screen vertices of B */
  116. int nv1,nv2;                        /* sizes of A and B */
  117. int xx=32,yy=192;                   /* query location, menu */
  118.  
  119. /* ----------------- graphics entry of polygons -------------------------- */
  120. /* Fills the global integer arrays ax1[],ay1[],ax2[],ay2[] with the screen
  121.    coordinates of the vertices of two polygons entered by the user. The
  122.    integers nv1,nv2 are set to the sizes of the polygons.                  */
  123. int
  124. graf_in(void)
  125. {
  126.    int i;
  127.  
  128.    for (i=0; i<12; i++) fname[i] = ' ';  /* be sure display name is empty */
  129.    fname[12] = '\0';
  130. enter_polys:
  131.    setviewport(0,0,sxmax,yb-1,1);
  132.    clearviewport();
  133.    setviewport(0,0,sxmax,symax,1);
  134.    xc=x0; yc=y0;
  135.    moveto(xc,yc);
  136.    if (mouse)
  137.      msgotoxy(xc,yc);
  138.    putimage(xc-5,yc-5,cross,XOR_PUT);
  139.    prompt(xb,yb+3,1,"Mark vertices of first polygon, press Enter when done");
  140.    display();                            /* show values of cx,cy */
  141.    colr = 10;                            /* draw A in green */
  142.    i = get_poly();                       /* get user input for first polygon */
  143.    if (i==-1)                            /* Esc pressed during poly input */
  144.       {
  145.        np=0;
  146.        cleardevice();
  147.        return 0;
  148.       }
  149.    if (np<3)
  150.      {
  151.       prompt(xb,yb+3,1,
  152.          "At least 3 vertices must be marked. Press any key to reenter");
  153.       if (getch() == 27)
  154.         {
  155.          np=0;
  156.          cleardevice();
  157.          return 0;
  158.         }
  159.       else
  160.         goto enter_polys;
  161.      }
  162.    nv1 = np;
  163.    for (i=0; i<nv1; i++)
  164.      {
  165.       ax1[i] = mx[i];
  166.       ay1[i] = my[i];
  167.      }
  168.    np = 0;
  169.    prompt(xb,yb+3,1,"Mark vertices of second polygon, press Enter when done");
  170.    colr = 12;                            /* draw B in red */
  171.    i = get_poly();                       /* get user input for next polygon */
  172.     if (i==-1)                            /* Esc pressed during poly input */
  173.       {
  174.        cleardevice();
  175.        return 0;
  176.       }
  177.    if (np<3)
  178.      {
  179.       prompt(xb,yb+3,1,
  180.          "At least 3 vertices must be marked. Press any key to reenter");
  181.       if (getch() == 27)
  182.         {
  183.          cleardevice();
  184.          return 0;
  185.         }
  186.       goto enter_polys;
  187.      }
  188.    nv2 = np;
  189.    for (i=0; i<nv2; i++)
  190.      {
  191.       ax2[i] = mx[i];
  192.       ay2[i] = my[i];
  193.      }
  194.    np = 0;
  195.  
  196.    prompt(xb,yb+3,1,"Press any key to continue");
  197.    getch();
  198.    cleardevice();
  199.    return 1;
  200. }
  201.  
  202. /* ------------------------------------------------------------------------ */
  203.              /* accept user input of polygon from screen */
  204. int
  205. get_poly(void)
  206. {
  207.    int i,j,c,xtmp=xc,ytmp=yc;
  208.  
  209.    np = 0;
  210.    if (mouse) {
  211.      msinit();                     /* clear mouse parameters */
  212.      msgotoxy(xc,yc);
  213.    }
  214.    while (1) {
  215.      if (kbhit()) {
  216.        c = getkey();
  217.        if (c == 13)                          /* Enter key exits */
  218.          goto gp_ret;
  219.        check(c);                              /* cursor movement, +/- */
  220.        if (c==INS)                            /* Ins marks (xc,yc) */
  221.          mark();
  222.        if (c==DEL)                            /* clear last mark */
  223.          clrmark();
  224.        if (c==27)
  225.           return -1;                           /* quit if Esc pressed */
  226.      }
  227.      if (mouse) {
  228.        msstatus(&stat,&xtmp,&ytmp);
  229.        if (stat == 2)                            /* right button exits */
  230.          goto gp_ret;
  231.        if (stat == 1) {                          /* left button marks point) */
  232.           mark();                                /* mark current point */
  233.           while (stat == 1)                      /* wait for button release */
  234.              msstatus(&stat,&xtmp,&ytmp);
  235.           continue;
  236.        }
  237.        if (stat == 0) {               /* no button pressed */
  238.      msmotion(&i,&j);             /* check movement */
  239.      if (i || j)                  /* if mouse moved... */
  240.        move_to(xtmp,ytmp);        /* ..update cursor and (xc,yc) */
  241.        }
  242.      }
  243.    }
  244. gp_ret:
  245.    if (np) {
  246.      move_to(x0,y0);                    /* get cross hairs out of the way */
  247.      setcolor(colr);                    /* green for A, red for B */
  248.      line(mx[np-1],my[np-1],mx[0],my[0]);         /* close up polygon */
  249.    }
  250.    setcolor(normcolr);
  251.    return np;
  252. }
  253.  
  254. /* ----------------------- hand entry of polygons ------------------------ */
  255. int
  256. kb_in(void)
  257. {
  258.    int i=0;
  259.    char s[256];
  260.  
  261.    for (i=0; i<12; i++) fname[i] = ' ';  /* be sure display name is empty */
  262.    fname[12] = '\0';
  263.    printf("Vertices must be in the range [0,1]\n");
  264. vA:
  265.    printf("Enter number of vertices for polygon A : ");
  266.    gets(s);
  267.    if (strlen(s)==0 || *s == 27)  return 0;
  268.    getint(1,s);
  269.    A.nverts = nv1 = vi[0];
  270.    if (A.nverts<3 || A.nverts>MAXPTS)
  271.      {
  272.       printf("Too many or not enough vertices. Please reenter.\n");
  273.       goto vA;
  274.      }
  275.    printf("Enter vertices of A :\n");
  276.    gets(s);
  277.    if (getdouble(2*A.nverts,s) != 2*A.nverts)
  278.      {
  279.       printf("Too many or not enough vertices. Please reenter.\n");
  280.       goto vA;
  281.      }
  282.    for (i=0; i<A.nverts; i++)
  283.      {
  284.       A.x[i] = vd[2*i];
  285.       ax1[i] = sx(A.x[i]);
  286.       A.y[i] = vd[2*i+1];
  287.       ay1[i] = sy(A.y[i]);
  288.      }
  289. vB:
  290.    printf("Enter number of vertices for polygon B : ");
  291.    gets(s);
  292.    if (strlen(s)==0 || *s == 27)  return 0;
  293.    getint(1,s);
  294.    B.nverts = nv2 = vi[0];
  295.    if (B.nverts<3 || B.nverts>MAXPTS)
  296.      {
  297.       printf("Too many or not enough vertices. Please reenter.\n");
  298.       goto vB;
  299.      }
  300.    printf("Enter vertices of B :\n");
  301.    gets(s);
  302.    if (getdouble(2*B.nverts,s) != 2*B.nverts)
  303.      {
  304.       printf("Too many or not enough vertices. Please reenter.\n");
  305.       goto vB;
  306.      }
  307.    for (i=0; i<B.nverts; i++)
  308.      {
  309.       B.x[i] = vd[2*i];
  310.       ax2[i] = sx(B.x[i]);
  311.       B.y[i] = vd[2*i+1];
  312.       ay2[i] = sy(B.y[i]);
  313.      }
  314.    return 1;
  315. }
  316.  
  317. /* ---------- read polygons (and world coords) from disk file ----------- */
  318. int
  319. load_data(char *s)
  320. {
  321.    FILE *fp;
  322.    int i,j,nv,v[2*MAXPTS];
  323.    int c;
  324.    char s1[20], *sp, *sp1;
  325.    double z;
  326.  
  327.    if (strncmpi(s,"pdat",4)==0)      /* file 'poly.dat' contains numerous */
  328.      {                               /* subfiles named 'pdat1, pdat2,...  */
  329.       fp = fopen("poly.dat","rt");
  330.       if (fp == NULL)                 /* if 'poly.dat' does not exist .. */
  331.          goto b;                      /* .. try to open stand alone file */
  332.  
  333.       /* search "poly.dat" for requested filename */
  334.       while (!feof(fp))
  335.         {
  336.          sp=s1;
  337.          while(isalnum(c = getc(fp)))
  338.            {
  339.             *sp = c;
  340.             sp++;
  341.            }
  342.          *sp = '\0';
  343.          if (!strcmp(s1,s))
  344.            {
  345.             c = 'F';                               /* to show filename found */
  346.             break;
  347.            }
  348.          while(!isalpha(c = getc(fp)) && c != -1)
  349.             ;
  350.          if (c != -1)
  351.             ungetc(c,fp);
  352.         }
  353.       if (c != 'F')
  354.         {
  355.          fclose(fp);
  356.          goto b;    /* not found in 'poly.dat' so try to open stand alone */
  357.         }
  358.      }
  359.    else                                                  /* not 'pdat*' file */
  360. b:
  361.    if ((fp = fopen(s,"rt")) == NULL)
  362.       return 0;
  363.    strcpy(filename,s);      /* save filename */
  364.                             /* make 12-character display name */
  365.    sp = filename+strlen(filename);
  366.    sp1 = fname+12;
  367.    while(sp >= filename && *sp != '\\' && *sp != ':')
  368.       *sp1-- = *sp--;
  369.    while (sp1 >= fname) *sp1-- = ' ';   /* pad left to 12 characters */
  370.    /* -------------- get data from file fp -------------- */
  371.    fscanf(fp,"%d",&nv1);            /* number of vertices, polygon 1 */
  372.    A.nverts = nv1;
  373.    for (i=0; i<nv1; i++) {
  374.       fscanf(fp,"%lf",&z);
  375.       A.x[i] = z;
  376.       ax1[i] = sx(z);               /* screen x-coordinates, A */
  377.     }
  378.    for (i=0; i<nv1; i++) {
  379.       fscanf(fp,"%lf",&z);
  380.       A.y[i] = z;
  381.       ay1[i] = sy(z);               /* screen y-coordinates, A */
  382.    }
  383.    fscanf(fp,"%d",&nv2);            /*  similar data for B */
  384.    B.nverts = nv2;
  385.    for (i=0; i<nv2; i++) {
  386.       fscanf(fp,"%lf",&z);
  387.       B.x[i] = z;
  388.       ax2[i] = sx(z);               /* screen x-coordinates, B */
  389.    }
  390.    for (i=0; i<nv2; i++) {
  391.       fscanf(fp,"%lf",&z);
  392.       B.y[i] = z;
  393.       ay2[i] = sy(z);               /* screen y-coordinates, B */
  394.    }
  395.    fclose(fp);
  396.    return 1;
  397. }
  398. /* ======================================================================== */
  399.       /* miscellaneous supporting routines , listed alphabetically */
  400. /* ======================================================================== */
  401.  
  402. /* ---- extract n integer values from string s, put them in array vi[] --- */
  403. int
  404. getint(int n, char *s)
  405. {
  406.   int cnt=0;
  407.   char *p;
  408.  
  409.   if (n == 0) return cnt;
  410.  
  411.   p = s;
  412.   while (cnt < n && *p)
  413.     {
  414.      while (!isdigit(*p)) p++;
  415.      vi[cnt] = atoi(p);
  416.      while (isdigit(*p)) p++;
  417.      cnt++;
  418.     }
  419.   return cnt;
  420. }
  421.  
  422. /* ==================== Graphics interface functions ==================== */
  423. /* Functions necessary to make the interface work, listed alphabetically  */
  424. /* ---------------------------------------------------------------------- */
  425.                   /* check user keystroke for arrow keys and +/- commands */
  426. void
  427. check(int c)
  428. {
  429.    switch(c)
  430.      {
  431.       case PLUS:                           /* increase cursor increment */
  432.         delta = MIN(10*delta,100);
  433.         break;
  434.       case MINUS:                          /* decrease cursor increment */
  435.         delta = MAX(delta/10,1);
  436.         break;
  437.       case UP:
  438.         move_to(xc,yc-delta);
  439.         break;
  440.      case DN:
  441.         move_to(xc,yc+delta);
  442.         break;
  443.       case LEFT:
  444.         move_to(xc-delta,yc);
  445.         break;
  446.      case RIGHT:
  447.         move_to(xc+delta,yc);
  448.         break;
  449.      case HOME:                             /* diagonal UL */
  450.         move_to(xc-delta,yc-delta);
  451.         break;
  452.      case END:                              /* diagonal DL */
  453.         move_to(xc-delta,yc+delta);
  454.         break;
  455.      case PGUP:                             /* diagonal UR */
  456.         move_to(xc+delta,yc-delta);
  457.         break;
  458.      case PGDN:                             /* diagonal DR */
  459.         move_to(xc+delta,yc+delta);
  460.         break;
  461.      case SHFT_HOME:                        /* home position for cursor */
  462.         move_to(x0,y0);
  463.         break;
  464.     }
  465. }
  466.  
  467. /* ---------------------------------------------------------------------- */
  468. void
  469. clearline(int x, int y)
  470. {
  471.    bar(x,y,sxmax,y+8);
  472. }
  473. /* ---------------------------------------------------------------------- */
  474.                  /* clear last mark made */
  475. void
  476. clrmark(void)
  477. {
  478.  int i;
  479.  int x,y;
  480.  
  481.  if (np==0)
  482.     return;
  483.  np--;
  484.  if(np)
  485.    {
  486.     putimage(xc-5,yc-5,cross,XOR_PUT);
  487.     setcolor(bkcolor);
  488.     line(mx[np-1],my[np-1],mx[np],my[np]); /* erase line from last mark */
  489.     setcolor(normcolr);
  490.     putimage(xc-5,yc-5,cross,XOR_PUT);
  491.     }
  492. }
  493.  
  494. /* ---------------------------------------------------------------------- */
  495.                  /* show coordinates of CP on  screen                     */
  496.                  /* the display is on line 24, starting at column 62      */
  497. void 
  498. display(void)
  499. {
  500.    bar(496,yb+1,sxmax-2,symax-1);                   /* clear display space */
  501.    gprintf(496,yb+3,colr3,"%.2f  %.2f",wx(xc),wy(yc));
  502.    setcolor(15);
  503.    line(sxmax,yb,sxmax,symax);
  504. }
  505.  
  506. /* ---------------------------------------------------------------------- */
  507. /* graphics version of printf(); from Borland graphics demo BGIDEMO.C     */
  508. /* prints string at pixel location (x,y) in color c                       */
  509.  
  510. void 
  511. gprintf(int x, int y, int c, char *fmt, ...)
  512. {
  513.    va_list argptr;
  514.    char str[140];
  515.  
  516.    va_start(argptr, fmt);
  517.    vsprintf(str, fmt, argptr);
  518.    setcolor(c);
  519.    outtextxy(x, y, str);
  520.    setcolor(normcolr);
  521.    va_end(argptr);
  522. }
  523.  
  524. /* ----------------------------------------------------------------------- */
  525.                  /* set graphics mode; initialize various global constants */
  526. void 
  527. initialize(void)
  528. {
  529.    int graphdriver, graphmode;
  530.    int font=0, charsize=1;
  531.    int i,j;
  532.    detectgraph(&graphdriver, &graphmode);
  533.    if (graphdriver != EGA && graphdriver != VGA)
  534.      {
  535.       printf("\nProgram requires VGA or 256K EGA graphics capability.");
  536.       exit(1);
  537.      }
  538.    if (graphmode == VGAHI) graphmode = VGAMED; /* to allow two pages */
  539.    if (registerbgidriver(EGAVGA_driver) < 0)
  540.      {
  541.       printf("\nEGAVGA.OBJ must be included in GRAPHICS.LIB\n");
  542.       exit(1);
  543.      }
  544.    initgraph(&graphdriver, &graphmode, "");
  545.    mode = graphmode;
  546.    sxmax = getmaxx(); xscale = sxmax-10;    /* xscale, yscale, ... are */
  547.    symax = getmaxy(); yscale = symax-20;    /* used to convert from screen */
  548.    xscale1 = 1/xscale, yscale1 = 1/yscale;  /* coords to [0,1] and back */
  549.    xb = 8; yb = symax-13;                   /* for graphics prompts */
  550.    setviewport( 0, 0, sxmax, symax, 1 );    /* full screen */
  551.    setfillstyle(1,10);                      /* use bright green for marker1 */
  552.    bar(0,0,1,1);                            /* draw marker1 */
  553.    block1 = malloc(14);                     /* size of 1X1 block1 is 14 */
  554.    getimage(0,0,1,1,block1);                /* store marker1 */
  555.    putimage(0,0,block1,XOR_PUT);            /* erase marker */
  556.    setfillstyle(1,12);                      /* use bright red for marker2 */
  557.    bar(0,0,1,1);                            /* draw marker2 */
  558.    block2 = malloc(14);
  559.    getimage(0,0,1,1,block2);                /* store marker2 */
  560.    putimage(0,0,block2,XOR_PUT);            /* erase marker2 */
  561.    for (j=1; j<=3; j++)                     /* draw cross (bright white) */
  562.      putpixel(5,j,15);
  563.    for (i=1; i<=3; i++)
  564.      putpixel(i,5,15);
  565.    for (i=7; i<=9; i++)
  566.      putpixel(i,5,15);
  567.    for (j=7; j<=9; j++)
  568.      putpixel(5,j,15);
  569.    cross = malloc(imagesize(0,0,8,8));
  570.    getimage(0,0,8,8,cross);                 /* store cross */
  571.    putimage(0,0,cross,XOR_PUT);             /* erase cross */
  572.    settextstyle(font,HORIZ_DIR,charsize);   /* use default font for text */
  573.  
  574.    if (msinit())                            /* check for and initialize mouse */
  575.       {
  576.        mouse = 1;
  577.        mshbounds(10,sxmax-10);
  578.        msvbounds(10,symax-20);
  579.        mspage(1);
  580.       }
  581. }
  582.  
  583. /* ----------------------------------------------------------------------- */
  584.                  /* mark point under crosshairs */
  585.                  /* green if colr = 10, red otherwise */
  586. void
  587. mark(void)
  588. {
  589.  int c;
  590.  
  591.  if (np >= MAXPTS)  
  592.     return;                                  /* ignore excess points */
  593.  if (np>0 && mx[np-1]==xc && my[np-1]==yc) 
  594.     return;                                  /* don't take immediate repeat */
  595.  mx[np] = xc;
  596.  my[np] = yc;
  597.  if (np == 0)
  598.    {
  599.     if (colr==10)
  600.        putimage(xc,yc,block1,XOR_PUT);                /* green marker */
  601.     else
  602.        putimage(xc,yc,block2,XOR_PUT);                /* red marker */
  603.    }
  604.  if (np == 1)
  605.    {
  606.     if (colr==10)
  607.        putimage(mx[0],my[0],block1,XOR_PUT);
  608.     else
  609.        putimage(mx[0],my[0],block2,XOR_PUT);
  610.    }
  611.  if (np)
  612.    {
  613.     putimage(xc-5,yc-5,cross,XOR_PUT);
  614.     setcolor(colr);
  615.     line(mx[np-1],my[np-1],xc,yc);  /* draw line from last mark */
  616.     putimage(xc-5,yc-5,cross,XOR_PUT);
  617.    }
  618.  np++;
  619. }
  620.  
  621. /* ---------------------------------------------------------------------- */
  622.                  /* change current position and CP marker */
  623. void 
  624. move_to(int x1,int y1)
  625. {
  626.    putimage(xc-5,yc-5,cross,XOR_PUT);      /* erase current cursor mark */
  627.    xc = CLIP(x1,10,sxmax-10);              /* x range is 10 to symax-10 */
  628.    yc = CLIP(y1,10,symax-20);              /* y range is 10 to symax-20 */
  629.    moveto(xc,yc);                          /* (xc,yc) in new position */
  630.    if (mouse)
  631.       msgotoxy(xc,yc);
  632.    putimage(xc-5,yc-5,cross,XOR_PUT);       /* show new cursor mark */
  633.    display();                               /* show current position */
  634. }
  635.  
  636. /* ---------------------------------------------------------------------- */
  637.                  /* put prompt message at (x1,y1) */
  638. int
  639. prompt(int x1, int y1, int colour, char *msg)
  640. {
  641.  int length;
  642.  
  643.  length = x1+textwidth(msg);
  644.  bar(x1,y1,sxmax-1,y1+8);    /* clear prompt area */
  645.  setcolor(colour);
  646.  outtextxy(x1,y1,msg);       /* write message at (x1,y1) */
  647.  setcolor(normcolr);         /* restore normal color */
  648.  return length+8;            /* start user input 8 pixels past prompt */
  649. }
  650.  
  651. /* ---------------------------------------------------------------------- */
  652. /* convert from world coordinates to screen coordinates */
  653. int
  654. sx(double x)  { return (int)(xscale*x + .5); }
  655. int 
  656. sy(double y)  { return (int)(yscale*(1-y) + .5); }
  657. /* ---------------------------------------------------------------------- */
  658. /* convert from screen coordinates to world coordinates */
  659. double 
  660. wx(int x)  { return xscale1*x; }
  661. double 
  662. wy(int y)  { return 1 - yscale1*y; }
  663. /* ---------------------------------------------------------------------- */
  664.  
  665.  
  666. /* ======================================================================== */
  667. /*                           Mouse Functions                                */
  668. /* These functions are for a Genius mouse, but they ought to work for other */
  669. /* mouses, as well. They have the same names as the corresponding functions */
  670. /* in Mike Smedley's CXL utilities, but are taken from the Genius manual.   */
  671. /* ======================================================================== */
  672. int
  673. msinit(void)
  674. {
  675.    _AX = 0;
  676.    geninterrupt(0x33);
  677.    return _AX;
  678. }
  679. void
  680. msshowcur(void)
  681. {
  682.    _AX = 1;
  683.    geninterrupt(0x33);
  684. }
  685. void
  686. mshidecur(void)
  687. {
  688.    _AX = 2;
  689.    geninterrupt(0x33);
  690. }
  691. void
  692. msstatus(int *stat, int *x, int *y) /* button press status, current x,y */
  693. {
  694.    unsigned b;
  695.  
  696.    _AX = 3;
  697.    geninterrupt(0x33);
  698.    b = _BX;
  699.    *stat = b;
  700.    *x = _CX;
  701.    *y = _DX;
  702. }
  703.  
  704. void
  705. msgotoxy(int x, int y)        /* move mouse cursor to (x,y) pixel position */
  706. {
  707.    _AX = 4;
  708.    _CX = x;
  709.    _DX = y;
  710.    geninterrupt(0x33);
  711. }
  712.  
  713. int
  714. msrelease(int button)
  715. {
  716.    _AX = 6;
  717.    _BX = button;  /* 0,1,2 = left,right,middle */
  718.    geninterrupt(0x33);
  719.    return _BX;
  720. }
  721.  
  722. void
  723. mshbounds(int minx, int maxx) /* limit mouse cursor horizontally */
  724. {
  725.    _AX = 7;
  726.    _CX = minx;
  727.    _DX = maxx;
  728.    geninterrupt(0x33);
  729. }
  730.  
  731. void
  732. msvbounds(int miny, int maxy) /* limit mouse cursor vertically */
  733. {
  734.    _AX = 8;
  735.    _CX = miny;
  736.    _DX = maxy;
  737.    geninterrupt(0x33);
  738. }
  739.  
  740. void
  741. msmotion(int *i, int *j)  /* i,j are set to the x- y-motions since last call */
  742. {
  743.    _AX = 11;
  744.    geninterrupt(0x33);
  745.    *i = _CX;
  746.    *j = _DX;
  747. }
  748.  
  749. void
  750. mspage(int p)
  751. {
  752.    _AX = 29;
  753.    _BX = p;
  754.    geninterrupt(0x33);
  755. }
  756.  
  757.