0,0 → 1,1984 |
; |
; application : Deus Caritas Est - app shows three models shading |
; compiler : FASM 1.65.13 |
; system : KolibriOS/MenuetOS |
; author : macgub |
; email : macgub3@wp.pl |
; web : www.menuet.xt.pl |
; Fell free to use this intro in your own distribution of KolibriOS/MenuetOS. |
; Special greetings to all MenuetOS maniax in the world. |
; I hope because my intros Christian Belive will be near to each of You. |
|
|
; Some adjustments made by Madis Kalme |
; madis.kalme@mail.ee |
; I tried optimizing it a bit, but don't know if it was successful. The objects |
; can be: |
; 1) Read from a file (*.3DS standard) |
; 2) Written in manually (at the end of the code) |
SIZE_X equ 250 |
SIZE_Y equ 250 |
TIMEOUT equ 4 |
ROUND equ 10 |
TEX_X equ 512 ; texture width |
TEX_Y equ 512 ; height |
TEX_SHIFT equ 9 ; texture widith shifting |
TEX equ SHIFTING ; TEX={SHIFTING | FLUENTLY} |
FLUENTLY = 0 |
SHIFTING = 1 |
;CATMULL_SHIFT equ 8 |
NON = 0 |
MMX = 1 |
|
Ext = MMX ;Ext={ NON | MMX} |
|
use32 |
org 0x0 |
db 'MENUET01' ; 8 byte id |
dd 0x01 ; header version |
dd START ; start of code |
dd I_END ; size of image |
dd I_END ; memory for app |
dd I_END ; esp |
dd 0x0 , 0x0 ; I_Param , I_Icon |
|
START: ; start of execution |
cld |
; call alloc_buffer_mem |
call read_from_file |
call init_triangles_normals |
call init_point_normals |
call init_envmap |
call draw_window |
|
|
still: |
mov eax,23 ; wait here for event with timeout |
mov ebx,TIMEOUT |
cmp [speed_flag],1 |
jne .skip |
mov eax,11 |
.skip: |
int 0x40 |
|
cmp eax,1 ; redraw request ? |
je red |
cmp eax,2 ; key in buffer ? |
je key |
cmp eax,3 ; button in buffer ? |
je button |
|
jmp noclose |
|
red: ; redraw |
call draw_window |
jmp noclose |
|
key: ; key |
mov eax,2 ; just read it and ignore |
int 0x40 |
jmp noclose |
|
button: ; button |
mov eax,17 ; get id |
int 0x40 |
|
cmp ah,1 ; button id=1 ? |
jne .ch_another |
|
mov eax,-1 ; close this program |
int 0x40 |
.ch_another: |
cmp ah,2 |
jne .ch_another1 |
inc [r_flag] |
cmp [r_flag],3 |
jne noclose |
mov [r_flag],0 |
.ch_another1: |
cmp ah,3 |
jne .ch_another2 |
inc [dr_flag] |
cmp [dr_flag],3 |
jne noclose |
mov [dr_flag],0 |
.ch_another2: |
cmp ah,4 ; toggle speed |
jne @f |
inc [speed_flag] |
cmp [speed_flag],2 |
jne noclose |
mov [speed_flag],0 |
@@: |
cmp ah,5 |
jne @f ;scale- |
mov [scale],0.7 |
fninit |
fld [sscale] |
fmul [scale] |
fstp [sscale] |
call read_from_file |
mov ax,[vect_x] ;-- last change |
mov bx,[vect_y] |
mov cx,[vect_z] |
call add_vector |
; call do_scale |
@@: |
cmp ah,6 |
jne @f ; scale+ |
mov [scale],1.3 |
fninit |
fld [sscale] |
fmul [scale] |
fstp [sscale] |
call read_from_file |
mov ax,[vect_x] |
mov bx,[vect_y] |
mov cx,[vect_z] |
call add_vector |
call init_triangles_normals |
call init_point_normals |
@@: |
cmp ah,7 |
jne @f |
xor ax,ax ;add vector to object and rotary point |
mov bx,-10 |
xor cx,cx |
call add_vector |
sub [vect_y],10 |
sub [yo],10 |
@@: |
cmp ah,8 |
jne @f |
xor ax,ax |
xor bx,bx |
mov cx,10 |
call add_vector |
add [vect_z],10 |
add [zo],10 |
@@: |
cmp ah,9 |
jne @f |
mov ax,-10 |
xor bx,bx |
xor cx,cx |
call add_vector |
sub [vect_x],10 |
sub [xo],10 |
@@: |
cmp ah,10 |
jne @f |
mov ax,10 |
xor bx,bx |
xor cx,cx |
call add_vector |
add [vect_x],10 |
add [xo],10 |
@@: |
cmp ah,11 |
jne @f |
xor ax,ax |
xor bx,bx |
mov cx,-10 |
call add_vector |
sub [vect_z],10 |
sub [zo],10 |
@@: |
cmp ah,12 |
jne @f |
xor ax,ax |
mov bx,10 |
xor cx,cx |
call add_vector |
add [vect_y],10 |
add [yo],10 |
@@: |
cmp ah,13 ; change main color - |
jne @f ; - lead color setting |
cmp [max_color_r],245 |
jge @f |
add [max_color_r],10 |
call init_envmap |
@@: |
cmp ah,14 |
jne @f |
cmp [max_color_g],245 |
jge @f |
add [max_color_g],10 |
call init_envmap |
@@: |
cmp ah,15 |
jne @f |
cmp [max_color_b],245 |
jge @f |
add [max_color_b],10 |
call init_envmap |
@@: |
cmp ah,16 ; change main color |
jne @f |
cmp [max_color_r],10 |
jle @f |
sub [max_color_r],10 |
call init_envmap |
@@: |
cmp ah,17 |
jne @f |
cmp [max_color_g],10 |
jle @f |
sub [max_color_g],10 |
call init_envmap |
@@: |
cmp ah,18 |
jne @f |
cmp [max_color_b],10 |
jle @f |
sub [max_color_b],10 |
call init_envmap |
@@: |
cmp ah,19 |
jne @f |
inc [catmull_flag] |
cmp [catmull_flag],2 |
jne @f |
mov [catmull_flag],0 |
@@: |
noclose: |
|
call calculate_angle ; calculates sinus and cosinus |
call copy_point_normals |
; copy normals and rotate the copy using sin/cosbeta - best way |
call rotate_point_normals |
call calculate_colors |
call copy_points |
call rotate_points |
call translate_perspective_points; translate from 3d to 2d |
call clrscr ; clear the screen |
cmp [dr_flag],2 |
je @f |
cmp [catmull_flag],1 ;if env_mapping sort faces |
je @f |
@@: |
call sort_triangles |
@@: |
call fill_Z_buffer |
|
RDTSC |
push eax |
call draw_triangles ; draw all triangles from the list |
|
RDTSC |
sub eax,[esp] |
sub eax,41 |
; lea esi,[debug_points] |
; lea edi,[debug_points+6] |
; lea ebx,[debug_vector1] |
; call make_vector |
; fninit |
; fld [sinbeta_one] |
; fimul [debug_dwd] |
; fistp [debug_dd] |
; movzx eax,[debug_dd] |
|
|
mov ecx,10 |
.dc: |
xor edx,edx |
mov edi,10 |
div edi |
add dl,30h |
mov [STRdata+ecx-1],dl |
loop .dc |
pop eax |
macro show |
{ |
mov eax,7 ; put image |
mov ebx,screen |
mov ecx,SIZE_X shl 16 + SIZE_Y |
mov edx,5 shl 16 + 20 |
int 0x40 |
} |
show |
mov eax,4 ; function 4 : write text to window |
mov ebx,5*65536+23 ; [x start] *65536 + [y start] |
mov ecx,-1 |
mov edx,STRdata ; pointer to text beginning |
mov esi,10 ; text length |
int 40h |
|
|
|
jmp still |
|
;-------------------------------------------------------------------------------- |
;-------------------------PROCEDURES--------------------------------------------- |
;-------------------------------------------------------------------------------- |
include "../../3DS/TEX3.INC" |
include "../../3DS/FLAT_CAT.INC" |
include "../../3DS/GRD_CAT.INC" |
include "../../3DS/3DMATH.INC" |
include "../../3DS/GRD3.INC" |
include "../../3DS/FLAT3.INC" |
|
|
;alloc_buffer_mem: |
; mov eax,68 |
; mov ebx,5 |
; mov ecx,SIZE_X*SIZE_Y*3 |
; int 0x40 |
; mov [screen],eax |
;ret |
init_envmap: |
|
.temp equ word [ebp-2] |
push ebp |
mov ebp,esp |
sub esp,2 |
mov edi,envmap |
fninit |
|
mov dx,-256 |
.ie_ver: |
mov cx,-256 |
.ie_hor: |
mov .temp,cx |
fild .temp |
fmul st,st0 |
mov .temp,dx |
fild .temp |
fmul st,st0 |
faddp |
fsqrt |
mov .temp,254 |
fisubr .temp |
fmul [env_const] |
fistp .temp |
mov ax,.temp |
|
or ax,ax |
jge .ie_ok1 |
xor ax,ax |
jmp .ie_ok2 |
.ie_ok1: |
cmp ax,254 |
jle .ie_ok2 |
mov ax,254 |
.ie_ok2: |
push dx |
mov bx,ax |
mul [max_color_b] |
shr ax,8 |
stosb |
mov ax,bx |
mul [max_color_g] |
shr ax,8 |
stosb |
mov ax,bx |
mul [max_color_r] |
shr ax,8 |
stosb |
pop dx |
|
inc cx |
cmp cx,256 |
jne .ie_hor |
|
inc dx |
cmp dx,256 |
jne .ie_ver |
|
mov esp,ebp |
pop ebp |
macro debug |
{ |
mov edi,envmap |
mov ecx,512*512*3/4 |
mov eax,0xffffffff |
rep stosd |
} |
ret |
calculate_colors: |
fninit |
xor ebx,ebx |
movzx ecx,[points_count_var] |
lea ecx,[ecx*3] |
add ecx,ecx |
.cc_again: |
mov esi,light_vector |
lea edi,[point_normals_rotated+ebx*2] |
call dot_product |
fcom [dot_min] |
fstsw ax |
sahf |
ja .cc_ok1 |
ffree st |
mov dword[points_color+ebx],0 |
mov word[points_color+ebx+4],0 |
add ebx,6 |
cmp ebx,ecx |
jne .cc_again |
jmp .cc_done |
.cc_ok1: |
fcom [dot_max] |
fstsw ax |
sahf |
jb .cc_ok2 |
ffree st |
mov dword[points_color+ebx],0 ; clear r,g,b |
mov word[points_color+ebx+4],0 |
add ebx,6 |
cmp ebx,ecx |
jne .cc_again |
jmp .cc_done |
.cc_ok2: |
fld st |
fld st |
fimul [max_color_r] |
fistp word[points_color+ebx] ;each color as word |
fimul [max_color_g] |
fistp word[points_color+ebx+2] |
fimul [max_color_b] |
fistp word[points_color+ebx+4] |
add ebx,6 |
cmp ebx,ecx |
jne .cc_again |
.cc_done: |
ret |
copy_point_normals: |
movzx ecx,[points_count_var] |
shl ecx,2 |
inc ecx |
mov esi,point_normals |
mov edi,point_normals_rotated |
rep movsd |
ret |
rotate_point_normals: |
movzx ecx,[points_count_var] |
mov ebx,point_normals_rotated |
fninit ; for now only rotate around Z axle |
.again_r: |
cmp [r_flag],1 |
je .z_rot |
cmp [r_flag],2 |
je .x_rot |
|
.y_rot: |
fld dword[ebx] ; x |
fld [sinbeta] |
fmul dword[ebx+8] ; z * sinbeta |
fchs |
fld [cosbeta] |
fmul dword[ebx] ; x * cosbeta |
faddp |
fstp dword[ebx] ; new x |
fmul [sinbeta] ; old x * sinbeta |
fld [cosbeta] |
fmul dword[ebx+8] ; z * cosbeta |
faddp |
fstp dword[ebx+8] ; new z |
add ebx,12 |
loop .y_rot |
jmp .end_rot |
.z_rot: |
fld dword[ebx] ;x |
fld [sinbeta] |
fmul dword[ebx+4] ;y |
fld [cosbeta] |
fmul dword[ebx] ;x |
faddp |
fstp dword[ebx] ;new x |
fmul [sinbeta] ; sinbeta * old x |
fchs |
fld [cosbeta] |
fmul dword[ebx+4] ; cosbeta * y |
faddp |
fstp dword[ebx+4] ; new y |
add ebx,12 |
loop .z_rot |
jmp .end_rot |
.x_rot: |
fld dword[ebx+4] ;y |
fld [sinbeta] |
fmul dword[ebx+8] ;z |
fld [cosbeta] |
fmul dword[ebx+4] ;y |
faddp |
fstp dword[ebx+4] ; new y |
fmul [sinbeta] ; sinbeta * old y |
fchs |
fld [cosbeta] |
fmul dword[ebx+8] |
faddp |
fstp dword[ebx+8] |
add ebx,12 |
loop .x_rot |
.end_rot: |
ret |
init_triangles_normals: |
mov ebx,triangles_normals |
mov ebp,triangles |
@@: |
push ebx |
mov ebx,vectors |
movzx esi,word[ebp] ; first point index |
lea esi,[esi*3] |
lea esi,[points+esi*2] ; esi - pointer to 1st 3d point |
movzx edi,word[ebp+2] ; second point index |
lea edi,[edi*3] |
lea edi,[points+edi*2] ; edi - pointer to 2nd 3d point |
call make_vector |
add ebx,12 |
mov esi,edi |
movzx edi,word[ebp+4] ; third point index |
lea edi,[edi*3] |
lea edi,[points+edi*2] |
call make_vector |
mov edi,ebx ; edi - pointer to 2nd vector |
mov esi,ebx |
sub esi,12 ; esi - pointer to 1st vector |
pop ebx |
call cross_product |
mov edi,ebx |
call normalize_vector |
add ebp,6 |
add ebx,12 |
cmp dword[ebp],-1 |
jne @b |
ret |
|
init_point_normals: |
.x equ dword [ebp-4] |
.y equ dword [ebp-8] |
.z equ dword [ebp-12] |
.point_number equ word [ebp-26] |
.hit_faces equ word [ebp-28] |
|
fninit |
mov ebp,esp |
sub esp,28 |
mov edi,point_normals |
mov .point_number,0 |
.ipn_loop: |
mov .hit_faces,0 |
mov .x,0 |
mov .y,0 |
mov .z,0 |
mov esi,triangles |
xor ecx,ecx ; ecx - triangle number |
.ipn_check_face: |
xor ebx,ebx ; ebx - 'position' in one triangle |
.ipn_check_vertex: |
movzx eax,word[esi+ebx] ; eax - point_number |
cmp ax,.point_number |
jne .ipn_next_vertex |
push esi |
mov esi,ecx |
lea esi,[esi*3] |
lea esi,[triangles_normals+esi*4] |
; shl esi,2 |
; add esi,triangles_normals |
|
fld .x |
fadd dword[esi+vec_x] |
fstp .x |
fld .y |
fadd dword[esi+vec_y] |
fstp .y |
fld .z |
fadd dword[esi+vec_z] |
fstp .z |
pop esi |
inc .hit_faces |
jmp .ipn_next_face |
.ipn_next_vertex: |
add ebx,2 |
cmp ebx,6 |
jne .ipn_check_vertex |
.ipn_next_face: |
add esi,6 |
inc ecx |
cmp cx,[triangles_count_var] |
jne .ipn_check_face |
|
fld .x |
fidiv .hit_faces |
fstp dword[edi+vec_x] |
fld .y |
fidiv .hit_faces |
fstp dword[edi+vec_y] |
fld .z |
fidiv .hit_faces |
fstp dword[edi+vec_z] |
call normalize_vector |
add edi,12 ;type vector 3d |
inc .point_number |
mov dx,.point_number |
cmp dx,[points_count_var] |
jne .ipn_loop |
|
mov esp,ebp |
ret |
|
add_vector: |
mov ebp,points |
@@: |
add word[ebp],ax |
add word[ebp+2],bx |
add word[ebp+4],cx |
add ebp,6 |
cmp dword[ebp],-1 |
jne @b |
ret |
;do_scale: |
; fninit |
; mov ebp,points |
; .next_sc: |
; fld1 |
; fsub [scale] |
; fld st |
; fimul [xo] |
; fld [scale] |
; fimul word[ebp] ;x |
; faddp |
; fistp word[ebp] |
; fld st |
; fimul [yo] |
; fld [scale] |
; fimul word[ebp+2] |
; faddp |
; fistp word[ebp+2] |
; fimul [zo] |
; fld [scale] |
; fimul word[ebp+4] |
; faddp |
; fistp word[ebp+4] |
; add ebp,6 |
; cmp dword[ebp],-1 |
; jne .next_sc |
;ret |
sort_triangles: |
mov esi,triangles |
mov edi,triangles_with_z |
mov ebp,points_rotated |
|
make_triangle_with_z: ;makes list with triangles and z position |
movzx eax,word[esi] |
lea eax,[eax*3] |
movzx ecx,word[ebp+eax*2+4] |
|
movzx eax,word[esi+2] |
lea eax,[eax*3] |
add cx,word[ebp+eax*2+4] |
|
movzx eax,word[esi+4] |
lea eax,[eax*3] |
add cx,word[ebp+eax*2+4] |
|
mov ax,cx |
; cwd |
; idiv word[i3] |
movsd ; store vertex coordinates |
movsw |
stosw ; middle vertex coordinate 'z' in triangles_with_z list |
cmp dword[esi],-1 |
jne make_triangle_with_z |
movsd ; copy end mark |
mov eax,4 |
lea edx,[edi-8-trizdd] |
mov [high],edx |
call quicksort |
mov eax,4 |
mov edx,[high] |
call insertsort |
jmp end_sort |
|
quicksort: |
mov ecx,edx |
sub ecx,eax |
cmp ecx,32 |
jc .exit |
lea ecx,[eax+edx] |
shr ecx,4 |
lea ecx,[ecx*8-4]; i |
mov ebx,[trizdd+eax]; trizdd[l] |
mov esi,[trizdd+ecx]; trizdd[i] |
mov edi,[trizdd+edx]; trizdd[h] |
cmp ebx,esi |
jg @f ; direction NB! you need to negate these to invert the order |
if Ext=NON |
mov [trizdd+eax],esi |
mov [trizdd+ecx],ebx |
mov ebx,[trizdd+eax-4] |
mov esi,[trizdd+ecx-4] |
mov [trizdd+eax-4],esi |
mov [trizdd+ecx-4],ebx |
mov ebx,[trizdd+eax] |
mov esi,[trizdd+ecx] |
else |
movq mm0,[trizdq+eax-4] |
movq mm1,[trizdq+ecx-4] |
movq [trizdq+ecx-4],mm0 |
movq [trizdq+eax-4],mm1 |
xchg ebx,esi |
end if |
@@: |
cmp ebx,edi |
jg @f ; direction |
if Ext=NON |
mov [trizdd+eax],edi |
mov [trizdd+edx],ebx |
mov ebx,[trizdd+eax-4] |
mov edi,[trizdd+edx-4] |
mov [trizdd+eax-4],edi |
mov [trizdd+edx-4],ebx |
mov ebx,[trizdd+eax] |
mov edi,[trizdd+edx] |
else |
movq mm0,[trizdq+eax-4] |
movq mm1,[trizdq+edx-4] |
movq [trizdq+edx-4],mm0 |
movq [trizdq+eax-4],mm1 |
xchg ebx,edi |
end if |
@@: |
cmp esi,edi |
jg @f ; direction |
if Ext=NON |
mov [trizdd+ecx],edi |
mov [trizdd+edx],esi |
mov esi,[trizdd+ecx-4] |
mov edi,[trizdd+edx-4] |
mov [trizdd+ecx-4],edi |
mov [trizdd+edx-4],esi |
else |
movq mm0,[trizdq+ecx-4] |
movq mm1,[trizdq+edx-4] |
movq [trizdq+edx-4],mm0 |
movq [trizdq+ecx-4],mm1 |
; xchg ebx,esi |
end if |
@@: |
mov ebp,eax ; direction |
add ebp,8 ; j |
if Ext=NON |
mov esi,[trizdd+ebp] |
mov edi,[trizdd+ecx] |
mov [trizdd+ebp],edi |
mov [trizdd+ecx],esi |
mov esi,[trizdd+ebp-4] |
mov edi,[trizdd+ecx-4] |
mov [trizdd+ecx-4],esi |
mov [trizdd+ebp-4],edi |
else |
movq mm0,[trizdq+ebp-4] |
movq mm1,[trizdq+ecx-4] |
movq [trizdq+ecx-4],mm0 |
movq [trizdq+ebp-4],mm1 |
end if |
mov ecx,edx ; i; direction |
mov ebx,[trizdd+ebp]; trizdd[j] |
.loop: |
sub ecx,8 ; direction |
cmp [trizdd+ecx],ebx |
jl .loop ; direction |
@@: |
add ebp,8 ; direction |
cmp [trizdd+ebp],ebx |
jg @b ; direction |
cmp ebp,ecx |
|