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