home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / fish / graphics / applications / dkbtrace / src / ibm.c < prev    next >
C/C++ Source or Header  |  1990-08-26  |  11KB  |  361 lines

  1. /*****************************************************************************
  2. *
  3. *                                      ibm.c
  4. *
  5. *   from DKBTrace (c) 1990  David Buck
  6. *
  7. *  This module implements the IBM-specific routines for DKBTrace.
  8. *
  9. * This software is freely distributable. The source and/or object code may be
  10. * copied or uploaded to communications services so long as this notice remains
  11. * at the top of each file.  If any changes are made to the program, you must
  12. * clearly indicate in the documentation and in the programs startup message
  13. * who it was who made the changes. The documentation should also describe what
  14. * those changes were. This software may not be included in whole or in
  15. * part into any commercial package without the express written consent of the
  16. * author.  It may, however, be included in other public domain or freely
  17. * distributed software so long as the proper credit for the software is given.
  18. *
  19. * This software is provided as is without any guarantees or warranty. Although
  20. * the author has attempted to find and correct any bugs in the software, he
  21. * is not responsible for any damage caused by the use of the software.  The
  22. * author is under no obligation to provide service, corrections, or upgrades
  23. * to this package.
  24. *
  25. * Despite all the legal stuff above, if you do find bugs, I would like to hear
  26. * about them.  Also, if you have any comments or questions, you may contact me
  27. * at the following address:
  28. *
  29. *     David Buck
  30. *     22C Sonnet Cres.
  31. *     Nepean Ontario
  32. *     Canada, K2H 8W7
  33. *
  34. *  I can also be reached on the following bulleton boards:
  35. *
  36. *     ATX              (613) 526-4141
  37. *     OMX              (613) 731-3419
  38. *     Mystic           (613) 731-0088 or (613) 731-6698
  39. *
  40. *  Fidonet:   1:163/109.9
  41. *  Internet:  David_Buck@Carleton.CA
  42. *
  43. *  IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
  44. *
  45. *     Lattice BBS                      (708) 916-1200
  46. *     The Information Exchange BBS     (708) 945-5575
  47. *     Stillwaters BBS                  (708) 403-2826
  48. *
  49. *****************************************************************************/
  50.  
  51. #include "frame.h"
  52. #include "dkbproto.h"
  53.  
  54. /* IBM VGA "colour" output routines for MS/DOS by Aaron A. Collins.  This
  55.    will deliver approximate colorings using HSV values for the approximation.
  56.    The pallette map is divided into 4 parts - upper and lower half generated
  57.    with full and half "value" (intensity), respectively.  These halves are
  58.    further halved by full and half saturation values of each range (pastels).
  59.    There are three constant colors, black, white, and grey.  They are used
  60.    when the saturation is low enough that the hue becomes undefined, and which
  61.    one is selected is based on a simple range map of "value".  Usage of the
  62.    pallette is accomplished by converting the requested color RGB into an HSV
  63.    value.  If the saturation is too low (< .25) then black, white or grey is
  64.    selected.  If there is enough saturation to consider looking at the hue,
  65.    then the hue range of 1-63 is scaled into one of the 4 pallette quadrants
  66.    based on its "value" and "saturation" characteristics.
  67. */
  68.  
  69. #include <dos.h>    /* MS-DOS specific - for int86() REGS struct, etc. */
  70.  
  71. void set_pallette_register(unsigned, unsigned, unsigned, unsigned);
  72. void hsv_to_rgb(DBL, DBL, DBL, unsigned *, unsigned *, unsigned *);
  73. void rgb_to_hsv(unsigned, unsigned, unsigned, DBL *, DBL *, DBL *);
  74.  
  75. extern unsigned _stklen = 32768U;   /* HUGE stack for HEAVY recursion */
  76. extern int Options;
  77.  
  78. void display_init()
  79.    {
  80.    union REGS inr, outr;
  81.    register unsigned m;
  82.    unsigned r, g, b;
  83.    register DBL hue, sat, val;
  84.  
  85.    inr.x.ax = 0x0013;           /* setup to VGA 320x200x256 (mode 13H) */
  86.    int86(0x10, &inr, &outr);
  87.  
  88.    inr.x.ax = 0x1010;           /* make pallette register 0 black */
  89.    inr.x.bx = 0;
  90.    inr.h.ch = inr.h.cl = inr.h.dh = 0;   /* full off */
  91.    int86(0x10, &inr, &outr);
  92.  
  93.    inr.x.ax = 0x1010;           /* make pallette register 64 white */
  94.    inr.x.bx = 64;
  95.    inr.h.ch = inr.h.cl = inr.h.dh = 63;  /* full on */
  96.    int86(0x10, &inr, &outr);
  97.  
  98.    inr.x.ax = 0x1010;           /* make pallette register 128 dark grey */
  99.    inr.x.bx = 128;
  100.    inr.h.ch = inr.h.cl = inr.h.dh = 31;  /* half on (dark grey) */
  101.    int86(0x10, &inr, &outr);
  102.  
  103.    inr.x.ax = 0x1010;           /* make pallette register 192 lite grey */
  104.    inr.x.bx = 192;
  105.    inr.h.ch = inr.h.cl = inr.h.dh = 48;  /* 3/4 on (lite grey) */
  106.    int86(0x10, &inr, &outr);
  107.  
  108.    for (m = 1; m < 64; m++)     /* for the 1st 64 colors... */
  109.       {
  110.       sat = 0.5;                /* start with the saturation and intensity low */
  111.       val = 0.5;
  112.       hue = 360.0 * ((DBL)(m)) / 64.0;   /* normalize to 360 */
  113.       hsv_to_rgb (hue, sat, val, &r, &g, &b);
  114.       set_pallette_register (m, r, g, b); /* set m to rgb value */
  115.  
  116.       sat = 1.0;                /* high saturation and half intensity (shades) */
  117.       val = 0.50;
  118.       hue = 360.0 * ((DBL)(m)) / 64.0;   /* normalize to 360 */
  119.       hsv_to_rgb (hue, sat, val, &r, &g, &b);
  120.       set_pallette_register (m + 64, r, g, b);  /* set m + 64 */
  121.  
  122.       sat = 0.5;                /* half saturation and high intensity (pastels) */
  123.       val = 1.0;
  124.  
  125.       hue = 360.0 * ((DBL)(m)) / 64.0;   /* normalize to 360 */
  126.       hsv_to_rgb (hue, sat, val, &r, &g, &b);
  127.       set_pallette_register (m + 128, r, g, b); /* set m + 128 */
  128.  
  129.       sat = 1.0;                /* normal full HSV set at full intensity */
  130.       val = 1.0;
  131.    
  132.       hue = 360.0 * ((DBL)(m)) / 64.0;   /* normalize to 360 */
  133.       hsv_to_rgb (hue, sat, val, &r, &g, &b);
  134.       set_pallette_register (m + 192, r, g, b); /* set m + 192 */
  135.       }
  136.    return;
  137.    }
  138.  
  139. void display_finished ()
  140.    {
  141.    if (Options & PROMPTEXIT)
  142.       {
  143.       printf ("\007\007");   /* long beep */
  144.       getch();
  145.       }
  146.    }
  147.  
  148. void display_close()   /* setup to Text 80x25 (mode 3) */
  149.    {
  150.    union REGS inr, outr;
  151.  
  152.    inr.x.ax = 0x0003;
  153.    int86(0x10, &inr, &outr);
  154.    return;
  155.    }
  156.  
  157. void display_plot (x, y, Red, Green, Blue)   /* plot a single RGB pixel */
  158.    int x, y;
  159.    char Red, Green, Blue;
  160.    {
  161.    register unsigned char color;
  162.    unsigned char far *fp;
  163.    DBL h, s, v;
  164.  
  165.    /* Translate RGB value to best of 256 pallete Colors (by HSV?) */
  166.  
  167.    rgb_to_hsv((unsigned)Red,(unsigned)Green,(unsigned)Blue, &h, &s, &v);
  168.  
  169.    if (s < 0.25)   /* black or white if no saturation of color... */
  170.       {
  171.       if (v < 0.25)
  172.          color = 0;        /* black */
  173.       else if (v > 0.75)
  174.          color = 64;       /* white */
  175.       else if (v > 0.5)
  176.          color = 192;      /* lite grey */
  177.       else
  178.          color = 128;      /* dark grey */
  179.       }
  180.    else
  181.       {
  182.       color = (unsigned char) (64.0 * ((DBL)(h)) / 360.0);
  183.  
  184.       if (!color)
  185.          color = 1;        /* avoid black, white or grey */
  186.       
  187.       if (color > 63)
  188.          color = 63;       /* avoid same */
  189.  
  190.       if (v > 0.50)
  191.          color |= 0x80;    /* colors 128-255 for high inten. */
  192.  
  193.       if (s > 0.50)        /* more than half saturated? */
  194.          color |= 0x40;    /* color range 64-128 or 192-255 */
  195.       }
  196.  
  197.    fp = MK_FP(0xa000, 320 * y + x);
  198.  
  199.    *fp = color;            /* normalize color to 256 */
  200.  
  201.    return;
  202.    }
  203.  
  204. void set_pallette_register (Val, Red, Green, Blue)
  205.    unsigned Val;
  206.    unsigned Red, Green, Blue;
  207.    {
  208.    union REGS Regs;
  209.  
  210.    Regs.x.ax = 0x1010;              /* Set one pallette register function */
  211.    Regs.x.bx = Val;                 /* the pallette register to set (color #) */
  212.    Regs.h.dh = (char) Red & 0xff;   /* set the gun values (6 bits ea.) */
  213.    Regs.h.ch = (char) Green & 0xff;
  214.    Regs.h.cl = (char) Blue & 0xff;
  215.    int86(0x10, &Regs, &Regs);       /* Do the video interrupt */
  216.    }
  217.  
  218. /* Conversion from Hue, Saturation, Value to Red, Green, and Blue and back */
  219. /* From "Computer Graphics", Donald Hearn & M. Pauline Baker, p. 304 */
  220.  
  221. void hsv_to_rgb(hue, s, v, r, g, b)
  222.    DBL hue, s, v;               /* hue (0.0 to 360.0) s and v are from 0.0 - 1.0) */
  223.    unsigned *r, *g, *b;         /* values from 0 to 63 */
  224.    {
  225.    register DBL i, f, p1, p2, p3;
  226.    register DBL xh;
  227.    register DBL nr, ng, nb;     /* rgb values of 0.0 - 1.0      */
  228.  
  229.    if (hue == 360.0)
  230.       hue = 0.0;                /* (THIS LOOKS BACKWARDS BUT OK) */
  231.  
  232.    xh = hue / 60.0;             /* convert hue to be in 0,6     */
  233.    i = floor(xh);               /* i = greatest integer <= h    */
  234.    f = xh - i;                  /* f = fractional part of h     */
  235.    p1 = v * (1 - s);
  236.    p2 = v * (1 - (s * f));
  237.    p3 = v * (1 - (s * (1 - f)));
  238.  
  239.    switch ((int) i)
  240.       {
  241.       case 0:
  242.          nr = v;
  243.          ng = p3;
  244.          nb = p1;
  245.          break;
  246.       case 1:
  247.          nr = p2;
  248.          ng = v;
  249.          nb = p1;
  250.          break;
  251.       case 2:
  252.          nr = p1;
  253.          ng = v;
  254.          nb = p3;
  255.          break;
  256.       case 3:
  257.          nr = p1;
  258.          ng = p2;
  259.          nb = v;
  260.          break;
  261.       case 4:
  262.          nr = p3;
  263.          ng = p1;
  264.          nb = v;
  265.          break;
  266.       case 5:
  267.          nr = v;
  268.          ng = p1;
  269.          nb = p2;
  270.          break;
  271.         }
  272.  
  273.    *r = (unsigned)(nr * 63.0); /* Normalize the values to 63 */
  274.    *g = (unsigned)(ng * 63.0);
  275.    *b = (unsigned)(nb * 63.0);
  276.    
  277.    return;
  278.    }
  279.  
  280. void rgb_to_hsv(r, g, b, h, s, v)
  281.    unsigned r, g, b;
  282.    DBL *h, *s, *v;
  283.    {
  284.    register DBL m, r1, g1, b1;
  285.    register DBL nr, ng, nb;      /* rgb values of 0.0 - 1.0      */
  286.    register DBL nh, ns, nv;      /* hsv local values */
  287.  
  288.    nr = (DBL) r / 255.0;
  289.    ng = (DBL) g / 255.0;
  290.    nb = (DBL) b / 255.0;
  291.  
  292.    nv = max (nr, max (ng, nb));
  293.    m = min (nr, min (ng, nb));
  294.  
  295.    if (nv != 0.0)                /* if no value, it's black! */
  296.       ns = (nv - m) / nv;
  297.    else
  298.       ns = 0.0;                 /* black = no colour saturation */
  299.  
  300.    if (ns == 0.0)                /* hue undefined if no saturation */
  301.    {
  302.       *h = 0.0;                  /* return black level (?) */
  303.       *s = 0.0;
  304.       *v = nv;
  305.       return;
  306.    }
  307.  
  308.    r1 = (nv - nr) / (nv - m);    /* distance of color from red   */
  309.    g1 = (nv - ng) / (nv - m);    /* distance of color from green   */
  310.    b1 = (nv - nb) / (nv - m);    /* distance of color from blue   */
  311.  
  312.    if (nv == nr)
  313.    {
  314.       if (m == ng)
  315.          nh = 5. + b1;
  316.       else
  317.          nh = 1. - g1;
  318.    } 
  319.  
  320.    if (nv == ng)
  321.       {
  322.       if (m == nb)
  323.          nh = 1. + r1;
  324.       else
  325.          nh = 3. - b1;
  326.       }
  327.  
  328.    if (nv == nb)
  329.       {
  330.       if (m == nr)
  331.          nh = 3. + g1;
  332.       else
  333.          nh = 5. - r1;
  334.       }
  335.  
  336.    *h = nh * 60.0;      /* return h converted to degrees */
  337.    *s = ns;
  338.    *v = nv;
  339.    return;
  340.    }
  341.  
  342. #if !__STDC__
  343.  
  344. /* ANSI Standard random number generator */
  345.  
  346. static unsigned long int next = 1;
  347.  
  348. int rand()
  349.    {
  350.    next = next * 1103515245L + 12345L;
  351.    return ((int) (next / 0x10000L) & 0x7FFF);
  352.    }
  353.  
  354. void srand(seed)
  355.    unsigned int seed;
  356.    {
  357.    next = seed;
  358.    }
  359.  
  360. #endif
  361.