home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1997 March / VPR9703A.ISO / VPR_DATA / DOGA / SOURCES / REND.LZH / REND / DISPLAY.C < prev    next >
C/C++ Source or Header  |  1995-11-13  |  15KB  |  696 lines

  1. /*
  2. *
  3. *        画面表示
  4. *
  5. *            CopyRight    T.Kobayashi
  6. *            1989.4.28
  7. */
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <assert.h>
  12.  
  13. #include "reader.h"
  14. #include "glib.h"
  15.  
  16. #define ERROR_LEVEL 200L
  17.  
  18. typedef enum _EdgeStaus {
  19.     STAT_WAIT,
  20.     STAT_LEFTEDGE,
  21.     STAT_CENTER,
  22.     STAT_CURRENT,
  23.     STAT_TRANS
  24. }
  25.     EdgeStatus ;
  26.  
  27. typedef struct    {
  28.             EdgeStatus    stat ;
  29.             short        startx, xcount ;
  30.             long        z, dzdx ;
  31.             char        traflag ;
  32.             unsigned char        tra[3] ;
  33.             ColorCode    code ;
  34.             ShadeTable    shade ;
  35.             MapTable    map ;
  36.     }
  37.         ActiveBuf ;
  38.  
  39. #define    FLAT_ACTIVE_SIZE    ( sizeof( ActiveBuf ) - sizeof( ShadeTable ) \
  40.                             - sizeof( MapTable ) )
  41. #define    GOURAUD_ACTIVE_SIZE    ( sizeof( ActiveBuf ) )
  42. #define    active_comp( a1, a2 )    ( (long)(a1) - (long)(a2) )
  43.  
  44. #if defined(X68000) || defined(DJ) || defined(UNIX) || defined(__WIN32__)
  45.     #define    _inc_active( ac )        (char*)ac += sizeof_active
  46. #elif defined(MSC) || defined(__BORLANDC__)
  47.     #define    _inc_active( ac )\
  48.         {\
  49.             ac = (Pointer(ActiveBuf*))( (char*)ac + sizeof_active );\
  50.             nomalize_pointer( ac );\
  51.         }
  52. #else
  53.     #error "MACHINE TYPE UNKNOWN!"
  54. #endif    /* MSC */
  55.  
  56. #ifdef    VIRTUAL
  57.     #define    inc_active( ac )                            \
  58.         {                                                \
  59.             if ( virtualmode )                             \
  60.                 ac = virarynext( ac, sizeof_active );    \
  61.             else                                        \
  62.                 _inc_active( ac );                        \
  63.         }
  64. #else
  65.     #define    inc_active( ac )    _inc_active( ac )
  66. #endif    /* VIRTUAL */
  67.  
  68.  
  69. static    Pointer(EdgeList*)        ae ;                /*    アクティブエッジリスト        */
  70. static    ColorCode    *framebuf = NULL ;    /*    フレームバッファ            */
  71. static    ColorCode    back ;                /*    バックのカラーコード        */
  72. static    Pointer(ActiveBuf*)        active = NULL ;        /*    アクティブエッジバッファ    */
  73. static    int            activecount = 0 ;    /*  アクティブバッファ数        */
  74. static    int            sizeof_active;        /*  アクティブバッファのサイズ  */
  75. static    Pointer(void*)        mark ;                /*  マーク                        */
  76.  
  77.  
  78.  
  79. /*
  80.     proto -s display.c > temp
  81. */
  82. static    void    scanline( int );
  83. static    Pointer(ActiveBuf*)    initactivebuf( int );
  84. static    ColorCode    transparent( int, Pointer(ActiveBuf*), Pointer(ActiveBuf*), Pointer(ActiveBuf*) );
  85. static    EdgeList    *getedge( EdgeList* );
  86. static    void    DDAinc( DDA* );
  87.  
  88. /*        表示ルーチン    */
  89. void    Display( frame, n )
  90. Frame    *frame ;
  91. int        n ;            /*    プリミティブの数  */
  92. {
  93.     int            x, y, edgelock ;
  94.     REGISTER    int            edgenum, flag ;
  95.     REGISTER    Pointer(EdgeList*)        *pp;
  96.     REGISTER    Pointer(EdgeList*)        p1;
  97.     REGISTER    Pointer(EdgeList*)    p2 ;
  98.     REGISTER    EdgeList    *edge1, *edge2 ;
  99.  
  100.     if ( ShadingModel == GOURAUD_SHADE )
  101.         sizeof_active = GOURAUD_ACTIVE_SIZE ;
  102.     else
  103.         sizeof_active = FLAT_ACTIVE_SIZE ;
  104.  
  105.     /*    アクティブエッジリストの初期化 */
  106.     ae = NULL ;
  107.     edgenum = 0 ;
  108.     activecount = 0 ;
  109.     mark = datamark();
  110.     /*    フレームバッファ確保  */
  111.     if ( framebuf == NULL )
  112.         framebuf = (ColorCode*)tempalloc( sizeof( ColorCode ) * XPixel );
  113.  
  114.     /*    バックの計算  */
  115.     if ( BackLoad )
  116.     {
  117.         BackOpen( BackFile );
  118.     }
  119.     else
  120.     {
  121. #ifdef FULLCOLOR
  122.         back = ColorToCode( frame->env.back ) & 0xf8f8f8ffL;
  123. #else
  124.         back = ColorToCode( frame->env.back ) ;
  125. #endif
  126.         if ( back == 0 || TraBack )
  127.             back += 255 ;
  128.     }
  129.  
  130.     /*    メインループ  */
  131.     for( y = 0 ; y < YPixel ; ++y )
  132.     {
  133.         /*    アクティブエッジリストの追加  */
  134.         for( p1 = EdgeBuf[y] ; p1 != NULL ; p1 = p2 )
  135.         {
  136.             edge1 = (EdgeList*)pointer( p1 );
  137.             edgelock = datalock();
  138.             p2 = edge1->next ;
  139.             x = edge1->dxdy.x ;
  140.             pp = & ae ;
  141.             while( *pp != NULL )
  142.             {
  143.                 edge2 = pointer( *pp );
  144.                 if ( edge2->dxdy.x > x )
  145.                     break ;
  146.                 pp = &( edge2->next );
  147.             }
  148.             edge1->next = *pp ;
  149.             *pp = p1 ;
  150.             dataunlock( edgelock );
  151.             edgenum ++ ;
  152.         }
  153.  
  154.         /*    描画  */
  155.         scanline( edgenum ) ;
  156.  
  157.         /*    アクティブエッジリストの更新、削除    */
  158.         pp = & ae ;
  159.         edgelock = -1 ;
  160.         while( *pp != NULL )
  161.         {
  162.             edge1 = pointer( *pp );
  163.             if ( -- ( edge1->n ) == 0 )
  164.             {
  165.                 *pp = edge1->next ;
  166.                 edgenum -- ;
  167.             }
  168.             else
  169.             {
  170.                 /*    x,z座標の更新  */
  171.                 DDAinc( &( edge1->dxdy ) );
  172.                 edge1->z += edge1->dzdy ;
  173.                 if ( ShadingModel == GOURAUD_SHADE )
  174.                 {
  175.                     if ( edge1->mapflag )
  176.                         IncAtrTable( &( edge1->shade ), &( edge1->map ) );
  177.                     else
  178.                         IncAtrTable( &( edge1->shade ), NULL );
  179.                 }
  180. #ifdef VIRTUAL
  181.                 if ( edgelock != -1 )
  182.                     dataunlock( edgelock );
  183.                 edgelock = datalock();
  184. #endif
  185.                 pp = &( edge1->next );
  186.             }
  187.         }
  188. #ifdef VIRTUAL
  189.         if ( edgelock != -1 )
  190.             dataunlock( edgelock );
  191. #endif
  192.         /*    アクティブエッジリストのソート    */
  193.         if ( ae != NULL )
  194.         {
  195.             flag = TRUE ;
  196.             while( flag )
  197.             {
  198.                 flag = FALSE ;
  199.                 pp = & ae ;
  200.                 edge1 = pointer( *pp );
  201.                 while( edge1->next != NULL )
  202.                 {
  203.                     p2 = edge1->next ;
  204.                     edge2 = pointer( p2 );
  205.                     if ( edge1->dxdy.x > edge2->dxdy.x )
  206.                     {
  207.                         /*    入れ替え  */
  208.                         flag = TRUE ;
  209.                         edge1->next = edge2->next ;
  210.                         edge2->next = *pp ;
  211.                         *pp = p2 ;
  212.                     }
  213.                     else
  214.                         pp = &( edge1->next );
  215.                     edge1 = pointer( *pp );
  216.                 }
  217.             }
  218.         }
  219.     }
  220.  
  221.     if ( BackLoad )
  222.         BackClose();
  223. }
  224.  
  225. /*        描画ルーチン    */
  226. static    void    scanline( edgenum )
  227. int        edgenum ;
  228. {
  229.     int            i, n ;
  230.     int            px ;
  231.     Pointer(ActiveBuf*)        start;
  232.     Pointer(ActiveBuf*)        end;
  233.     Pointer(ActiveBuf*)        bufend;
  234.     REGISTER    long        z, dzdx ;
  235.     REGISTER    Pointer(ActiveBuf*)        pac;
  236.     REGISTER    Pointer(ActiveBuf*)        maxac ;
  237.     REGISTER    ActiveBuf    *ac ;
  238.  
  239.     /*  背景処理  */
  240.     if ( BackLoad )
  241.     {
  242.         BackCopy( framebuf );
  243.     }
  244.     else
  245.     {
  246.         for( i = 0 ; i < XPixel ; ++i )
  247.             framebuf[i] = back ;
  248.     }
  249. #ifdef STAR
  250.     StarCopy(framebuf);
  251. #endif
  252.     if ( edgenum == 0 )
  253.     {
  254.         (*PictureOutput)( framebuf );
  255.         return ;
  256.     }
  257.  
  258.     /*  バッファの初期化  */
  259.     assert( ( edgenum % 2 ) == 0 );
  260.     if ( edgenum / 2 + 1 > activecount )
  261.     {
  262.         if ( activecount > 0 )
  263.             datarelease( mark );
  264.         activecount = edgenum / 2 + 1 ;
  265.         active = dataaryalloc( activecount, sizeof_active );
  266.     }
  267.     bufend = initactivebuf( edgenum );
  268.  
  269.     /*    メインループ    */
  270.     start = active ;
  271.     end = active ;
  272.     for( px = 0 ; px < XPixel ; ++px )
  273.     {
  274.         /*  削除  */
  275.         pac = start ;
  276.         while( active_comp( pac, end ) < 0L )
  277.         {
  278.             ac = pointer( pac );
  279.             if ( ac->stat != STAT_WAIT )
  280.             {
  281.                 if ( -- (ac->xcount) == 0 )
  282.                 {
  283.                     ac->stat = STAT_WAIT ;
  284.                     if ( start == pac )
  285.                     {
  286.                         do
  287.                         {
  288.                             inc_active( pac );
  289.                             ac = pointer( pac );
  290.                         }
  291.                         while( ac->stat == STAT_WAIT &&
  292.                                             active_comp( pac, end ) < 0L );
  293.                         start = pac ;
  294.                         continue ;
  295.                     }
  296.                 }
  297.                 else
  298.                     ac->z += ac->dzdx ;
  299.             }
  300.             inc_active( pac );
  301.         }
  302.  
  303.         /*  登録  */
  304.         ac = pointer( pac );
  305.         while( ac->startx == px && active_comp( pac, bufend ) < 0L )
  306.         {
  307.             ac->stat = STAT_LEFTEDGE ;
  308.             inc_active( pac );
  309.             ac = pointer( pac );
  310.         }
  311.         end = pac ;
  312.  
  313.         /*    表示色決定    */
  314.         z = 0L ;
  315.         dzdx = 0L ;
  316.         pac = start ;
  317.         while( active_comp( pac, end ) < 0L )
  318.         {
  319.             ac = pointer( pac );
  320.             switch( ac->stat )
  321.             {
  322.                 case STAT_LEFTEDGE :
  323.                     ac->stat = STAT_CENTER ;
  324.                     if ( ( ac->z - ERROR_LEVEL > z ) ||
  325.                          ( ac->z + ERROR_LEVEL > z &&
  326. /*                           ac->z + ac->dzdx > z + dzdx ) )*/
  327.                            ac->dzdx > dzdx ) )
  328.                     {                        z = ac->z ;
  329.                         dzdx = ac->dzdx ;
  330.                         maxac = pac ;
  331.                     }
  332.                     break ;
  333.                 case STAT_TRANS :
  334.                 case STAT_CURRENT :
  335.                     (int)(ac->stat) -- ;
  336.                 case STAT_CENTER :
  337.                     if ( ac->z > z )
  338.                     {
  339.                         z = ac->z ;
  340.                         dzdx = ac->dzdx ;
  341.                         maxac = pac ;
  342.                     }
  343.                     break ;
  344.             }
  345.             inc_active( pac );
  346.         }
  347.         if ( z != 0L )
  348.         {
  349.             ac = pointer( maxac );
  350.             if ( ac->traflag || ( ShadingModel == GOURAUD_SHADE && ac->map.map != NULL ) )
  351.             {
  352.                 /*  半透明処理  */
  353.                 framebuf[px] = transparent( px, maxac, start, end );
  354.             }
  355.             else
  356.             {
  357.                 if ( ShadingModel == GOURAUD_SHADE )
  358.                 {
  359.                     if ( ac->stat != STAT_CURRENT )
  360.                         AddAtrTable( &(ac->shade), &(ac->map), px - ac->startx );
  361. #ifdef SPEC
  362.                     framebuf[px] = GetColorAllCode( &(ac->shade), &(ac->map) );
  363. #else
  364.                     framebuf[px] = GetColorCode( &(ac->shade), &(ac->map) );
  365. #endif
  366.                     /*  バッファの更新  */
  367.                     IncAtrTable( &(ac->shade), &(ac->map) );
  368.                     ac->stat = STAT_TRANS ;
  369.                     ac->startx = px + 1 ;
  370. #if 0
  371.  
  372. #ifdef SPEC
  373.                     framebuf[px] = GetColorAllCode( &(ac->shade), &(ac->map) );
  374. #else
  375.                     framebuf[px] = GetColorCode( &(ac->shade), &(ac->map) );
  376. #endif
  377.                     /*  バッファの更新  */
  378.                     if ( ac->stat == STAT_CURRENT )
  379.                     {
  380.                         IncAtrTable( &(ac->shade), &(ac->map) );
  381.                     }
  382.                     else
  383.                     {
  384.                         AddAtrTable( &(ac->shade), &(ac->map),
  385.                                                 px - ac->startx + 1 );
  386.                     }
  387.                     ac->stat = STAT_TRANS ;
  388.                     ac->startx = px + 1 ;
  389. #endif
  390.                 }
  391.                 else
  392.                     framebuf[px] = ac->code ;
  393.             }
  394.         }
  395.     }
  396.  
  397.     /*    画面出力  */
  398.     (*PictureOutput)( framebuf );
  399. }
  400.  
  401. /*    アクティブエッジバッファの初期化    */
  402. static    Pointer(ActiveBuf*)    initactivebuf( edgenum )
  403. int        edgenum ;
  404. {
  405.     int            n, edgelock, aclock ;
  406.     REGISTER    int            i, dx ;
  407.     REGISTER    Pointer(EdgeList*) p;
  408.     REGISTER    Pointer(ActiveBuf*) pac ;
  409.     REGISTER    EdgeList    *edge1, *edge2 ;
  410.     REGISTER    ActiveBuf    *ac ;
  411.  
  412.     pac = active ;
  413.     n = 0 ;
  414.     for( p = ae ; p != NULL ; p = edge1->next )
  415.     {
  416.         ac = pointer( pac );
  417.         aclock = datalock();
  418.         edge1 = pointer( p );
  419.         if ( edge1->flag == FALSE )
  420.         {
  421.             edgelock = datalock();
  422.             edge2 = getedge( edge1 );
  423.             edge2->flag = TRUE ;
  424.             dx = edge2->dxdy.x - edge1->dxdy.x ;
  425.             if ( dx == 0 )
  426.             {
  427.                 dataunlock( edgelock );
  428.                 dataunlock( aclock );
  429.                 continue ;
  430.             }
  431.             ac->stat = STAT_WAIT ;
  432.             ac->startx = edge1->dxdy.x ;
  433.             ac->xcount = dx ;
  434.             ac->z = edge1->z ;
  435.             ac->dzdx = ( edge2->z - edge1->z + dx / 2 ) / dx ;
  436.             ac->traflag = edge2->traflag ;
  437.             for( i = 0 ; i < 3 ; ++i )
  438.                 ac->tra[i] = edge1->tra[i] ;
  439.  
  440.             if ( ShadingModel == GOURAUD_SHADE )
  441.             {
  442.                 ac->shade = edge1->shade ;
  443.                 if ( edge1->mapflag)
  444.                     ac->map = edge1->map ;
  445.                 else
  446.                     ac->map.map = NULL ;
  447.                 if ( dx != 0 )
  448.                 {
  449.                     SetAtrStep( &( ac->shade ), &( edge2->shade ),
  450.                                 &( ac->map ),   &( edge2->map ), dx );
  451. #ifdef EXTENDMAP
  452.                     if (edge1->mapflag) {
  453.                         SetAtrStepMap(ac->z, edge2->z,
  454.                                 &( ac->map ),   &( edge2->map ), dx );
  455.                     }
  456. #endif
  457.                 }
  458.             }
  459.             else
  460.                 ac->code = edge1->code ;
  461.             inc_active( pac );
  462.             dataunlock( edgelock );
  463.             n ++ ;
  464.         }
  465.         else
  466.             edge1->flag = FALSE ;
  467.         dataunlock( aclock );
  468.     }
  469.     assert( n <= edgenum / 2 );
  470.     return( pac );
  471. }
  472.  
  473. /*    半透明処理    */
  474. static    ColorCode    transparent( px, maxac, start, end )
  475. int            px ;
  476. Pointer(ActiveBuf*)    start;
  477. Pointer(ActiveBuf*)    end ;
  478. REGISTER    Pointer(ActiveBuf*)        maxac ;
  479. {
  480.     int        i ;
  481. #ifdef SPEC
  482.     ColorCode    cc, spec;
  483.     unsigned short code[4], tmpcode;
  484. #else
  485.     REGISTER    ColorCode    code, cc ;
  486. #endif
  487.     REGISTER    long    z ;
  488.     REGISTER    ActiveBuf    *ac ;
  489.     REGISTER    Pointer    (ActiveBuf*)    pac ;
  490.     static    unsigned char    tra[3] ;
  491.     static    int        shift[] = { 16, 24, 8, 0} ;    /*    r g b のシフト数        */
  492.     int maptra;
  493. #define COLORBITS 8
  494.     tra[0] = tra[1] = tra[2] = 128;
  495. #ifdef SPEC
  496.     code[0] = 0; code[1] = 0; code[2] = 0; code[3] = 0;
  497. #else
  498.     code = 0 ;
  499. #endif
  500.     for(;;)
  501.     {
  502.         ac = pointer( maxac );
  503.         if ( ShadingModel == GOURAUD_SHADE )
  504.         {
  505.             if ( ac->stat != STAT_CURRENT )
  506.                 AddAtrTable( &(ac->shade), &(ac->map), px - ac->startx );
  507.  
  508.             cc = GetColorCode( &(ac->shade), &(ac->map) );
  509. #ifdef SPEC
  510.             spec = GetSpecularColorCode( &(ac->shade));
  511. #endif
  512.             /*  バッファの更新  */
  513.             IncAtrTable( &(ac->shade), &(ac->map) );
  514.             ac->startx = px + 1 ;
  515. #if 0
  516.             cc = GetColorCode( &(ac->shade), &(ac->map) );
  517. #ifdef SPEC
  518.             spec = GetSpecularColorCode( &(ac->shade), &(ac->map) );
  519. #endif
  520.             /*  バッファの更新  */
  521.             if ( ac->stat == STAT_CURRENT )
  522.                 IncAtrTable( &(ac->shade), &(ac->map) );
  523.             else
  524.                 AddAtrTable( &(ac->shade), &(ac->map),
  525.                                         px - ac->startx + 1 );
  526.             ac->startx = px + 1 ;
  527. #endif
  528.         }
  529.         else
  530.         {
  531.             cc = ac->code ;
  532. #ifdef SPEC
  533.             spec = 0;
  534. #endif
  535.         }
  536.         ac->stat = STAT_TRANS ;
  537.  
  538.         if ((ShadingModel != GOURAUD_SHADE || ac->map.map == NULL)
  539.          || (cc & 255) != 255) {
  540.             if ((maptra = (int)(cc & 255U)) > 128) {
  541.                 maptra++;
  542.             }
  543.             for( i = 0 ; i < 3 ; ++i )
  544.             {
  545. #ifdef SPEC
  546.                 long plus;
  547. #if 0
  548.                 plus =
  549.                     (
  550.                         ( ( (long)cc >> shift[i] ) & 255 )
  551.                         * (long)tra[i] * ( 128 - (long)ac->tra[i] )
  552.                         * (256-maptra) / (long)(128*128*256)
  553.  
  554.                     ) + (
  555.                         ( ( (long)spec >> shift[i]) & 255)
  556.                         * (long)tra[i] / (long)(128)
  557.                     );
  558. #else
  559.                 plus =
  560.                     (
  561.                         ( ( (long)cc >> shift[i] ) & 255 )
  562.                         * (long)tra[i] * ( 128 - (long)ac->tra[i] )
  563.                         / (long)(128*128)
  564.  
  565.                     ) + (
  566.                         ( ( (long)spec >> shift[i]) & 255)
  567.                         * (long)tra[i] / (long)(128)
  568.                     );
  569. #endif
  570.                 if (ac->shade.depthrate > 0) {
  571.                     plus = ( plus * (SHADE_POINT - ac->shade.depthrate)
  572.                          + (ac->shade.depthcolor[i] >> (SHADE_SHIFT - COLORBITS))
  573.                          * ac->shade.depthrate / 128 * tra[i]) / SHADE_POINT;
  574.                 }
  575.                 code[i] += (unsigned short)plus;
  576. #else
  577. #if 0
  578.                 code +=
  579.                     (
  580.                         ( ( (long)cc >> shift[i] ) & 255 )
  581.                         * (long)tra[i] * ( 128 - (long)ac->tra[i] )
  582.                         * (256-maptra) / (long)(128*128*256)
  583.                     ) << (long)shift[i] ;
  584. #else
  585.                 code +=
  586.                     (
  587.                         ( ( (long)cc >> shift[i] ) & 255 )
  588.                         * (long)tra[i] * ( 128 - (long)ac->tra[i] )
  589.                         / (long)(128*128)
  590.                     ) << (long)shift[i] ;
  591. #endif
  592. #endif
  593.                 tra[i] = (int)tra[i] *
  594.                          ((int)ac->tra[i] * 256 + (128 - (int)ac->tra[i]) * maptra)
  595.                        / (128*256);
  596.             }
  597.         }
  598.         if ( ! ( tra[0] || tra[1] || tra[2] ) )
  599. #ifdef SPEC
  600.         {
  601.             for (i = 0; i < 3; ++i) {
  602.                 if (code[i] > 255)    code[i] = 255;
  603.             }
  604.             return( (code[0] << shift[0])
  605.                   + (code[1] << shift[1])
  606.                   + (code[2] << shift[2]));
  607.         }
  608. #else
  609.             return( code );
  610. #endif
  611.  
  612.         z = 0L ;
  613.         maxac = NULL ;
  614.         pac = start ;
  615.         while( active_comp( pac, end ) < 0L )
  616.         {
  617.             ac = pointer( pac );
  618.             if ( ac->stat != STAT_WAIT && ac->stat != STAT_TRANS )
  619.             {
  620.                 if ( ac->z > z )
  621.                 {
  622.                     z = ac->z ;
  623.                     maxac = pac ;
  624.                 }
  625.             }
  626.             inc_active( pac );
  627.         }
  628.         if ( maxac == NULL )
  629.         {
  630.             for( i = 0 ; i < 3 ; ++i )
  631.             {
  632. #ifdef SPEC
  633.                 code[i] +=
  634.                     (unsigned short)(
  635.                         ( ( (long)framebuf[px] >> shift[i] ) & 255 )
  636.                              * tra[i] / 128
  637.                     );
  638. #else
  639.                 code +=
  640.                     (ColorCode)(
  641.                         ( ( (long)framebuf[px] >> shift[i] ) & 255 )
  642.                              * tra[i] / 128
  643.                     ) << (long)shift[i] ;
  644. #endif
  645.             }
  646.  
  647. #ifdef SPEC
  648.             for (i = 0; i < 3; ++i) {
  649.                 if (code[i] > 255)    code[i] = 255;
  650.             }
  651.             return (code[0] << shift[0])
  652.                  + (code[1] << shift[1])
  653.                  + (code[2] << shift[2])
  654.                  + (framebuf[px] & 255) * (tra[0]+tra[1]) / 256;
  655. #else
  656.             code += (framebuf[px] & 255) * (tra[0]+tra[1]) / 256;
  657.             return( code );
  658. #endif
  659.         }
  660.     }
  661. }
  662.  
  663. /*    1辺からもう1辺を検索する    */
  664. static    EdgeList    *getedge( edge )
  665. REGISTER    EdgeList    *edge ;
  666. {
  667.     REGISTER    int        id ;
  668.     REGISTER    Pointer(EdgeList*)    p ;
  669.  
  670.     id = edge->polyid ;
  671.     p = edge->next ;
  672.     while( p != NULL )
  673.     {
  674.         edge = pointer( p );
  675.         if ( edge->polyid == id )
  676.             return( edge );
  677.         p = edge->next ;
  678.     }
  679.     assert( FALSE );
  680.     return NULL;
  681. }
  682.  
  683. /*    DDA のインクリメント    */
  684. static    void    DDAinc( dda )
  685. REGISTER    DDA        *dda ;
  686. {
  687.     dda->x += dda->dxdy ;
  688.     dda->totalmod += dda->mod ;
  689.     if ( dda->totalmod >= dda->dy )
  690.     {
  691.         dda->totalmod -= dda->dy ;
  692.         dda->x ++ ;
  693.     }
  694. }
  695.  
  696.