Subversion Repositories Kolibri OS

Rev

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