{ • Texturovací procedura optimalizovaná pro režim 320x200x256 a 386/486 • }

Procedure TextureFace(X1,Y1,U1,V1,  { Souřadnice trojúhelníku v textuře a  }
                      X2,Y2,U2,V2,  { cílové plošky, která se má zobrazit. }
                      X3,Y3,U3,V3:Integer;
                Texture:Pointer;    { Ukazatel na texturu s rozměry 256x256 }
                OutSeg:Word); { Cílový segment vykreslování (např. SegA000) }

var S_I,N_P,USeg,Uofs,VSeg,VOfs,Tseg,Tofs,i320:Word;
    { Pole pro předávání nainterpolovaných souřadnic }
    U,V,XL,XR,UL,UR,VL,VR : TData;
    j,i,i2:Integer;

begin

{ Přerovná body trojúhelníků podle velikosti Y }
for i:=1 to 2 do begin
if Y1>Y2 then begin
J:=Y2;Y2:=Y1;Y1:=J;
J:=X2;X2:=X1;X1:=J;
J:=U2;U2:=U1;U1:=J;
J:=V2;V2:=V1;V1:=J;
end;
if Y2>Y3 then begin
J:=Y3;Y3:=Y2;Y2:=J;
J:=X3;X3:=X2;X2:=J;
J:=U3;U3:=U2;U2:=J;
J:=V3;V3:=V2;V2:=J;
end end;

{ Interpoluje souřadnice X,U,V podle Y, pro případ: }
          { dvě kratší strany vlevo }
if (X2<X1) or (X2<X3) then
begin
Interpol(X1,Y1,X2,Y2,@XL);
Interpol(X2,Y2,X3,Y3,@XL);
Interpol(X1,Y1,X3,Y3,@XR);
                            {    /|   }
Interpol(U1,Y1,U2,Y2,@UL);  { XL/ |   }
Interpol(U2,Y2,U3,Y3,@UL);  {  /  |XR }
Interpol(U1,Y1,U3,Y3,@UR);  {  \  |   }
                            { XL\ |   }
Interpol(V1,Y1,V2,Y2,@VL);  {    \|   }
Interpol(V2,Y2,V3,Y3,@VL);
Interpol(V1,Y1,V3,Y3,@VR);
end
else

{ Interpoluje souřadnice X,U,V podle Y, pro případ: }
          { dvě kratší strany vpravo }
if (X2>X1) or (X2>X3) then
begin
Interpol(X1,Y1,X2,Y2,@XR);
Interpol(X2,Y2,X3,Y3,@XR);
Interpol(X1,Y1,X3,Y3,@XL);
                            {   |\    }
Interpol(U1,Y1,U2,Y2,@UR);  {   | \XR }
Interpol(U2,Y2,U3,Y3,@UR);  { XL|  \  }
Interpol(U1,Y1,U3,Y3,@UL);  {   |  /  }
                            {   | /XR }
Interpol(V1,Y1,V2,Y2,@VR);  {   |/    }
Interpol(V2,Y2,V3,Y3,@VR);
Interpol(V1,Y1,V3,Y3,@VL);
end;

{ Naplní pomocné proměnné }
TSeg:=Seg(Texture^);
TOfs:=Ofs(Texture^);
USeg:=Seg(U);UOfs:=Ofs(U);
VSeg:=Seg(V);VOfs:=Ofs(V);

{ Ořeže Y souřadnice }
if Y1<0 then Y1:=0;
if Y3<0 then Y3:=0;
if Y1>199 then Y1:=199;
if Y3>199 then Y3:=199;

{ Absolutní adresa prvního bodu (Y1*320) }
i320:=(Y1 shl 8)+(Y1 shl 6);

{ Začne vykreslovat postupně od Y1 do Y3, pokud je co... }
if Y3-Y1>0 then for i:=Y1 to Y3 do
begin

{ Ochrana proti nežáducímu prohození XL a XR souřadnic }
if XL[i]>XR[i] then
begin
J:=XL[i];XL[i]:=XR[i];XR[i]:=J;
J:=UL[i];UL[i]:=UR[i];UR[i]:=J;
J:=VL[i];VL[i]:=VR[i];VR[i]:=J;
end;

S_I:=XL[i];N_P:=XR[i]-S_I;

{ Pokud má scan-line nějakou délku, vykreslí ji... }
if N_P>0 then begin

{ Interpoluje souřadnice v textuře U a V podle X }
Interpol(UL[i],XL[i],UR[i],XR[i],@U);
Interpol(VL[i],XL[i],VR[i],XR[i],@V);

{  Optimalizovaná vykreslovací smyčka pro režim 320x200x256 a
   texturu s rozměry 256x256, jsou použity instrukce procesoru 386+ }

asm
push ds
mov  di,i320
mov  bx,Uofs
mov  dx,Vofs
mov  ax,S_I
add  di,ax      { di = S_I + i320 }
shl  ax,1
add  bx,ax      { bx = S_I * 2 + Uofs }
add  dx,ax      { dx = S_I * 2 + Vofs }
mov  ax,bx
mov  cx,N_P
push OutSeg
pop  es
push USeg
pop  fs         { db 0Fh,0A1h }
push VSeg
pop  gs         { db 0Fh,0A9h }
push TSeg
pop  ds
@pix:
mov  bx,ax
mov  si,fs:[bx] { db 64h;mov si,[bx] }
mov  bx,dx
add  ax,gs:[bx] { db 65h;mov bx,[bx] }
xchg bl,bh      { bx = bx * 256 }
add  si,bx
movsb           { ds:si -> es:di (1 bajt) }
add  ax,2
add  dx,2
dec  cx
jnz  @pix       { opakuje pro další pixel }
pop  ds
end end;i320:=i320+320
end end;


            výheň