home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / graphics / utility / mgif35s / low.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-14  |  21.1 KB  |  1,203 lines

  1. #define V_HIST            /* def for vertical histogram */
  2. #undef DBL_LOOP            /* def for for(x..., for(y... loops */
  3. #undef FULL_SCREEN        /* def to write entire screen, not just wxh */
  4.  
  5. /*
  6.  *    low.c - low level stuff for mgif.
  7.  */
  8.  
  9. static char *sccsid  = "@(#) low.c 1.0 91/6/14 rosenkra\0\0                ";
  10.  
  11. #include <stdio.h>
  12. #include <osbind.h>
  13. #include "mgif.h"
  14.  
  15.  
  16. /*
  17.  *    globals
  18.  */
  19. extern int    Batch;
  20.  
  21.  
  22. /*
  23.  *    local functions
  24.  */
  25. int        do_hist ();
  26. int        draw_hist ();
  27. int        drhhist ();
  28. int        drvhist ();
  29. int        grid ();
  30. int        do_line ();        /* atari ST (line A) */
  31. void        xor_line ();
  32. void        xor_dash ();        /* atari ST (line A) */
  33. int        cursor ();        /* atari ST (gemdos, vt52) */
  34. int        clr_cmd ();        /* atari ST (gemdos, vt52) */
  35. int        mv_cursor ();        /* atari ST (vt52) */
  36. int        clr_screen ();        /* atari ST (gemdos, vt52) */
  37. long        do_time ();        /* atari ST (gemdos, sysvar) */
  38. int        check_key ();        /* atari ST (BIOS) */
  39. int        get_key ();
  40. int        get_string ();
  41. long        get_rkey ();
  42. int        get_xypos ();
  43. int        wait_key ();        /* atari ST (BIOS) */
  44. int        wait_ms ();
  45.  
  46.  
  47.  
  48.  
  49. /*------------------------------*/
  50. /*    do_hist            */
  51. /*------------------------------*/
  52. do_hist (pras, w, h, hist)
  53. uchar_t           *pras;
  54. int        w;
  55. int        h;
  56. long           *hist;
  57. {
  58.     long            x;
  59.     long            y;
  60.     register long        ii;
  61.     register long        lim;
  62.     register uchar_t       *ps;
  63.     register long           *ph;
  64.     register uint_t        hval;        /* ptr into Hist */
  65.  
  66.  
  67.     for (ph = hist, ii = 0L; ii < HISTSIZ; ii++)
  68.         *ph++ = 0L;
  69.  
  70. #ifdef DBL_LOOP
  71.     for (y = 0; y < h; y++)
  72.     {
  73.         for (x = 0; x < w; x++)
  74.         {
  75.             hval        = (uint_t) (pras[(y*w) + x]);
  76.             hist[hval] += 1;
  77.         }
  78.     }
  79. #else
  80.     lim = (long) h * (long) w;
  81.     for (ph = hist, ps = pras, ii = 0L; ii < lim; ii++, ps++)
  82.     {
  83.         hval      = (uint_t) *ps;
  84.         ph[hval] += 1;
  85.     }
  86. #endif
  87.  
  88.     return (1);
  89. }
  90.  
  91.  
  92.  
  93.  
  94. /*------------------------------*/
  95. /*    draw_hist        */
  96. /*------------------------------*/
  97. int draw_hist (hist)
  98. long   *hist;
  99. {
  100.  
  101. /*
  102.  *    draw histogram
  103.  */
  104.  
  105.     long    hmax;
  106.     int    x1,
  107.          x2,
  108.          y1,
  109.          y2;
  110.     long    htot;
  111.     long    ii;
  112.  
  113.  
  114.     /*
  115.      *   find max values in histo for scaling. also total pixels (should
  116.      *   be w*h)
  117.      */
  118.     for (htot = 0, hmax = 0, ii = 0; ii < HISTSIZ; ii++)
  119.     {
  120.         htot += hist[ii];
  121.  
  122.         if (hist[ii] > hmax)
  123.             hmax = hist[ii];
  124.     }
  125.  
  126.  
  127.     /*
  128.      *   overall histogram...
  129.      */
  130. #ifdef V_HIST
  131.     x1 = 100;         y1 = 88;
  132.      x2 = x1 + HISTSIZ;     y2 = y1 + 208;
  133.  
  134.     drvhist (hist, HISTSIZ, hmax, x1, y1, x2, y2, 4, 1, 1);
  135.     mv_cursor ( 0, 19); printf ("           00                               FF");
  136.     mv_cursor ( 0,  5); printf ("    %6ld", hmax);
  137.     mv_cursor ( 0, 18); printf ("         0");
  138. #else
  139.     x1 = 100;     y1 = 50;
  140.      x2 = x1 + 400;     y2 = y1 + HISTSIZ;
  141.  
  142.     drhhist (hist, HISTSIZ, hmax, x1, y1, x2, y2, 4, 1, 1);
  143.     mv_cursor ( 0,  3); printf ("     00");
  144.     mv_cursor ( 0, 19); printf ("     FF");
  145. #endif
  146.  
  147.  
  148.     /*
  149.      *   legends
  150.      */
  151.     mv_cursor ( 1,  1); printf ("  Histogram for this image:");
  152.     mv_cursor ( 1, 22); printf ("  Total pixels %ld", htot);
  153. }
  154.  
  155.  
  156.  
  157.  
  158. /*------------------------------*/
  159. /*    drhhist            */
  160. /*------------------------------*/
  161. int drhhist (hst, hstsiz, hmax, xmn, ymn, xmx, ymx, bordr, vspace, barsize)
  162. long   *hst;
  163. int    hstsiz;
  164. long    hmax;
  165. int    xmn;
  166. int    ymn;
  167. int    xmx;
  168. int    ymx;
  169. int    bordr;
  170. int    vspace;
  171. int    barsize;
  172. {
  173.  
  174. /*
  175.  *    draw a histogram, vertical axis, horizontal values. UL/LR corners
  176.  *    specified (pixel coord). border outside the corners if bordr >= 0.
  177.  *    vert spacing (in pixels) given by vspace. if hmax is > 0, scale
  178.  *    the length to this value, otherwise automatically scale to fit.
  179.  *
  180.  *     ____________________________________________
  181.  *    |   /----- start here: (xmn,ymn)         |<-- border, drawn
  182.  *    |  +XXXXXXXXXXXXXXXXXXXXXXXXX                |    if bordr >= 0
  183.  *    |  XXXXXXXXX                                 |
  184.  *    |  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX  |
  185.  *    |  XXXXXXXXXXXXXXXXXXX                       |
  186.  *    .                         .
  187.  *    .                         .
  188.  *    .                         .
  189.  *    |  XXXXXXXXXXXXX                             |
  190.  *    |  XXXXXXXXXXXXXXXXXXXXXXXXX              +  |
  191.  *    |____________________________________________|
  192.  *
  193.  *    width of each bar given by barsize (in pixels). vspace should include
  194.  *    barsize:
  195.  *
  196.  *    XXXXXXXXXXXXXXXXXXXXXX ------------------------------------------
  197.  *    XXXXXXXXXXXXXXXXXXXXXX            barsize(=3)
  198.  *    XXXXXXXXXXXXXXXXXXXXXX ----------------------------    vspace(=4)
  199.  *    
  200.  *    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX---------------------------------
  201.  *    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  202.  *    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  203.  */
  204.  
  205.     int    i;
  206.     int    j;
  207.     int    x1,
  208.          x2,
  209.          y1,
  210.          y2;
  211.     long    xsz;
  212.  
  213.  
  214.     /*
  215.      *   check data...
  216.      */
  217.     if (vspace < 1)
  218.         vspace = 1;
  219.     if ((vspace * hstsiz) > (ymx - ymn + 1))
  220.         vspace = (ymx - ymn) / hstsiz;
  221.     if (vspace < 1)
  222.         return;
  223.     if (barsize > vspace)
  224.         barsize = vspace;
  225.  
  226.  
  227.     /*
  228.      *   find max value if necessary...
  229.      */
  230.     if (hmax < 0)
  231.     {
  232.         hmax = 0;
  233.         for (i = 0; i < hstsiz; i++)
  234.         {
  235.             if (hst[i] > hmax)
  236.                 hmax = hst[i];
  237.         }
  238.     }
  239.  
  240.  
  241.     /*
  242.      *   draw box around histogram
  243.      */
  244.     if (bordr >= 0)
  245.     {
  246.         do_line (xmn-bordr, ymn-bordr, xmx+bordr, ymn-bordr);
  247.         do_line (xmn-bordr, ymn-bordr, xmn-bordr, ymx+bordr);
  248.         do_line (xmx+bordr, ymx+bordr, xmx+bordr, ymn-bordr);
  249.         do_line (xmx+bordr, ymx+bordr, xmn-bordr, ymx+bordr);
  250.     }
  251.  
  252.  
  253.     /*
  254.      *   draw the lines. note that a "baseline" could appear because for
  255.      *   hst entries of 0, the line is just a dot so we do not draw these.
  256.      */
  257.     xsz = (long) (xmx - xmn);
  258.     for (i = 0; i < hstsiz; i++)
  259.     {
  260.         x1 = xmn;
  261.         y1 = ymn + (i * vspace);
  262.         x2 = x1 + (int) ((xsz * hst[i]) / hmax);
  263.         y2 = y1;
  264.         if (x2 - x1 > 0)
  265.         {
  266.             for (j = 0; j < barsize; j++, y1++, y2++)
  267.                 do_line (x1, y1, x2, y2);
  268.         }
  269.     }
  270. }
  271.  
  272.  
  273.  
  274.  
  275. /*------------------------------*/
  276. /*    drvhist            */
  277. /*------------------------------*/
  278. int drvhist (hst, hstsiz, hmax, xmn, ymn, xmx, ymx, bordr, hspace, barsize)
  279. long   *hst;
  280. int    hstsiz;
  281. long    hmax;
  282. int    xmn;
  283. int    ymn;
  284. int    xmx;
  285. int    ymx;
  286. int    bordr;
  287. int    hspace;
  288. int    barsize;
  289. {
  290.  
  291. /*
  292.  *    draw a histogram, horizontal axis, vertical values. UL/LR corners
  293.  *    specified (pixel coord). border outside the corners if bordr >= 0.
  294.  *    vert spacing (in pixels) given by hspace. if hmax is > 0, scale
  295.  *    the length to this value, otherwise automatically scale to fit.
  296.  *
  297.  *     _________ . . . _____
  298.  *    |    X              |<-- border, drawn
  299.  *    |    X   X      X   |    if bordr >= 0
  300.  *    |    XX  X      X   |
  301.  *    |    XX  X      X   |
  302.  *    |  X XXX X     XX   |
  303.  *    |  X XXX X     XXX  |
  304.  *    |  X XXXXX     XXX  |
  305.  *    |  +XXXXXX     XXXX |
  306.  *    |  \-- start here:    |
  307.  *    |      (xmn,ymn)      |
  308.  *    |_________ . . . _____|
  309.  *
  310.  *    width of each bar given by barsize (in pixels). hspace should include
  311.  *    barsize:
  312.  *
  313.  *      /-------- barsize(=3)
  314.  *      |   /---- hspace(=4)
  315.  *    | | | | |
  316.  *    | | | v |
  317.  *    | | |<->|
  318.  *    | | |   |
  319.  *    | |||  ||
  320.  *    | v||  ||
  321.  *    |<>||  ||
  322.  *    |  ||  ||
  323.  *    XXX |  ||
  324.  *    XXX |  ||
  325.  *    XXX |  |XXX
  326.  *    XXX |  |XXX
  327.  *    XXX XXX XXX
  328.  *    XXX XXX XXX
  329.  *    XXX XXX XXX
  330.  */
  331.  
  332.     int    i;
  333.     int    j;
  334.     int    x1,
  335.          x2,
  336.          y1,
  337.          y2;
  338.     long    ysz;
  339.  
  340.  
  341.     /*
  342.      *   check data...
  343.      */
  344.     if (hspace < 1)
  345.         hspace = 1;
  346.     if ((hspace * hstsiz) > (xmx - xmn + 1))
  347.         hspace = (xmx - xmn) / hstsiz;
  348.     if (hspace < 1)
  349.         return;
  350.     if (barsize > hspace)
  351.         barsize = hspace;
  352.  
  353.  
  354.     /*
  355.      *   find max value if necessary...
  356.      */
  357.     if (hmax < 0)
  358.     {
  359.         hmax = 0;
  360.         for (i = 0; i < hstsiz; i++)
  361.         {
  362.             if (hst[i] > hmax)
  363.                 hmax = hst[i];
  364.         }
  365.     }
  366.  
  367.  
  368.     /*
  369.      *   draw box around histogram
  370.      */
  371.     if (bordr >= 0)
  372.     {
  373.         do_line (xmn-bordr, ymn-bordr, xmx+bordr, ymn-bordr);
  374.         do_line (xmn-bordr, ymn-bordr, xmn-bordr, ymx+bordr);
  375.         do_line (xmx+bordr, ymx+bordr, xmx+bordr, ymn-bordr);
  376.         do_line (xmx+bordr, ymx+bordr, xmn-bordr, ymx+bordr);
  377.     }
  378.  
  379.  
  380.     /*
  381.      *   draw the lines. note that a "baseline" could appear because for
  382.      *   hst entries of 0, the line is just a dot so we do not draw these.
  383.      */
  384.     ysz = (long) (ymx - ymn);
  385.     for (i = 0; i < hstsiz; i++)
  386.     {
  387.         y1 = ymx;
  388.         y2 = y1 - (int) ((ysz * hst[i]) / hmax);
  389.         x1 = xmn + (i * hspace);
  390.         x2 = x1;
  391.  
  392.         if (y1 - y2 > 0)
  393.         {
  394.             for (j = 0; j < barsize; j++, x1++, x2++)
  395.                 do_line (x1, y1, x2, y2);
  396.         }
  397.     }
  398. }
  399.  
  400.  
  401.  
  402.  
  403. /*------------------------------*/
  404. /*    grid            */
  405. /*------------------------------*/
  406. grid (x, y, w, h, sp)
  407. int    x;
  408. int    y;
  409. int    w;
  410. int    h;
  411. int    sp;
  412. {
  413.     int    i;
  414.  
  415.     /*
  416.      *   limit the grid so as not to go off screen! else line A will
  417.      *   crash...
  418.      */
  419.     if (x < 0)
  420.         x = 0;
  421.     if (y < 0)
  422.         y = 0;
  423.     if (x+w >= 640)
  424.         w = 640 - x - 1;
  425.     if (y+h >= 400)
  426.         h = 400 - y - 1;
  427.  
  428.  
  429.     /*
  430.      *   verticals
  431.      */
  432.     for (i = x; i < x+w; i += sp)
  433.         xor_dash (i, y, i, y+h-1);
  434.  
  435.     /* last (right) one */
  436.     xor_dash (x+w-1, y, x+w-1, y+h-1);
  437.  
  438.  
  439.     /*
  440.      *   horizontals
  441.      */
  442.     for (i = y; i < y+h; i += sp)
  443.         xor_dash (x, i, x+w-1, i);
  444.  
  445.     /* last (bottom) one */
  446.     xor_dash (x, y+h-1, x+w-1, y+h-1);
  447. }
  448.  
  449.  
  450.  
  451.  
  452. /*------------------------------*/
  453. /*    do_line            */
  454. /*------------------------------*/
  455. do_line (x1, y1, x2, y2)
  456. int    x1, y1, x2, y2;
  457. {
  458.  
  459. /*
  460.  *    draw a line from (x1,y1) to (x2,y2). uses line A
  461.  */
  462.  
  463.     extern long    linea0 ();
  464.     extern int    linea3 ();
  465.  
  466.     static long    A_ptr = 0L;
  467.  
  468.  
  469.     /*
  470.      *   line A init first, if needed
  471.      */
  472.     if (!A_ptr)
  473.         A_ptr = linea0 ();
  474.  
  475.     linea3 (A_ptr, x1, y1, x2, y2, 0, 0xFFFF, 0);
  476.  
  477. }
  478.  
  479.  
  480.  
  481.  
  482. /*------------------------------*/
  483. /*    xor_line        */
  484. /*------------------------------*/
  485. void xor_line (x1, y1, x2, y2)
  486. int    x1, y1, x2, y2;
  487. {
  488.  
  489. /*
  490.  *    draw a line from (x1,y1) to (x2,y2), XOR. uses line A
  491.  */
  492.  
  493.     extern long    linea0 ();
  494.     extern int    linea3 ();
  495.  
  496.     static long    A_ptr = 0L;
  497.  
  498.  
  499.     /*
  500.      *   line A init first, if needed
  501.      */
  502.     if (!A_ptr)
  503.         A_ptr = linea0 ();
  504.  
  505.     linea3 (A_ptr, x1, y1, x2, y2, 2, 0xffff, 0);
  506. }
  507.  
  508.  
  509.  
  510.  
  511. /*------------------------------*/
  512. /*    xor_dash        */
  513. /*------------------------------*/
  514. void xor_dash (x1, y1, x2, y2)
  515. int    x1, y1, x2, y2;
  516. {
  517.  
  518. /*
  519.  *    draw a line from (x1,y1) to (x2,y2), XOR. uses line A
  520.  */
  521.  
  522.     extern long    linea0 ();
  523.     extern int    linea3 ();
  524.  
  525.     static long    A_ptr = 0L;
  526.  
  527.  
  528.     /*
  529.      *   line A init first, if needed
  530.      */
  531.     if (!A_ptr)
  532.         A_ptr = linea0 ();
  533.  
  534.     linea3 (A_ptr, x1, y1, x2, y2, 2, 0x3333, 0);
  535. }
  536.  
  537.  
  538.  
  539.  
  540. /*------------------------------*/
  541. /*    cursor            */
  542. /*------------------------------*/
  543. cursor (visible)
  544. int    visible;
  545. {
  546.  
  547. /*
  548.  *    turn cursor on/off
  549.  */
  550.  
  551.     if (visible)
  552.         Cconws ("\33e");
  553.     else
  554.         Cconws ("\33f");
  555. }
  556.  
  557.  
  558.  
  559.  
  560. /*------------------------------*/
  561. /*    clr_cmd            */
  562. /*------------------------------*/
  563. clr_cmd ()
  564. {
  565.  
  566. /*
  567.  *    clear "command" line
  568.  */
  569.  
  570.     mv_cursor (0, 24);
  571.     Cconws ("\33K");
  572. }
  573.  
  574.  
  575.  
  576.  
  577. /*------------------------------*/
  578. /*    mv_cursor        */
  579. /*------------------------------*/
  580. mv_cursor (col, row)
  581. int    col;
  582. int    row;
  583. {
  584.  
  585. /*
  586.  *    move cursor to row,col (0,0 is UL corner). for printing
  587.  */
  588.  
  589.     int    esc = 0x1B;
  590.     int    spc = 0x20;
  591.     char    msg[10];
  592.  
  593.     sprintf (msg, "%cY%c%c\0", (char) esc, (char) (row + spc), (char) (col + spc));
  594.     Cconws (msg);
  595. }
  596.  
  597.  
  598.  
  599.  
  600. /*------------------------------*/
  601. /*    clr_screen        */
  602. /*------------------------------*/
  603. clr_screen ()
  604. {
  605.  
  606. /*
  607.  *    clear screen, home cursor
  608.  */
  609.  
  610.     Cconws ("\33E");
  611. }
  612.  
  613.  
  614.  
  615.  
  616. /*------------------------------*/
  617. /*    do_time            */
  618. /*------------------------------*/
  619. long do_time (opt)
  620. int    opt;                /* 0=init,1=start,2=end (ret elapsed)*/
  621. {
  622.  
  623. /*
  624.  *    timing functions. here we time using 200 Hz system timer
  625.  */
  626.  
  627.     static ulong_t    start;
  628.     static ulong_t    stop;
  629.  
  630.     long        savessp;
  631.     ulong_t        elapsed;        /* seconds */
  632.  
  633.  
  634.     switch (opt)
  635.     {
  636.     case 0:                        /* reset clock */
  637.     case 1:                        /* start clock */
  638.         savessp = Super (0L);
  639.         start   = *(long *) (0x4ba);
  640.         Super (savessp);
  641.         break;
  642.  
  643.     case 2:                        /* stop and elapsed */
  644.         savessp = Super (0L);
  645.         stop    = *(long *) (0x4ba);
  646.         Super (savessp);
  647.  
  648.         if (stop < start)
  649.             elapsed = (long) (stop - start + 0x7FFFFFFFL) / 200L;
  650.         else
  651.             elapsed = (long) (stop - start) / 200L;
  652.  
  653.         return ((long) elapsed);
  654.     }
  655.  
  656.     return (0L);
  657.  
  658. }
  659.  
  660.  
  661.  
  662.  
  663. /*------------------------------*/
  664. /*    check_key        */
  665. /*------------------------------*/
  666. int check_key ()
  667. {
  668.  
  669. /*
  670.  *    ckecks for a key and flushes keyboard buffer.
  671.  */
  672.  
  673.     if (Bconstat (2))            /* if CONSOLE has a char... */
  674.     {
  675.         while (Bconstat (2))        /* read char while there are */
  676.             Bconin (2);        /* chars to read (flush) */
  677.  
  678.         return (1);            /* yes, there was a key */
  679.     }
  680.  
  681.     return (0);                /* no key */
  682. }
  683.  
  684.  
  685.  
  686.  
  687. /*------------------------------*/
  688. /*    get_key            */
  689. /*------------------------------*/
  690. int get_key ()
  691. {
  692.  
  693. /*
  694.  *    gets a key. just the ascii part of Bconin. only low byte is filled.
  695.  */
  696.  
  697.     long    ret;
  698.  
  699.     cursor (1);
  700.     while (!Bconstat (2))        /* wait for a key... */
  701.         ;
  702.     ret = Bconin (2) & 0x000000ffL;/* get key */
  703.     cursor (0);
  704.  
  705.     return ((int) ret);
  706. }
  707.  
  708.  
  709.  
  710.  
  711. /*------------------------------*/
  712. /*    get_string        */
  713. /*------------------------------*/
  714. get_string (n, buf)
  715. int    n;        /* <= 125 */
  716. char   *buf;
  717. {
  718.     int        i;
  719.     uint_t        num;
  720.  
  721.     if (n > 125)
  722.         n = 125;
  723.     buf[0] = (char) n;
  724.     cursor (1);
  725.     Cconrs (buf);
  726.     cursor (0);
  727.     num = (uint_t) buf[1];
  728.     for (i = 0; i < num; i++)
  729.         buf[i] = buf[i+2];
  730.     buf[num] = '\0';
  731. }
  732.  
  733.  
  734.  
  735.  
  736. /*------------------------------*/
  737. /*    get_rkey        */
  738. /*------------------------------*/
  739. long get_rkey ()
  740. {
  741.  
  742. /*
  743.  *    gets a key. the full long is returned
  744.  */
  745.  
  746.     long    ret;
  747.  
  748.     while (!Bconstat (2))        /* wait for a key... */
  749.         ;
  750.     ret = Bconin (2);        /* get key */
  751.  
  752.     return ((long) ret);
  753. }
  754.  
  755.  
  756.  
  757.  
  758. /*------------------------------*/
  759. /*    get_xypos        */
  760. /*------------------------------*/
  761. int get_xypos (opt, type, xorg, yorg, width, height, rwidth, rheight, xstart, ystart, x, y)
  762. int    opt;        /* 0=vert(hor pos), 1=horiz(vert pos), 2=both */
  763. int    type;        /* 0=xhair, 1=box */
  764. int    xorg;        /* UL of limit rect */
  765. int    yorg;
  766. int    width;        /* size of limit rect */
  767. int    height;
  768. int    rwidth;        /* size of rect if type=box */
  769. int    rheight;
  770. int    xstart;        /* start position */
  771. int    ystart;
  772. int    *x;        /* returned coords */
  773. int    *y;
  774. {
  775.  
  776. /*
  777.  *    draw crosshair or box, let user move with arrow (8 pixel) or
  778.  *    shift-arrows (1 pixel) and return final x,y. return value is as
  779.  *    follows:
  780.  *
  781.  *        if INSERT
  782.  *            ret = 1
  783.  *        else
  784.  *            ret = 0
  785.  *
  786.  *    space to confine cursor/box to is defined by xorg, yorg, width, height.
  787.  *    coord of last point returned in x,y no matter how we exit. crosshair
  788.  *    starts at (xstart,ystart). ClrHome moves to xorg,yorg, shift-ClrHome
  789.  *    moves to (xstart,ystart). box specified with xstart,ystart,rwidth,
  790.  *    rheight.
  791.  */
  792.  
  793.     register long    lkey;
  794.     register int    drawit;
  795.     register int    xpos;
  796.     register int    ypos;
  797.     int        xrlim, xllim;
  798.     int        yulim, yllim;
  799.     int        i;
  800.     int        done;
  801.     int        ret;
  802.  
  803.  
  804.     /*
  805.      *   check for bad input...
  806.      */
  807.     if (width > 640)
  808.         width = 640;
  809.     if (height > 400)
  810.         height = 400;
  811.     if ((width < 2) || (height < 2))
  812.         return (0);
  813.     if ((xorg < 0) || (xorg >= 640))
  814.         return (0);
  815.     if ((yorg < 0) || (yorg >= 400))
  816.         return (0);
  817.     if ((xorg + width - 1 > 640) || (yorg + height - 1 > 400))
  818.         return (0);
  819.     if ((xstart > xorg + width - 1) || (xstart < xorg))
  820.         return (0);
  821.     if ((ystart > yorg + height - 1) || (ystart < yorg))
  822.         return (0);
  823.  
  824.  
  825.     /*
  826.      *   set start positions and limits
  827.      */
  828.     xpos = xstart;
  829.     ypos = ystart;
  830.  
  831.     if (type == 0)
  832.     {
  833.         xllim = xorg;
  834.         xrlim = xllim + (width-1);
  835.         yulim = yorg;
  836.         yllim = yorg + (height-1);
  837.     }
  838.     else
  839.     {
  840.         xllim = xorg;
  841.         xrlim = xllim + (rwidth-1);
  842.         yulim = yorg;
  843.         yllim = yorg + (rheight-1);
  844.     }
  845.  
  846.  
  847.     /*
  848.      *   draw initial position crosshair (xor mode)...
  849.      */
  850.     if (type == 0)
  851.     {
  852.         switch (opt)
  853.         {
  854.         case H_COORD:
  855.             xor_line (xpos,yulim,xpos,yllim);    /* vert */
  856.             break;
  857.         case V_COORD:
  858.             xor_line (xllim,ypos,xrlim,ypos);    /* horiz */
  859.             break;
  860.         case VH_COORD:
  861.             xor_line (xpos,yulim,xpos,yllim);    /* vert */
  862.             xor_line (xllim,ypos,xrlim,ypos);    /* horiz */
  863.             break;
  864.         default:
  865.             return (0);
  866.             break;
  867.         }
  868.     }
  869.     else
  870.     {
  871.         xor_line (xpos,ypos,xpos,ypos+rheight-1);
  872.         xor_line (xpos,ypos,xpos+rwidth-1,ypos);
  873.         xor_line (xpos,ypos+rheight-1,xpos+rwidth-1,ypos+rheight-1);
  874.         xor_line (xpos+rwidth-1,ypos,xpos+rwidth-1,ypos+rheight-1);
  875.     }
  876.  
  877.  
  878.     /*
  879.      *   directions (on cmd line)
  880.      */
  881.     mv_cursor (0,24);
  882. printf ("ARROWS 8 pix, Shift-ARROWS 1 pix. INSERT detects, any other quit.            ");
  883.  
  884.  
  885.     /*
  886.      *   loop...
  887.      */
  888.     done = 0;
  889.     ret  = 0;
  890.     while (!done)
  891.     {
  892.         /*
  893.          *   get raw key, update coord on screen...
  894.          */
  895.         mv_cursor (70,24); printf ("%3d,%3d", xpos, ypos);
  896.         lkey = get_rkey ();
  897. #if 0
  898.         mv_cursor (70,23); printf ("%08lx", lkey);
  899. #endif
  900.  
  901.         /*
  902.          *   undraw...
  903.          */
  904.         if (type == 0)
  905.         {
  906.             switch (opt)
  907.             {
  908.             case H_COORD:
  909.                 xor_line (xpos,yulim,xpos,yllim);    /* vert */
  910.                 break;
  911.             case V_COORD:
  912.                 xor_line (xllim,ypos,xrlim,ypos);    /* horiz */
  913.                 break;
  914.             case VH_COORD:
  915.                 xor_line (xpos,yulim,xpos,yllim);    /* vert */
  916.                 xor_line (xllim,ypos,xrlim,ypos);    /* horiz */
  917.                 break;
  918.             }
  919.         }
  920.         else
  921.         {
  922.             xor_line (xpos,ypos,xpos,ypos+rheight-1);
  923.             xor_line (xpos,ypos,xpos+rwidth-1,ypos);
  924.             xor_line (xpos,ypos+rheight-1,xpos+rwidth-1,ypos+rheight-1);
  925.             xor_line (xpos+rwidth-1,ypos,xpos+rwidth-1,ypos+rheight-1);
  926.         }
  927.  
  928.  
  929.         /*
  930.          *   what key?
  931.          */
  932.         if (lkey == RARROW)            /* right arrow */
  933.         {
  934.             /*
  935.              *   some arrows not used for some opts, so check
  936.              */
  937.             if (opt != V_COORD)
  938.             {
  939.                 /*
  940.                  *   bump it and check if beyond limit
  941.                  */
  942.                 xpos += 8;
  943.                 if (xpos > xrlim)
  944.                 {
  945.                     /*
  946.                      *   if so, limit and bell
  947.                      */
  948.                     xpos = xrlim;
  949.                     Cconws ("\07");
  950.                 }
  951.             }
  952.         }
  953.         else if (lkey == S_RARRAW)        /* shift right arrow */
  954.         {
  955.             if (opt != V_COORD)
  956.             {
  957.                 xpos += 1;
  958.                 if (xpos > xrlim)
  959.                 {
  960.                     xpos = xrlim;
  961.                     Cconws ("\07");
  962.                 }
  963.             }
  964.         }
  965.         else if (lkey == LARRAW)        /* left arrow */
  966.         {
  967.             if (opt != V_COORD)
  968.             {
  969.                 xpos -= 8;
  970.                 if (xpos < xllim)
  971.                 {
  972.                     xpos = xllim;
  973.                     Cconws ("\07");
  974.                 }
  975.             }
  976.         }
  977.         else if (lkey == S_LARRAW)        /* shift left arrow */
  978.         {
  979.             if (opt != V_COORD)
  980.             {
  981.                 xpos -= 1;
  982.                 if (xpos < xllim)
  983.                 {
  984.                     xpos = xllim;
  985.                     Cconws ("\07");
  986.                 }
  987.             }
  988.         }
  989.         else if (lkey == UARRAW)        /* up arrow */
  990.         {
  991.             if (opt != H_COORD)
  992.             {
  993.                 ypos -= 8;
  994.                 if (ypos < yulim)
  995.                 {
  996.                     ypos = yulim;
  997.                     Cconws ("\07");
  998.                 }
  999.             }
  1000.         }
  1001.         else if (lkey == S_UARRAW)        /* shift up arrow */
  1002.         {
  1003.             if (opt != H_COORD)
  1004.             {
  1005.                 ypos -= 1;
  1006.                 if (ypos < yulim)
  1007.                 {
  1008.                     ypos = yulim;
  1009.                     Cconws ("\07");
  1010.                 }
  1011.             }
  1012.         }
  1013.         else if (lkey == DARRAW)        /* down arrow */
  1014.         {
  1015.             if (opt != H_COORD)
  1016.             {
  1017.                 ypos += 8;
  1018.                 if (ypos > yllim)
  1019.                 {
  1020.                     ypos = yllim;
  1021.                     Cconws ("\07");
  1022.                 }
  1023.             }
  1024.         }
  1025.         else if (lkey == S_DARRAW)        /* shift down arrow */
  1026.         {
  1027.             if (opt != H_COORD)
  1028.             {
  1029.                 ypos += 1;
  1030.                 if (ypos > yllim)
  1031.                 {
  1032.                     ypos = yllim;
  1033.                     Cconws ("\07");
  1034.                 }
  1035.             }
  1036.         }
  1037.  
  1038.  
  1039.         else if (lkey == INSERT)
  1040.         {
  1041.             ret  = 1;
  1042.             done = 1;
  1043. /*            mv_cursor (70,23); printf ("INSERT  ", lkey);*/
  1044.         }
  1045.         else if (lkey == CLRHOME)
  1046.         {
  1047.             /*
  1048.              *   move to org point
  1049.              */
  1050.             xpos = xorg + 3;
  1051.             ypos = yorg + 3;
  1052. /*            mv_cursor (70,23); printf ("CLRHOME ", lkey);*/
  1053.         }
  1054.         else if (lkey == S_CLRHOME)
  1055.         {
  1056.             /*
  1057.              *   move to start point
  1058.              */
  1059.             xpos = xstart;
  1060.             ypos = ystart;
  1061. /*            mv_cursor (70,23); printf ("S_CLRHOM", lkey);*/
  1062.         }
  1063. #if 0
  1064.         else if (lkey == S_INSERT)
  1065.         {
  1066.             mv_cursor (70,23); printf ("S_INSERT", lkey);
  1067.         }
  1068.         else if (lkey == HELP)
  1069.         {
  1070.             mv_cursor (70,23); printf ("HELP    ", lkey);
  1071.         }
  1072.         else if (lkey == UNDO)
  1073.         {
  1074.             mv_cursor (70,23); printf ("UNDO    ", lkey);
  1075.         }
  1076. #endif
  1077.  
  1078.  
  1079.         else
  1080.         {
  1081.             /*
  1082.              *   any other key causes us to quit...
  1083.              */
  1084.             done = 1;
  1085.         }
  1086.  
  1087.  
  1088.  
  1089.  
  1090.  
  1091.         /*
  1092.          *   check for exit condition...
  1093.          */
  1094.         if (done)
  1095.             break;
  1096.  
  1097.  
  1098.         /*
  1099.          *   draw new postion
  1100.          */
  1101.         if (type == 0)
  1102.         {
  1103.             switch (opt)
  1104.             {
  1105.             case H_COORD:
  1106.                 xor_line (xpos,yulim,xpos,yllim);    /* vert */
  1107.                 break;
  1108.             case V_COORD:
  1109.                 xor_line (xllim,ypos,xrlim,ypos);    /* horiz */
  1110.                 break;
  1111.             case VH_COORD:
  1112.                 xor_line (xpos,yulim,xpos,yllim);    /* vert */
  1113.                 xor_line (xllim,ypos,xrlim,ypos);    /* horiz */
  1114.                 break;
  1115.             }
  1116.         }
  1117.         else
  1118.         {
  1119.             xor_line (xpos,ypos,xpos,ypos+rheight-1);
  1120.             xor_line (xpos,ypos,xpos+rwidth-1,ypos);
  1121.             xor_line (xpos,ypos+rheight-1,xpos+rwidth-1,ypos+rheight-1);
  1122.             xor_line (xpos+rwidth-1,ypos,xpos+rwidth-1,ypos+rheight-1);
  1123.         }
  1124.     }
  1125.  
  1126.  
  1127.  
  1128.     /*
  1129.      *   set return values
  1130.      */
  1131.     *x = xpos;
  1132.     *y = ypos;
  1133.  
  1134.     return (ret);
  1135. }
  1136.  
  1137.  
  1138.  
  1139.  
  1140. /*------------------------------*/
  1141. /*    wait_key        */
  1142. /*------------------------------*/
  1143. wait_key ()
  1144. {
  1145.  
  1146. /*
  1147.  *    waits for a key and flushes keyboard buffer.
  1148.  */
  1149.  
  1150.     if (Batch)
  1151.     {
  1152.         wait_ms (1000);
  1153.     }
  1154.     else
  1155.     {
  1156.         while (!Bconstat (2))        /* wait for a key... */
  1157.             ;
  1158.  
  1159.         while (Bconstat (2))        /* keep reading while there */
  1160.             Bconin (2);        /* are key inputs... */
  1161.     }
  1162. }
  1163.  
  1164.  
  1165.  
  1166.  
  1167. /*------------------------------*/
  1168. /*    wait_ms            */
  1169. /*------------------------------*/
  1170.  
  1171. #define MSLOOP        192            /* for function */
  1172.  
  1173. wait_ms (ms)
  1174. int    ms;
  1175. {
  1176.  
  1177. /*
  1178.  *    wait the presribed number of milliseconds. nothing fancy, just
  1179.  *    kill time...
  1180.  */
  1181.  
  1182.     int    i;
  1183.  
  1184.     /*
  1185.      *   trivial case (no neg wait)
  1186.      */
  1187.     if (ms <= 0)
  1188.         return;
  1189.  
  1190.     /*
  1191.      *   here we do the loop. inner one is just about 1 ms
  1192.      */
  1193.     for ( ; ms > 0; ms--)
  1194.         for (i = MSLOOP; i > 0; i--)
  1195.             ;
  1196.     return;
  1197. }
  1198.  
  1199.  
  1200.  
  1201.  
  1202.  
  1203.