avp/3dc/win95/SCANDRAW.ASM
Rebellion Developments 218ca90543 Import Aliens vs Predator - Gold (Build 116)
Source code release, imported from:
https://www.gamefront.com/games/aliens-vs-predator-3/file/avp-gold-complete-source-code

All text files were converted to Unix format.
2019-08-19 05:45:17 +02:00

2096 lines
55 KiB
NASM

;.586
;.8087
;
; Assembly scandraws - designed for Pentiums/Pentium Pros but should work ok
; on 486s and strange hybrid processors.
;
; (C) Kevin Lea 12:03:17 96/12/05
;
; Please excuse the mess, I haven't tidied up yet. Only the inner loops are
; well coded, since these take far more runtime than initialisation routines.
;
SOURCE_SBITSV EQU 16
SOURCE_SBITSU EQU 7
_DATA SEGMENT DWORD PUBLIC 'DATA'
EXTRN _SCASM_Lighting:DWORD
EXTRN _SCASM_Destination:DWORD
EXTRN _SCASM_Bitmap:DWORD
EXTRN _SCASM_StartU:DWORD
EXTRN _SCASM_StartV:DWORD
EXTRN _SCASM_StartI:DWORD
EXTRN _SCASM_DeltaU:DWORD
EXTRN _SCASM_DeltaV:DWORD
EXTRN _SCASM_DeltaI:DWORD
EXTRN _SCASM_ScanLength:DWORD
EXTRN _SCASM_ShadingTableSize:DWORD
EXTRN _SCASM_TextureDeltaScan:DWORD
; EXTRN _TLT:BYTE PTR
if 0
EXTRN _sine:DWORD ;
EXTRN _cosine:DWORD ; these 2 in 3D engine already
EXTRN _MTRB_Bitmap:DWORD
EXTRN _MTRB_Destination:DWORD
EXTRN _MTRB_ScanOffset:DWORD
EXTRN _MTRB_Angle:DWORD;
EXTRN _MTRB_InvScale:DWORD;
EXTRN _MTRB_ScreenHeight:DWORD; equ 48
EXTRN _MTRB_ScreenWidth:DWORD; equ (49*2+1)
EXTRN _MTRB_ScreenCentreX:DWORD; equ (MTRB_ScreenWidth/2+1)
EXTRN _MTRB_ScreenCentreY:DWORD; equ MTRB_ScreenHeight
EXTRN _MTRB_CentreU:DWORD
EXTRN _MTRB_CentreV:DWORD
endif
align
FixedScale dd 65536.0
FixedScale8 dd 8192.0 ; 2^16 / 8
One dd 1.0
FloatTemp dd ?
FPUCW word ?
OldFPUCW word ?
DeltaUFrac dd ?
DeltaVFrac dd ?
DeltaIFrac dd ?
Wholesections dd ?
PixelsRemaining dd ?
UVintVfracStepVCarry dd ?
UVintVfracStepVNoCarry dd ?
UVintVfracStep equ UVintVfracStepVNoCarry
IintWithCarry dd ?
IintNoCarry dd ?
IintStep equ IintNoCarry
StackStore dd ?
ShadeTable equ _TextureLightingTable
aspectAdjust dd (6 SHL 16) / 5
startingU dd 0
startingV dd 0
dUCol dd 0
dVCol dd 0
dURow dd 0
dVRow dd 0
rowCount dd 0
_DATA ENDS
_TEXT SEGMENT BYTE PUBLIC 'CODE'
ASSUME cs:_TEXT, ds:_DATA
.586
if 0
align
PUBLIC _ScanDraw_GouraudScan
PUBLIC ScanDraw_GouraudScan_
ScanDraw_GouraudScan_:
_ScanDraw_GouraudScan:
; calculate horizontal deltas
pushad
; mov [StackStore],esp
mov eax,_SCASM_ScanLength
mov ebp,eax
and eax,7
shr ebp,3
mov [PixelsRemaining],eax
mov [Wholesections],ebp ; store widths
; setup initial coordinates
mov ebx,_SCASM_DeltaI ; get i 16.16 step
mov eax,ebx ; copy it
sar eax,16 ; get i int step
shl ebx,16 ; get i frac step
imul eax,_SCASM_ShadingTableSize
mov IintNoCarry,eax ; save whole step in non-i-carry slot
add eax,_SCASM_ShadingTableSize ; calculate whole step + i carry
mov IintWithCarry,eax ; save in i-carry slot
mov esi,_SCASM_StartI
mov edx,esi
sar esi,16
shl edx,16
imul esi,_SCASM_ShadingTableSize
add esi,_SCASM_Lighting
xor eax,eax
mov edi,_SCASM_Destination
test ebp,ebp
jz GS_EndPixels
if 1
GS_ScanLoop:
; 8 pixel span code
; edi = dest dib bits at current pixel
; esi = lighting pointer
; edx = i fraction 0.32
; ebp = carry scratch
; mov al,[esi]
; add edx,DeltaIFrac
; sbb ebp,ebp
; add esi,[4*ebp + IintStep]
; mov [edi],al
mov al,[esi] ;get colour to draw
add edx,ebx ;increase intensity
sbb ebp,ebp ;check for overflow
add esi,[4*ebp + IintStep] ;add to esi required change
add edx,ebx ;increase intensity
sbb ebp,ebp ;check for overflow
mov [edi+0],al ;draw out pixel
mov al,[esi]
add esi,[4*ebp + IintStep]
add edx,ebx
sbb ebp,ebp
mov [edi+1],al
mov al,[esi]
add esi,[4*ebp + IintStep]
add edx,ebx
sbb ebp,ebp
mov [edi+2],al
mov al,[esi]
add esi,[4*ebp + IintStep]
add edx,ebx
sbb ebp,ebp
mov [edi+3],al
mov al,[esi]
add esi,[4*ebp + IintStep]
add edx,ebx
sbb ebp,ebp
mov [edi+4],al
mov al,[esi]
add esi,[4*ebp + IintStep]
add edx,ebx
sbb ebp,ebp
mov [edi+5],al
mov al,[esi]
add esi,[4*ebp + IintStep]
add edx,ebx
sbb ebp,ebp
mov [edi+6],al
mov al,[esi]
add esi,[4*ebp + IintStep]
mov [edi+7],al
lea edi,[edi+8]
dec Wholesections ; decrement span count
jnz GS_ScanLoop ; loop back
endif
mov eax,[PixelsRemaining]
test eax,eax
jz GS_finish
GS_EndPixels:
mov al,[esi] ; get texture pixel
lea edi,[edi+1]
add edx,ebx
sbb ebp,ebp
mov [edi-1],al
add esi,[4*ebp + IintStep]
dec [PixelsRemaining]
jnz GS_EndPixels
GS_finish:
; mov esp, [StackStore]
popad
ret
endif
if 1
align
PUBLIC _ScanDraw_GouraudScan
PUBLIC ScanDraw_GouraudScan_
ScanDraw_GouraudScan_:
_ScanDraw_GouraudScan:
; calculate horizontal deltas
pushad
mov [StackStore],esp
mov eax,_SCASM_ScanLength
mov ecx,eax
; and ecx,7
shr eax,3
mov [PixelsRemaining],ecx
mov [Wholesections],eax ; store widths
; setup initial coordinates
mov esp,_SCASM_DeltaI ; get i 16.16 step
; sar esp,8 ; get i frac step
mov ebx,_SCASM_StartI
; sar ebx,8
mov edx,ebx
sar edx,8
and edx,0xff00h
mov esi,_SCASM_Lighting
mov edi,_SCASM_Destination
add edi,ecx
; test eax,eax
neg ecx
sub eax,eax
jz GS_EndPixels
if 1
mov ecx,eax
GS_ScanLoop:
mov al,[esi+edx]
mov edx,ebx
add ebx,esp
and edx,0xff00h
mov [edi+0],al
nop
lea edi,[edi+8]
dec ecx ; decrement span count
jnz GS_ScanLoop ; loop back
endif
mov ecx,[PixelsRemaining]
test ecx,ecx
jz GS_finish
GS_EndPixels:
mov al,[esi+edx]
mov edx,ebx
sar edx,8
add ebx,esp
and edx,0xff00h
mov [edi+ecx],al
inc ecx
jnz GS_EndPixels
GS_finish:
mov esp, [StackStore]
popad
ret
endif
align
; Drawing a 2D polygon which has DeltaV=0 and is transparent
PUBLIC _ScanDraw2D_VAlignedTransparent
PUBLIC ScanDraw2D_VAlignedTransparent_
_ScanDraw2D_VAlignedTransparent:
ScanDraw2D_VAlignedTransparent_:
pushad
mov [StackStore],esp
mov edx,_SCASM_ScanLength
mov esi,_SCASM_StartU ; get u 16.16 fixedpoint coordinate
mov esp,esi ; copy it
sar esi,16 ; get integer part
shl esp,16 ; get fractional part
mov eax,_SCASM_StartV ; get v 16.16 fixedpoint coordinate
sar eax,16 ; get integer part
imul eax,_SCASM_TextureDeltaScan ; calc texture scanline address
add esi,eax ; calc texture offset
add esi,_SCASM_Bitmap ; calc address
mov edi,_SCASM_Destination
mov ebx,_SCASM_DeltaU ; get u 16.16 step
mov ecx,ebx ; copy it
sar ebx,16 ; get u int step
shl ecx,16 ; get u frac step
; ebx u int delta
; ecx u frac delta
; esp u frac total
; edi dest
; esi source
; edx pixels to draw
VAT_ScanLoop:
mov al,[esi] ; get texture pixel 0
add esp,ecx
adc esi,ebx
inc edi
test al,al
jz VAT_SkipPixel
mov [edi-1],al
VAT_SkipPixel:
dec edx ; decrement span count
jnz VAT_ScanLoop ; loop back
mov esp, [StackStore]
popad
ret
; Drawing a 2D polygon which has DeltaV=0 and is opaque
align
PUBLIC ScanDraw2D_VAlignedOpaque_
PUBLIC _ScanDraw2D_VAlignedOpaque
ScanDraw2D_VAlignedOpaque_:
_ScanDraw2D_VAlignedOpaque:
pushad
mov [StackStore],esp
mov edx,_SCASM_ScanLength
mov esi,_SCASM_StartU ; get u 16.16 fixedpoint coordinate
mov esp,esi ; copy it
sar esi,16 ; get integer part
shl esp,16 ; get fractional part
mov eax,_SCASM_StartV ; get v 16.16 fixedpoint coordinate
sar eax,16 ; get integer part
imul eax,_SCASM_TextureDeltaScan ; calc texture scanline address
add esi,eax ; calc texture offset
add esi,_SCASM_Bitmap ; calc address
mov edi,_SCASM_Destination
mov ebx,_SCASM_DeltaU ; get u 16.16 step
mov ecx,ebx ; copy it
sar ebx,16 ; get u int step
shl ecx,16 ; get u frac step
; ebx u int delta
; ecx u frac delta
; esp u frac total
; edi dest
; esi source
; edx pixels to draw
VAO_ScanLoop:
mov al,[esi] ; get texture pixel 0
add esp,ecx
adc esi,ebx
dec edx ; decrement span count
mov [edi],al
lea edi,[edi+1]
jnz VAO_ScanLoop ; loop back
mov esp, [StackStore]
popad
ret
;
; 2d case with shading
;
; mov eax,_SCASM_DeltaU
; mov bl,ah
; mov eax,_SCASM_DeltaV
; mov cl,ah
if 0
align
PUBLIC ScanDraw2D_Gouraud_
PUBLIC _ScanDraw2D_Gouraud
ScanDraw2D_Gouraud_:
_ScanDraw2D_Gouraud:
; calculate horizontal deltas
pushad
mov [StackStore],esp
mov eax,_SCASM_ScanLength
mov ebp,eax
; and eax,7
shr ebp,3
mov [PixelsRemaining],eax
mov [Wholesections],ebp ; store widths
mov eax,_SCASM_DeltaV ; C1 1 ; get v 16.16 step
mov edx,_SCASM_DeltaU ; C2 1 ; get u 16.16 step
mov ebx,eax ; C1 2 ; copy v 16.16 step
sar eax,16 ; C1 3 ; get v int step
mov ecx,edx ; C2 2 ; copy u 16.16 step
shl ebx,16 ; C1 4 ; get v frac step
mov esi,_SCASM_DeltaI ; C3 1 ; get i 16.16 step
sar edx,16 ; C2 3 ; get u int step
mov esp,esi ; C3 2 ; copy i 16.16 step
shl ecx,16 ; C2 4 ; get u frac step
mov DeltaVFrac,ebx ; C1 5 ; store it
imul eax,_SCASM_TextureDeltaScan ; C1 6 ; calculate texture step for v int step
sar esp,16-8 ; C3 3 ; get i int step
mov DeltaUFrac,ecx ; C2 5 ; store it
sar esi,8 ; C3 4 ; get i frac step
add eax,edx ; C1+C2 1 ; calculate uint + vint step
mov DeltaIFrac,esi ; C3 5 ; store it
mov UVintVfracStepVNoCarry,eax ; C1+C2 2 ; save whole step in non-v-carry slot
and esp,0xffffff00h ; C3 6
add eax,_SCASM_TextureDeltaScan ; C1+C2 3 ; calculate whole step + v carry
mov IintNoCarry,esp ; C3 7 ; save whole step in non-i-carry slot
mov edi,_SCASM_Destination
mov UVintVfracStepVCarry,eax ; C1+C2 4 ; save in v-carry slot
add esp,256 ; C3 8 ; calculate whole step + i carry
mov IintWithCarry,esp ; C3 9 ; save in i-carry slot
mov esp,_SCASM_StartI ; C4 1
mov edx,esp ; C4 2
mov esi,_SCASM_StartU ; C5 1 ; get u 16.16 fixedpoint coordinate
sar esp,16-8 ; C4 3
mov ebx,esi ; C5 2 ; copy it
sar edx,8 ; C4 4
mov ecx,_SCASM_StartV ; C6 1 ; get v 16.16 fixedpoint coordinate
sar esi,16 ; C5 3 ; get integer part
mov eax,[edi] ; preread destination
shl ebx,16 ; C5 4 ; get fractional part
mov eax,ecx ; C6 2 ; copy it
sar eax,16 ; C6 3 ; get integer part
and esp,0xffffff00h ; C4 5
shl ecx,16 ; C6 4 ; get fractional part shift [tears removal]
add esp,_SCASM_Lighting ; C4 6
imul eax,_SCASM_TextureDeltaScan ; C6 5 ; calc texture scanline address
add esi,eax ; C7 1 ; calc texture offset
xor eax,eax
add esi,_SCASM_Bitmap ; C7 2 ; calc address
test ebp,ebp
sar ebx,16
sar ecx,16
mov eax,_SCASM_DeltaU
mov bl,ah
mov eax,_SCASM_DeltaV
mov cl,ah
mov esp,[PixelsRemaining]
add edi,esp
neg esp
; mov eax,edx
; add ch,cl
jmp G3D_EndPixels
jz G3D_EndPixels
if 1
G3D_ScanLoop:
; 8 pixel span code
; edi = dest dib bits at current pixel
; esi = texture pointer at current u,v
; esp = lighting pointer
; ebx = u fraction 0.32
; ecx = v fraction 0.32
; edx = i fraction 0.32
; ebp = carry scratch
; mov al,[edi] ; preread the destination cache line
mov al,[esi] ; get texture pixel 0
add ecx,DeltaVFrac;test to remove tears
sbb ebp,ebp ; get -1 if carry
add ebx,DeltaUFrac
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
add edx,DeltaIFrac
sbb ebp,ebp
mov al,[esp+eax]
add esp,[4*ebp + IintStep]
add ecx,DeltaVFrac;test to remove tears
sbb ebp,ebp ; get -1 if carry
mov [edi],al ; store pixel 0
add ebx,DeltaUFrac
mov al,[esi] ; get texture pixel 1
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
add edx,DeltaIFrac
sbb ebp,ebp
mov al,[esp+eax]
add esp,[4*ebp + IintStep]
add ecx,DeltaVFrac;test to remove tears
sbb ebp,ebp ; get -1 if carry
mov [edi+1],al ; store pixel 1
add ebx,DeltaUFrac
mov al,[esi] ; get texture pixel 2
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
add edx,DeltaIFrac
sbb ebp,ebp
mov al,[esp+eax]
add esp,[4*ebp + IintStep]
add ecx,DeltaVFrac;test to remove tears
sbb ebp,ebp ; get -1 if carry
mov [edi+2],al ; store pixel 2
add ebx,DeltaUFrac
mov al,[esi] ; get texture pixel 3
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
add edx,DeltaIFrac
sbb ebp,ebp
mov al,[esp+eax]
add esp,[4*ebp + IintStep]
add ecx,DeltaVFrac;test to remove tears
sbb ebp,ebp ; get -1 if carry
mov [edi+3],al ; store pixel 3
add ebx,DeltaUFrac
mov al,[esi] ; get texture pixel 4
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
add edx,DeltaIFrac
sbb ebp,ebp
mov al,[esp+eax]
add esp,[4*ebp + IintStep]
add ecx,DeltaVFrac;test to remove tears
sbb ebp,ebp ; get -1 if carry
mov [edi+4],al ; store pixel 4
add ebx,DeltaUFrac
mov al,[esi] ; get texture pixel 5
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
add edx,DeltaIFrac
sbb ebp,ebp
mov al,[esp+eax]
add esp,[4*ebp + IintStep]
add ecx,DeltaVFrac;test to remove tears
sbb ebp,ebp ; get -1 if carry
mov [edi+5],al ; store pixel 5
add ebx,DeltaUFrac
mov al,[esi] ; get texture pixel 6
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
add edx,DeltaIFrac
sbb ebp,ebp
mov al,[esp+eax]
add esp,[4*ebp + IintStep]
add ecx,DeltaVFrac;test to remove tears
sbb ebp,ebp ; get -1 if carry
mov [edi+6],al ; store pixel 6
add ebx,DeltaUFrac
mov al,[esi] ; get texture pixel 7
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
add edx,DeltaIFrac
sbb ebp,ebp
mov al,[esp+eax]
add esp,[4*ebp + IintStep]
dec Wholesections ; decrement span count
mov [edi+7],al ; store pixel 7
lea edi,[edi+8]
jnz G3D_ScanLoop ; loop back
endif
mov eax,[PixelsRemaining]
test eax,eax
jz G3D_finish
G3D_EndPixels:
add ch,cl
mov eax,edx
sbb ebp,ebp ; get -1 if carry
mov al,[esi]
inc esp
add bh,bl
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
add edx,DeltaIFrac
mov al,[eax+_TLT]
test esp,esp
mov [edi+esp],al
jnz G3D_EndPixels
G3D_finish:
mov esp, [StackStore]
popad
ret
endif
;
;
; NEW CODE
;
;
if 1
align
PUBLIC ScanDraw2D_Gouraud_
PUBLIC _ScanDraw2D_Gouraud
ScanDraw2D_Gouraud_:
_ScanDraw2D_Gouraud:
; calculate horizontal deltas
pushad
mov [StackStore],esp
mov eax,_SCASM_ScanLength
mov ebp,eax
and eax,7
shr ebp,3
mov [PixelsRemaining],eax
mov [Wholesections],ebp ; store widths
mov eax,_SCASM_DeltaV ; C1 1 ; get v 16.16 step
mov edx,_SCASM_DeltaU ; C2 1 ; get u 16.16 step
mov ebx,eax ; C1 2 ; copy v 16.16 step
sar eax,16 ; C1 3 ; get v int step
mov ecx,edx ; C2 2 ; copy u 16.16 step
shl ebx,16 ; C1 4 ; get v frac step
mov esi,_SCASM_DeltaI ; C3 1 ; get i 16.16 step
sar edx,16 ; C2 3 ; get u int step
mov esp,esi ; C3 2 ; copy i 16.16 step
shl ecx,16 ; C2 4 ; get u frac step
mov DeltaVFrac,ebx ; C1 5 ; store it
imul eax,_SCASM_TextureDeltaScan ; C1 6 ; calculate texture step for v int step
sar esp,16-8 ; C3 3 ; get i int step
mov DeltaUFrac,ecx ; C2 5 ; store it
shl esi,16 ; C3 4 ; get i frac step
add eax,edx ; C1+C2 1 ; calculate uint + vint step
mov DeltaIFrac,esi ; C3 5 ; store it
mov UVintVfracStepVNoCarry,eax ; C1+C2 2 ; save whole step in non-v-carry slot
and esp,0xffffff00h ; C3 6
add eax,_SCASM_TextureDeltaScan ; C1+C2 3 ; calculate whole step + v carry
mov IintNoCarry,esp ; C3 7 ; save whole step in non-i-carry slot
mov edi,_SCASM_Destination
mov UVintVfracStepVCarry,eax ; C1+C2 4 ; save in v-carry slot
add esp,256 ; C3 8 ; calculate whole step + i carry
mov IintWithCarry,esp ; C3 9 ; save in i-carry slot
mov esp,_SCASM_StartI ; C4 1
mov edx,esp ; C4 2
mov esi,_SCASM_StartU ; C5 1 ; get u 16.16 fixedpoint coordinate
sar esp,16-8 ; C4 3
mov ebx,esi ; C5 2 ; copy it
shl edx,16 ; C4 4
mov ecx,_SCASM_StartV ; C6 1 ; get v 16.16 fixedpoint coordinate
sar esi,16 ; C5 3 ; get integer part
mov eax,[edi] ; preread destination
; shl ebx,16 ; C5 4 ; get fractional part
and ebx,0xffffh
mov eax,ecx ; C6 2 ; copy it
sar eax,16 ; C6 3 ; get integer part
and esp,0xffffff00h ; C4 5
; shl ecx,16 ; C6 4 ; get fractional part shift [tears removal]
and ecx,0xffffh
add esp,_SCASM_Lighting ; C4 6
imul eax,_SCASM_TextureDeltaScan ; C6 5 ; calc texture scanline address
add esi,eax ; C7 1 ; calc texture offset
mov eax,_SCASM_DeltaU
mov bl,ah
mov eax,_SCASM_DeltaV
mov cl,ah
xor eax,eax
add esi,_SCASM_Bitmap ; C7 2 ; calc address
test ebp,ebp
; jmp G3D_EndPixels
jz G3D_EndPixels
if 1
G3D_ScanLoop:
; 8 pixel span code
; edi = dest dib bits at current pixel
; esi = texture pointer at current u,v
; esp = lighting pointer
; ebx = u fraction 0.32
; ecx = v fraction 0.32
; edx = i fraction 0.32
; ebp = carry scratch
; mov al,[edi] ; preread the destination cache line
mov al,[esi] ; get texture pixel 0
; add ecx,DeltaVFrac;test to remove tears
add ch,cl
sbb ebp,ebp ; get -1 if carry
; add ebx,DeltaUFrac
add bh,bl
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
add edx,DeltaIFrac
sbb ebp,ebp
mov al,[esp+eax]
add esp,[4*ebp + IintStep]
; add ecx,DeltaVFrac;test to remove tears
add ch,cl
sbb ebp,ebp ; get -1 if carry
mov [edi],al ; store pixel 0
; add ebx,DeltaUFrac
add bh,bl
mov al,[esi] ; get texture pixel 1
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
add edx,DeltaIFrac
sbb ebp,ebp
mov al,[esp+eax]
add esp,[4*ebp + IintStep]
; add ecx,DeltaVFrac;test to remove tears
add ch,cl
sbb ebp,ebp ; get -1 if carry
mov [edi+1],al ; store pixel 1
; add ebx,DeltaUFrac
add bh,bl
mov al,[esi] ; get texture pixel 2
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
add edx,DeltaIFrac
sbb ebp,ebp
mov al,[esp+eax]
add esp,[4*ebp + IintStep]
; add ecx,DeltaVFrac;test to remove tears
add ch,cl
sbb ebp,ebp ; get -1 if carry
mov [edi+2],al ; store pixel 2
; add ebx,DeltaUFrac
add bh,bl
mov al,[esi] ; get texture pixel 3
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
add edx,DeltaIFrac
sbb ebp,ebp
mov al,[esp+eax]
add esp,[4*ebp + IintStep]
; add ecx,DeltaVFrac;test to remove tears
add ch,cl
sbb ebp,ebp ; get -1 if carry
mov [edi+3],al ; store pixel 3
; add ebx,DeltaUFrac
add bh,bl
mov al,[esi] ; get texture pixel 4
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
add edx,DeltaIFrac
sbb ebp,ebp
mov al,[esp+eax]
add esp,[4*ebp + IintStep]
; add ecx,DeltaVFrac;test to remove tears
add ch,cl
sbb ebp,ebp ; get -1 if carry
mov [edi+4],al ; store pixel 4
; add ebx,DeltaUFrac
add bh,bl
mov al,[esi] ; get texture pixel 5
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
add edx,DeltaIFrac
sbb ebp,ebp
mov al,[esp+eax]
add esp,[4*ebp + IintStep]
; add ecx,DeltaVFrac;test to remove tears
add ch,cl
sbb ebp,ebp ; get -1 if carry
mov [edi+5],al ; store pixel 5
; add ebx,DeltaUFrac
add bh,bl
mov al,[esi] ; get texture pixel 6
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
add edx,DeltaIFrac
sbb ebp,ebp
mov al,[esp+eax]
add esp,[4*ebp + IintStep]
; add ecx,DeltaVFrac;test to remove tears
add ch,cl
sbb ebp,ebp ; get -1 if carry
mov [edi+6],al ; store pixel 6
; add ebx,DeltaUFrac
add bh,bl
mov al,[esi] ; get texture pixel 7
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
add edx,DeltaIFrac
sbb ebp,ebp
mov al,[esp+eax]
add esp,[4*ebp + IintStep]
dec Wholesections ; decrement span count
mov [edi+7],al ; store pixel 7
lea edi,[edi+8]
jnz G3D_ScanLoop ; loop back
endif
mov eax,[PixelsRemaining]
test eax,eax
jz G3D_finish
G3D_EndPixels:
mov eax,[esi]
add ch,cl
; add ecx,DeltaVFrac
sbb ebp,ebp ; get -1 if carry
and eax,0xffh
add bh,bl
; add ebx,DeltaUFrac
lea edi,[edi+1]
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
add edx,DeltaIFrac
sbb ebp,ebp
mov al,[esp+eax]
mov [edi-1],al
mov eax,[PixelsRemaining]
add esp,[4*ebp + IintStep]
dec eax
; dec [PixelsRemaining]
mov [PixelsRemaining],eax
jnz G3D_EndPixels
G3D_finish:
mov esp, [StackStore]
popad
ret
endif
;
;
; NEW CODE
;
;
align
PUBLIC ScanDraw2D_GouraudTransparent_
PUBLIC _ScanDraw2D_GouraudTransparent
ScanDraw2D_GouraudTransparent_:
_ScanDraw2D_GouraudTransparent:
; calculate horizontal deltas
pushad
mov [StackStore],esp
mov eax,_SCASM_ScanLength
mov [PixelsRemaining],eax
mov eax,_SCASM_DeltaV ; get v 16.16 step
mov ebx,eax ; copy it
sar eax,16 ; get v int step
shl ebx,16 ; get v frac step
mov DeltaVFrac,ebx ; store it
imul eax,_SCASM_TextureDeltaScan ; calculate texture step for v int step
mov ebx,_SCASM_DeltaU ; get u 16.16 step
mov ecx,ebx ; copy it
sar ebx,16 ; get u int step
shl ecx,16 ; get u frac step
mov DeltaUFrac,ecx ; store it
add eax,ebx ; calculate uint + vint step
mov UVintVfracStepVNoCarry,eax; save whole step in non-v-carry slot
add eax,_SCASM_TextureDeltaScan ; calculate whole step + v carry
mov UVintVfracStepVCarry,eax ; save in v-carry slot
; setup initial coordinates
mov edx,_SCASM_DeltaI ; get i 16.16 step
mov eax,edx ; copy it
sar eax,16 ; get i int step
shl edx,16 ; get i frac step
mov DeltaIFrac,edx ; store it
imul eax,_SCASM_ShadingTableSize
mov IintNoCarry,eax ; save whole step in non-i-carry slot
add eax,_SCASM_ShadingTableSize ; calculate whole step + i carry
mov IintWithCarry,eax ; save in i-carry slot
mov esp,_SCASM_StartI
mov edx,esp
sar esp,16
shl edx,16
imul esp,_SCASM_ShadingTableSize
add esp,_SCASM_Lighting
mov esi,_SCASM_StartU ; get u 16.16 fixedpoint coordinate
mov ebx,esi ; copy it
sar esi,16 ; get integer part
shl ebx,16 ; get fractional part
mov ecx,_SCASM_StartV ; get v 16.16 fixedpoint coordinate
mov eax,ecx ; copy it
sar eax,16 ; get integer part
shl ecx,16 ; get fractional part shift [tears removal]
imul eax,_SCASM_TextureDeltaScan ; calc texture scanline address
add esi,eax ; calc texture offset
add esi,_SCASM_Bitmap ; calc address
; mov eax,_SCASM_DeltaU
; mov bl,ah
; mov eax,_SCASM_DeltaV
; mov cl,ah
xor eax,eax
mov edi,_SCASM_Destination
G2DT_EndPixels:
mov al,[esi] ; get texture pixel
add ecx,DeltaVFrac;test to remove tears
sbb ebp,ebp ; get -1 if carry
test eax,eax
jz G2DT_SkipPixel
mov al,[esp+eax] ; store pixel 0
mov [edi],al
G2DT_SkipPixel:
lea edi,[edi+1]
add ebx,DeltaUFrac
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
add edx,DeltaIFrac
sbb ebp,ebp
add esp,[4*ebp + IintStep]
dec [PixelsRemaining]
jnz G2DT_EndPixels
mov esp, [StackStore]
popad
ret
align
PUBLIC ScanDraw2D_Opaque_
PUBLIC _ScanDraw2D_Opaque
ScanDraw2D_Opaque_:
_ScanDraw2D_Opaque:
; calculate horizontal deltas
pushad
mov [StackStore],esp
mov eax,_SCASM_ScanLength
mov ebp,eax
and eax,7
shr ebp,3
mov [PixelsRemaining],eax
mov [Wholesections],ebp ; store widths
mov eax,_SCASM_DeltaV ; get v 16.16 step
mov ebx,eax ; copy it
sar eax,16 ; get v int step
shl ebx,16 ; get v frac step
mov DeltaVFrac,ebx ; store it
;shl eax,7
imul eax,_SCASM_TextureDeltaScan ; calculate texture step for v int step
mov ebx,_SCASM_DeltaU ; get u 16.16 step
mov ecx,ebx ; copy it
sar ebx,16 ; get u int step
shl ecx,16 ; get u frac step
mov DeltaUFrac,ecx ; store it
add eax,ebx ; calculate uint + vint step
mov UVintVfracStepVNoCarry,eax; save whole step in non-v-carry slot
add eax,_SCASM_TextureDeltaScan ; calculate whole step + v carry
mov UVintVfracStepVCarry,eax ; save in v-carry slot
; setup initial coordinates
mov esi,_SCASM_StartU ; get u 16.16 fixedpoint coordinate
mov ebx,esi ; copy it
sar esi,16 ; get integer part
shl ebx,16 ; get fractional part
mov ecx,_SCASM_StartV ; get v 16.16 fixedpoint coordinate
mov edx,ecx ; copy it
sar edx,16 ; get integer part
shl ecx,16 ; get fractional part
; shl edx,7
imul edx,_SCASM_TextureDeltaScan ; calc texture scanline address
add esi,edx ; calc texture offset
add esi,_SCASM_Bitmap ; calc address
mov edx,DeltaUFrac ; get register copy
mov esp,DeltaVFrac
mov edi,_SCASM_Destination
test ebp,ebp
jz O2D_EndPixels
if 1
O2D_ScanLoop:
; 8 pixel span code
; edi = dest dib bits at current pixel
; esi = texture pointer at current u,v
; ebx = u fraction 0.32
; ecx = v fraction 0.32
; edx = u frac step
; ebp = v carry scratch
; mov al,[edi] ; preread the destination cache line
mov al,[esi] ; get texture pixel 0
add ecx,esp ; increment v fraction
sbb ebp,ebp ; get -1 if carry
add ebx,edx ; increment u fraction
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
add ecx,esp ; increment v fraction
sbb ebp,ebp ; get -1 if carry
mov [edi+0],al ; store pixel 0
add ebx,edx ; increment u fraction
mov al,[esi] ; get texture pixel 1
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
add ecx,esp ; increment v fraction
sbb ebp,ebp ; get -1 if carry
mov [edi+1],al ; store pixel 1
add ebx,edx ; increment u fraction
mov al,[esi] ; get texture pixel 2
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
add ecx,esp ; increment v fraction
sbb ebp,ebp ; get -1 if carry
mov [edi+2],al ; store pixel 2
add ebx,edx ; increment u fraction
mov al,[esi] ; get texture pixel 3
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
add ecx,esp ; increment v fraction
sbb ebp,ebp ; get -1 if carry
mov [edi+3],al ; store pixel 3
add ebx,edx ; increment u fraction
mov al,[esi] ; get texture pixel 4
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
add ecx,esp ; increment v fraction
sbb ebp,ebp ; get -1 if carry
mov [edi+4],al ; store pixel 4
add ebx,edx ; increment u fraction
mov al,[esi] ; get texture pixel 5
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
add ecx,esp ; increment v fraction
sbb ebp,ebp ; get -1 if carry
mov [edi+5],al ; store pixel 5
add ebx,edx ; increment u fraction
mov al,[esi] ; get texture pixel 6
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
add ecx,esp ; increment v fraction
sbb ebp,ebp ; get -1 if carry
mov [edi+6],al ; store pixel 6
add ebx,edx ; increment u fraction
mov al,[esi] ; get texture pixel 7
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
mov [edi+7],al ; store pixel 7
add edi,8 ; increment to next span
dec Wholesections ; decrement span count
jnz O2D_ScanLoop ; loop back
endif
mov eax,[PixelsRemaining]
test eax,eax
jz O2D_finish
O2D_EndPixels:
mov al,[esi] ; get texture pixel
add ecx,esp ; increment v fraction
sbb ebp,ebp ; get -1 if carry
add ebx,edx ; increment u fraction
mov [edi],al ; store pixel
lea edi,[edi+1]
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
dec [PixelsRemaining]
jnz O2D_EndPixels
O2D_finish:
mov esp, [StackStore]
popad
ret
align
PUBLIC ScanDraw2D_Transparent_
PUBLIC _ScanDraw2D_Transparent
ScanDraw2D_Transparent_:
_ScanDraw2D_Transparent:
; calculate horizontal deltas
pushad
mov [StackStore],esp
mov ebp,_SCASM_ScanLength
mov [PixelsRemaining],ebp
mov eax,_SCASM_DeltaV ; get v 16.16 step
mov ebx,eax ; copy it
sar eax,16 ; get v int step
shl ebx,16 ; get v frac step
mov DeltaVFrac,ebx ; store it
;shl eax,7
imul eax,_SCASM_TextureDeltaScan ; calculate texture step for v int step
mov ebx,_SCASM_DeltaU ; get u 16.16 step
mov ecx,ebx ; copy it
sar ebx,16 ; get u int step
shl ecx,16 ; get u frac step
mov DeltaUFrac,ecx ; store it
add eax,ebx ; calculate uint + vint step
mov UVintVfracStepVNoCarry,eax; save whole step in non-v-carry slot
add eax,_SCASM_TextureDeltaScan ; calculate whole step + v carry
mov UVintVfracStepVCarry,eax ; save in v-carry slot
; setup initial coordinates
mov esi,_SCASM_StartU ; get u 16.16 fixedpoint coordinate
mov ebx,esi ; copy it
sar esi,16 ; get integer part
shl ebx,16 ; get fractional part
mov ecx,_SCASM_StartV ; get v 16.16 fixedpoint coordinate
mov edx,ecx ; copy it
sar edx,16 ; get integer part
shl ecx,16 ; get fractional part
; shl edx,7
imul edx,_SCASM_TextureDeltaScan ; calc texture scanline address
add esi,edx ; calc texture offset
add esi,_SCASM_Bitmap ; calc address
mov edx,DeltaUFrac ; get register copy
mov esp,DeltaVFrac
mov edi,_SCASM_Destination
T2D_EndPixels:
mov al,[esi] ; get texture pixel
add ecx,esp ; increment v fraction
sbb ebp,ebp ; get -1 if carry
test al,al
jz T2D_SkipPixel
mov [edi],al ; store pixel
T2D_SkipPixel:
lea edi,[edi+1]
add ebx,edx ; increment u fraction
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
dec [PixelsRemaining]
jnz T2D_EndPixels
mov esp, [StackStore]
popad
ret
align
PUBLIC ScanDraw2D_TransparentLit_
PUBLIC _ScanDraw2D_TransparentLit
ScanDraw2D_TransparentLit_:
_ScanDraw2D_TransparentLit:
; calculate horizontal deltas
pushad
mov [StackStore],esp
mov ebp,_SCASM_ScanLength
mov [PixelsRemaining],ebp
mov esp,_SCASM_StartI
imul esp,_SCASM_ShadingTableSize
add esp,_SCASM_Lighting
mov eax,_SCASM_DeltaV ; get v 16.16 step
mov ebx,eax ; copy it
sar eax,16 ; get v int step
shl ebx,16 ; get v frac step
mov DeltaVFrac,ebx ; store it
;shl eax,7
imul eax,_SCASM_TextureDeltaScan ; calculate texture step for v int step
mov ebx,_SCASM_DeltaU ; get u 16.16 step
mov ecx,ebx ; copy it
sar ebx,16 ; get u int step
shl ecx,16 ; get u frac step
mov DeltaUFrac,ecx ; store it
add eax,ebx ; calculate uint + vint step
mov UVintVfracStepVNoCarry,eax; save whole step in non-v-carry slot
add eax,_SCASM_TextureDeltaScan ; calculate whole step + v carry
mov UVintVfracStepVCarry,eax ; save in v-carry slot
; setup initial coordinates
mov esi,_SCASM_StartU ; get u 16.16 fixedpoint coordinate
mov ebx,esi ; copy it
sar esi,16 ; get integer part
shl ebx,16 ; get fractional part
mov ecx,_SCASM_StartV ; get v 16.16 fixedpoint coordinate
mov edx,ecx ; copy it
sar edx,16 ; get integer part
shl ecx,16 ; get fractional part
; shl edx,7
imul edx,_SCASM_TextureDeltaScan ; calc texture scanline address
add esi,edx ; calc texture offset
add esi,_SCASM_Bitmap ; calc address
mov edx,DeltaUFrac ; get register copy
; mov esp,DeltaVFrac
mov edi,_SCASM_Destination
xor eax,eax
TL2D_EndPixels:
mov al,[esi] ; get texture pixel
add ecx,DeltaVFrac ; increment v fraction
sbb ebp,ebp ; get -1 if carry
test al,al
jz TL2D_SkipPixel
mov al,[eax+esp]
mov [edi],al ; store pixel
TL2D_SkipPixel:
lea edi,[edi+1]
add ebx,edx ; increment u fraction
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
dec [PixelsRemaining]
jnz TL2D_EndPixels
mov esp, [StackStore]
popad
ret
if 0
PUBLIC MotionTrackerRotateBlit_
MotionTrackerRotateBlit_:
; calculate horizontal deltas
pushad
mov [StackStore],esp
mov eax,_MTRB_Angle
mov eax,[_cosine + eax * 4]
shl eax,16 - 7
imul [_MTRB_InvScale]
shrd eax,edx,16
mov [dUCol],eax
mov eax,[_MTRB_Angle]
mov eax,[_sine + eax * 4]
shl eax,16 - 7
imul [_MTRB_InvScale]
shrd eax,edx,16
mov [dVCol],eax
mov esp,eax
; calculate vertical deltas
mov eax,[dVCol]
neg eax
; imul [aspectAdjust]
; shrd eax,edx,16
mov [dURow],eax
mov eax,[dUCol]
; imul [aspectAdjust]
; shrd eax,edx,16
mov [dVRow],eax
mov eax,_MTRB_CentreU ; put CentreU&V in 16.16 for now
shl eax,16-7
mov [startingU],eax
mov eax,_MTRB_CentreV
shl eax,16-7
mov [startingV],eax
; move up by yOrg
mov eax,[dUCol]
imul eax,_MTRB_ScreenCentreX
sub [startingU],eax
mov eax,[dURow]
imul eax,_MTRB_ScreenCentreY
sub [startingU],eax
mov eax,[dVCol]
imul eax,_MTRB_ScreenCentreX
sub [startingV],eax
mov eax,[dVRow]
imul eax,_MTRB_ScreenCentreY
sub [startingV],eax
; fixup end of row deltas
mov eax,[dUCol]
imul eax,_MTRB_ScreenWidth
neg eax
add eax,[dURow]
mov [dURow],eax
mov eax,[dVCol]
imul eax,_MTRB_ScreenWidth
neg eax
add eax,[dVRow]
mov [dVRow],eax
mov esi,[_MTRB_Bitmap]
mov edi,[_MTRB_Destination]
mov ecx,[startingU]
mov edx,[startingV]
mov ebx,_MTRB_ScreenHeight ; initialize row count
mov ah,bl
MTRB_RowLoop:
mov ebx,_MTRB_ScreenWidth ; initialize column count
MTRB_ColLoop:
mov ebp,edx
shr ebp,32 - 7
shld ebp,ecx,7
add edx,esp
add ecx,[dUCol]
mov al,[esi+ebp]
test al,al
jz MTRB_SkipPixel
mov [edi],al
MTRB_SkipPixel:
lea edi,[edi+1]
dec ebx
jnz MTRB_ColLoop
add ecx,[dURow]
add edx,[dVRow]
add edi,[_MTRB_ScanOffset]
dec ah
jnz MTRB_RowLoop
mov esp, [StackStore]
popad
ret
PUBLIC MotionTrackerRotateBlit8_
PUBLIC _MotionTrackerRotateBlit8
MotionTrackerRotateBlit8_:
_MotionTrackerRotateBlit8:
; calculate horizontal deltas
pushad
mov [StackStore],esp
mov eax,_MTRB_Angle
mov eax,[_cosine + eax * 4]
shl eax,16 - 8
imul [_MTRB_InvScale]
shrd eax,edx,16
mov [dUCol],eax
mov eax,[_MTRB_Angle]
mov eax,[_sine + eax * 4]
shl eax,16 - 8
imul [_MTRB_InvScale]
shrd eax,edx,16
mov [dVCol],eax
mov esp,eax
; calculate vertical deltas
mov eax,[dVCol]
neg eax
; imul [aspectAdjust]
; shrd eax,edx,16
mov [dURow],eax
mov eax,[dUCol]
; imul [aspectAdjust]
; shrd eax,edx,16
mov [dVRow],eax
mov eax,_MTRB_CentreU ; put CentreU&V in 16.16 for now
shl eax,16-8
mov [startingU],eax
mov eax,_MTRB_CentreV
shl eax,16-8
mov [startingV],eax
; move up by yOrg
mov eax,[dUCol]
imul eax,_MTRB_ScreenCentreX
sub [startingU],eax
mov eax,[dURow]
imul eax,_MTRB_ScreenCentreY
sub [startingU],eax
mov eax,[dVCol]
imul eax,_MTRB_ScreenCentreX
sub [startingV],eax
mov eax,[dVRow]
imul eax,_MTRB_ScreenCentreY
sub [startingV],eax
; fixup end of row deltas
mov eax,[dUCol]
imul eax,_MTRB_ScreenWidth
neg eax
add eax,[dURow]
mov [dURow],eax
mov eax,[dVCol]
imul eax,_MTRB_ScreenWidth
neg eax
add eax,[dVRow]
mov [dVRow],eax
mov esi,[_MTRB_Bitmap]
mov edi,[_MTRB_Destination]
mov ecx,[startingU]
mov edx,[startingV]
mov ebx,_MTRB_ScreenHeight ; initialize row count
mov ah,bl
MTRB_RowLoop8:
mov ebx,_MTRB_ScreenWidth ; initialize column count
MTRB_ColLoop8:
mov ebp,edx
shr ebp,32 - 8
shld ebp,ecx,8
add edx,esp
add ecx,[dUCol]
mov al,[esi+ebp]
test al,al
jz MTRB_SkipPixel8
mov [edi],al
MTRB_SkipPixel8:
lea edi,[edi+1]
dec ebx
jnz MTRB_ColLoop8
add ecx,[dURow]
add edx,[dVRow]
add edi,[_MTRB_ScanOffset]
dec ah
jnz MTRB_RowLoop8
mov esp, [StackStore]
popad
ret
endif
; floating point test area
if 0
PUBLIC ScanDrawF3D_Gouraud_
ScanDrawF3D_Gouraud_:
; calculate horizontal deltas
pushad
; put the FPU in 32 bit mode
; @todo move this out of here!
; fstcw [OldFPUCW] ; store copy of CW
; mov ax,OldFPUCW ; get it in ax
; and eax,NOT 1100000000y ; 24 bit precision
; mov [FPUCW],ax ; store it
; fldcw [FPUCW] ; load the FPU
finit
; mov [StackStore],esp
mov eax,_SCASM_ScanLength
mov ebp,eax
and eax,7
shr ebp,3
mov [PixelsRemaining],eax
mov [Wholesections],ebp ; store widths
if 0
; setup initial coordinates
mov edx,_SCASM_DeltaI ; get i 16.16 step
mov eax,edx ; copy it
sar eax,16 ; get i int step
shl edx,16 ; get i frac step
mov DeltaIFrac,edx ; store it
imul eax,_SCASM_ShadingTableSize
mov IintNoCarry,eax ; save whole step in non-i-carry slot
add eax,_SCASM_ShadingTableSize ; calculate whole step + i carry
mov IintWithCarry,eax ; save in i-carry slot
mov esp,_SCASM_StartI
mov edx,esp
sar esp,16
shl edx,16
imul esp,_SCASM_ShadingTableSize
add esp,_SCASM_Lighting
endif
;******************************************************************************************
mov ebx,_ScanDescPtr
; calculate ULeft and VLeft ; FPU Stack (ZL = ZLeft)
; st0 st1 st2 st3 st4 st5 st6 st7
fld DWORD PTR [ebx+4] ; V/ZL
fld DWORD PTR [ebx] ; U/ZL V/ZL
fld DWORD PTR [ebx+8] ; 1/ZL U/ZL V/ZL
fld1 ; 1 1/ZL U/ZL V/ZL
fdiv st,st(1) ; ZL 1/ZL U/ZL V/ZL
fld st ; ZL ZL 1/ZL U/ZL V/ZL
fmul st,st(4) ; VL ZL 1/ZL U/ZL V/ZL
fxch st(1) ; ZL VL 1/ZL U/ZL V/ZL
fmul st,st(3) ; UL VL 1/ZL U/ZL V/ZL
fstp st(5) ; VL 1/ZL U/ZL V/ZL UL
fstp st(5) ; 1/ZL U/ZL V/ZL UL VL
; calculate right side OverZ terms ; st0 st1 st2 st3 st4 st5 st6 st7
fadd DWORD PTR [ebx+20] ; 1/ZR U/ZL V/ZL UL VL
fxch st(1) ; U/ZL 1/ZR V/ZL UL VL
fadd DWORD PTR [ebx+12] ; U/ZR 1/ZR V/ZL UL VL
fxch st(2) ; V/ZL 1/ZR U/ZR UL VL
fadd DWORD PTR [ebx+16] ; V/ZR 1/ZR U/ZR UL VL
; calculate right side coords ; st0 st1 st2 st3 st4 st5 st6 st7
fld1 ; 1 V/ZR 1/ZR U/ZR UL VL
; @todo overlap this guy
fdiv st,st(2) ; ZR V/ZR 1/ZR U/ZR UL VL
fld st ; ZR ZR V/ZR 1/ZR U/ZR UL VL
fmul st,st(2) ; VR ZR V/ZR 1/ZR U/ZR UL VL
fxch st(1) ; ZR VR V/ZR 1/ZR U/ZR UL VL
fmul st,st(4) ; UR VR V/ZR 1/ZR U/ZR UL VL
;******************************************************************************************
xor eax,eax
mov edi,_SCASM_Destination
test ebp,ebp
jz GF3D_EndPixels
GF3D_ScanLoop:
; at this point the FPU contains ; st0 st1 st2 st3 st4 st5 st6 st7
; UR VR V/ZR 1/ZR U/ZR UL VL
; convert left side coords
fld st(5) ; UL UR VR V/ZR 1/ZR U/ZR UL VL
fmul [FixedScale] ; UL16 UR VR V/ZR 1/ZR U/ZR UL VL
fistp [_SCASM_StartU] ; UR VR V/ZR 1/ZR U/ZR UL VL
fld st(6) ; VL UR VR V/ZR 1/ZR U/ZR UL VL
fmul [FixedScale] ; VL16 UR VR V/ZR 1/ZR U/ZR UL VL
fistp [_SCASM_StartV] ; UR VR V/ZR 1/ZR U/ZR UL VL
; calculate deltas ; st0 st1 st2 st3 st4 st5 st6 st7
fsubr st(5),st ; UR VR V/ZR 1/ZR U/ZR dU VL
fxch st(1) ; VR UR V/ZR 1/ZR U/ZR dU VL
fsubr st(6),st ; VR UR V/ZR 1/ZR U/ZR dU dV
fxch st(6) ; dV UR V/ZR 1/ZR U/ZR dU VR
fmul [FixedScale8] ; dV8 UR V/ZR 1/ZR U/ZR dU VR
fistp [_SCASM_DeltaV] ; UR V/ZR 1/ZR U/ZR dU VR
fxch st(4) ; dU V/ZR 1/ZR U/ZR UR VR
fmul [FixedScale8] ; dU8 V/ZR 1/ZR U/ZR UR VR
fistp [_SCASM_DeltaU] ; V/ZR 1/ZR U/ZR UR VR
; increment terms for next span ; st0 st1 st2 st3 st4 st5 st6 st7
; Right terms become Left terms---->; V/ZL 1/ZL U/ZL UL VL
mov ebx,_ScanDescPtr
fadd DWORD PTR [ebx+16] ; V/ZR 1/ZL U/ZL UL VL
fxch st(1) ; 1/ZL V/ZR U/ZL UL VL
fadd DWORD PTR [ebx+20] ; 1/ZR V/ZR U/ZL UL VL
fxch st(2) ; U/ZL V/ZR 1/ZR UL VL
fadd DWORD PTR [ebx+12] ; U/ZR V/ZR 1/ZR UL VL
fxch st(2) ; 1/ZR V/ZR U/ZR UL VL
fxch st(1) ; V/ZR 1/ZR U/ZR UL VL
; calculate right side coords ; st0 st1 st2 st3 st4 st5 st6 st7
fld1 ; 1 V/ZR 1/ZR U/ZR UL VL
fdiv st,st(2) ; ZR V/ZR 1/ZR U/ZR UL VL
; set up affine registers
; setup delta values
mov eax,_SCASM_DeltaV ; get v 16.16 step
mov ebx,eax ; copy it
sar eax,16 ; get v int step
shl ebx,16 ; get v frac step
mov DeltaVFrac,ebx ; store it
imul eax,_SCASM_TextureDeltaScan ; calculate texture step for v int step
mov ebx,_SCASM_DeltaU ; get u 16.16 step
mov ecx,ebx ; copy it
sar ebx,16 ; get u int step
shl ecx,16 ; get u frac step
mov DeltaUFrac,ecx ; store it
add eax,ebx ; calculate uint + vint step
mov UVintVfracStepVNoCarry,eax; save whole step in non-v-carry slot
add eax,_SCASM_TextureDeltaScan ; calculate whole step + v carry
mov UVintVfracStepVCarry,eax ; save in v-carry slot
mov esi,_SCASM_StartU ; get u 16.16 fixedpoint coordinate
mov ebx,esi ; copy it
sar esi,16 ; get integer part
shl ebx,16 ; get fractional part
mov ecx,_SCASM_StartV ; get v 16.16 fixedpoint coordinate
mov eax,ecx ; copy it
sar eax,16 ; get integer part
shl ecx,16 ; get fractional part shift [tears removal]
imul eax,_SCASM_TextureDeltaScan ; calc texture scanline address
add esi,eax ; calc texture offset
add esi,_SCASM_Bitmap ; calc address
; 8 pixel span code
; edi = dest dib bits at current pixel
; esi = texture pointer at current u,v
; esp = lighting pointer
; ebx = u fraction 0.32
; ecx = v fraction 0.32
; edx = i fraction 0.32
; ebp = carry scratch
; mov al,[edi] ; preread the destination cache line
mov al,[esi] ; get texture pixel 0
add ecx,DeltaVFrac;test to remove tears
sbb ebp,ebp ; get -1 if carry
add ebx,DeltaUFrac
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
; add edx,DeltaIFrac
; sbb ebp,ebp
; mov al,[esp+eax]
; add esp,[4*ebp + IintStep]
add ecx,DeltaVFrac;test to remove tears
sbb ebp,ebp ; get -1 if carry
mov [edi],al ; store pixel 0
add ebx,DeltaUFrac
mov al,[esi] ; get texture pixel 1
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
; add edx,DeltaIFrac
; sbb ebp,ebp
; mov al,[esp+eax]
; add esp,[4*ebp + IintStep]
add ecx,DeltaVFrac;test to remove tears
sbb ebp,ebp ; get -1 if carry
mov [edi+1],al ; store pixel 1
add ebx,DeltaUFrac
mov al,[esi] ; get texture pixel 2
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
; add edx,DeltaIFrac
; sbb ebp,ebp
; mov al,[esp+eax]
; add esp,[4*ebp + IintStep]
add ecx,DeltaVFrac;test to remove tears
sbb ebp,ebp ; get -1 if carry
mov [edi+2],al ; store pixel 2
add ebx,DeltaUFrac
mov al,[esi] ; get texture pixel 3
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
; add edx,DeltaIFrac
; sbb ebp,ebp
; mov al,[esp+eax]
; add esp,[4*ebp + IintStep]
add ecx,DeltaVFrac;test to remove tears
sbb ebp,ebp ; get -1 if carry
mov [edi+3],al ; store pixel 3
add ebx,DeltaUFrac
mov al,[esi] ; get texture pixel 4
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
; add edx,DeltaIFrac
; sbb ebp,ebp
; mov al,[esp+eax]
; add esp,[4*ebp + IintStep]
add ecx,DeltaVFrac;test to remove tears
sbb ebp,ebp ; get -1 if carry
mov [edi+4],al ; store pixel 4
add ebx,DeltaUFrac
mov al,[esi] ; get texture pixel 5
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
; add edx,DeltaIFrac
; sbb ebp,ebp
; mov al,[esp+eax]
; add esp,[4*ebp + IintStep]
add ecx,DeltaVFrac;test to remove tears
sbb ebp,ebp ; get -1 if carry
mov [edi+5],al ; store pixel 5
add ebx,DeltaUFrac
mov al,[esi] ; get texture pixel 6
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
; add edx,DeltaIFrac
; sbb ebp,ebp
; mov al,[esp+eax]
; add esp,[4*ebp + IintStep]
add ecx,DeltaVFrac;test to remove tears
sbb ebp,ebp ; get -1 if carry
mov [edi+6],al ; store pixel 6
add ebx,DeltaUFrac
mov al,[esi] ; get texture pixel 7
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
; add edx,DeltaIFrac
; sbb ebp,ebp
; mov al,[esp+eax]
; add esp,[4*ebp + IintStep]
dec Wholesections ; decrement span count
mov [edi+7],al ; store pixel 7
lea edi,[edi+8]
; the fdiv is done, finish right ; st0 st1 st2 st3 st4 st5 st6 st7
; ZR V/ZR 1/ZR U/ZR UL VL
fld st ; ZR ZR V/ZR 1/ZR U/ZR UL VL
fmul st,st(2) ; VR ZR V/ZR 1/ZR U/ZR UL VL
fxch st(1) ; ZR VR V/ZR 1/ZR U/ZR UL VL
fmul st,st(4) ; UR VR V/ZR 1/ZR U/ZR UL VL
jnz GF3D_ScanLoop ; loop back
mov eax,[PixelsRemaining]
test eax,eax
jz GF3D_finish
GF3D_EndPixels:
if 0
mov al,[esi] ; get texture pixel
add ecx,DeltaVFrac;test to remove tears
sbb ebp,ebp ; get -1 if carry
add ebx,DeltaUFrac
lea edi,[edi+1]
mov al,[esp+eax] ; store pixel 0
adc esi,[4*ebp+UVintVfracStep] ; add in step ints & carries
add edx,DeltaIFrac
sbb ebp,ebp
mov [edi-1],al
add esp,[4*ebp + IintStep]
dec [PixelsRemaining]
jnz GF3D_EndPixels
endif
FPUReturn:
; busy FPU registers: ; st0 st1 st2 st3 st4 st5 st6 st7
; xxx xxx xxx xxx xxx xxx xxx
ffree st(0)
ffree st(1)
ffree st(2)
ffree st(3)
ffree st(4)
ffree st(5)
ffree st(6)
finit
; fldcw [OldFPUCW] ; restore the FPU
GF3D_finish:
; mov esp, [StackStore]
popad
ret
endif
_TEXT ENDS
END