Subversion Repositories Kolibri OS

Rev

Rev 5939 | Rev 6126 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;
  2. ; We draw a triangle with various interpolations
  3. ;
  4. ; Порядок преобразований цветов вершин:
  5. ; ZBufferPoint.r -> r1 (+drdl_min or +drdl_max) -> or1 (+drdx) -> [pixel buffer]
  6. ; ZBufferPoint.g -> g1 (+dgdl_min or +dgdl_max) -> og1 (+dgdx) -> [pixel buffer]
  7. ; ZBufferPoint.b -> b1 (+dbdl_min or +dbdl_max) -> ob1 (+dbdx) -> [pixel buffer]
  8. ;
  9. ; В некоторых случаях значения цвета (во 2-м байте переменных: or1,og1,ob1)
  10. ; может становиться < 0 или > 255, тогда появляються пиксели не правильного
  11. ; цвета. Скорее всего это связано с ошибками округления дробных чисел,
  12. ; при вычислении коэфициентов для плавного перехода цвета.
  13. ;
  14. ; Для лечения этой проблемы в версии на C++ специально ограничиваються
  15. ; минимальные и максимальные значения цвета точек (например от 3 до 252).
  16. ; Потому цвета граней могут немного отличаться от указанных в программе.
  17. ;
  18. ; В даной версии алгоритм немного другой. В наиболее вероятных местах появления
  19. ; пикселей не правильного цвета (обычно начало и конец линии) иправляеться
  20. ; цвет испорченных пикселей. Цвет получаеться наиболее близким к указанному
  21. ; пользователем.
  22.  
  23.         pr1 dd ? ;ZBufferPoint*
  24.         pr2 dd ? ;ZBufferPoint*
  25.         l1 dd ? ;ZBufferPoint*
  26.         l2 dd ? ;ZBufferPoint*
  27.         fdx1 dd ? ;float
  28.         fdx2 dd ? ;float
  29.         fdy1 dd ? ;float
  30.         fdy2 dd ? ;float
  31.         fz dd ? ;float
  32.         d1 dd ? ;float
  33.         d2 dd ? ;float
  34.         pz1 dd ? ;unsigned short*
  35.         pp1 dd ? ;PIXEL*
  36.         part dd ?
  37.         update_left dd ?
  38.         update_right dd ?
  39.  
  40.         nb_lines dd ? ;число горизонтальных линий в половине треугольника
  41.         dx1 dd ?
  42.         dy1 dd ?
  43.         ;dx2 dd ?
  44.         dy2 dd ?
  45.  
  46.         error dd ? ;int
  47.         derror dd ? ;int
  48.         x1 dd ? ;int
  49.         dxdy_min dd ? ;int
  50.         dxdy_max dd ? ;int
  51.         ; warning: x2 is multiplied by 2^16
  52.         x2 dd ? ;int
  53.         dx2dy2 dd ? ;int
  54.  
  55.         pz dd ? ;unsigned short *
  56.         z dd ? ;uint
  57.         zz dd ? ;uint
  58.  
  59. if INTERP_Z eq 1
  60.         z1 dd ? ;int
  61.         dzdx dd ? ;int
  62.         dzdy dd ? ;int
  63.         dzdl_min dd ? ;int
  64.         dzdl_max dd ? ;int
  65. end if
  66. if INTERP_RGB eq 1
  67.         r1 dd ? ;int
  68.         drdx dd ?
  69.         drdy dd ?
  70.         drdl_min dd ?
  71.         drdl_max dd ?
  72.         g1 dd ?
  73.         dgdx dd ?
  74.         dgdy dd ?
  75.         dgdl_min dd ?
  76.         dgdl_max dd ?
  77.         b1 dd ?
  78.         dbdx dd ?
  79.         dbdy dd ?
  80.         dbdl_min dd ?
  81.         dbdl_max dd ?
  82. end if
  83. if INTERP_ST eq 1
  84.         s1 dd ? ;int
  85.         dsdx dd ? ;int
  86.         dsdy dd ? ;int
  87.         dsdl_min dd ? ;int
  88.         dsdl_max dd ? ;int
  89.         t1 dd ? ;int
  90.         dtdx dd ? ;int
  91.         dtdy dd ? ;int
  92.         dtdl_min dd ? ;int
  93.         dtdl_max dd ? ;int
  94. end if
  95. if INTERP_STZ eq 1
  96.         sz1 dd ? ;float
  97.         dszdx dd ? ;float
  98.         dszdy dd ? ;float
  99.         dszdl_min dd ? ;float
  100.         dszdl_max dd ? ;float
  101.         tz1 dd ? ;float
  102.         dtzdx dd ? ;float
  103.         dtzdy dd ? ;float
  104.         dtzdl_min dd ? ;float
  105.         dtzdl_max dd ? ;float
  106.         s_z dd ? ;float
  107.         t_z dd ? ;float
  108. end if
  109.         n dd ? ;int - длинна горизонтальной линии в пикселях
  110. if INTERP_RGB eq 1
  111.         or1 dd ? ;uint
  112.         og1 dd ? ;uint
  113.         ob1 dd ? ;uint
  114. end if
  115. if INTERP_ST eq 1
  116.         s dd ? ;uint
  117.         t dd ? ;uint
  118. end if
  119.  
  120. if DRAW_LINE_M eq 1
  121.         DRAW_LINE 0 ;переменные делаются в макросе
  122. end if
  123.  
  124. endl
  125. pushad
  126.  
  127.         ; we sort the vertex with increasing y
  128.         mov ebx,[p0]
  129.         mov ecx,[p1]
  130.         mov edx,[p2]
  131.         mov eax,[edx+offs_zbup_y]
  132.         cmp [ecx+offs_zbup_y],eax ;(2-1)
  133.         jle @f
  134.                 xchg edx,ecx
  135.         @@:
  136.         mov eax,[ecx+offs_zbup_y]
  137.         cmp [ebx+offs_zbup_y],eax ;(1-0)
  138.         jle @f
  139.                 xchg ecx,ebx
  140.         @@:
  141.         mov eax,[edx+offs_zbup_y]
  142.         cmp [ecx+offs_zbup_y],eax ;(2-1)
  143.         jle @f
  144.                 xchg edx,ecx
  145.         @@:
  146.         mov [p0],ebx
  147.         mov [p1],ecx
  148.         mov [p2],edx
  149.  
  150.         ; we compute dXdx and dXdy for all interpolated values
  151.         mov eax,[ecx+offs_zbup_x]
  152.         sub eax,[ebx+offs_zbup_x]
  153.         mov [fdx1],eax ;p1.x - p0.x
  154.         mov eax,[ecx+offs_zbup_y]
  155.         sub eax,[ebx+offs_zbup_y]
  156.         mov [fdy1],eax ;p1.y - p0.y
  157.  
  158.         mov eax,[edx+offs_zbup_x]
  159.         sub eax,[ebx+offs_zbup_x]
  160.         mov [fdx2],eax ;p2.x - p0.x
  161.         mov eax,[edx+offs_zbup_y]
  162.         sub eax,[ebx+offs_zbup_y]
  163.         mov [fdy2],eax ;p2.y - p0.y
  164.  
  165.         fild dword[fdx1]
  166.         fst dword[fdx1]
  167.         fild dword[fdy2]
  168.         fst dword[fdy2]
  169.         fmulp
  170.         fild dword[fdx2]
  171.         fst dword[fdx2]
  172.         fild dword[fdy1]
  173.         fst dword[fdy1]
  174.         fmulp
  175.         fsubp ;st0 = st1-st0
  176.         fst dword[fz] ;fz = fdx1 * fdy2 - fdx2 * fdy1
  177.         fldz
  178.         fcompp ;if (fz == 0) return
  179.         fstsw ax
  180.         sahf
  181.         je .end_f
  182.  
  183.         fld1
  184.         fdiv dword[fz] ;fz = 1.0 / fz
  185.         fst dword[fz]  ;st0 = fz
  186.  
  187.         fld dword[fdx1]
  188.         fmul st0,st1
  189.         fstp dword[fdx1] ;fdx1 *= fz
  190.         fld dword[fdy1]
  191.         fmul st0,st1
  192.         fstp dword[fdy1] ;fdy1 *= fz
  193.         fld dword[fdx2]
  194.         fmul st0,st1
  195.         fstp dword[fdx2] ;fdx2 *= fz
  196.         fld dword[fdy2]
  197.         fmul st0,st1
  198.         fstp dword[fdy2] ;fdy2 *= fz
  199.         ffree st0
  200.         fincstp
  201.  
  202. if INTERP_Z eq 1
  203.         mov eax,[ecx+offs_zbup_z]
  204.         sub eax,[ebx+offs_zbup_z]
  205.         mov [d1],eax
  206.         mov eax,[edx+offs_zbup_z]
  207.         sub eax,[ebx+offs_zbup_z]
  208.         mov [d2],eax
  209.         fild dword[d1] ;d1 = p1.z - p0.z
  210.         fild dword[d2] ;d2 = p2.z - p0.z
  211.  
  212.         fld dword[fdy2]
  213.         fmul st0,st2
  214.         fld dword[fdy1]
  215.         fmul st0,st2
  216.         fsubp
  217.         fistp dword[dzdx] ;dzdx = (int) (fdy2*d1 - fdy1*d2)
  218.         fld dword[fdx1]
  219.         fmul st0,st1
  220.         fld dword[fdx2]
  221.         fmul st0,st3
  222.         fsubp
  223.         fistp dword[dzdy] ;dzdy = (int) (fdx1*d2 - fdx2*d1)
  224.         ffree st0 ;free d2
  225.         fincstp
  226.         ffree st0 ;free d1
  227.         fincstp
  228. end if
  229.  
  230. if INTERP_RGB eq 1
  231.         mov eax,[ecx+offs_zbup_r]
  232.         sub eax,[ebx+offs_zbup_r]
  233.         mov [d1],eax
  234.         mov eax,[edx+offs_zbup_r]
  235.         sub eax,[ebx+offs_zbup_r]
  236.         mov [d2],eax
  237.         fild dword[d1] ;d1 = p1.r - p0.r
  238.         fild dword[d2] ;d2 = p2.r - p0.r
  239.  
  240.         fld dword[fdy2]
  241.         fmul st0,st2
  242.         fld dword[fdy1]
  243.         fmul st0,st2
  244.         fsubp
  245.         fistp dword[drdx] ;drdx = (int) (fdy2*d1 - fdy1*d2)
  246.         fld dword[fdx1]
  247.         fmul st0,st1
  248.         fld dword[fdx2]
  249.         fmul st0,st3
  250.         fsubp
  251.         fistp dword[drdy] ;drdy = (int) (fdx1*d2 - fdx2*d1)
  252.         ffree st0 ;free d2
  253.         fincstp
  254.         ffree st0 ;free d1
  255.         fincstp
  256.  
  257.         mov eax,[ecx+offs_zbup_g]
  258.         sub eax,[ebx+offs_zbup_g]
  259.         mov [d1],eax
  260.         mov eax,[edx+offs_zbup_g]
  261.         sub eax,[ebx+offs_zbup_g]
  262.         mov [d2],eax
  263.         fild dword[d1] ;d1 = p1.g - p0.g
  264.         fild dword[d2] ;d2 = p2.g - p0.g
  265.  
  266.         fld dword[fdy2]
  267.         fmul st0,st2
  268.         fld dword[fdy1]
  269.         fmul st0,st2
  270.         fsubp
  271.         fistp dword[dgdx] ;dgdx = (int) (fdy2*d1 - fdy1*d2)
  272.         fld dword[fdx1]
  273.         fmul st0,st1
  274.         fld dword[fdx2]
  275.         fmul st0,st3
  276.         fsubp
  277.         fistp dword[dgdy] ;dgdy = (int) (fdx1*d2 - fdx2*d1)
  278.         ffree st0 ;free d2
  279.         fincstp
  280.         ffree st0 ;free d1
  281.         fincstp
  282.  
  283.         mov eax,[ecx+offs_zbup_b]
  284.         sub eax,[ebx+offs_zbup_b]
  285.         mov [d1],eax
  286.         mov eax,[edx+offs_zbup_b]
  287.         sub eax,[ebx+offs_zbup_b]
  288.         mov [d2],eax
  289.         fild dword[d1] ;d1 = p1.b - p0.b
  290.         fild dword[d2] ;d2 = p2.b - p0.b
  291.  
  292.         fld dword[fdy2]
  293.         fmul st0,st2
  294.         fld dword[fdy1]
  295.         fmul st0,st2
  296.         fsubp
  297.         fistp dword[dbdx] ;dbdx = (int) (fdy2*d1 - fdy1*d2)
  298.         fld dword[fdx1]
  299.         fmul st0,st1
  300.         fld dword[fdx2]
  301.         fmul st0,st3
  302.         fsubp
  303.         fistp dword[dbdy] ;dbdy = (int) (fdx1*d2 - fdx2*d1)
  304.         ffree st0 ;free d2
  305.         fincstp
  306.         ffree st0 ;free d1
  307.         fincstp
  308. end if
  309.  
  310. if INTERP_ST eq 1
  311.         mov eax,[ecx+offs_zbup_s]
  312.         sub eax,[ebx+offs_zbup_s]
  313.         mov [d1],eax
  314.         mov eax,[edx+offs_zbup_s]
  315.         sub eax,[ebx+offs_zbup_s]
  316.         mov [d2],eax
  317.         fild dword[d1] ;d1 = p1.s - p0.s
  318.         fild dword[d2] ;d2 = p2.s - p0.s
  319.  
  320.         fld dword[fdy2]
  321.         fmul st0,st2
  322.         fld dword[fdy1]
  323.         fmul st0,st2
  324.         fsubp
  325.         fistp dword[dsdx] ;dsdx = (int) (fdy2*d1 - fdy1*d2)
  326.         fld dword[fdx2]
  327.         fmul st0,st2
  328.         fld dword[fdx1]
  329.         fmul st0,st2
  330.         fsub st0,st1
  331.         fistp dword[dsdy] ;dsdy = (int) (fdx1*d2 - fdx2*d1)
  332.         ffree st0
  333.         fincstp
  334.         ffree st0 ;free d2
  335.         fincstp
  336.         ffree st0 ;free d1
  337.         fincstp
  338.  
  339.         mov eax,[ecx+offs_zbup_t]
  340.         sub eax,[ebx+offs_zbup_t]
  341.         mov [d1],eax
  342.         mov eax,[edx+offs_zbup_t]
  343.         sub eax,[ebx+offs_zbup_t]
  344.         mov [d2],eax
  345.         fild dword[d1] ;d1 = p1.t - p0.t
  346.         fild dword[d2] ;d2 = p2.t - p0.t
  347.  
  348.         fld dword[fdy1]
  349.         fmul st0,st1
  350.         fld dword[fdy2]
  351.         fmul st0,st3
  352.         fsub st0,st1
  353.         fistp dword[dtdx] ;dtdx = (int) (fdy2*d1 - fdy1*d2)
  354.         ffree st0
  355.         fincstp
  356.         fld dword[fdx2]
  357.         fmul st0,st2
  358.         fld dword[fdx1]
  359.         fmul st0,st2
  360.         fsub st0,st1
  361.         fistp dword[dtdy] ;dtdy = (int) (fdx1*d2 - fdx2*d1)
  362.         ffree st0
  363.         fincstp
  364.         ffree st0 ;free d2
  365.         fincstp
  366.         ffree st0 ;free d1
  367.         fincstp
  368. end if
  369.  
  370. if INTERP_STZ eq 1
  371.         fild dword[ebx+offs_zbup_z]
  372.         fild dword[ebx+offs_zbup_s]
  373.         fmul st0,st1
  374.         fstp dword[ebx+offs_zbup_sz] ;p0.sz = (float) p0.s * p0.z
  375.         fild dword[ebx+offs_zbup_t]
  376.         fmulp
  377.         fstp dword[ebx+offs_zbup_tz] ;p0.tz = (float) p0.t * p0.z
  378.  
  379.         fild dword[ecx+offs_zbup_z]
  380.         fild dword[ecx+offs_zbup_s]
  381.         fmul st0,st1
  382.         fstp dword[ecx+offs_zbup_sz] ;p1.sz = (float) p1.s * p1.z
  383.         fild dword[ecx+offs_zbup_t]
  384.         fmulp
  385.         fstp dword[ecx+offs_zbup_tz] ;p1.tz = (float) p1.t * p1.z
  386.  
  387.         fild dword[edx+offs_zbup_z]
  388.         fild dword[edx+offs_zbup_s]
  389.         fmul st0,st1
  390.         fstp dword[edx+offs_zbup_sz] ;p2.sz = (float) p2.s * p2.z
  391.         fild dword[edx+offs_zbup_t]
  392.         fmulp
  393.         fstp dword[edx+offs_zbup_tz] ;p2.tz = (float) p2.t * p2.z
  394.  
  395.         fld dword[ecx+offs_zbup_sz]
  396.         fsub dword[ebx+offs_zbup_sz] ;d1 = p1.sz - p0.sz
  397.         fld dword[edx+offs_zbup_sz]
  398.         fsub dword[ebx+offs_zbup_sz] ;d2 = p2.sz - p0.sz
  399.  
  400.         fld dword[fdy2]
  401.         fmul st0,st2
  402.         fld dword[fdy1]
  403.         fmul st0,st2
  404.         fsubp
  405.         fstp dword[dszdx] ;dszdx = (fdy2*d1 - fdy1*d2)
  406.         fld dword[fdx2]
  407.         fmul st0,st2
  408.         fld dword[fdx1]
  409.         fmul st0,st2
  410.         fsub st0,st1
  411.         fstp dword[dszdy] ;dszdy = (fdx1*d2 - fdx2*d1)
  412.         ffree st0
  413.         fincstp
  414.         ffree st0 ;free d2
  415.         fincstp
  416.         ffree st0 ;free d1
  417.         fincstp
  418.  
  419.         fld dword[ecx+offs_zbup_tz]
  420.         fsub dword[ebx+offs_zbup_tz] ;d1 = p1.tz - p0.tz
  421.         fld dword[edx+offs_zbup_tz]
  422.         fsub dword[ebx+offs_zbup_tz] ;d2 = p2.tz - p0.tz
  423.  
  424.         fld dword[fdy1]
  425.         fmul st0,st1
  426.         fld dword[fdy2]
  427.         fmul st0,st3
  428.         fsub st0,st1
  429.         fstp dword[dtzdx] ;dtzdx = (fdy2*d1 - fdy1*d2)
  430.         ffree st0
  431.         fincstp
  432.         fld dword[fdx2]
  433.         fmul st0,st2
  434.         fld dword[fdx1]
  435.         fmul st0,st2
  436.         fsub st0,st1
  437.         fstp dword[dtzdy] ;dtzdy = (fdx1*d2 - fdx2*d1)
  438.         ffree st0
  439.         fincstp
  440.         ffree st0 ;free d2
  441.         fincstp
  442.         ffree st0 ;free d1
  443.         fincstp
  444. end if
  445.  
  446.         ; screen coordinates
  447.         mov eax,[zb]
  448.         mov edx,[eax+offs_zbuf_linesize]
  449.         imul edx,[ebx+offs_zbup_y]
  450.         add edx,[eax+offs_zbuf_pbuf]
  451.         mov [pp1],edx ;pp1 = zb.pbuf + zb.linesize * p0.y
  452.         mov edx,[eax+offs_zbuf_xsize]
  453.         imul edx,[ebx+offs_zbup_y]
  454.         shl edx,1
  455.         add edx,[eax+offs_zbuf_zbuf]
  456.         mov [pz1],edx ;pz1 = zb.zbuf + zb.xsize * p0.y
  457.  
  458.         DRAW_INIT
  459.  
  460.         mov dword[part],0
  461.         .cycle_0:
  462.                 mov ebx,[p0]
  463.                 mov ecx,[p1]
  464.                 mov edx,[p2]
  465.                 cmp dword[part],0 ;if (part == 0)
  466.                 jne .els_0
  467.                         mov dword[update_left],1
  468.                         mov dword[update_right],1
  469.                         mov [l1],ebx
  470.                         mov [pr1],ebx
  471.                         fldz
  472.                         fld dword[fz]
  473.                         fcompp ;if (fz > 0)
  474.                         fstsw ax
  475.                         sahf
  476.                         jbe .els_1
  477.                                 mov [l2],edx
  478.                                 mov [pr2],ecx
  479.                                 jmp .end_1
  480.                         .els_1:
  481.                                 mov [l2],ecx
  482.                                 mov [pr2],edx
  483.                         .end_1:
  484.                         mov eax,[ecx+offs_zbup_y]
  485.                         sub eax,[ebx+offs_zbup_y]
  486.                         mov [nb_lines],eax ;nb_lines = p1.y - p0.y
  487.                         jmp .end_0
  488.                 .els_0:
  489.                         ; second part
  490.                         fldz
  491.                         fld dword[fz]
  492.                         fcompp ;if (fz > 0)
  493.                         fstsw ax
  494.                         sahf
  495.                         jbe .els_2
  496.                                 mov dword[update_left],0
  497.                                 mov dword[update_right],1
  498.                                 mov [pr1],ecx
  499.                                 mov [pr2],edx
  500.                                 jmp .end_2
  501.                         .els_2:
  502.                                 mov dword[update_left],1
  503.                                 mov dword[update_right],0
  504.                                 mov [l1],ecx
  505.                                 mov [l2],edx
  506.                         .end_2:
  507.                         mov eax,[edx+offs_zbup_y]
  508.                         sub eax,[ecx+offs_zbup_y]
  509.                         inc eax
  510.                         mov [nb_lines],eax ;nb_lines = p2.y - p1.y + 1
  511.                 .end_0:
  512.  
  513.         ; compute the values for the left edge
  514.         cmp dword[update_left],0 ;if (update_left)
  515.         je .end_upd_l
  516.                 mov ebx,[l1]
  517.                 mov ecx,[l2]
  518.                 mov edx,[ecx+offs_zbup_y]
  519.                 sub edx,[ebx+offs_zbup_y]
  520.                 mov [dy1],edx ;dy1 = l2.y - l1.y
  521.                 mov eax,[ecx+offs_zbup_x]
  522.                 sub eax,[ebx+offs_zbup_x]
  523.                 mov [dx1],eax ;dx1 = l2.x - l1.x
  524.                 cmp edx,0 ;if (dy1 > 0)
  525.                 jle .els_3
  526.                         xor edx,edx
  527.                         cmp eax,0
  528.                         jl .otr_dx1
  529.                         shl eax,16
  530.                         div dword[dy1] ;eax = (dx1 << 16) / dy1
  531.                         jmp .end_3
  532.                         .otr_dx1:
  533.                         neg eax
  534.                         inc eax
  535.                         shl eax,16
  536.                         div dword[dy1] ;eax = (-dx1 << 16) / dy1
  537.                         neg eax
  538.                         inc eax
  539.                         jmp .end_3
  540.                 .els_3:
  541.                         xor eax,eax
  542.                 .end_3:
  543.                 mov edx,[ebx+offs_zbup_x]
  544.                 mov [x1],edx ;x1 = l1.x
  545.                 mov dword[error],0 ;error = 0
  546.                 mov dword[derror],eax
  547.                 and dword[derror],0xffff ;derror = eax & 0x0000ffff
  548.                 sar eax,16
  549.                 mov [dxdy_min],eax ;dxdy_min = eax >> 16
  550.                 inc eax
  551.                 mov [dxdy_max],eax
  552.  
  553. if INTERP_Z eq 1
  554.         mov eax,[l1]
  555.         mov eax,[eax+offs_zbup_z]
  556.         mov [z1],eax ;z1 = l1.z
  557.         mov eax,[dzdx]
  558.         imul eax,[dxdy_min]
  559.         add eax,[dzdy]
  560.         mov [dzdl_min],eax ;dzdl_min = (dzdy +dzdx*dxdy_min)
  561.         add eax,[dzdx]
  562.         mov [dzdl_max],eax ;dzdl_max = dzdl_min +dzdx
  563. end if
  564. if INTERP_RGB eq 1
  565.         mov ebx,[l1]
  566.         mov eax,[ebx+offs_zbup_r]
  567.         mov [r1],eax ;r1 = l1.r
  568.         mov eax,[drdx]
  569.         imul eax,[dxdy_min]
  570.         add eax,[drdy]
  571.         mov [drdl_min],eax ;drdl_min = (drdy +drdx*dxdy_min)
  572.         add eax,[drdx]
  573.         mov [drdl_max],eax ;drdl_max = drdl_min +drdx
  574.  
  575.         mov eax,[ebx+offs_zbup_g]
  576.         mov [g1],eax ;g1 = l1.g
  577.         mov eax,[dgdx]
  578.         imul eax,[dxdy_min]
  579.         add eax,[dgdy]
  580.         mov [dgdl_min],eax ;dgdl_min = (dgdy +dgdx*dxdy_min)
  581.         add eax,[dgdx]
  582.         mov [dgdl_max],eax ;dgdl_max = dgdl_min +dgdx
  583.  
  584.         mov eax,[ebx+offs_zbup_b]
  585.         mov [b1],eax ;b1 = l1.b
  586.         mov eax,[dbdx]
  587.         imul eax,[dxdy_min]
  588.         add eax,[dbdy]
  589.         mov [dbdl_min],eax ;dbdl_min = (dbdy +dbdx*dxdy_min)
  590.         add eax,[dbdx]
  591.         mov [dbdl_max],eax ;dbdl_max = dbdl_min +dbdx
  592. end if
  593. if INTERP_ST eq 1
  594.         mov ebx,[l1]
  595.         mov eax,[ebx+offs_zbup_s]
  596.         mov [s1],eax ;s1 = l1.s
  597.         mov eax,[dsdx]
  598.         imul eax,[dxdy_min]
  599.         add eax,[dsdy]
  600.         mov [dsdl_min],eax ;dsdl_min = (dsdy +dsdx*dxdy_min)
  601.         add eax,[dsdx]
  602.         mov [dsdl_max],eax ;dsdl_max = dsdl_min +dsdx
  603.  
  604.         mov eax,[ebx+offs_zbup_t]
  605.         mov [t1],eax ;t1 = l1.t
  606.         mov eax,[dtdx]
  607.         imul eax,[dxdy_min]
  608.         add eax,[dtdy]
  609.         mov [dtdl_min],eax ;dtdl_min = (dtdy +dtdx*dxdy_min)
  610.         add eax,[dtdx]
  611.         mov [dtdl_max],eax ;dtdl_max = dtdl_min +dtdx
  612. end if
  613. if INTERP_STZ eq 1
  614.         mov ebx,[l1]
  615.         mov eax,[ebx+offs_zbup_sz]
  616.         mov [sz1],eax ;sz1 = l1.sz - преобразований нет, потому без сопроцессора
  617.         fild dword[dxdy_min]
  618.         fmul dword[dszdx]
  619.         fadd dword[dszdy]
  620.         fst dword[dszdl_min] ;dszdl_min = (dszdy +dszdx*dxdy_min)
  621.         fadd dword[dszdx]
  622.         fstp dword[dszdl_max] ;dszdl_max = dszdl_min +dszdx
  623.  
  624.         mov eax,[ebx+offs_zbup_tz]
  625.         mov [tz1],eax ;tz1 = l1.tz - преобразований нет, потому без сопроцессора
  626.         fild dword[dxdy_min]
  627.         fmul dword[dtzdx]
  628.         fadd dword[dtzdy]
  629.         fst dword[dtzdl_min] ;dtzdl_min = (dtzdy +dtzdx*dxdy_min)
  630.         fadd dword[dtzdx]
  631.         fstp dword[dtzdl_max] ;dtzdl_max = dtzdl_min +dtzdx
  632. end if
  633.         .end_upd_l:
  634.  
  635.         ; compute values for the right edge
  636.  
  637.         cmp dword[update_right],0 ;if(update_right)
  638.         je .end_upd_r
  639.                 mov ebx,[pr1]
  640.                 mov ecx,[pr2]
  641.                 mov edx,[ebx+offs_zbup_x]
  642.                 mov eax,[ecx+offs_zbup_x]
  643.                 sub eax,edx
  644.                 ;mov [dx2],eax ;dx2 = pr2.x - pr1.x
  645.                 shl edx,16
  646.                 mov [x2],edx ; x2 = pr1.x << 16
  647.                 mov edx,[ecx+offs_zbup_y]
  648.                 sub edx,[ebx+offs_zbup_y]
  649.                 mov [dy2],edx ;dy2 = pr2.y - pr1.y
  650.                 cmp edx,0 ;if (dy2 > 0)
  651.                 jle .els_4
  652.                         xor edx,edx
  653.                         cmp eax,0
  654.                         jl .otr_dx2
  655.                         shl eax,16
  656.                         div dword[dy2] ;eax = (dx2 << 16) / dy2
  657.                         jmp .end_4
  658.                         .otr_dx2:
  659.                         neg eax
  660.                         inc eax ;dx2 *= -1
  661.                         shl eax,16
  662.                         div dword[dy2] ;eax = (-dx2 << 16) / dy2
  663.                         neg eax
  664.                         inc eax
  665.                         jmp .end_4
  666.                 .els_4:
  667.                         xor eax,eax
  668.                 .end_4:
  669.                 mov [dx2dy2],eax
  670.         .end_upd_r:
  671.  
  672.         ; we draw all the scan line of the part
  673. if DEBUG ;[nb_lines]
  674. push ecx edi
  675.         mov eax,[nb_lines]
  676.         mov ecx,80
  677.         lea edi,[buf_param]
  678.         stdcall convert_int_to_str,ecx
  679.  
  680.         stdcall str_n_cat,edi,txt_nl,2
  681.         stdcall dbg_print,f_fill_tr_nl,buf_param
  682. pop edi ecx
  683. end if
  684.  
  685.         .beg_w_lin:
  686.         cmp dword[nb_lines],0 ;while (nb_lines>0)
  687.         jle .end_w_lin
  688.                 dec dword[nb_lines]
  689. if DRAW_LINE_M eq 1
  690.                 DRAW_LINE 1
  691. else
  692.                 ; generic draw line
  693.                 mov eax,[x2]
  694.                 sar eax,16
  695.                 mov edi,[x1]
  696.                 sub eax,edi
  697.                 mov [n],eax ;n = (x2 >> 16) - x1
  698.                 imul edi,PSZB
  699.                 add edi,[pp1] ;pp = pp1 + x1 * PSZB
  700.  
  701. if INTERP_Z eq 1
  702.                 mov eax,[x1]
  703.                 shl eax,1
  704.                 add eax,[pz1]
  705.                 mov [pz],eax
  706.                 mov eax,[z1]
  707.                 mov [z],eax
  708. end if
  709. if INTERP_RGB eq 1
  710.                 mov eax,[r1]
  711.                 bt eax,31 ; коректирование испорченных пикселей (в начале линии)
  712.                 jnc @f
  713.                         xor eax,eax
  714.                 @@:
  715.                 bt eax,16
  716.                 jnc @f
  717.                         mov eax,0xff00
  718.                 @@:
  719.                 mov [or1],eax
  720.                 mov eax,[g1]
  721.                 bt eax,31
  722.                 jnc @f
  723.                         xor eax,eax
  724.                 @@:
  725.                 bt eax,16
  726.                 jnc @f
  727.                         mov eax,0xff00
  728.                 @@:
  729.                 mov [og1],eax
  730.                 mov eax,[b1]
  731.                 bt eax,31
  732.                 jnc @f
  733.                         xor eax,eax
  734.                 @@:
  735.                 bt eax,16
  736.                 jnc @f
  737.                         mov eax,0xff00
  738.                 @@:
  739.                 mov [ob1],eax
  740. end if
  741. if INTERP_ST eq 1
  742.                 mov eax,[s1]
  743.                 mov [s],eax
  744.                 mov eax,[t1]
  745.                 mov [t],eax
  746. end if
  747. if INTERP_STZ eq 1
  748.                 mov eax,[sz1]
  749.                 mov [s_z],eax
  750.                 mov eax,[tz1]
  751.                 mov [t_z],eax
  752. end if
  753.  
  754. align 4
  755.                 .cycle_1: ;while (n>=3)
  756. if INTERP_RGB eq 1
  757.                 cmp dword[n],5
  758.                 jl .cycle_2
  759. else
  760.                 cmp dword[n],3
  761.                 jl .cycle_2
  762. end if
  763.                         PUT_PIXEL 0
  764.                         PUT_PIXEL 1
  765.                         PUT_PIXEL 2
  766.                         PUT_PIXEL 3
  767. if INTERP_Z eq 1
  768.                         add dword[pz],8 ;=4*sizeof(uint)
  769. end if
  770.                         add edi,4*PSZB
  771.                         sub dword[n],4
  772.                 jmp .cycle_1
  773.                 .cycle_2: ;while (n>=0)
  774.                 cmp dword[n],0
  775.                 jl .cycle_2_end
  776. if INTERP_RGB eq 1
  777.                 ; коректирование испорченных пикселей (в конце линии)
  778.                 bt dword[or1],31
  779.                 jnc @f
  780.                         mov dword[or1],0
  781.                         jmp .end_r
  782.                 @@:
  783.                 bt dword[or1],16
  784.                 jnc .end_r
  785.                         mov dword[or1],0xff00
  786.                 .end_r:
  787.                 bt dword[og1],31
  788.                 jnc @f
  789.                         mov dword[og1],0
  790.                         jmp .end_g
  791.                 @@:
  792.                 bt dword[og1],16
  793.                 jnc .end_g
  794.                         mov dword[og1],0xff00
  795.                 .end_g:
  796.                 bt dword[ob1],31
  797.                 jnc @f
  798.                         mov dword[ob1],0
  799.                         jmp .end_b
  800.                 @@:
  801.                 bt dword[ob1],16
  802.                 jnc .end_b
  803.                         mov dword[ob1],0xff00
  804.                 .end_b:
  805. end if
  806.                         PUT_PIXEL 0
  807. if INTERP_Z eq 1
  808.                         add dword[pz],2 ;=sizeof(uint)
  809. end if
  810.                         add edi,PSZB
  811.                         dec dword[n]
  812.                 jmp .cycle_2
  813.                 .cycle_2_end:
  814. end if ;проверка от макроса DRAW_LINE
  815.  
  816.         ; left edge
  817.         mov eax,[derror]
  818.         add [error],eax
  819.         cmp dword[error],0 ;if (error > 0)
  820.         jle .els_er
  821.                 sub dword[error],0x10000
  822.                 mov eax,[dxdy_max]
  823.                 add [x1],eax
  824. if INTERP_Z eq 1
  825.                 mov eax,[dzdl_max]
  826.                 add [z1],eax
  827. end if      
  828. if INTERP_RGB eq 1
  829.                 mov eax,[drdl_max]
  830.                 add [r1],eax
  831.                 mov eax,[dgdl_max]
  832.                 add [g1],eax
  833.                 mov eax,[dbdl_max]
  834.                 add [b1],eax
  835. end if
  836. if INTERP_ST eq 1
  837.                 mov eax,[dsdl_max]
  838.                 add [s1],eax
  839.                 mov eax,[dtdl_max]
  840.                 add [t1],eax
  841. end if
  842. if INTERP_STZ eq 1
  843.                 fld dword[dszdl_max]
  844.                 fadd dword[sz1]
  845.                 fstp dword[sz1]
  846.                 fld dword[dtzdl_max]
  847.                 fadd dword[tz1]
  848.                 fstp dword[tz1]
  849. end if
  850.                 jmp .end_er
  851.         .els_er:
  852.                 mov eax,[dxdy_min]
  853.                 add [x1],eax
  854. if INTERP_Z eq 1
  855.                 mov eax,[dzdl_min]
  856.                 add [z1],eax
  857. end if
  858. if INTERP_RGB eq 1
  859.                 mov eax,[drdl_min]
  860.                 add [r1],eax
  861.                 mov eax,[dgdl_min]
  862.                 add [g1],eax
  863.                 mov eax,[dbdl_min]
  864.                 add [b1],eax
  865. end if
  866. if INTERP_ST eq 1
  867.                 mov eax,[dsdl_min]
  868.                 add [s1],eax
  869.                 mov eax,[dtdl_min]
  870.                 add [t1],eax
  871. end if
  872. if INTERP_STZ eq 1
  873.                 fld dword[dszdl_min]
  874.                 fadd dword[sz1]
  875.                 fstp dword[sz1]
  876.                 fld dword[dtzdl_min]
  877.                 fadd dword[tz1]
  878.                 fstp dword[tz1]
  879. end if
  880.         .end_er:
  881.  
  882.                         ; right edge
  883.                         mov eax,[dx2dy2]
  884.                         add [x2],eax
  885.  
  886.                         ; screen coordinates
  887.                         mov ebx,[zb]
  888.                         mov eax,[ebx+offs_zbuf_linesize]
  889.                         add [pp1],eax
  890.                         mov eax,[ebx+offs_zbuf_xsize]
  891.                         shl eax,1
  892.                         add [pz1],eax
  893.                         jmp .beg_w_lin
  894.                 .end_w_lin:
  895.                 inc dword[part]
  896.                 cmp dword[part],2
  897.                 jl .cycle_0
  898.         .end_f:
  899. popad
  900.         ret
  901. endp
  902.  
  903. restore INTERP_Z
  904. restore INTERP_RGB
  905. restore INTERP_ST
  906. restore INTERP_STZ
  907. restore DRAW_LINE_M
  908.  
  909. purge DRAW_INIT
  910. purge DRAW_LINE
  911. purge PUT_PIXEL
  912.