0,0 → 1,768 |
; |
; application : Flag - Polonia in Tertio Millenium - wavy shading rotary area |
; compiler : FASM |
; system : MenuetOS |
; author : macgub |
; email : macgub3@wp.pl |
; web : www.menuet.xt.pl |
; Fell free to use this intro in your own distribution of MenuetOS. |
SIZE_X equ 220 |
SIZE_Y equ 260 |
TIMEOUT equ 1 |
ROUND equ 12 |
points_count equ 50 |
triangles_count equ 54 |
|
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 |
|
call draw_window |
; call generate_map |
|
still: |
|
mov eax,23 ; wait here for event with timeout |
mov ebx,TIMEOUT |
cmp [speed_flag],0xff |
jne speed_skip |
mov eax,11 |
speed_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 shad_button |
mov eax,-1 ; close this program |
int 0x40 |
shad_button: |
cmp ah,2 |
jne speed_button |
not [shad_flag] ; set shadow / flag mode |
speed_button: |
cmp ah,3 |
jne noclose |
not [speed_flag] |
noclose: |
|
call calculate_angle ; calculates sinus and cosinus |
call generate_map |
call copy_points |
call rotate_points |
call translate_points ; translate from 3d to 2d |
call clrscr ; clear the screen |
call sort_triangles |
call draw_triangles ; draw all triangles from the list |
|
mov eax,7 ; put image |
mov ebx,screen |
mov ecx,SIZE_X shl 16 + SIZE_Y |
mov edx,5 shl 16 + 20 |
int 0x40 |
|
jmp still |
generate_map: |
finit |
mov edi,points |
xor ebx,ebx ;z |
again_gen1: |
mov eax,70 ;x |
again_gen: |
mov word[edi],ax |
mov word[edi+4],bx |
fild word[edi] |
fidiv [i20] |
fadd [current_angle] |
fsin |
fimul [i20] |
fiadd [i75] |
fistp word [edi+2] |
; fild word[edi] ;another map generation |
; fisub [i100] |
; fidiv [i75] |
; fmul st,st0 |
; fild word[edi+4] |
; fisub [i50] |
; fidiv [i20] |
; fmul st,st0 |
; faddp |
; fsqrt |
; fadd [current_angle] |
; fsin |
; fimul [i20] |
; fiadd [i75] |
; fistp word[edi+2] |
|
add ax,10 |
add edi,6 |
cmp ax,170 |
jne again_gen |
add bx,20 |
cmp bx,100 |
jne again_gen1 |
mov dword[edi],0xffffffff |
ret |
i20 dw 20 |
i50 dw 50 |
i75 dw 75 |
i100 dw 100 |
|
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 |
xor eax,eax |
mov ax,word[esi] |
shl eax,1 |
mov ebx,eax |
shl eax,1 |
add eax,ebx |
push ebp |
add ebp,eax |
xor ecx,ecx |
mov cx,word[ebp+4] |
pop ebp |
|
xor eax,eax |
mov ax,word[esi+2] |
shl eax,1 |
mov ebx,eax |
shl eax,1 |
add eax,ebx |
push ebp |
add ebp,eax |
add cx,word[ebp+4] |
pop ebp |
|
xor eax,eax |
mov ax,word[esi+4] |
shl eax,1 |
mov ebx,eax |
shl eax,1 |
add eax,ebx |
push ebp |
add ebp,eax |
add cx,word[ebp+4] |
pop ebp |
|
mov ax,cx |
cwd |
idiv [i3] |
cld |
movsd ; store vertex coordinates |
movsw |
stosw ; middle vertex coordinate 'z' in triangles_with_z list |
cmp dword[esi],0xffffffff |
jne make_triangle_with_z |
movsd ; copy end mark |
|
;macro sort |
|
mov [sort_flag],1 |
next_booble: |
mov esi,triangles_with_z ;sort list triangles_with_z booble metod |
cmp [sort_flag],0 |
je end_sort |
mov [sort_flag],0 |
check_and_check: |
; cmp dword[esi],0xffffffff |
; je next_booble |
cmp dword[esi+8],0xffffffff |
je next_booble |
mov ax,word[esi+6] |
cmp ax,word[esi+14] |
jge no_chg_pos |
mov eax,dword[esi] |
mov ebx,dword[esi+4] |
xchg eax,dword[esi+8] |
xchg ebx,dword[esi+12] |
mov dword[esi],eax |
mov dword[esi+4],ebx ; sort_flag=1 if change occured |
mov [sort_flag],1 |
no_chg_pos: |
add esi,8 |
jmp check_and_check ;check end mark end if greater |
end_sort: |
|
; translate triangles_with_z to sorted_triangles |
mov esi,triangles_with_z |
mov edi,sorted_triangles |
again_copy: |
movsd |
movsw |
add esi,2 |
cmp dword[esi],0xffffffff |
jne again_copy |
movsd ; copy end mark too |
ret |
sort_flag db 0 |
clrscr: |
mov edi,screen |
mov ecx,SIZE_X*SIZE_Y*3/4 |
xor eax,eax |
cld |
rep stosd |
ret |
calculate_angle: |
finit |
fldpi |
fidiv [i180] |
fimul [angle_counter] |
fst [current_angle] |
fld st |
fidiv [i2] |
fsincos |
fstp [singamma] |
fstp [cosgamma] |
fsincos |
fstp [sinbeta] |
fstp [cosbeta] |
inc [angle_counter] |
cmp [angle_counter],360 |
jne end_calc_angle |
mov [angle_counter],0 |
end_calc_angle: |
ret |
i180 dw 90 |
i2 dw 2 |
rotate_points: |
finit ; y axle rotate |
mov ebx,points_rotated |
again_r: |
mov ax,word[ebx] ;x |
sub ax,[xo] |
mov [xsub],ax |
mov ax,word[ebx+4] ;z |
sub ax,[zo] |
mov [zsub],ax |
fld [sinbeta] |
fimul [zsub] |
fchs |
fld [cosbeta] |
fimul [xsub] |
faddp |
fiadd [xo] |
fistp word[ebx] ;x |
fld [sinbeta] |
fimul [xsub] |
;fchs |
fld [cosbeta] |
fimul [zsub] |
faddp |
fiadd [zo] |
fistp word[ebx+4] ;z |
|
mov ax,word[ebx+2] ;y ; z axle rotate |
sub ax,[yo] |
mov [ysub],ax |
mov ax,word[ebx] ;x |
sub ax,[xo] |
mov [xsub],ax |
fld [singamma] |
fimul[ysub] |
fld [cosgamma] |
fimul [xsub] |
faddp |
fiadd [xo] |
fistp word[ebx] ;x |
fld [cosgamma] |
fimul [ysub] |
fld [singamma] |
fimul [xsub] |
fchs |
faddp |
fiadd [yo] |
fistp word[ebx+2] ;y |
|
add ebx,6 |
cmp dword[ebx],0xffffffff |
jne again_r |
ret |
xsub dw ? |
ysub dw ? |
zsub dw ? |
draw_triangles: |
mov [tr_counter],1 |
mov ebp,points_rotated |
; mov esi,triangles |
mov esi,sorted_triangles |
again_dts: |
xor eax,eax |
mov ax,word[esi] |
shl eax,1 |
mov [dtpom],eax |
shl eax,1 |
add eax,[dtpom] |
push ebp |
add ebp,eax |
mov ax,word[ebp] |
mov [xx1],ax |
mov ax,word[ebp+2] |
mov [yy1],ax |
mov ax,word[ebp+4] |
mov [zz1],ax |
pop ebp |
|
xor eax,eax |
mov ax,word[esi+2] |
shl eax,1 |
mov [dtpom],eax |
shl eax,1 |
add eax,[dtpom] |
push ebp |
add ebp,eax |
mov ax,word[ebp] |
mov [xx2],ax |
mov ax,word[ebp+2] |
mov [yy2],ax |
mov ax,word[ebp+4] |
mov [zz2],ax |
pop ebp |
|
xor eax,eax |
mov ax,word[esi+4] |
shl eax,1 |
mov [dtpom],eax |
shl eax,1 |
add eax,[dtpom] |
push ebp |
add ebp,eax |
mov ax,word[ebp] |
mov [xx3],ax |
mov ax,word[ebp+2] |
mov [yy3],ax |
mov ax,word[ebp+4] |
mov [zz3],ax |
pop ebp |
push ebp |
push esi |
|
macro set_flag |
{ |
mov edx,0x00ffffff |
inc [tr_counter] |
cmp [tr_counter],triangles_count/2 |
jl skip_red |
set_red: |
mov edx,0x00ff0000 |
skip_red: |
} |
|
mov ax,[zz1] |
add ax,[zz2] |
add ax,[zz3] |
cwd |
idiv [i3] |
sub ax,100 ;77 |
; shl ax,1 |
neg al |
xor edx,edx |
mov dh,al ;set color according to z position |
mov dl,al |
; push dx |
; shl edx,8 |
; pop dx |
|
cmp [shad_flag],0 |
je skip_col |
set_flag |
skip_col: |
mov ax,[xx1] |
shl eax,16 |
mov ax,[yy1] |
mov bx,[xx2] |
shl ebx,16 |
mov bx,[yy2] |
mov cx,[xx3] |
shl ecx,16 |
mov cx,[yy3] |
mov edi,screen |
call draw_triangle |
pop esi |
pop ebp |
|
add esi,6 |
cmp dword[esi],0xffffffff |
jne again_dts |
ret |
i3 dw 3 |
tr_counter dw 0 |
dtpom dd ? |
xx1 dw ? |
yy1 dw ? |
zz1 dw ? |
xx2 dw ? |
yy2 dw ? |
zz2 dw ? |
xx3 dw ? |
yy3 dw ? |
zz3 dw ? |
translate_points: |
finit |
mov ebx,points_rotated |
again_trans: |
fild word[ebx+4] ;z1 |
fmul [sq] |
fld st |
fiadd word[ebx] ;x1 |
fistp word[ebx] |
fchs |
fiadd word[ebx+2] ;y1 |
fistp word[ebx+2] ;y1 |
|
add ebx,6 |
cmp dword[ebx],0xffffffff |
jne again_trans |
ret |
copy_points: |
mov esi,points |
mov edi,points_rotated |
mov ecx,points_count*3+2 |
cld |
rep movsw |
ret |
|
draw_triangle: |
;----------in - eax - x1 shl 16 + y1 |
;------------- -ebx - x2 shl 16 + y2 |
;---------------ecx - x3 shl 16 + y3 |
;---------------edx - color 0x00rrggbb |
;---------------edi - pointer to screen buffer |
@ch3: |
cmp ax,bx |
jg @ch1 |
@ch4: ; sort parameters |
cmp bx,cx |
jg @ch2 |
jle @chEnd |
@ch1: |
xchg eax,ebx |
jmp @ch4 |
@ch2: |
xchg ebx,ecx |
jmp @ch3 |
@chEnd: |
mov [@y1],ax ; ....and store to user friendly variables |
mov [@y2],bx |
mov [@y3],cx |
shr eax,16 |
shr ebx,16 |
shr ecx,16 |
mov [@x1],ax |
mov [@x2],bx |
mov [@x3],cx |
mov [@col],edx |
|
cmp [@y1],0 |
jl @end_triangle |
cmp [@y2],0 |
jl @end_triangle |
cmp [@y3],0 |
jl @end_triangle |
cmp [@x1],0 |
jl @end_triangle |
cmp [@x2],0 |
jl @end_triangle |
cmp [@x3],0 |
jl @end_triangle |
cmp [@y1],SIZE_Y |
jg @end_triangle |
cmp [@y2],SIZE_Y |
jg @end_triangle |
cmp [@y3],SIZE_Y |
jg @end_triangle |
cmp [@x1],SIZE_X |
jg @end_triangle |
cmp [@x2],SIZE_X |
jg @end_triangle |
cmp [@x3],SIZE_X |
jg @end_triangle |
|
neg ax ; calculate delta 12 |
add ax,bx |
cwde |
shl eax,ROUND |
cdq |
mov bx,[@y2] |
mov cx,[@y1] |
sub ebx,ecx |
cmp ebx,0 |
jne @noZero1 |
mov [@dx12],0 |
jmp @yesZero1 |
@noZero1: |
idiv ebx |
mov [@dx12],eax |
@yesZero1: |
|
mov ax,[@x3] ; calculate delta 13 |
sub ax,[@x1] |
cwde |
shl eax,ROUND |
cdq |
xor ebx,ebx |
xor ecx,ecx |
or bx,[@y3] |
or cx,[@y1] |
sub ebx,ecx |
cmp ebx,0 |
jne @noZero2 |
mov [@dx13],0 |
jmp @yesZero2 |
@noZero2: |
idiv ebx |
mov [@dx13],eax |
@yesZero2: |
|
mov ax,[@x3] ; calculate delta 23 [dx23] |
sub ax,[@x2] |
cwde |
shl eax,ROUND |
cdq |
xor ebx,ebx |
xor ecx,ecx |
or bx,[@y3] |
or cx,[@y2] |
sub ebx,ecx |
cmp ebx,0 |
jne @noZero3 |
mov [@dx23],0 |
jmp @yesZero3 |
@noZero3: |
idiv ebx |
mov [@dx23],eax |
@yesZero3: |
|
|
xor eax,eax ;eax - xk1 |
or ax,[@x1] |
shl eax,ROUND |
mov ebx,eax ; ebx - xk2 |
xor esi,esi ; esi - y |
or si,[@y1] |
@next_line1: |
mov ecx,eax ; ecx - x11 |
sar ecx,ROUND |
mov edx,ebx ;edx - x12 |
sar edx,ROUND |
cmp ecx,edx |
jle @nochg |
xchg ecx,edx |
@nochg: |
pusha |
mov ebx,ecx |
sub edx,ecx |
mov ecx,edx |
mov edx,esi |
mov eax,[@col] |
call @horizontal_line |
popa |
add eax,[@dx13] |
add ebx,[@dx12] |
inc esi |
cmp si,[@y2] |
jl @next_line1 |
|
xor esi,esi |
or si,[@y2] |
xor ebx,ebx |
mov bx,[@x2] |
shl ebx,ROUND |
@next_line2: |
mov ecx,eax |
sar ecx,ROUND |
mov edx,ebx |
sar edx,ROUND |
cmp ecx,edx |
jle @nochg1 |
xchg ecx,edx |
@nochg1: |
pusha |
mov eax,[@col] |
mov ebx,ecx |
sub edx,ecx |
mov ecx,edx |
mov edx,esi |
call @horizontal_line |
popa |
add eax,[@dx13] |
add ebx,[@dx23] |
inc esi |
cmp si,[@y3] |
jl @next_line2 |
@end_triangle: |
ret |
@col dd ? |
@y1 dw ? |
@x1 dw ? |
@y2 dw ? |
@x2 dw ? |
@y3 dw ? |
@x3 dw ? |
@dx12 dd ? |
@dx13 dd ? |
@dx23 dd ? |
|
@horizontal_line: |
;---------in |
;---------eax - color of line, 0x00RRGGBB |
;---------ebx - x1 - x position of line begin |
;---------ecx - lenght of line |
;---------edx - y position of line |
;---------edi - pointer to buffer |
jcxz @end_hor_l |
push eax |
mov eax,SIZE_X*3 |
mul edx |
add edi,eax ; calculate line begin adress |
add edi,ebx |
shl ebx,1 |
add edi,ebx |
pop eax |
cld |
@ddraw: |
push eax |
stosw |
shr eax,16 |
stosb |
pop eax |
loop @ddraw |
@end_hor_l: |
ret |
|
|
|
|
; ********************************************* |
; ******* WINDOW DEFINITIONS AND DRAW ******** |
; ********************************************* |
|
|
draw_window: |
|
|
mov eax,12 ; function 12:tell os about windowdraw |
mov ebx,1 ; 1, start of draw |
int 0x40 |
|
; DRAW WINDOW |
mov eax,0 ; function 0 : define and draw window |
mov ebx,100*65536+SIZE_X+20 ; [x start] *65536 + [x size] |
mov ecx,100*65536+SIZE_Y+30 ; [y start] *65536 + [y size] |
mov edx,0x02000000 ; color of work area RRGGBB,8->color gl |
mov esi,0x805080d0 ; color of grab bar RRGGBB,8->color gl |
mov edi,0x005080d0 ; color of frames RRGGBB |
int 0x40 |
|
; WINDOW LABEL |
mov eax,4 ; function 4 : write text to window |
mov ebx,8*65536+8 ; [x start] *65536 + [y start] |
mov ecx,0x20ddeeff ; font 1 & color ( 0xF0RRGGBB ) |
mov edx,labelt ; pointer to text beginning |
mov esi,labellen-labelt ; text length |
int 0x40 |
|
; CLOSE BUTTON |
mov eax,8 ; function 8 : define and draw button |
mov ebx,(SIZE_X+20-19)*65536+12 ; [x start] *65536 + [x size] |
mov ecx,5*65536+12 ; [y start] *65536 + [y size] |
mov edx,1 ; button id |
mov esi,0x6688dd ; button color RRGGBB |
int 0x40 |
; flag color button |
mov eax,8 ; function 8 : define and draw button |
mov ebx,(SIZE_X-30)*65536+20 ; [x start] *65536 + [x size] |
mov ecx,5*65536+12 ; [y start] *65536 + [y size] |
mov edx,2 ; button id |
mov esi,0x2288dd ; button color RRGGBB |
int 0x40 |
; spped button |
mov eax,8 ; function 8 : define and draw button |
mov ebx,(SIZE_X-60)*65536+20 ; [x start] *65536 + [x size] |
mov ecx,5*65536+12 ; [y start] *65536 + [y size] |
mov edx,3 ; button id |
mov esi,0x2288dd ; button color RRGGBB |
int 0x40 |
|
mov eax,12 ; function 12:tell os about windowdraw |
mov ebx,2 ; 2, end of draw |
int 0x40 |
|
ret |
|
|
; DATA AREA |
angle_counter dw 0 |
sq dd 0.707 |
xo dw 110 ;87 |
zo dw 0 |
yo dw 125 |
shad_flag db 0 |
speed_flag db 0 |
|
triangles: |
dw 0,1,10, 10,11,1, 1,2,11, 11,12,2, 2,3,12, 12,13,3, 3,4,13, 13,14,4, 4,5,14 |
dw 14,15,5, 5,6,15, 15,16,6, 6,7,16, 16,17,7, 7,8,17, 17,18,8, 8,9,18, 18,19,9 |
dw 10,11,20, 20,21,11, 11,12,21, 21,22,12, 12,13,22, 22,23,13, 13,14,23 |
dw 23,24,14, 14,15,24, 24,25,15, 15,16,25, 25,26,16, 16,17,26, 26,27,17 |
dw 17,18,27, 27,28,18, 18,19,28, 28,29,19, 20,21,30, 30,31,21, 21,22,31 |
dw 31,32,22, 22,23,32, 32,33,23, 23,24,33, 33,34,24, 24,25,34, 34,35,25 |
dw 25,26,35, 35,36,26, 26,27,36, 36,37,27, 27,28,37, 37,38,28, 28,29,38 |
dw 38,39,29 |
dd 0xffffffff ;<- end marker |
|
|
|
labelt: |
db '3d wavy rotaring area' |
labellen: |
sinbeta rd 1 |
cosbeta rd 1 |
singamma rd 1 |
cosgamma rd 1 |
current_angle rd 1 |
|
points rw points_count*3 + 2 |
points_rotated rw points_count*3 + 2 |
triangles_with_z rw triangles_count*4 + 2 ; triangles triple dw + z position |
sorted_triangles rw triangles_count*3 + 2 |
screen rb SIZE_X * SIZE_Y * 3 ; screen buffer |
memStack rb 1000 ;memory area for stack |
I_END: |
|
|
|
|