Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 1244 → Rev 1245

/programs/demos/3DS/GRD_TEX.INC
0,0 → 1,929
 
 
CATMULL_SHIFT equ 8
ROUND equ 8
;NON=0
;MMX=1
;Ext=MMX
;TEX_SIZE=0x3fff
;SIZE_X equ 512
;SIZE_Y equ 512
;ROUND = 8
;TEX_SHIFT equ 6
 
; procedure drawing textured triangle with Gouraud shading
; Z-buffer alghoritm included, Z coord interpolation ----
; I set the color by this way -- (col1 * col2)/256 ------
;------------------in - eax - x1 shl 16 + y1 ------------
;---------------------- ebx - x2 shl 16 + y2 ------------
;---------------------- ecx - x3 shl 16 + y3 ------------
;---------------------- esi - pointer to Z-buffer--------
;---------------------- edx - pointer to texture---------
;---------------------- Z-buffer filled with dd variables
;---------------------- shifted CATMULL_SHIFT------------
;---------------------- edi - pointer to screen buffer---
;---------------------- stack : colors-------------------
 
 
 
tex_plus_grd_triangle:
; parameters :
.tex_y3 equ [ebp+38] ; 36 bytes through stack
.tex_x3 equ [ebp+36]
.tex_y2 equ [ebp+34]
.tex_x2 equ [ebp+32]
.tex_y1 equ [ebp+30]
.tex_x1 equ [ebp+28]
 
.z3 equ [ebp+26]
.col3b equ [ebp+24]
.col3g equ [ebp+22]
.col3r equ [ebp+20]
 
.z2 equ [ebp+18]
.col2b equ [ebp+16]
.col2g equ [ebp+14]
.col2r equ [ebp+12]
 
.z1 equ [ebp+10]
.col1b equ [ebp+8]
.col1g equ [ebp+6]
.col1r equ [ebp+4]
 
; local variables:
 
.tex_ptr equ dword[ebp-4]
.z_ptr equ dword[ebp-8]
.scr_buff equ dword[ebp-12]
 
.x1 equ word[ebp-14] ;dw ? ;equ word[ebp-10]
.y1 equ word[ebp-16] ;dw ? ;equ word[ebp-12]
.x2 equ word[ebp-18] ;dw ? ;equ word[ebp-14]
.y2 equ word[ebp-20] ;dw ? ;equ word[ebp-16]
.x3 equ word[ebp-22] ;dw ? ;equ word[ebp-18]
.y3 equ word[ebp-24] ;dw ? ;equ word[ebp-20]
 
.dx12 equ dword[ebp-28] ;dd ?
.tex_dx12 equ dword[ebp-32] ;dd ?
.tex_dy12 equ dword[ebp-36] ;dd ?
.dz12 equ dword[ebp-40] ;dd ?
.dc12r equ dword[ebp-44] ;dd ?
.dc12g equ dword[ebp-48] ;dd ?
.dc12b equ dword[ebp-52] ;dd ?
 
.dx23 equ dword[ebp-56] ;dd ?
.tex_dx23 equ dword[ebp-60] ;dd ?
.tex_dy23 equ dword[ebp-64] ;dd ?
.dz23 equ dword[ebp-68] ;dd ?
.dc23r equ dword[ebp-72] ;dd ?
.dc23g equ dword[ebp-76] ;dd ?
.dc23b equ dword[ebp-80] ;dword[ebp-8]dd ?
 
.dx13 equ dword[ebp-84] ;dd ?
.tex_dx13 equ dword[ebp-88] ;dd ?
.tex_dy13 equ dword[ebp-92] ;dd ?
.dz13 equ dword[ebp-96] ;dd ?
.dc13r equ dword[ebp-100] ;dd ?
.dc13g equ dword[ebp-104] ;dd ?
.dc13b equ dword[ebp-108] ;dd ?
 
.zz1 equ dword[ebp-112] ;dw ?
.zz2 equ dword[ebp-116] ;dw ?
.cur1r equ dword[ebp-120] ;dw ?
.cur1g equ dword[ebp-124] ;dw ?
.cur1b equ dword[ebp-128] ;dw ?
.cur2r equ dword[ebp-132] ;dw ?
.cur2g equ dword[ebp-136] ;dw ?
.cur2b equ dword[ebp-140] ;dw ?
.scan_x1 equ dword[ebp-144] ;dd ?
.scan_x2 equ dword[ebp-148] ;dd ?
.scan_y1 equ dword[ebp-152] ;dd ?
.scan_y2 equ dword[ebp-156] ;dd ?
 
 
mov ebp,esp
if Ext>=MMX
emms
end if
 
; mov .tex_ptr,edx
; mov .z_ptr,esi
; mov .scr_buff,edi
push edx esi edi
; push esi
; push edi
mov edx,80008000h ; eax,ebx,ecx are ANDd together into edx which means that
and edx,ebx ; if *all* of them are negative a sign flag is raised
and edx,ecx
and edx,eax
test edx,80008000h ; Check both X&Y at once
jne .loop2_end
 
.sort3:
cmp ax,bx
jle .sort1
xchg eax,ebx
if Ext>=MMX
movq mm0, .col1r ; exchange r, g, b, z
movq mm1, .col2r
movq .col1r ,mm1
movq .col2r ,mm0
else
mov edx,dword .col1r ; exchange both r and g
xchg edx,dword .col2r
mov dword .col1r ,edx
 
mov edx,dword .col1b ; b and z
xchg edx,dword .col2b
mov dword .col1b ,edx
end if
 
mov edx,dword .tex_x1
xchg edx,dword .tex_x2
mov dword .tex_x1 ,edx
 
.sort1:
cmp bx,cx
jle .sort2
xchg ebx,ecx
 
if Ext>=MMX
movq mm0, .col2r ; exchange r, g, b, z
movq mm1, .col3r
movq .col3r ,mm0
movq .col2r ,mm1
else
 
mov edx,dword .col2r ; r, g
xchg edx,dword .col3r
mov dword .col2r,edx
 
mov edx,dword .col2b ; b, z
xchg edx,dword .col3b
mov dword .col2b,edx
end if
 
mov edx,dword .tex_x2
xchg edx,dword .tex_x3
mov dword .tex_x2,edx
 
jmp .sort3
 
.sort2:
 
push eax ebx ecx ; store in variables
; push ebx
; push ecx
 
;****************** delta computng zone **************
;+++++++++ first zone
mov bx,.y2 ; calc delta12
sub bx,.y1
jnz .dx12_make
mov ecx,7
@@:
push dword 0
loop @b
jmp .dx12_done
.dx12_make:
 
 
mov ax,.x2
sub ax,.x1
cwde
movsx ebx,bx
shl eax,ROUND
cdq
idiv ebx
; mov .dx12,eax
push eax
 
if 0 ; Ext=SSE
movd mm0,.col1r ; 2 words r, g
pxor mm1,mm1
punpcklwd mm0,mm1
cvtpi2ps xmm0,mm0
movlhps xmm0,xmm0
movd mm0,.col1g ; 2 words b, z
punpcklwd mm0,mm1
cvtpi2ps xmm0,mm0
; xmm0=four float double words
divss xmm0,.pack3
;convert and insert mm0 to lower xmm1 ..
end if
 
mov ax,word .tex_x2
sub ax,word .tex_x1
cwde
shl eax,ROUND
cdq
idiv ebx
; mov .tex_dx12r,eax
push eax
 
mov ax,word .tex_y2
sub ax,word .tex_y1
cwde
shl eax,ROUND
cdq
idiv ebx
; mov .tex_dx12,eax
push eax
 
mov ax,word .z2
sub ax,word .z1
cwde
shl eax,CATMULL_SHIFT
cdq
idiv ebx
; mov .dz12,eax
push eax ; .dza12
 
mov ax,word .col2r
sub ax,word .col1r
cwde
shl eax,ROUND
cdq
idiv ebx
; mov .dc12r,eax
push eax
 
mov ax,word .col2g
sub ax,word .col1g
cwde
shl eax,ROUND
cdq
idiv ebx
; mov .dc12g,eax
push eax
 
mov ax,word .col2b ;;---
sub ax,word .col1b
cwde
shl eax,ROUND
cdq
idiv ebx
; mov .dc12b,eax
push eax
 
;+++++++++++++++++ second zone +++++++++++++
.dx12_done:
 
mov bx,.y3 ; calc delta23
sub bx,.y2
jnz .dx23_make
mov ecx,7
@@:
push dword 0
loop @b
jmp .dx23_done
 
.dx23_make:
mov ax,.x3
sub ax,.x2
cwde
movsx ebx,bx
shl eax,ROUND
cdq
idiv ebx
; mov .dx23,eax
push eax
 
mov ax,word .tex_x3
sub ax,word .tex_x2
cwde
shl eax,ROUND
cdq
idiv ebx
; mov .tex_dx23,eax
push eax
 
mov ax,word .tex_y3
sub ax,word .tex_y2
cwde
shl eax,ROUND
cdq
idiv ebx
; mov .tex_dy23,eax
push eax
 
mov ax,word .z3
sub ax,word .z2
cwde ;
shl eax,CATMULL_SHIFT ; 2222222
cdq ; 2 2
idiv ebx ; 2
; mov .dz23,eax ; 2
push eax ; .dza12 ; 2
; 2
mov ax,word .col3r ; 2
sub ax,word .col2r ; 2222222
cwde ; second delta
shl eax,ROUND ;
cdq ;
idiv ebx ;
; mov .dc23r,eax ;
push eax
 
mov ax,word .col3g
sub ax,word .col2g
cwde
shl eax,ROUND
cdq
idiv ebx
; mov .dc23g,eax
push eax
 
mov ax,word .col3b ;;---
sub ax,word .col2b
cwde
shl eax,ROUND
cdq
idiv ebx
; mov .dc23b,eax
push eax
 
.dx23_done:
;++++++++++++++++++third zone++++++++++++++++++++++++
mov bx,.y3 ; calc delta13
sub bx,.y1
jnz .dx13_make
mov ecx,7
@@:
push dword 0
loop @b
jmp .dx13_done
.dx13_make:
mov ax,.x3
sub ax,.x1
cwde
movsx ebx,bx
shl eax,ROUND
cdq
idiv ebx
; mov .dx13,eax
push eax
 
mov ax,word .tex_x3 ; triangle b
sub ax,word .tex_x1
cwde
shl eax,ROUND
cdq
idiv ebx
; mov .tex_dx13r,eax
push eax
 
mov ax,word .tex_y3
sub ax,word .tex_y1
cwde
shl eax,ROUND
cdq
idiv ebx
; mov .tex_dy13,eax
push eax
 
mov ax,word .z3
sub ax,word .z1 ; 333333333
cwde ; 3 3
shl eax,CATMULL_SHIFT ; 3
cdq ; 3
idiv ebx ; 3
; mov .dz13,eax ; 3
push eax ; .dza12 ; 3
; 3
mov ax,word .col3r ; 3333333333
sub ax,word .col1r ; 3
cwde ; 3
shl eax,ROUND ; 3
cdq ; 3
idiv ebx ; 3
; mov .dc13r,eax ; 3 3
push eax ; 33333333
 
mov ax,word .col3g
sub ax,word .col1g
cwde
shl eax,ROUND
cdq
idiv ebx
; mov .dc13g,eax
push eax
 
mov ax,word .col3b ;;---
sub ax,word .col1b
cwde
shl eax,ROUND
cdq
idiv ebx
; mov .dc13b,eax
push eax
 
.dx13_done:
 
; <<<<<<< ::delta zone end+++++++++++++++++++++ >>>>>>>>
sub esp,55 ;(12*4)
 
movsx eax,.x1 ; eax - cur x1
shl eax,ROUND ; ebx - cur x2
mov ebx,eax
movsx edx,word .z1
shl edx,CATMULL_SHIFT
mov .zz1,edx
mov .zz2,edx
 
movzx edi,word .col1r
shl edi,ROUND
mov .cur1r,edi
mov .cur2r,edi
movzx esi,word .col1g
shl esi,ROUND
mov .cur1g,esi
mov .cur2g,esi
movzx edx,word .col1b
shl edx,ROUND
mov .cur1b,edx
mov .cur2b,edx
 
movzx edi,word .tex_x1
shl edi,ROUND
mov .scan_x1,edi
mov .scan_x2,edi
movzx edx,word .tex_y1
shl edx,ROUND
mov .scan_y1,edx
mov .scan_y2,edx
 
mov cx,.y1
cmp cx,.y2
jge .loop1_end
.loop_1:
; push eax ebx ebp
pushad
 
push .tex_ptr
push .scr_buff
push .z_ptr
push cx
 
push .zz2
 
push .scan_x2
push .scan_y2
push .cur2r
push .cur2g
push .cur2b
 
push .zz1
 
push .scan_x1
push .scan_y1
push .cur1r
push .cur1g
push .cur1b
 
sar eax,ROUND
sar ebx,ROUND
call horizontal_tex_grd_line
 
; pop ebp ebx eax
popad
mov edx,.dc13b
add .cur1b,edx
mov esi,.dc13g
add .cur1g,esi
mov edi,.dc13r
add .cur1r,edi
mov edx,.tex_dx13
add .scan_x1,edx
mov esi,.tex_dy13
add .scan_y1,esi
mov edx,.dz13
add .zz1,edx
 
mov edi,.dc12b
add .cur2b,edi
mov esi,.dc12g
add .cur2g,esi
mov edx,.dc12r
add .cur2r,edx
mov edi,.tex_dx12
add .scan_x2,edi
mov esi,.tex_dy12
add .scan_y2,esi
mov edx,.dz12
add .zz2,edx
add eax,.dx13
add ebx,.dx12
inc cx
cmp cx,.y2
jl .loop_1
.loop1_end:
movzx ecx,.y2
cmp cx,.y3
jge .loop2_end
 
movsx ebx,.x2 ; eax - cur x1
shl ebx,ROUND ; ebx - cur x2
 
movsx edx,word .z2
shl edx,CATMULL_SHIFT
; mov .zz1,edx
mov .zz2,edx
 
movzx edi,word .col2r
shl edi,ROUND
; mov .cur1r,edi
mov .cur2r,edi
movzx esi,word .col2g
shl esi,ROUND
; mov .cur1g,esi
mov .cur2g,esi
movzx edx,word .col2b
shl edx,ROUND
; mov .cur1b,edx
mov .cur2b,edx
 
movzx edi,word .tex_x2
shl edi,ROUND
; mov .scan_x1,edi
mov .scan_x2,edi
movzx edx,word .tex_y2
shl edx,ROUND
; mov .scan_y1,edx
mov .scan_y2,edx
 
.loop_2:
pushad
 
push .tex_ptr
push .scr_buff
push .z_ptr
push cx
 
push .zz2
 
push .scan_x2
push .scan_y2
push .cur2r
push .cur2g
push .cur2b
 
push .zz1
 
push .scan_x1
push .scan_y1
push .cur1r
push .cur1g
push .cur1b
 
sar eax,ROUND
sar ebx,ROUND
call horizontal_tex_grd_line
 
popad
mov edx,.dc13b
add .cur1b,edx
mov esi,.dc13g
add .cur1g,esi
mov edi,.dc13r
add .cur1r,edi
mov edx,.tex_dx13
add .scan_x1,edx
mov esi,.tex_dy13
add .scan_y1,esi
mov edx,.dz13
add .zz1,edx
 
mov edi,.dc23b
add .cur2b,edi
mov esi,.dc23g
add .cur2g,esi
mov edx,.dc23r
add .cur2r,edx
mov edi,.tex_dx23
add .scan_x2,edi
mov esi,.tex_dy23
add .scan_y2,esi
mov edx,.dz23
add .zz2,edx
add eax,.dx13
add ebx,.dx23
inc cx
cmp cx,.y3
jl .loop_2
 
.loop2_end:
mov esp,ebp
ret 36
horizontal_tex_grd_line:
;in:
; eax : x1, ebx : x2
 
.tex_ptr equ [ebp+62]
.screen equ [ebp+58]
.z_buffer equ [ebp+54]
.y equ [ebp+52]
 
.z2 equ [ebp+48]
.tex_x2 equ [ebp+44]
.tex_y2 equ [ebp+40]
.r2 equ [ebp+36]
.g2 equ [ebp+32]
.b2 equ [ebp+28]
 
.z1 equ [ebp+24]
.tex_x1 equ [ebp+20]
.tex_y1 equ [ebp+16]
.r1 equ [ebp+12]
.g1 equ [ebp+8]
.b1 equ [ebp+4]
 
.x1 equ word[ebp-2]
.x2 equ word[ebp-4]
.dz equ dword[ebp-8]
.db equ dword[ebp-12]
.dg equ dword[ebp-16]
.dr equ dword[ebp-20]
.dtex_x equ dword[ebp-24]
.dtex_y equ dword[ebp-28]
 
.c_ty equ [ebp-32]
.c_tx equ [ebp-36]
.cb equ [ebp-40]
.cg equ [ebp-44]
.cr equ [ebp-48]
.t_col equ [ebp-52]
 
.dtex_yM equ qword[ebp-28]
.drM equ qword[ebp-20]
.dbM equ qword[ebp-12]
 
mov ebp,esp
; sub esp,30
 
mov cx,word .y
or cx,cx
jl .quit_l
 
cmp cx,SIZE_Y
jge .quit_l
 
cmp ax,bx
je .quit_l
jl @f
 
xchg eax,ebx
 
if Ext=NON
mov ecx,dword .r1
xchg ecx, .r2
mov dword .r1, ecx
 
mov ecx,dword .g1
xchg ecx, .g2
mov dword .g1, ecx
 
mov ecx,dword .b1
xchg ecx, .b2
mov dword .b1, ecx
 
mov ecx,dword .tex_x1
xchg ecx, .tex_x2
mov dword .tex_x1, ecx
 
mov ecx,dword .tex_y1
xchg ecx, .tex_y2
mov dword .tex_y1, ecx
 
mov ecx,dword .z1
xchg ecx, .z2
mov dword .z1, ecx
 
else
movq mm0,.b1 ; b, g
movq mm1,.b2
movq .b1, mm1
movq .b2, mm0
movq mm2,.r1 ; r, y
movq mm3,.r2
movq .r1,mm3
movq .r2,mm2
movq mm4,.tex_x1 ; x, z
movq mm5,.tex_x2
movq .tex_x1,mm5
movq .tex_x2,mm4
 
end if
 
@@:
or bx,bx
jle .quit_l
cmp ax,SIZE_X
jge .quit_l
 
push ax
push bx
 
mov eax,.z2 ; delta zone************
sub eax,.z1
cdq
mov bx,.x2
sub bx,.x1
movsx ebx,bx
idiv ebx
push eax ; .dz
 
mov eax,.b2
sub eax,.b1
cdq
idiv ebx
push eax ; .db
 
mov eax,.g2
sub eax,.g1
cdq
idiv ebx
push eax ; .dg
 
mov eax,.r2
sub eax,.r1
cdq
idiv ebx
push eax ; .dr
 
mov eax,.tex_x2
sub eax,.tex_x1
cdq
idiv ebx
push eax ; .dtex_x
 
mov eax,.tex_y2
sub eax,.tex_y1
cdq
idiv ebx
push eax ; .dtey_x
 
cmp .x1,0
jg @f
 
mov eax,.dz ; clipping
movsx ebx,.x1
neg ebx
imul ebx
add .z1,eax
mov .x1,0
 
mov eax,.dr
imul ebx
add .r1,eax
;if Ext=NON
mov eax,.dg
imul ebx
add .g1,eax
 
mov eax,.db
imul ebx
add .b1,eax
 
mov eax,.dtex_x
imul ebx
add .tex_x1,eax
 
mov eax,.dtex_y
imul ebx
add .tex_y1,eax
@@:
mov edx,SIZE_X
cmp .x2,dx
jl @f
mov .x2,dx
@@:
; calc line addres begin in screen and Z buffer
movsx eax,word .y
mul edx
movsx edx,.x1
add eax,edx
 
mov esi,eax
shl esi,2
add esi,.z_buffer
 
lea eax,[eax*3]
mov edi,.screen
add edi,eax
 
mov cx,.x2
sub cx,.x1
movzx ecx,cx
 
; init current variables
push dword .tex_y1
;if Ext=NON
push dword .tex_x1
 
push dword .b1
push dword .g1
push dword .r1
 
if Ext>=MMX
movq mm4,.cr ; lo -> r,g
movq mm6,.cb ; hi -> b, tex_x
pxor mm0,mm0
end if
mov ebx,.z1
.ddraw:
cmp ebx,dword[esi]
jge @f
mov eax,.c_ty
; if ROUND<TEX_SHIFT
; shl eax,TEX_SHIFT-ROUND
; end if
; if ROUND>TEX_SHIFT
; shr eax,ROUND-TEX_SHIFT
; end if
shr eax,ROUND
shl Eax,TEX_SHIFT
mov edx,.c_tx ; calc texture pixel mem addres
shr edx,ROUND
add eax,edx
and eax,TEXTURE_SIZE ; cutting
lea eax,[3*eax]
add eax,.tex_ptr
mov dword[esi],ebx
if Ext = NON
mov eax,dword[eax]
; mov .tex_col,eax
push ax
shl eax,8
pop ax
mov edx,.cr
sar edx,ROUND
mul dl ; al*dl
shr ax,8
stosb
ror eax,16
push ax
mov edx,.cg
sar edx,ROUND
mul dl
shr ax,8
stosb
pop ax
shr ax,8
mov edx,.cb
sar edx,ROUND
mul dl
shr ax,8
stosb
jmp .no_skip
else
movd mm1,[eax]
punpcklbw mm1,mm0
movq mm3,mm4 ;.cr ; lo -> r,g
movq mm5,mm6 ;.cb ; lo -> b,tex_x
psrld mm3,ROUND ;
psrld mm5,ROUND ;
packssdw mm3,mm5
pmullw mm1,mm3
psrlw mm1,8
packuswb mm1,mm0
movd [edi],mm1
end if
mov dword[esi],ebx
if Ext = NON
jmp .no_skip
end if
@@:
add edi,3
.no_skip:
add esi,4
add ebx,.dz
 
mov eax,.dtex_x
add .c_tx, eax
mov edx,.dtex_y
add .c_ty, edx
if Ext=NON
mov eax,.dr
add .cr,eax
mov edx,.dg
add .cg,edx
mov eax,.db
add .cb,eax
 
else
paddd mm4,.drM
paddd mm6,.dbM
;; paddd mm7,.dtex_y ; mm4 - b, g
;; movq .c_tx,mm7
; mm6 - r, x
end if ; mm7 - y, x
 
dec ecx
jnz .ddraw
 
.quit_l:
 
mov esp,ebp
ret 42+20 ; horizontal line