Unreal Texture Filtration.

Algorithm.

Unreal texture filtration is very simple, in a fact it's table bilinear filtration, and it can easily be included in every inner loop.

Let's define this table:

```                          +----------+-----------+
Y\X|   even   |    odd    |
e +----------+-----------+
v | du = .25 | du = 0    |
e | dv = .75 | dv = .50  |
n |          |           |
- +----------+-----------+
o | du = .50 | du = .75  |
d | dv = 0   | dv = .25  |
d |          |           |
+----------+-----------+```

du,dv - texture correction values for U and V,
"even" - even X/Y(on screen),
"odd" - odd X/Y

Algorithm:

1. get screen X,Y (usually it exists in the inner loop)

2. looks in our table, get du,dv

3. correct texture coordinates U,V

(they must be float or fixed point, otherwise the algorithm won't work)

4. put texel on screen.

6. goto 1.

Optimization.

Every coder understands that looking up every texel in a table is really slow. I found a solution while debugging my code. =) In the scanline drawing routine I carefully watched my variables du and dv. They changed like (0.25,0.75), (0.0,0.50), (0.25,0.75), (0.0,0.50),... hmm. Systematic... 0.25 goes to 0.0 and back, and 0.75 goes to 0.50 and back to 0.75. Flash! Wow! It's a simple XOR!

In a fixedpoint loop you must just XOR "start" du,dv with a constant value and add the result to U and V. "start" du,dv are taken from our table on entering the scanline loop!

Sample code.

Here's a scanline filling code with perspective correction and zbuffer (in fact it's only the part that does the filling of the remainder of affine subdivision of the scanline by 16 pixels). For U and V I use 8:8 fixedpoint.

```;scanline enter
;eax - X*4
;esi - Y
ifdef filtering
shr eax,2  				;get start order
and eax,1
mov ebx,esi
and ebx,1
shl ebx,2

mov dh,byte ptr _orderTab[ebx*4]	;our table
mov dl,byte ptr _orderTab[ebx*4 + 4]
endif

mov ecx,dword ptr _Inner1Count
xor eax,eax
xor ebx,ebx
dsall66:					;inner loop
fld dword ptr _256
fdiv st(0),st(1)

fld st(0)
fmul dword ptr _Ze
fistp dword ptr _Zs			;zbuff

fld st(0)				;(1/z)/(1/z)/z/v/u...
fmul st(0),st(3)
fistp dword ptr _Vs
fmul st(0),st(3)
fistp dword ptr _Us

or ecx,ecx
jz dsall67

ZZZsm1:
mov eax,dword ptr [edi + 12345678h]	;zbuffer
mov ebx,dword ptr _Zs
cmp eax,ebx
;	jl dZl1
jb dZl1
ZZZsm2:
xor eax,eax
mov ax,word ptr _Vs
ifdef filtering
endif
xor ebx,ebx
shr ax,8

mov bx,word ptr _Us
ifdef filtering
endif
shr bx,8
SMpt2:
mov ebx,dword ptr [ebx*4 + 12345678h]

mov dword ptr [edi],ebx

dZl1:
fld dword ptr _C.y