home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1997 March / VPR9703A.ISO / VPR_DATA / DOGA / SOURCES / POLYEDIT.LZH / MODEL / GRAPH98.C < prev    next >
C/C++ Source or Header  |  1994-08-10  |  11KB  |  501 lines

  1. #include <stdio.h>
  2. #include <dos.h>
  3. #ifdef __GNUC__
  4.     #include <pc.h>
  5. #else
  6.     #include <conio.h>
  7.     #define outportb(port,value)    outp(port,value)
  8. #endif
  9. #include "graph.h"
  10.  
  11. #define GRAPHIC_MODE_COLOR_16    2
  12. #define GRAPH_ADDRESS_B        (0xe00a8000)
  13. #define GRAPH_ADDRESS_R        (0xe00b0000)
  14. #define GRAPH_ADDRESS_G        (0xe00b8000)
  15. #define GRAPH_ADDRESS_I        (0xe00e0000)
  16.  
  17. static short paletdata[16];
  18.  
  19. static    void    graph_apage(int page);
  20. static    void    graph_vpage(int page);
  21. static    void    EGCset(int color);
  22.  
  23. #ifdef __GNUC__
  24. #define far
  25. static unsigned int longleftedge[32] = {
  26.     0xffffffff, 0xffffff7f, 0xffffff3f, 0xffffff1f,
  27.     0xffffff0f, 0xffffff07, 0xffffff03, 0xffffff01,
  28.     0xffffff00, 0xffff7f00, 0xffff3f00, 0xffff1f00,
  29.     0xffff0f00, 0xffff0700, 0xffff0300, 0xffff0100,
  30.     0xffff0000, 0xff7f0000, 0xff3f0000, 0xff1f0000,
  31.     0xff0f0000, 0xff070000, 0xff030000, 0xff010000,
  32.     0xff000000, 0x7f000000, 0x3f000000, 0x1f000000,
  33.     0x0f000000, 0x07000000, 0x03000000, 0x01000000,
  34. };
  35. static unsigned int longrightedge[32] = {
  36.     0x00000080, 0x000000c0, 0x000000e0, 0x000000f0,
  37.     0x000000f8, 0x000000fc, 0x000000fe, 0x000000ff,
  38.     0x000080ff, 0x0000c0ff, 0x0000e0ff, 0x0000f0ff,
  39.     0x0000f8ff, 0x0000fcff, 0x0000feff, 0x0000ffff,
  40.     0x0080ffff, 0x00c0ffff, 0x00e0ffff, 0x00f0ffff,
  41.     0x00f8ffff, 0x00fcffff, 0x00feffff, 0x00ffffff,
  42.     0x80ffffff, 0xc0ffffff, 0xe0ffffff, 0xf0ffffff,
  43.     0xf8ffffff, 0xfcffffff, 0xfeffffff, 0xffffffff,
  44. };
  45. #endif
  46. static unsigned char charleftedge[8] = {
  47.     0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01
  48. };
  49. static unsigned char charrightedge[8] = {
  50.     0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff
  51. };
  52.  
  53. static void graph_line_1(int x1, int y1, int x2, int y2, int color)
  54. {
  55.     int temp;
  56.     int i;
  57.     int offset;
  58.     int data;
  59.     unsigned char *gram = (unsigned char *)GRAPH_ADDRESS_I;
  60.     if (y1 > y2) {
  61.         temp = y1; y1 = y2; y2 = temp;
  62.     }
  63.     gram += offset = y1 * 80 + x1 / 8;
  64.     data = 0x80 >> (x1 % 8);
  65.     for (i = y2 - y1 + 1; i > 0; --i) {
  66.         if ( color == 18 )
  67.             *gram ^= data;
  68.         else
  69.             *gram = data;
  70.         gram += 80;
  71.     }
  72. }
  73.  
  74. static void graph_line_2(int x1, int y1, int x2, int y2, int color)
  75. {
  76.     int i;
  77.     int offset;
  78.     int data;
  79.     int diff;
  80.     int plus, minus;
  81.     unsigned char *gram = (unsigned char *)GRAPH_ADDRESS_I;
  82.     plus = (y1 - y2) * 2;
  83.     minus = (x2 - x1) * 2;
  84.     diff = plus / 2;
  85.     gram += offset = y1 * 80 + x1 / 8;
  86.     data = 0x80 >> (x1 % 8);
  87.     for (i = y1 - y2 + 1; i > 0; --i) {
  88.         if ( color == 18 )
  89.             *gram ^= data;
  90.         else
  91.             *gram = data;
  92.         gram -= 80;
  93.         if ((diff -= minus) < 0) {
  94.             if ((data >>= 1) == 0) {
  95.                 data = 0x80;
  96.                 gram++;
  97.             }
  98.             diff += plus;
  99.         }
  100.     }
  101. }
  102.  
  103. static void graph_line_3(int x1, int y1, int x2, int y2, int color)
  104. {
  105.     int i;
  106.     int offset;
  107.     int data;
  108.     unsigned char *gram = (unsigned char *)GRAPH_ADDRESS_I;
  109.     gram += offset = y1 * 80 + x1 / 8;
  110.     data = 0x80 >> (x1 % 8);
  111.     for (i = y1 - y2 + 1; i > 0; --i) {
  112.         if ( color == 18 )
  113.             *gram ^= data;
  114.         else
  115.             *gram = data;
  116.         gram -= 80;
  117.         if ((data >>= 1) == 0) {
  118.             data = 0x80;
  119.             gram++;
  120.         }
  121.     }
  122. }
  123.  
  124. static void graph_line_4(int x1, int y1, int x2, int y2, int color)
  125. {
  126.     int i;
  127.     int offset;
  128.     int diff;
  129.     int plus, minus;
  130.     int start, end;
  131.     unsigned char *gram = (unsigned char *)GRAPH_ADDRESS_I;
  132.     plus = (x2 - x1) * 2;
  133.     minus = (y1 - y2) * 2;
  134.     diff = plus / 2;
  135.     gram += offset = y1 * 80 + x1 / 8;
  136.     start = end = x1 % 8;
  137.     for (i = x2 - x1 + 1; i > 0; --i) {
  138.         end++;
  139.         if ((diff -= minus) < 0) {
  140.             if ( color == 18 )
  141.                 *gram ^= charleftedge[start] & charrightedge[(end-1)];
  142.             else
  143.                 *gram = charleftedge[start] & charrightedge[(end-1)];
  144.             gram -= 80;
  145.             if (end == 8) {
  146.                 gram++;
  147.                 end = 0;
  148.             }
  149.             start = end;
  150.             diff += plus;
  151.         } else if (end == 8) {
  152.             if ( color == 18 )
  153.                 *gram++ ^= charleftedge[start];
  154.             else
  155.                 *gram++ = charleftedge[start];
  156.             start = end = 0;
  157.         }
  158.     }
  159.     if (end != 0) {
  160.         if ( color == 18 )
  161.             *gram ^= charleftedge[start] & charrightedge[end-1];
  162.         else
  163.             *gram = charleftedge[start] & charrightedge[end-1];
  164.     }
  165. }
  166.  
  167. static void graph_line_5(int x1, int y1, int x2, int y2, int color)
  168. {
  169.     int i;
  170.     int offset1, offset2;
  171.  
  172.     unsigned int *gram = (unsigned int *)GRAPH_ADDRESS_I;
  173.     offset1 = y1 * 20 + x1 / 32;
  174.     offset2 = y1 * 20 + x2 / 32;
  175.     gram += offset1;
  176.     if (offset1 == offset2) {
  177.         if ( color == 18 )
  178.             *gram ^= longleftedge[x1%32] & longrightedge[x2%32];
  179.         else
  180.             *gram = longleftedge[x1%32] & longrightedge[x2%32];
  181.     } else if (offset2 == offset1 + 1) {
  182.         if ( color == 18 )
  183.         {
  184.             *gram++ ^= longleftedge[x1%32];
  185.             *gram ^= longrightedge[x2%32];
  186.         }
  187.         else
  188.         {
  189.             *gram++ = longleftedge[x1%32];
  190.             *gram = longrightedge[x2%32];
  191.         }
  192.     } else {
  193.         if ( color == 18 )
  194.             *gram++ ^= longleftedge[x1%32];
  195.         else
  196.             *gram++ = longleftedge[x1%32];
  197.         for (i = offset2 - offset1 - 1;i > 0; --i) {
  198.             if ( color == 18 )
  199.                 *gram++ ^= 0xffffffff;
  200.             else
  201.                 *gram++ = 0xffffffff;
  202.         }
  203.         if ( color == 18 )
  204.             *gram ^= longrightedge[x2%32];
  205.         else
  206.             *gram = longrightedge[x2%32];
  207.     }
  208. }
  209.  
  210. static void graph_line_6(int x1, int y1, int x2, int y2, int color)
  211. {
  212.     int i;
  213.     int offset;
  214.     int diff;
  215.     int plus, minus;
  216.     int start, end;
  217.     unsigned char *gram = (unsigned char *)GRAPH_ADDRESS_I;
  218.     plus = (x2 - x1) * 2;
  219.     minus = (y2 - y1) * 2;
  220.     diff = plus / 2;
  221.     gram += offset = y1 * 80 + x1 / 8;
  222.     start = end = x1 % 8;
  223.     for (i = x2 - x1 + 1; i > 0; --i) {
  224.         end++;
  225.         if ((diff -= minus) < 0) {
  226.             if ( color == 18 )
  227.                 *gram ^= charleftedge[start] & charrightedge[(end-1)];
  228.             else
  229.                 *gram = charleftedge[start] & charrightedge[(end-1)];
  230.             gram += 80;
  231.             start = end;
  232.             diff += plus;
  233.             if (end == 8) {
  234.                 gram++;
  235.                 start = end = 0;
  236.             }
  237.         } else if (end == 8) {
  238.             if ( color == 18 )
  239.                 *gram++ ^= charleftedge[start];
  240.             else
  241.                 *gram++ = charleftedge[start];
  242.             start = end = 0;
  243.         }
  244.     }
  245.     if (end != 0) {
  246.         if ( color == 18 )
  247.             *gram ^= charleftedge[start] & charrightedge[end-1];
  248.         else
  249.             *gram = charleftedge[start] & charrightedge[end-1];
  250.     }
  251. }
  252.  
  253. static void graph_line_7(int x1, int y1, int x2, int y2, int color)
  254. {
  255.     int i;
  256.     int offset;
  257.     int data;
  258.     unsigned char *gram = (unsigned char *)GRAPH_ADDRESS_I;
  259.     gram += offset = y1 * 80 + x1 / 8;
  260.     data = 0x80 >> (x1 % 8);
  261.     for (i = y2 - y1 + 1; i > 0; --i) {
  262.         if ( color == 18 )
  263.             *gram ^= data ;
  264.         else
  265.             *gram = data ;
  266.         gram += 80;
  267.         if ((data >>= 1) == 0) {
  268.             data = 0x80;
  269.             gram++;
  270.         }
  271.     }
  272. }
  273.  
  274. static void graph_line_8(int x1, int y1, int x2, int y2, int color)
  275. {
  276.     int i;
  277.     int offset;
  278.     int data;
  279.     int diff;
  280.     int plus, minus;
  281.     unsigned char *gram = (unsigned char *)GRAPH_ADDRESS_I;
  282.     plus = (y2 - y1) * 2;
  283.     minus = (x2 - x1) * 2;
  284.     diff = plus / 2;
  285.     gram += offset = y1 * 80 + x1 / 8;
  286.     data = 0x80 >> (x1 % 8);
  287.     for (i = y2 - y1 + 1; i > 0; --i) {
  288.         if ( color == 18 )
  289.             *gram ^= data ;
  290.         else
  291.             *gram = data ;
  292.         gram += 80;
  293.         if ((diff -= minus) < 0) {
  294.             if ((data >>= 1) == 0) {
  295.                 data = 0x80;
  296.                 gram++;
  297.             }
  298.             diff += plus;
  299.         }
  300.     }
  301. }
  302.  
  303. void graph_line(int x1, int y1, int x2, int y2, int color)
  304. {
  305.     int temp;
  306.     if (y1 > y2) {
  307.         temp = x1; x1 = x2; x2 = temp;
  308.         temp = y1; y1 = y2; y2 = temp;
  309.     }
  310.     if (y2 < 0 || y1 > 399) {
  311.         return;
  312.     }
  313.     if (y1 < 0) {
  314.         x1 = (x1 * y2 - x2 * y1) / (y2 - y1);
  315.         y1 = 0;
  316.     }
  317.     if (y2 > 399) {
  318.         x2 = (x2 - x1) * (399 - y1) / (y2 - y1) + x1;
  319.         y2 = 399;
  320.     }
  321.     if (x1 > x2) {
  322.         temp = x1; x1 = x2; x2 = temp;
  323.         temp = y1; y1 = y2; y2 = temp;
  324.     }
  325.     if (x2 < 0 || x1 > 639) {
  326.         return;
  327.     }
  328.     if (x1 < 0) {
  329.         y1 = (y1 * x2 - y2 * x1) / (x2 - x1);
  330.         x1 = 0;
  331.     }
  332.     if (x2 > 639) {
  333.         y2 = (y2 - y1) * (639 - x1) / (x2 - x1) + y1;
  334.         x2 = 639;
  335.     }
  336. /*
  337.                 1 2 3
  338.                 |  / 
  339.                 | / 4
  340.                 |/  
  341.                 .---5
  342.                  \
  343.                   \ 6
  344.                    \
  345.                 9 8 7
  346. */
  347.     EGCset( color );
  348.  
  349.     if (x1 == x2) {
  350.         graph_line_1(x1, y1, x2, y2, color);
  351.     } else if (y1 == y2) {
  352.         graph_line_5(x1, y1, x2, y2, color);
  353.     } else if (y2 < y1) {
  354.         if (y1 - y2 > x2 - x1) {
  355.             graph_line_2(x1, y1, x2, y2, color);
  356.         } else if (y1 - y2 == x2 - x1) {
  357.             graph_line_3(x1, y1, x2, y2, color);
  358.         } else {
  359.             graph_line_4(x1, y1, x2, y2, color);
  360.         }
  361.     } else {
  362.         if (y2 - y1 < x2 - x1) {
  363.             graph_line_6(x1, y1, x2, y2, color);
  364.         } else if (y2 - y1 == x2 - x1) {
  365.             graph_line_7(x1, y1, x2, y2, color);
  366.         } else {
  367.             graph_line_8(x1, y1, x2, y2, color);
  368.         }
  369.     }
  370.     outportb(0x7c, 0 );
  371. }
  372.  
  373. void graph_palet(int paletmode, int g, int r, int b)
  374. {
  375.     int    color ;
  376.  
  377.     color = ( ( g >> 4 ) << 8 )|( ( r >> 4 ) << 4 )|( b >> 4 );
  378.     paletdata[paletmode & 15] = color;
  379.     outportb(0xa8, paletmode);
  380.     outportb(0xaa, color >> 8);
  381.     outportb(0xac, color >> 4);
  382.     outportb(0xae, color     );
  383. }
  384.  
  385.  
  386. void graph_init( void )
  387. {
  388.     union    REGS in;
  389.     union    REGS out;
  390.     int i;
  391.  
  392.     in.h.ah = 0x42;
  393.     in.h.ch = 0xc0;
  394.     int86( 0x18, &in, &out );    /*graphic bios set gvram domain*/
  395. #if 0
  396.     outportb( 0x68, 2 );        /*graphic mode = color*/
  397.     outportb( 0x68, 8 );        /*brp mode = 400line*/
  398.     outportb( 0x6a, 1 );        /*color = 8*/
  399. #endif
  400.     in.h.ah = 0x40;
  401.     int86( 0x18, &in, &out );
  402.     outportb( 0x6a, 1);
  403.     for (i = 0; i < 8; ++i) {
  404.         graph_palet(i, (i&4) ? 255 : 0, (i&2) ? 255 : 0, (i&1) ? 255 : 0);
  405.     }
  406.  
  407.     graph_apage(0);
  408.     graph_vpage(0);
  409.     graph_cls( 0 );
  410. }
  411.  
  412. void    graph_exit()
  413. {
  414. }
  415.  
  416. static    void graph_apage(int page)
  417. {
  418.     outportb(0xa6, page);
  419. }
  420.  
  421. static    void graph_vpage(int page)
  422. {
  423.     outportb(0xa4, page);
  424. }
  425.  
  426. void graph_cls( int color )
  427. {
  428.     int i;
  429.     unsigned long far *p;
  430.  
  431.     EGCset( color );
  432.     for (i = 8000, p = (unsigned long*)GRAPH_ADDRESS_I; i > 0; --i) {
  433.         *p++ = 0xffffffffUL;
  434.     }
  435.     outportb(0x7c, 0);
  436. }
  437.  
  438. #define    swap( a, b ) { int c ; c = a ; a = b ; b = c ; }
  439.  
  440. void graph_fill( int x1, int y1, int x2, int y2, int color )
  441. {
  442.     int        y ;
  443.  
  444.     if ( x1 > x2 )
  445.         swap( x1, x2 );
  446.     if ( y1 > y2 )
  447.         swap( y1, y2 );
  448.  
  449.     EGCset( color );
  450.     for( y = y1 ; y <= y2 ; y++ )
  451.         graph_line_5( x1, y, x2, y, color );
  452. }
  453.  
  454. static    void    EGCset( int color )
  455. {
  456.     if ( color == 18 ) {
  457.         outportb(0x7c, 0 );
  458.     } else if ( color >= 16 ) {
  459.         outportb(0x7c, 0xc7);
  460.         outportb(0x7e, 0 );
  461.         outportb(0x7e, 0 );
  462.         outportb(0x7e, 0 );
  463.         outportb(0x7e, (color & 15) ? 0xff : 0);
  464.     } else {
  465.         outportb(0x7c, 0xc0);
  466.         outportb(0x7e, (color & 1) ? 0xff : 0);
  467.         outportb(0x7e, (color & 2) ? 0xff : 0);
  468.         outportb(0x7e, (color & 4) ? 0xff : 0);
  469.         outportb(0x7e, (color & 8) ? 0xff : 0);
  470.     }
  471. }
  472.  
  473. void    graph_pattern( x, y, color, pat, h, v )
  474. int        x, y ;
  475. int        color ;
  476. short    *pat ;
  477. int        h, v ;
  478. {
  479. }
  480.  
  481. /*    ボタン表示    */
  482. void    graph_box( x1, y1, x2, y2, sw )
  483. int        x1, y1, x2, y2 ;
  484. int        sw ;
  485. {
  486.     if ( sw )
  487.     {
  488.         graph_line( x1, y1, x2, y1, 7 );
  489.         graph_line( x1, y1, x1, y2, 7 );
  490.         graph_line( x1, y2, x2, y2, 0 );
  491.         graph_line( x2, y1, x2, y2, 0 );
  492.     }
  493.     else
  494.     {
  495.         graph_line( x1, y1, x2, y1, 0 );
  496.         graph_line( x1, y1, x1, y2, 0 );
  497.         graph_line( x1, y2, x2, y2, 7 );
  498.         graph_line( x2, y1, x2, y2, 7 );
  499.     }
  500. }
  501.