Subversion Repositories Kolibri OS

Rev

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