kolibrios-gitea/programs/demos/3DS/GRD3.INC

698 lines
14 KiB
Plaintext
Raw Normal View History

gouraud_triangle:
;------------------in - eax - x1 shl 16 + y1 ---------
;---------------------- ebx - x2 shl 16 + y2 ---------
;---------------------- ecx - x3 shl 16 + y3 ---------
;---------------------- edi - pointer to screen buffer
;---------------------- stack : colors----------------
;----------------- procedure don't save registers !!--
.col1r equ ebp+4 ; each color as word
.col1g equ ebp+6
.col1b equ ebp+8
.col2r equ ebp+10
.col2g equ ebp+12
.col2b equ ebp+14
.col3r equ ebp+16
.col3g equ ebp+18
.col3b equ ebp+20
.x1 equ word[ebp-2]
.y1 equ word[ebp-4]
.x2 equ word[ebp-6]
.y2 equ word[ebp-8]
.x3 equ word[ebp-10]
.y3 equ word[ebp-12]
.dx12 equ dword[ebp-16]
.dc12r equ dword[ebp-20]
.dc12g equ [ebp-24]
.dc12b equ dword[ebp-28]
.dx13 equ dword[ebp-32]
.dc13r equ dword[ebp-36]
.dc13g equ [ebp-40]
.dc13b equ dword[ebp-44]
.dx23 equ dword[ebp-48]
.dc23r equ dword[ebp-52]
.dc23g equ [ebp-56]
.dc23b equ dword[ebp-60]
.c1r equ dword[ebp-64]
.c1g equ [ebp-68]
.c1b equ dword[ebp-72]
.c2r equ dword[ebp-76]
.c2g equ [ebp-80]
.c2b equ dword[ebp-84]
mov ebp,esp
; sub esp,72
.sort3: ; sort triangle coordinates...
cmp ax,bx
jle .sort1
xchg eax,ebx
mov edx,dword[.col1r]
xchg edx,dword[.col2r]
mov dword[.col1r],edx
mov dx,word[.col1b]
xchg dx,word[.col2b]
mov word[.col1b],dx
.sort1:
cmp bx,cx
jle .sort2
xchg ebx,ecx
mov edx,dword[.col2r]
xchg edx,dword[.col3r]
mov dword[.col2r],edx
mov dx,word[.col2b]
xchg dx,word[.col3b]
mov word[.col2b],dx
jmp .sort3
.sort2:
push eax ;store triangle coordinates in user friendly variables
push ebx
push ecx
; sub esp,72 ; set correctly value of esp
mov edx,eax ; check only X triangle coordinate
or edx,ebx
or edx,ecx
test edx,80000000h
jne .gt_loop2_end
mov dx,[size_x_var]
dec dx
shr eax,16
cmp ax,dx ;SIZE_X-1
jg .gt_loop2_end
shr ebx,16
cmp bx,dx ;SIZE_X-1
jg .gt_loop2_end
shr ecx,16
cmp cx,dx ;SIZE_X-1
jg .gt_loop2_end
mov bx,.y2 ; calc deltas
sub bx,.y1
jnz .gt_dx12_make
xor edx,edx
mov ecx,4
@@:
push edx
loop @b
; mov .dx12,0
; mov .dc12r,0
; mov .dc12g,0
; mov .dc12b,0
jmp .gt_dx12_done
.gt_dx12_make:
mov ax,.x2
sub ax,.x1
cwde
movsx ebx,bx
shl eax,ROUND
cdq
idiv ebx
; mov .dx12,eax
push eax
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
.gt_dx12_done:
mov bx,.y3
sub bx,.y1
jnz .gt_dx13_make
xor edx,edx
mov ecx,4
@@:
push edx
loop @b
; mov .dx13,0
; mov .dc13r,0
; mov .dc13g,0
; mov .dc13b,0
jmp .gt_dx13_done
.gt_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[.col3r]
sub ax,word[.col1r]
cwde
shl eax,ROUND
cdq
idiv ebx
; mov .dc13r,eax
push eax
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
.gt_dx13_done:
mov bx,.y3
sub bx,.y2
jnz .gt_dx23_make
xor edx,edx
mov ecx,4
@@:
push edx
loop @b
; mov .dx23,0
; mov .dc23r,0
; mov .dc23g,0
; mov .dc23b,0
jmp .gt_dx23_done
.gt_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[.col3r]
sub ax,word[.col2r]
cwde
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
.gt_dx23_done:
sub esp,24
movsx eax,.x1
shl eax,ROUND
mov ebx,eax
movsx edx,word[.col1r]
shl edx,ROUND
mov .c1r,edx
mov .c2r,edx
movsx edx,word[.col1g]
shl edx,ROUND
mov .c1g,edx
mov .c2g,edx
movsx edx,word[.col1b]
shl edx,ROUND
mov .c1b,edx
mov .c2b,edx
mov cx,.y1
cmp cx,.y2
jge .gt_loop1_end
.gt_loop1:
push eax ; eax - cur x1
push ebx ; ebx - cur x2
push cx ; cx - cur y
push edi
push ebp
sar ebx,ROUND
push bx
mov edx,.c2r ; c2r,c2g,c2b,c1r,c1g,c1b - current colors
sar edx,ROUND
push dx
mov edx,.c2g
sar edx,ROUND
push dx
mov edx,.c2b
sar edx,ROUND
push dx
sar eax,ROUND
push ax
mov edx,.c1r
sar edx,ROUND
push dx
mov edx,.c1g
sar edx,ROUND
push dx
mov edx,.c1b
sar edx,ROUND
push dx
push cx
call gouraud_line
pop ebp
pop edi
pop cx
pop ebx
pop eax
if Ext >= MMX
movq mm0,.c1g
paddd mm0,.dc13g
movq .c1g,mm0
else
mov edx,.dc13r
add .c1r,edx
mov edx,.dc13g
add .c1g,edx
end if
mov edx,.dc13b
add .c1b,edx
if Ext >= MMX
movq mm0,.c2g
paddd mm0,.dc12g
movq .c2g,mm0
else
mov edx,.dc12r
add .c2r,edx
mov edx,.dc12g
add .c2g,edx
end if
mov edx,.dc12b
add .c2b,edx
add eax,.dx13
add ebx,.dx12
inc cx
cmp cx,.y2
jl .gt_loop1
.gt_loop1_end:
mov cx,.y2
cmp cx,.y3
jge .gt_loop2_end
movsx ebx,.x2
shl ebx,ROUND
movsx edx,word[.col2r]
shl edx,ROUND
mov .c2r,edx
movsx edx,word[.col2g]
shl edx,ROUND
mov .c2g,edx
movsx edx,word[.col2b]
shl edx,ROUND
mov .c2b,edx
.gt_loop2:
push eax ; eax - cur x1
push ebx ; ebx - cur x2
push cx
push edi
push ebp
sar ebx,ROUND
push bx
mov edx,.c2r
sar edx,ROUND
push dx
mov edx,.c2g
sar edx,ROUND
push dx
mov edx,.c2b
sar edx,ROUND
push dx
sar eax,ROUND
push ax
mov edx,.c1r
sar edx,ROUND
push dx
mov edx,.c1g
sar edx,ROUND
push dx
mov edx,.c1b
sar edx,ROUND
push dx
push cx
call gouraud_line
pop ebp
pop edi
pop cx
pop ebx
pop eax
if Ext >= MMX
movq mm0,.c1g
paddd mm0,.dc13g
movq .c1g,mm0
else
mov edx,.dc13r
add .c1r,edx
mov edx,.dc13g
add .c1g,edx
end if
mov edx,.dc13b
add .c1b,edx
if Ext >= MMX
movq mm0,.c2g
paddd mm0,.dc23g
movq .c2g,mm0
else
mov edx,.dc23r
add .c2r,edx
mov edx,.dc23g
add .c2g,edx
end if
mov edx,.dc23b
add .c2b,edx
add eax,.dx13
add ebx,.dx23
inc cx
cmp cx,.y3
jl .gt_loop2
.gt_loop2_end:
; add esp,84
mov esp,ebp
ret 18
gouraud_line:
;-------------in - edi - pointer to screen buffer
;----------------- stack - another parameters
.y equ word [ebp+4]
.col1b equ ebp+6
.col1g equ ebp+8
.col1r equ ebp+10
.x1 equ [ebp+12]
.col2b equ ebp+14
.col2g equ ebp+16
.col2r equ ebp+18
.x2 equ [ebp+20]
.dc_r equ dword[ebp-4]
.dc_g equ dword[ebp-8]
.dc_b equ dword[ebp-12]
mov ebp,esp
mov ax,.y
or ax,ax
jl .gl_quit
mov dx,[size_y_var]
dec dx
cmp ax,dx ;SIZE_Y-1
jg .gl_quit
mov ax,.x1
cmp ax,.x2
je .gl_quit
jl .gl_ok
if Ext >= MMX
movq mm0,[.col1b]
movq mm1,[.col2b]
movq [.col1b],mm1
movq [.col2b],mm0
else
mov eax,[.col1b]
xchg eax,[.col2b]
mov [.col1b],eax
mov eax,[.col1r]
xchg eax,[.col2r]
mov [.col1r],eax
end if
.gl_ok:
; cmp .x1,SIZE_X-1 ;check
; jg .gl_quit
; cmp .x2,SIZE_X-1
; jl @f
; mov .x2,SIZE_X-1
; @@:
; cmp .x1,0
; jg @f
; mov .x1,0
; @@:
; cmp .x2,0
; jl .gl_quit
movsx ecx,.y
movzx eax,word[size_x_var]
lea eax,[eax*3]
; mov eax,SIZE_X*3
mul ecx
movsx ebx,word .x1
lea ecx,[ebx*2+eax]
add edi,ecx
add edi,ebx
mov ax,word[.col2r]
sub ax,word[.col1r]
cwde
shl eax,ROUND
cdq
mov cx,.x2
sub cx,.x1
movsx ecx,cx
idiv ecx
;mov .dc_r,eax ;first delta
push eax
mov ax,word[.col2g]
sub ax,word[.col1g]
cwde
shl eax,ROUND
cdq
idiv ecx
;mov .dc_g,eax
push eax
mov ax,word[.col2b]
sub ax,word[.col1b]
cwde
shl eax,ROUND
cdq
idiv ecx
; mov .dc_b,eax
push eax
movsx ebx,word[.col1r]
shl ebx,ROUND
movsx edx,word[.col1g]
shl edx,ROUND
movsx esi,word[.col1b]
shl esi,ROUND
.gl_draw:
mov eax,ebx
sar eax,ROUND
stosb
mov eax,edx
sar eax,ROUND
stosb
mov eax,esi
sar eax,ROUND
stosb
add ebx,.dc_r
add edx,.dc_g
add esi,.dc_b
loop .gl_draw
.gl_quit:
; add esp,12
mov esp,ebp
ret 18
if 0
gouraud_line_SSE: ; new
;-------------in - edi - pointer to screen buffer
;----------------- stack - another parameters
.y equ word [ebp+4]
.col1b equ ebp+6
.col1g equ ebp+8
.col1r equ ebp+10
.x1 equ [ebp+12]
.col2b equ ebp+14
.col2g equ ebp+16
.col2r equ ebp+18
.x2 equ [ebp+20]
.dc_r equ dword[ebp-4]
.dc_g equ dword[ebp-8]
.dc_b equ dword[ebp-12]
.lenght equ [ebp-16]
.factor equ [ebp-24] ;new
mov ebp,esp
mov ax,.y
or ax,ax
jl .gl_quit
cmp ax,SIZE_Y-1
jg .gl_quit
mov ax,.x1
cmp ax,.x2
je .gl_quit
jl .gl_ok
if Ext >= MMX
movq mm0,[.col1b]
movq mm1,[.col2b]
movq [.col1b],mm1
movq [.col2b],mm0
else
mov eax,[.col1b]
xchg eax,[.col2b]
mov [.col1b],eax
mov eax,[.col1r]
xchg eax,[.col2r]
mov [.col1r],eax
end if
.gl_ok:
; cmp .x1,SIZE_X-1 ;check
; jg .gl_quit
; cmp .x2,SIZE_X-1
; jl @f
; mov .x2,SIZE_X-1
; @@:
; cmp .x1,0
; jg @f
; mov .x1,0
; @@:
; cmp .x2,0
; jl .gl_quit
movsx ecx,.y
mov eax,SIZE_X*3
mul ecx
movsx ebx,word .x1
lea ecx,[ebx*2+eax]
add edi,ecx
add edi,ebx
mov ax,word[.col2r]
sub ax,word[.col1r]
cwde
shl eax,ROUND
cdq
mov cx,.x2
sub cx,.x1
movsx ecx,cx
idiv ecx
;mov .dc_r,eax ;first delta
push eax
mov ax,word[.col2g]
sub ax,word[.col1g]
cwde
shl eax,ROUND
cdq
idiv ecx
;mov .dc_g,eax
push eax
mov ax,word[.col2b]
sub ax,word[.col1b]
cwde
shl eax,ROUND
cdq
idiv ecx
; mov .dc_b,eax
push eax
movsx ebx,word[.col1r]
shl ebx,ROUND
movsx edx,word[.col1g]
shl edx,ROUND
movsx esi,word[.col1b]
shl esi,ROUND
push ecx ; store line lenght
movd mm3,.dc_r
psrlq mm3,16 ; load dr to lowest word of mm3
pxor mm2,mm2 ; clear mm2
movd mm4,.dc_g
punpcklwd mm3,mm3 ; unpack dr to lower 2 words in in mm3
psrlq mm4,16 ; load dg to lowest word of mm4
movd mm5,.dc_b
psrlq mm5,16 ; load db to lowest word of mm5
punpcklwd mm4,mm4 ; unpack dg to lower 2 words in in mm3
lea ecx,[factor]
punpckldq mm3,mm3
punpcklwd mm5,mm5 ; unpack db to lower 2 words in in mm5
movq mm6,[.col1b]
xor eax,eax
pinsrw mm6,eax,3 ; clear the highest word in mm6
mov eax,010000h
punpckldq mm4,mm4 ; unpack dg to 4 words in mm4
mov [ecx],eax
mov eax,030002h
punpckldq mm5,mm5 ; unpack db to 4 words in mm5
movq mm7,mm6 ; load r1r1,g1g1,b1b1 to the first three
; words of mm7
pxor mm1,mm1 ; clear mm1
.gl_draw:
mov eax,ebx
sar eax,ROUND
stosb
mov eax,edx
sar eax,ROUND
stosb
mov eax,esi
sar eax,ROUND
stosb
add ebx,.dc_r
add edx,.dc_g
add esi,.dc_b
loop .gl_draw
.gl_quit:
; add esp,12
mov esp,ebp
ret 18
end if