kolibrios/programs/3dcube2/trunk/3DCUBE2.ASM

691 lines
10 KiB
NASM
Raw Normal View History

;
; 3D POLYGONAL CUBE - ASCL
;
; Pavlushin Evgeni
; mail: waptap@mail.ru site: www.deck4.narod.ru
;
; Create on base 3D test sample
; Mikolaj Felix mfelix@polbox.com
;
use32
org 0x0
db 'MENUET01' ; 8 byte id
dd 0x01 ; header version
dd START ; start of code
dd I_END ; size of image
dd 0x30000 ; memory for app
dd 0x30000 ; esp
dd 0x0 , 0x0 ; I_Param , I_Icon
MAX_POINTS equ 8
MAX_TRIANGLES equ 12
SCREEN_X equ 320
SCREEN_Y equ 200
include 'lang.inc'
include 'ascl.inc'
include 'ascgl.inc'
include 'macros.inc'
START:
call draw_window
call init_sin_cos
still:
; mov eax,23 ; wait for system event with 10 ms timeout
; mov ebx,1 ; wait 10 ms, then continue
; int 0x40
mov eax,11
int 0x40
dec eax
; cmp eax,1 ; window redraw request ?
jz red
dec eax
; cmp eax,2 ; key in buffer ?
jz key
dec eax
; cmp eax,3 ; button in buffer ?
jz button
fps 280,8,cl_White,cl_Black
main_loop:
mov esi,object
mov edi,object_rotated
mov ecx,MAX_POINTS*3
cld
rep movsw
mov esi,angle_x
mov edi,object_rotated
mov ecx,MAX_POINTS
call rotate_points
mov esi,object_rotated
mov edi,object_translated
mov ecx,MAX_POINTS
call translate_points
call draw_faces
call clear_screen_buffer
add [angle_x],2
add [angle_y],3
add [angle_z],1
jmp still
red:
call draw_window
jmp still
key:
mov eax,2
int 0x40
jmp still
button:
mov eax,17
int 0x40
cmp ah,1
jne still
exit:
mov eax,-1
int 0x40
;Draw window
draw_window:
mov eax,12 ;Start
mov ebx,1
int 0x40
mov eax,0 ;Draw window
mov ebx,100*65536+(SCREEN_X+9) ;x start*65536+x size
mov ecx,100*65536+(SCREEN_Y+26) ;y start*65536+y size
mov edx,0x03000000 ;0x03 use skinned window
int 0x40
mov eax,4 ;Out Text
mov ebx,8*65536+8 ;x start*65536+y start
mov ecx,0x00ffffff ;color White
mov edx,head_label
mov esi,hl_end-head_label
int 0x40
mov eax,12 ;End
mov ebx,2
int 0x40
ret
head_label: db "3D TEST SAMPLE FOR MENUETOS"
hl_end:
; Draw faces procedure
draw_faces:
mov esi,link
mov ecx,MAX_TRIANGLES
df_draw:
push ecx
mov ecx,3
mov edi,@@tx1 ;bp
df_get_point:
xor bh,bh
mov bl,byte [esi]
shl bx,2
mov ax,word [object_translated+bx]
mov word [edi],ax
mov ax,word [object_translated+bx+2]
mov word [edi+2],ax
inc esi
add edi,4
dec ecx
jnz df_get_point
mov ax,[@@ty1]
sub ax,[@@ty3]
mov bx,[@@tx2]
sub bx,[@@tx1]
imul bx
shl edx,16
mov dx,ax
push edx
mov ax,[@@tx1]
sub ax,[@@tx3]
mov bx,[@@ty2]
sub bx,[@@ty1]
imul bx
shl edx,16
mov dx,ax
pop ebx
sub ebx,edx
or ebx,ebx
jge df_next
xor ah,ah
mov al,byte [si]
mov [@@xcol],ax
call filled_triangle
df_next:
inc si
pop ecx
dec ecx
jnz df_draw
ret
;modify
;include graphlib.asm
clear_screen_buffer:
;outscrbuf
mov ebx,scrbuf
mov ecx,SCREEN_X*65536+SCREEN_Y
mov edx,5*65536+22
mov ax,7
int 0x40
;White background
mov edi,scrbuf
mov ecx,(SCREEN_X*SCREEN_Y*3)/4
mov eax,0xffffffff
cld
rep stosd
ret
;include triangle.asm
; Mikolaj Felix 14/5/2001
; mfelix@polbox.com
;filled trangle procedure
@@tx1 dw 0
@@ty1 dw 0
@@tx2 dw 0
@@ty2 dw 0
@@tx3 dw 0
@@ty3 dw 0
@@xcol dw 0
@@dx12 dw 0
@@dx13 dw 0
@@dx23 dw 0
filled_triangle:
mov ax,[@@xcol] ;trnsforming color
mov bl,al ;byte bbbggrrx
mov dl,al ;to 3 byte
mov dh,al ;bbbxxxxx ggxxxxxx rrxxxxxx
and dh,00000001b
and al,11100000b
and bl,00011000b
and dl,00000110b
shl bl,3
shl dl,5
cmp dh,1
jne no_bitup
or al,00011111b
or bl,00111111b
or dl,00111111b
no_bitup:
shl eax,8 ;puck colors
mov al,bl
shl eax,8
mov al,dl
mov dword [@@rgb],eax
mov eax,0 ; for 16 bit instructions
mov ax,[@@ty1]
cmp ax,[@@ty3]
jb ft_check1
xchg ax,[@@ty3]
mov [@@ty1],ax
mov ax,[@@tx1]
xchg ax,[@@tx3]
mov [@@tx1],ax
ft_check1:
mov ax,[@@ty2]
cmp ax,[@@ty3]
jb ft_check2
xchg ax,[@@ty3]
mov [@@ty2],ax
mov ax,[@@tx2]
xchg ax,[@@tx3]
mov [@@tx2],ax
ft_check2:
mov ax,[@@ty1]
cmp ax,[@@ty2]
jb ft_check3
xchg ax,[@@ty2]
mov [@@ty1],ax
mov ax,[@@tx1]
xchg ax,[@@tx2]
mov [@@tx1],ax
ft_check3:
mov bx,[@@ty2]
sub bx,[@@ty1]
jnz ft_dx12_make
mov [@@dx12],word 0
jmp ft_dx12_done
ft_dx12_make:
mov ax,[@@tx2]
sub ax,[@@tx1]
shl ax,7
cwd
idiv bx
mov [@@dx12],ax ; dx12 = (x2-x1)/(y2-y1)
ft_dx12_done:
mov bx,[@@ty3]
sub bx,[@@ty1]
jnz ft_dx13_make
mov [@@dx13],word 0
jmp ft_dx13_done
ft_dx13_make:
mov ax,[@@tx3]
sub ax,[@@tx1]
shl ax,7
cwd
idiv bx
mov [@@dx13],ax ; dx13 = (x3-x1)/(y3-y1)
ft_dx13_done:
mov bx,[@@ty3]
sub bx,[@@ty2]
jnz ft_dx23_make
mov [@@dx23],word 0
jmp ft_dx23_done
ft_dx23_make:
mov ax,[@@tx3]
sub ax,[@@tx2]
shl ax,7
cwd
idiv bx
mov [@@dx23],ax ; dx23 = (x3-x2)/(y3-y2)
ft_dx23_done:
mov ax,[@@tx1]
shl ax,7
mov bx,ax
mov cx,[@@ty1]
ft_loop1:
pushad
mov [@@ly],cx
mov dx,bx
shr dx,7
mov [@@lx2],dx
mov dx,ax
shr dx,7
mov [@@lx1],dx
mov ax,[@@xcol]
mov [@@lcol],ax
call horizontal_line
popad
add ax,[@@dx13]
add bx,[@@dx12]
inc cx
cmp cx,[@@ty2]
jb ft_loop1
mov bx,[@@tx2]
shl bx,7
mov cx,[@@ty2]
ft_loop2:
pushad
mov [@@ly],cx
mov dx,bx
shr dx,7
mov [@@lx2],dx
mov dx,ax
shr dx,7
mov [@@lx1],dx
mov ax,[@@xcol]
mov [@@lcol],ax
call horizontal_line
popad
add ax,[@@dx13]
add bx,[@@dx23]
inc ecx
cmp cx,[@@ty3]
jb ft_loop2
ret
;horizontal line subproc
@@lx1 dw 0
@@lx2 dw 0
@@ly dw 0
@@lcol dw 0
@@rgb dd 0
horizontal_line:
mov ecx,0
mov cx,[@@lx1]
cmp cx,[@@lx2]
ja x12
je ext
; ret
mov cx,[@@lx2]
sub cx,[@@lx1]
mov edi,3
jmp xx
x12:
mov cx,[@@lx1]
sub cx,[@@lx2]
mov edi,-3
jmp xx
ext:
mov ecx,-1 ;1
; sub ebp,3
xx:
mov eax,0
mov ax,[@@ly]
mov ebx,SCREEN_X ;320
mul ebx
mov ebp,0
mov bp,[@@lx1] ;for correct 16 bit size
add eax,ebp
mov ebx,3
mul ebx
mov ebp,eax
sub ebp,3 ;for delete white dots
add ecx,2
loo:
mov eax,dword [@@rgb]
mov bl,al
shr eax,8 ;puck colors
mov byte [scrbuf+ebp],ah
mov byte [scrbuf+ebp+1],al
mov byte [scrbuf+ebp+2],bl
add ebp,edi
dec ecx
jnz loo
ret
;include fixed3d.asm
; Mikolaj Felix 25/5/2001
; mfelix@polbox.com
;------------------------------------------------------------
; ds:si - offset to angles
; ds:di - offset to 3d points
; cx - number of points
;------------------------------------------------------------
@@sin_x dw 0
@@cos_x dw 0
@@sin_y dw 0
@@cos_y dw 0
@@sin_z dw 0
@@cos_z dw 0
@@px equ word [edi]
@@py equ word [edi+2]
@@pz equ word [edi+4]
rotate_points:
push edi
mov edi,@@sin_x
mov edx,3
rp_sin_cos:
mov bx,word [esi]
and bx,511
shl bx,1
mov ax,word [sin_table+bx]
mov word [edi],ax
mov ax,word [cos_table+bx]
mov word [edi+2],ax
add esi,2
add edi,4
dec edx
jnz rp_sin_cos
pop edi
rp_rotate:
; rotate around x-axis
mov ax,@@py
imul [@@cos_x]
mov bx,ax
mov si,dx
mov ax,@@pz
imul [@@sin_x]
sub bx,ax
sbb si,dx
shrd bx,si,14
push bx
mov ax,@@py
imul [@@sin_x]
mov bx,ax
mov si,dx
mov ax,@@pz
imul [@@cos_x]
add bx,ax
adc si,dx
shrd bx,si,14
pop @@py
mov @@pz,bx
; rotate around y-axis
mov ax,@@px
imul [@@cos_y]
mov bx,ax
mov si,dx
mov ax,@@pz
imul [@@sin_y]
sub bx,ax
sbb si,dx
shrd bx,si,14
push bx
mov ax,@@px
imul [@@sin_y]
mov bx,ax
mov si,dx
mov ax,@@pz
imul [@@cos_y]
add bx,ax
adc si,dx
shrd bx,si,14
pop @@px
mov @@pz,bx
; rotate around z-axis
mov ax,@@px
imul [@@cos_z]
mov bx,ax
mov si,dx
mov ax,@@py
imul [@@sin_z]
sub bx,ax
sbb si,dx
shrd bx,si,14
push bx
mov ax,@@px
imul [@@sin_z]
mov bx,ax
mov si,dx
mov ax,@@py
imul [@@cos_z]
add bx,ax
adc si,dx
shrd bx,si,14
pop @@px
mov @@py,bx
add edi,6
dec ecx
jnz rp_rotate
ret
;------------------------------------------------------------
; ds:si - offset to 3d points
; es:di - offset to 2d points
; cx - number of points
;------------------------------------------------------------
mx dw 0
my dw 0
translate_points:
pushad
mov eax,37
mov ebx,1
int 0x40
mov ebx,eax
shr eax,16
and ebx,0xffff
cmp ax,SCREEN_X
jna x_n
mov ax,0 ;SCREEN_X
x_n:
cmp bx,SCREEN_Y
jna y_n
mov bx,0 ;SCREEN_Y
y_n:
mov [mx],ax
mov [my],bx
popad
mov ebx,0 ;?
mov bx,word [esi+4]
mov ax,[my]
cmp ax,0
jng no_m
shl ax,3
add bx,ax
no_m:
add bx,256 ; Z factor (zoom)
mov eax,0 ;?
mov ax,word [esi]
shl ax,8
cwd
idiv bx; bx
add ax,(SCREEN_X/2) ;160 ;X factor (center X)
stosw
mov eax,0 ;?
mov ax,word [esi+2]
shl ax,8
cwd
idiv bx
add ax,(SCREEN_Y/2) ;100 ;Y factor (center Y)
stosw
add esi,6
dec ecx
jnz translate_points
ret
init_sin_cos:
finit
fldz
fstp [temp]
xor edi,edi
mov ecx,512
isc_make:
fld [temp]
fld st0
fld st0
fsin
fmul [fixed_point_const]
fistp word [sin_table+edi]
fcos
fmul [fixed_point_const]
fistp word [cos_table+edi]
fadd [inc_angle]
fstp [temp]
add edi,2
loop isc_make
ret
temp dd 0
fixed_point_const dd 16384.0
inc_angle dd 0.01227184630309 ; pi/256
angle_x dw 0
angle_y dw 0
angle_z dw 0
object dw -50,-50,-50, 50,-50,-50, 50,50,-50, -50,50,-50
dw -50,-50, 50, 50,-50, 50, 50,50, 50, -50,50, 50
link:
db 0,1,2,10000011b, 0,2,3,10000011b ;purpure side
db 5,4,7,00000111b, 5,7,6,00000111b ;soft-red side
db 1,5,6,00011000b, 1,6,2,00011000b ;soft-lime side
db 4,0,3,11100001b, 4,3,7,11100001b ;soft-blue side
db 4,5,1,00011111b, 1,0,4,00011111b ;yellow side
db 3,2,6,00000000b, 3,6,7,00000000b ;black side
sin_table:
rw 512
cos_table:
rw 512
object_rotated:
rw MAX_POINTS*3
object_translated:
rw MAX_POINTS*2
scrbuf:
I_END: