Subversion Repositories Kolibri OS

Rev

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