home *** CD-ROM | disk | FTP | other *** search
/ Phoenix Heaven Sunny 2 / APPARE2.BIN / oh_towns / tetujin / src.lzh / POLY.C < prev    next >
Text File  |  1995-01-04  |  12KB  |  653 lines

  1. /*            polygon
  2.             1994 5/4
  3. */
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <egb.h>
  8. #include <mos.h>
  9. #include <winb.h>
  10. #include <te.h>
  11. #include <fntb.h>
  12. #include <gui.h>
  13. #include "poly.h"
  14.  
  15. #define ENDSW 2        /* 終了ボタンはマウス右 */
  16. #define CANCELSW 3    /* キャンセルボタンはマウス左右ボタン */
  17.  
  18. static int sw = 0,cx = 0,cy = 0;    /* MOUSE data */
  19.  
  20. static int pn = 0;            /* POLYGON point counter */
  21. static int ax1=0,ay1=0,ax2=0,ay2=0;        /* POLYGON area min & max */
  22. static short int poly[POLYMAX+2][2];    /* POLYGON point data */
  23.  
  24. static char para[256];        /* PARAM */
  25. static char *ework ;
  26. static char *buffer ;
  27. static int xlen ;
  28. static int ylen ;
  29. static int color ;
  30. static int ( *setDisplay )() ;
  31. static int initFlag = 0 ;
  32.  
  33. /* init */
  34. /* 引数 EGBワーク,ポリゴン作業領域,横,縦,カーソルを表示内に入れるための関数 */
  35. polygon_rectangle_init( char *egbWork, char *buf,
  36.                         int x, int y, int c, int ( *f )() )
  37. {
  38.     ework = egbWork ;
  39.     buffer = buf ;
  40.     xlen = x ;
  41.     ylen = y ;
  42.     color = c ;
  43.     setDisplay = f ;
  44.  
  45.     initFlag = 1 ;
  46.     return NOERR ;
  47. }
  48.  
  49. /* polygon 1 */
  50. polygon_1st( int *lux, int *luy, int *rdx, int *rdy )
  51. {
  52.     int x0,y0,ydis,d,loop,i,add,dini,numini;
  53.     double num,deg;
  54.     int ret ;
  55.  
  56.     ax1 = 0; ay1 = 0; ax2 = 0; ay2 = 0;
  57.     *lux = ax1; *luy = ay1;
  58.     *rdx = ax2; *rdy = ay2;
  59.  
  60.     if( initFlag == 0 )return -1 ;
  61.  
  62.     MOS_rdpos(&sw,&cx,&cy);    /* この場におよんで押してないのはやる気なし */
  63.     if( sw != 1 )
  64.     {
  65.         return -1 ;
  66.     }
  67.  
  68.     pn = 0;                    /* pn = 0 */
  69.     polygon_rectangle_clear() ;
  70.  
  71.     poly[0][0] = cx;
  72.     x0 = cx;
  73.     ax1 = cx;
  74.     ax2 = cx;
  75.     d=0;
  76.     poly[0][1] = cy;
  77.     y0 = cy;
  78.     ay1 = cy;
  79.     ay2 = cy;
  80.  
  81.     mouseInit() ;
  82.  
  83. plygn0:
  84.     ret = mouse( 1, 1 ) ;
  85. plygn1:
  86.     if( sw == CANCELSW )
  87.     {
  88.         while( sw )
  89.         {                /* マウスボタンリリースまで待つ */
  90.             int x, y ;
  91.  
  92.             MOS_rdpos(&sw,&x,&y);
  93.         }
  94.  
  95.         polygon_2nd() ;
  96.         polygon_rectangle_clear() ;
  97.         pn = 0 ;
  98.         return -1 ;
  99.     }
  100.     if( ret )sw = ENDSW ; /* ダブルクリックなら終わる */
  101.     if( (cx == x0) && (cy == y0) && (sw == 1) )goto plygn0;
  102. plygn2:
  103.     if( pn < POLYMAX ){
  104.         poly[pn + 1][0] = cx;
  105.         poly[pn + 1][1] = cy;
  106.  
  107.         polygonDispLine( pn ) ;
  108.  
  109.         pn = pn + 1;
  110.     }
  111.     ydis = cy - y0;
  112.     if( ydis == 0 )goto plygn3;
  113.     num = xlen*y0 + x0;
  114.     deg = xlen + ( (double)cx - (double)x0 ) / (double)ydis;
  115.     if( ydis < 0 )deg = -deg;
  116.     loop = ydis;
  117.     if( loop < 0 )loop = -loop;
  118.     if( d * ydis >= 0 ){
  119.         loop = loop - 1;
  120.         num = num + deg;
  121.     }
  122.     for(i=0;i<=loop;i++){
  123.         add = (int)( num + .5 ) ;
  124.         BYTE( buffer + (add >> 3) )
  125.         = BYTE( buffer + (add >> 3) ) ^ ( 0x80 >> (add % 8) ) ;
  126.         num = num + deg ;
  127.     }
  128.     if( d == 0 ){
  129.         dini = ydis ;
  130.         numini = xlen*y0 + x0 ;
  131.     }
  132.     d = 1;
  133.     if( ydis < 0 )d = -1;
  134. plygn3:
  135.     if( ax1 > cx )ax1 = cx;
  136.     if( ax2 < cx )ax2 = cx;
  137.     if( ay1 > cy )ay1 = cy;
  138.     if( ay2 < cy )ay2 = cy;
  139.     x0 = cx;
  140.     y0 = cy;
  141.     if( sw == 1 ){
  142.         for(i=0;i<100;i++);
  143.         goto plygn0;
  144.     }
  145.     if( sw == ENDSW ){
  146.  
  147.         while( sw )
  148.         {                /* マウスボタンリリースまで待つ */
  149.             int x, y ;
  150.  
  151.             MOS_rdpos(&sw,&x,&y);
  152.             if( sw == CANCELSW )break ;
  153.         }
  154.         if( sw == CANCELSW )goto plygn1 ;
  155.  
  156.         sw = 0;
  157.         cx = poly[0][0];
  158.         cy = poly[0][1];
  159.         goto plygn2;
  160.     }
  161.     if( d*dini < 0 ){
  162.         add = numini ;
  163.         BYTE( buffer + (add >> 3) )
  164.         = BYTE( buffer + (add >> 3) ) ^ ( 0x80 >> (add % 8) ) ;
  165.     }
  166.     polygonBufConnect( ay1, ay2 );
  167.     *lux = ax1; *luy = ay1;
  168.     *rdx = ax2; *rdy = ay2;
  169.  
  170.     return NOERR;
  171. }
  172.  
  173. /* polygon 2 */
  174. polygon_2nd()
  175. {
  176.     int i ;
  177.  
  178.     if( initFlag == 0 )return -1 ;
  179.  
  180.     if( pn == 0 )return -1;
  181.  
  182.     for( i=0 ; i<pn ; i++ )
  183.     {
  184.         polygonDispLine( i ) ;
  185.         polygonBufOrLine( i ) ;
  186.     }
  187.  
  188.     return 0;
  189. }
  190.  
  191. /* rectangle 1 */
  192. rectangle_1st( int *lux, int *luy, int *rdx, int *rdy )
  193. {
  194.     int x,y;
  195.  
  196.     ax1 = 0; ay1 = 0; ax2 = 0; ay2 = 0;
  197.     *lux = ax1; *luy = ay1;
  198.     *rdx = ax2; *rdy = ay2;
  199.  
  200.     if( initFlag == 0 )return -1 ;
  201.  
  202.     MOS_rdpos(&sw,&cx,&cy);    /* この場におよんで押してないのはやる気なし */
  203.     if( sw != 1 )
  204.     {
  205.         return -1 ;
  206.     }
  207.  
  208.     pn = 0;                    /* pn = 0 */
  209.     polygon_rectangle_clear() ;
  210.  
  211.     ax1 = cx;
  212.     ay1 = cy;
  213.  
  214.     if( boxMouse() )
  215.         return -1 ;
  216.  
  217.     ax2 = cx;
  218.     ay2 = cy;
  219.  
  220.     if( ax1 > ax2 )
  221.     {
  222.         int temp ;
  223.  
  224.         temp = ax1 ;
  225.         ax1 = ax2 ;
  226.         ax2 = temp ;
  227.     }
  228.     if( ay1 > ay2 )
  229.     {
  230.         int temp ;
  231.  
  232.         temp = ay1 ;
  233.         ay1 = ay2 ;
  234.         ay2 = temp ;
  235.     }
  236.  
  237.     for( y=ay1 ; y<=ay2 ; y++ )
  238.     {
  239.         for( x=ax1 ; x<=ax2 ; x++ )
  240.         {
  241.             int add ;
  242.  
  243.             add = xlen*y + x ;
  244.             BYTE( buffer + (add >> 3) )
  245.             = BYTE( buffer + (add >> 3) ) | ( 0x80 >> (add % 8) ) ;
  246.         }
  247.     }
  248.     *lux = ax1; *luy = ay1;
  249.     *rdx = ax2; *rdy = ay2;
  250.  
  251.     return NOERR ;
  252. }
  253.  
  254. /* rectangle 2 */
  255. rectangle_2nd()
  256. {
  257.     EGB_color(ework,0,color);
  258.     EGB_paintMode(ework,0x2);
  259.     EGB_writeMode(ework,4);
  260.  
  261.     WORD(para + 0) = ax1;
  262.     WORD(para + 2) = ay1;
  263.     WORD(para + 4) = ax2;
  264.     WORD(para + 6) = ay2;
  265.     EGB_rectangle(ework,para);
  266.  
  267.     EGB_writeMode(ework,0);
  268.     EGB_paintMode(ework,0x222);
  269.  
  270.     return NOERR ;
  271. }
  272.  
  273. /* read */
  274. polygon_rectangle_read( int x, int y )
  275. {
  276.     int add ;
  277.  
  278.     if( (x < 0) || (x >= xlen) )return 0 ;
  279.     if( (y < 0) || (y >= ylen) )return 0 ;
  280.  
  281.     add = xlen * y + x ;
  282.  
  283.     if( BYTE( buffer + (add >> 3) ) & ( 0x80 >> (add % 8) ) )
  284.         return 1 ;
  285.     else
  286.         return 0 ;
  287. }
  288.  
  289. /* polygon buffer clear */
  290. polygon_rectangle_clear()
  291. {
  292.     int i, n ;
  293.  
  294.     n = (xlen*ylen) >> 3 ;
  295.     for( i=0 ; i<n ; i++ )
  296.         BYTE( buffer + i ) = 0 ;
  297.  
  298.     return NOERR ;
  299. }
  300.  
  301. static polygonDispLine( n )
  302. {
  303.     EGB_color(ework,0,color);
  304.     EGB_paintMode(ework,0x222);
  305.     EGB_writeMode(ework,4);
  306.  
  307.     WORD(para + 0) = 2;
  308.     WORD(para + 2) = poly[n][0];
  309.     WORD(para + 4) = poly[n][1];
  310.     WORD(para + 6) = poly[n+1][0];
  311.     WORD(para + 8) = poly[n+1][1];
  312.     EGB_unConnect(ework,para);
  313.  
  314.     WORD(para + 0) = 2;
  315.     WORD(para + 2) = poly[n+1][0];
  316.     WORD(para + 4) = poly[n+1][1];
  317.     WORD(para + 6) = poly[n+1][0];
  318.     WORD(para + 8) = poly[n+1][1];
  319.     EGB_unConnect(ework,para);
  320.  
  321.     EGB_writeMode(ework,0);
  322.     return NOERR ;
  323. }
  324.  
  325. static polygonBufOrLine( n )
  326. {
  327.     int i, count ;
  328.     int x0, y0, x1, y1, xd, yd ;
  329.     int absxd, absyd ;
  330.     double xadd, yadd ;
  331.     double xdouble, ydouble ;
  332.  
  333.     x0 = poly[n][0];
  334.     y0 = poly[n][1];
  335.     x1 = poly[n+1][0];
  336.     y1 = poly[n+1][1];
  337.  
  338.     xd = x1 - x0 ;
  339.     yd = y1 - y0 ;
  340.  
  341.     if( xd > 0 )
  342.         absxd = xd ;
  343.     else
  344.         absxd = - xd ;
  345.  
  346.     if( yd > 0 )
  347.         absyd = yd ;
  348.     else
  349.         absyd = - yd ;
  350.  
  351.     if( (absxd == 0) && (absyd == 0) )
  352.     {
  353.         int add ;
  354.  
  355.         add = xlen*y0 + x0 ;
  356.         BYTE( buffer + (add >> 3) )
  357.         = BYTE( buffer + (add >> 3) ) | ( 0x80 >> (add % 8) ) ;
  358.  
  359.         return NOERR ;
  360.     }
  361.  
  362.     if( absxd >= absyd )
  363.     {
  364.         yadd = (double)yd / (double)xd ;
  365.         if( xd > 0 )
  366.             xadd = 1 ;
  367.         else
  368.         {
  369.             xadd = - 1 ;
  370.             yadd = - yadd ;
  371.         }
  372.         count = absxd ;
  373.     }
  374.     else
  375.     {
  376.         xadd = (double)xd / (double)yd ;
  377.         if( yd > 0 )
  378.             yadd = 1 ;
  379.         else
  380.         {
  381.             yadd = - 1 ;
  382.             xadd = - xadd ;
  383.         }
  384.         count = absyd ;
  385.     }
  386.  
  387.     xdouble = x0 ;
  388.     ydouble = y0 ;
  389.     for( i=0 ; i<count ; i++ )
  390.     {
  391.         int x, y, add ;
  392.  
  393.         x = xdouble + .5 ;
  394.         y = ydouble + .5 ;
  395.  
  396.         add = xlen*y + x ;
  397.         if( add < (xlen * ylen) )
  398.             BYTE( buffer + (add >> 3) )
  399.             = BYTE( buffer + (add >> 3) ) | ( 0x80 >> (add % 8) ) ;
  400.  
  401.         xdouble += xadd ;
  402.         ydouble += yadd ;
  403.     }
  404.  
  405.     return NOERR ;
  406. }
  407.  
  408. static polygonBufConnect( y1, y2 )
  409. {
  410.     int i, n1, n2, k, d, e ;
  411.  
  412.     n1 = xlen*y1 ;
  413.     n2 = xlen*( y2 + 1 ) ;
  414.     k = 0 ;
  415.  
  416.     for( i=n1 ; i<n2 ; i++ )
  417.     {
  418.         d = BYTE( buffer + (i >> 3) ) ;
  419.         e = 0x80 >> (i % 8) ;
  420.         if( d & e )
  421.             k ^= 1 ;
  422.         if( k )
  423.             BYTE( buffer + (i >> 3) ) = d | e ;
  424.     }
  425.  
  426.     return NOERR ;
  427. }
  428.  
  429. static int swmemory, cxmemory, cymemory ;
  430.  
  431. /* マウスイニシャライズ */
  432.  
  433. static int mouseInit()
  434. {
  435.     swmemory = -100000 ;
  436.     cxmemory = -100000 ;
  437.     cymemory = -100000 ;
  438.     return NOERR ;
  439. }
  440.  
  441. /*
  442.    backmode 0:マウスボタン開放時にreturn 1:マウスボタン押した時にreturn
  443.    dspmode 0:なにも表示しない 1:コネクトラインを表示
  444.    戻り値 0:ダブルクリックでない 1:ダブルクリックである
  445. */
  446.  
  447. static int mouse( int backmode, int dspmode )        /* mouse */
  448. {
  449.     int x,y,cx0,cy0,mdsp,dummy;
  450.     int doubleClick, ret ;
  451.  
  452.     EGB_color(ework,0,color);
  453.     EGB_paintMode(ework,0x222);
  454.     EGB_writeMode(ework,4);
  455.  
  456.     cx0 = -1; cy0 = -1; mdsp = 1; dummy = -1; doubleClick = 0 ;
  457.     if( mdsp ){
  458.         MOS_rdpos(&sw,&cx0,&cy0);
  459.         setDisplay( cx0, cy0 ) ;
  460.         if( dspmode )mousesub(dspmode,cx,cy,cx0,cy0);
  461.     }    
  462. mouse1:
  463.     MOS_rdpos(&sw,&x,&y);
  464.     setDisplay( x, y ) ;
  465.     if( sw )goto mouse2;
  466.     if( doubleClick == 0 )doubleClick = 1 ;
  467.     if( (cx0 == x) && (cy0  == y) )goto mouse1;
  468.     doubleClick = -1 ;
  469.     if( mdsp == 0 ){
  470.         cx0 = x;
  471.         cy0 = y;
  472.     }
  473.     if( dspmode )mousesub(dspmode,cx,cy,cx0,cy0);
  474.     mdsp = mdsp ^ 1;
  475.     goto mouse1;
  476. mouse2:
  477.     if( mdsp && dspmode )mousesub(dspmode,cx,cy,cx0,cy0);
  478.  
  479.     if(
  480.         (doubleClick > 0) && (x == cxmemory) && (y == cymemory) &&
  481.         (sw == 1) && (swmemory == 1)
  482.     )
  483.         ret = 1 ;
  484.     else
  485.         ret = 0 ;
  486.  
  487.     swmemory = sw ;
  488.     if( doubleClick )
  489.     {
  490.         cxmemory = x ;
  491.         cymemory = y ;
  492.     }
  493.     else if( (cx != x) || (cy != y) )
  494.     {
  495.         cxmemory = -100000 ;
  496.         cymemory = -100000 ;
  497.     }
  498.  
  499.     cx = x;
  500.     cy = y;
  501.     if( backmode )goto mouse3;
  502.     while( dummy ){
  503.         MOS_rdpos(&dummy,&x,&y);
  504.         setDisplay( x, y ) ;
  505.     }
  506.  
  507. mouse3:
  508.     EGB_writeMode(ework,0);
  509.     return ret ;
  510. }
  511.  
  512. static mousesub(int dspmode,int cx,int cy,int cx0,int cy0)    /* 特殊カーソル */
  513. {
  514.     switch( dspmode ){
  515.         case 0:
  516.             break;
  517.         case 1:
  518.             WORD(para + 0) = 2;
  519.             WORD(para + 2) = cx;
  520.             WORD(para + 4) = cy;
  521.             WORD(para + 6) = cx0;
  522.             WORD(para + 8) = cy0;
  523.             EGB_unConnect(ework,para);
  524.             break;
  525.         }
  526.     return 0;
  527. }
  528.  
  529. /* BOX用マウス */
  530.  
  531. static int boxMouse()
  532. {
  533.     int x,y,cx0,cy0,mdsp;
  534.     int ret ;
  535.  
  536.     EGB_color(ework,0,color);
  537.     EGB_paintMode(ework,0x2);
  538.     EGB_writeMode(ework,4);
  539.  
  540.     cx0 = -1; cy0 = -1; mdsp = 1; ret = 0 ;
  541.     if( mdsp ){
  542.         MOS_rdpos(&sw,&cx0,&cy0);
  543.         if( sw > 1 )ret = -1 ;
  544.         boxMousesub(cx,cy,cx0,cy0);
  545.         setDisplay( cx0, cy0 ) ;
  546.     }    
  547. mouse1:
  548.     MOS_rdpos(&sw,&x,&y);
  549.     if( sw == 0 )goto mouse2;
  550.     if( sw > 1 )ret = -1 ;
  551.     if( (cx0 == x) && (cy0  == y) )goto mouse1;
  552.     if( mdsp == 0 ){
  553.         cx0 = x;
  554.         cy0 = y;
  555.     }
  556.     boxMousesub(cx,cy,cx0,cy0);
  557.     setDisplay( cx0, cy0 ) ;
  558.     mdsp = mdsp ^ 1;
  559.     goto mouse1;
  560. mouse2:
  561.     if( ret )
  562.     {
  563.         if( mdsp )boxMousesub(cx,cy,cx0,cy0);
  564.         setDisplay( cx0, cy0 ) ;
  565.     }
  566.     else
  567.     {
  568.         if( mdsp == 0 )boxMousesub(cx,cy,cx0,cy0);
  569.         setDisplay( cx0, cy0 ) ;
  570.     }
  571.  
  572.     cx = cx0;
  573.     cy = cy0;
  574.  
  575. mouse3:
  576.     EGB_writeMode(ework,0);
  577.     EGB_paintMode(ework,0x222);
  578.     return ret ;
  579. }
  580.  
  581. static boxMousesub(int cx,int cy,int cx0,int cy0)    /* BOXカーソル */
  582. {
  583.     WORD(para + 0) = cx;
  584.     WORD(para + 2) = cy;
  585.     WORD(para + 4) = cx0;
  586.     WORD(para + 6) = cy0;
  587.     EGB_rectangle(ework,para);
  588.     return 0;
  589. }
  590.  
  591. /* fixRectangle lx, lyの大きさの長方形の左上座標のみの指定 */
  592. fixRectangle_1st( int lx, int ly, int *lux, int *luy )
  593. {
  594.     int x,y,mdsp,cx0,cy0;
  595.     int ret ;
  596.  
  597.     if( initFlag == 0 )return -1 ;
  598.  
  599.     MOS_rdpos(&sw,&cx,&cy);    /* この場におよんで押してないのはやる気なし */
  600.     if( sw != 1 )
  601.     {
  602.         return -1 ;
  603.     }
  604.  
  605.     EGB_color(ework,0,color);
  606.     EGB_paintMode(ework,0x2);
  607.     EGB_writeMode(ework,4);
  608.  
  609.     cx0 = -1; cy0 = -1; mdsp = 1; ret = 0 ;
  610.     if( mdsp ){
  611.         MOS_rdpos(&sw,&cx0,&cy0);
  612.         if( sw > 1 )ret = -1 ;
  613.         boxMousesub( cx0,cy0,cx0+lx-1,cy0+ly-1 );
  614.         setDisplay( cx0, cy0 ) ;
  615.     }    
  616. mouse1:
  617.     MOS_rdpos(&sw,&x,&y);
  618.     if( sw == 0 )goto mouse2;
  619.     if( sw > 1 )ret = -1 ;
  620.     if( (cx0 == x) && (cy0  == y) )goto mouse1;
  621.     if( mdsp == 0 ){
  622.         cx0 = x;
  623.         cy0 = y;
  624.     }
  625.     boxMousesub( cx0,cy0,cx0+lx-1,cy0+ly-1 );
  626.     if( mdsp )    /* 交互にディスプレイ内に入れる */
  627.         setDisplay( cx0, cy0 ) ;
  628.     else
  629.         setDisplay( cx0+lx, cy0+ly ) ;
  630.     mdsp = mdsp ^ 1;
  631.     goto mouse1;
  632. mouse2:
  633.     if( ret )
  634.     {    /* ボックスカーソル消し */
  635.         if( mdsp )boxMousesub( cx0,cy0,cx0+lx-1,cy0+ly-1 );
  636.         setDisplay( cx0, cy0 ) ;
  637.     }
  638.     else
  639.     {    /* ボックスカーソル消し */
  640.         if( mdsp )boxMousesub( cx0,cy0,cx0+lx-1,cy0+ly-1 );
  641.         setDisplay( cx0, cy0 ) ;
  642.     }
  643.  
  644.     *lux = cx0 ; *luy = cy0 ;
  645.  
  646. mouse3:
  647.     EGB_writeMode(ework,0);
  648.     EGB_paintMode(ework,0x222);
  649.  
  650.     return ret ;
  651. }
  652.  
  653.