forked from KolibriOS/kolibrios
Added sources of 'web' demo to SVN.
git-svn-id: svn://kolibrios.org@1770 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
2bf6bb3b5b
commit
c34ffaac70
421
programs/demos/web/web.asm
Normal file
421
programs/demos/web/web.asm
Normal file
@ -0,0 +1,421 @@
|
||||
;"Web" demo for KolibriOS, version 0.3
|
||||
;Copyright Alexander Meshcheryakov (Self-Perfection), 2009
|
||||
;Contact me: alexander.s.m@gmail.com
|
||||
;distributed under BSD license
|
||||
|
||||
;Used assumptions:
|
||||
; 1) Screen resolution does not change while app is running
|
||||
; 2) Screen width bigger then height
|
||||
; 3) Screen width and height are even (2*k)
|
||||
|
||||
include "macros.inc"
|
||||
|
||||
background_cl = 0x000000
|
||||
foreground_cl = 0xFFFFFF
|
||||
|
||||
delay = 4
|
||||
|
||||
; debug = 1
|
||||
|
||||
MEOS_APP_START
|
||||
|
||||
CODE
|
||||
;Preinit. Randomize start counter
|
||||
mcall 3
|
||||
mov [initial_counter], eax ;init with system time
|
||||
|
||||
;Query screen size
|
||||
mcall 14
|
||||
add eax, 0x00010001
|
||||
mov dword [y_max], eax ;store x_max and y_max
|
||||
shr eax, 1
|
||||
mov dword [radius], eax ;store radius and x_center
|
||||
|
||||
;Calc line_number
|
||||
mov ax, [y_max]
|
||||
mov dx, 0
|
||||
mov bx, 5
|
||||
div bx
|
||||
mov word [half_line_number], ax
|
||||
movzx edx, ax ;edx = half_line_number
|
||||
imul edx, 2 * line_coords_element_size ;Space needed for line_coords_array
|
||||
|
||||
;Demand memory
|
||||
mcall 68, 11 ; Init heap
|
||||
test eax, eax ; Is heap successfully inited?
|
||||
jnz @f
|
||||
mcall -1 ; Netu pamjati?! Nu i nahuj vas
|
||||
@@:
|
||||
movzx ecx, [y_max]
|
||||
inc ecx
|
||||
movzx eax, [x_max]
|
||||
imul ecx, eax ;[Remember to left here space for 1-2 emergency lines at bottom]
|
||||
add ecx, edx ;And add space for line_coords_array
|
||||
mcall 68, 12,
|
||||
test eax, eax ; Did we get something non zero?
|
||||
jnz @f
|
||||
mcall -1
|
||||
@@:
|
||||
mov [line_coords_array_pointer], eax
|
||||
add eax, edx
|
||||
mov [image_pointer], eax
|
||||
|
||||
|
||||
call clear_offscreen_bitmap
|
||||
|
||||
|
||||
|
||||
;Calc fixed line ends coords
|
||||
fninit
|
||||
fldpi
|
||||
fidiv word [half_line_number] ;Now st0 contains angle step of line start points
|
||||
|
||||
mov eax, [line_coords_array_pointer] ;cleanup: comment
|
||||
movzx ecx, word [half_line_number]
|
||||
shl ecx, 1
|
||||
fld st ;skip zero angle to avoid 1px fixed line at right side
|
||||
|
||||
|
||||
calculate_next_line_start_point:
|
||||
fld st
|
||||
|
||||
;Calculate line start points coords
|
||||
fsincos
|
||||
fimul [radius]
|
||||
fiadd [x_center]
|
||||
fistp word [eax+start_x_offset]
|
||||
; fchs ;affects direction, uncomment with corresponding line below
|
||||
fimul [radius]
|
||||
fiadd [radius]
|
||||
fistp word [eax+start_y_offset]
|
||||
|
||||
;Calculate line start point pointer
|
||||
movzx ebx, word [eax+start_y_offset]
|
||||
movzx edx, word [x_max]
|
||||
imul ebx, edx
|
||||
movzx edx, word [eax+start_x_offset]
|
||||
add ebx, edx
|
||||
add ebx, [image_pointer]
|
||||
|
||||
mov [eax+line_start_pointer_offset], ebx
|
||||
|
||||
|
||||
fadd st0, st1
|
||||
add eax, line_coords_element_size ;Move to next element in line_coords_array
|
||||
|
||||
loop calculate_next_line_start_point
|
||||
|
||||
fstp st0 ;drop current angle
|
||||
fidiv [divider] ;change angle step
|
||||
|
||||
|
||||
draw_window:
|
||||
|
||||
;Start line coords calculation
|
||||
|
||||
fld st ;skip zero angle to avoid 1px fixed line at right side
|
||||
|
||||
;Use time since start to get current counter value
|
||||
mcall 26, 9
|
||||
add eax, [initial_counter]
|
||||
mov [current_counter], eax
|
||||
|
||||
mov eax, [line_coords_array_pointer] ;cleanup: comment
|
||||
movzx ecx, word [half_line_number]
|
||||
shl ecx, 1
|
||||
|
||||
calculate_next_line_end_point:
|
||||
fld st
|
||||
|
||||
;Calculate line end points
|
||||
fimul [current_counter]
|
||||
fsincos
|
||||
fimul [radius]
|
||||
fiadd [x_center]
|
||||
fistp word [eax+2]
|
||||
; fchs ;affects direction, uncomment with corresponding line above
|
||||
fimul [radius]
|
||||
fiadd [radius]
|
||||
fistp word [eax+6]
|
||||
|
||||
fadd st0, st1
|
||||
|
||||
add eax, line_coords_element_size ;Move to next element in line_coords_array
|
||||
loop calculate_next_line_end_point
|
||||
|
||||
fstp st0 ;drop current angle
|
||||
|
||||
inc dword [initial_counter]
|
||||
|
||||
|
||||
; *********************************************
|
||||
; *******Draw lines on offscreen bitmap********
|
||||
; *********************************************
|
||||
|
||||
;draw end points
|
||||
movzx edi, [half_line_number]
|
||||
shl edi, 1
|
||||
mov esi, [line_coords_array_pointer]
|
||||
|
||||
draw_next_line:
|
||||
|
||||
if defined debug ;Draw red points next to line ends in debug mode
|
||||
movzx ebx, word [esi+start_y_offset]
|
||||
movzx eax, word [x_max]
|
||||
imul eax, ebx
|
||||
movzx ebx, word [esi+start_x_offset]
|
||||
add eax, ebx
|
||||
add eax, dword [image_pointer]
|
||||
inc eax
|
||||
mov [eax], byte red_cl_index
|
||||
|
||||
movzx ebx, word [esi+end_y_offset]
|
||||
movzx eax, word [x_max]
|
||||
imul eax, ebx
|
||||
movzx ebx, word [esi+end_x_offset]
|
||||
add eax, ebx
|
||||
add eax, dword [image_pointer]
|
||||
inc eax ;Move one right to make more visible
|
||||
mov [eax], byte red_cl_index
|
||||
end if
|
||||
|
||||
|
||||
;Drawing lines. Need to keep esi and edi values in process
|
||||
|
||||
mov eax, [esi+line_start_pointer_offset]
|
||||
|
||||
check_horizontal_line:
|
||||
|
||||
mov bx, word [esi+start_y_offset]
|
||||
cmp bx, word [esi+end_y_offset]
|
||||
jnz general_draw_line ;Jump to next test if dy!=0
|
||||
|
||||
pusha
|
||||
|
||||
movzx ecx, word [esi+end_x_offset]
|
||||
sub cx, word [esi+start_x_offset]
|
||||
|
||||
jnc @f
|
||||
neg cx
|
||||
sub eax, ecx
|
||||
@@:
|
||||
|
||||
cld
|
||||
inc cx
|
||||
|
||||
mov edi, eax
|
||||
mov al, foreground_cl_index
|
||||
rep stos byte [edi]
|
||||
|
||||
popa
|
||||
|
||||
jmp line_drawing_end
|
||||
|
||||
|
||||
|
||||
;General line draw algorithm. Based on Bresenham's algorithm (below) but heavily optimized
|
||||
; function line(x0, x1, y0, y1)
|
||||
; boolean steep := abs(y1 - y0) > abs(x1 - x0)
|
||||
; if steep then
|
||||
; swap(x0, y0)
|
||||
; swap(x1, y1)
|
||||
; if x0 > x1 then
|
||||
; swap(x0, x1)
|
||||
; swap(y0, y1)
|
||||
; int deltax := x1 - x0
|
||||
; int deltay := abs(y1 - y0)
|
||||
; int error := deltax / 2
|
||||
; int ystep
|
||||
; int y := y0
|
||||
; if y0 < y1 then ystep := 1 else ystep := -1
|
||||
; for x from x0 to x1
|
||||
; if steep then plot(y,x) else plot(x,y)
|
||||
; error := error - deltay
|
||||
; if error < 0 then
|
||||
; y := y + ystep
|
||||
; error := error + deltax
|
||||
|
||||
|
||||
|
||||
general_draw_line:
|
||||
pusha
|
||||
|
||||
;init step_base and step_secondary
|
||||
mov edx, esi
|
||||
mov esi, 1
|
||||
movzx edi, word [x_max]
|
||||
|
||||
;calc initial delta_base & delta_secondary values
|
||||
movzx ebx, word [edx+end_x_offset]
|
||||
sub bx, [edx+start_x_offset]
|
||||
jnc @f
|
||||
neg bx
|
||||
neg esi
|
||||
@@:
|
||||
movzx ecx, word [edx+end_y_offset]
|
||||
sub cx, [edx+start_y_offset]
|
||||
jnc @f
|
||||
neg cx
|
||||
neg edi
|
||||
@@:
|
||||
|
||||
;compare abs(y1 - y0) and abs(x1 - x0)
|
||||
cmp bx, cx
|
||||
jnc @f
|
||||
xchg ebx, ecx
|
||||
xchg esi, edi
|
||||
@@:
|
||||
|
||||
|
||||
shl ebx, 16
|
||||
mov bx, cx
|
||||
rol ebx, 16
|
||||
mov cx, bx ;init counter
|
||||
inc cx
|
||||
mov dx, bx ;init error
|
||||
shr dx, 1
|
||||
rol ebx, 16
|
||||
|
||||
|
||||
;At current point:
|
||||
;eax = current point pointer
|
||||
;ebx = (delta_base shl 16) + delta_secondary
|
||||
;ecx = counter
|
||||
;[e]dx = error
|
||||
;esi = step_base
|
||||
;edi = step_secondary
|
||||
|
||||
|
||||
brasenham_plot_point:
|
||||
mov byte [eax], foreground_cl_index
|
||||
add eax, esi
|
||||
|
||||
sub dx, bx
|
||||
|
||||
jnc end_loop
|
||||
|
||||
; y := y + ystep
|
||||
; error := error + deltax
|
||||
change_y:
|
||||
add eax, edi
|
||||
rol ebx, 16
|
||||
add dx, bx
|
||||
rol ebx, 16
|
||||
|
||||
end_loop:
|
||||
loopw brasenham_plot_point
|
||||
|
||||
end_bresenham:
|
||||
|
||||
popa
|
||||
|
||||
line_drawing_end:
|
||||
|
||||
add esi, line_coords_element_size ;Move to next element in line_coords_array
|
||||
dec edi
|
||||
jnz draw_next_line
|
||||
|
||||
|
||||
; *********************************************
|
||||
; ******* WINDOW DEFINITIONS AND DRAW ********
|
||||
; *********************************************
|
||||
; mcall 18, 14 ;Wait for scanning (it seems doesn't do any good now)
|
||||
|
||||
; start redraw (without calling 12 proc our window overwrites window that above it)
|
||||
mcall 12, 1
|
||||
xor eax,eax
|
||||
movzx ebx, [x_max]
|
||||
movzx ecx, [y_max]
|
||||
mov edx, 0x01000000 ;Window style ;Draw nothing
|
||||
; mov edx, 0x00000000 ;Window style
|
||||
; mov esi, 0x00000000 ;Header color (prevent odd color line on top of window in random cases)
|
||||
mcall ;Define window
|
||||
|
||||
|
||||
mov ebp, 0
|
||||
mov ecx, dword [y_max]
|
||||
mcall 65, [image_pointer], , <0,0>, 8, palette
|
||||
|
||||
|
||||
mcall 12, 2 ; end redraw
|
||||
|
||||
|
||||
call clear_offscreen_bitmap
|
||||
|
||||
wait_event:
|
||||
mcall 23, delay
|
||||
; mcall 10
|
||||
test eax, 0xFFFF - 1 ;Test for 0 (delay passed) or 1 (redraw) event
|
||||
jz draw_window ; Delay passed or redraw event
|
||||
dec eax
|
||||
dec eax
|
||||
jnz exit ; If not key then Alt+F4
|
||||
; key pressed, read it and ignore
|
||||
mcall 2
|
||||
cmp eax, 0x1B00 ;Test for Escape key press
|
||||
jnz wait_event
|
||||
|
||||
; button pressed; we have only one button, close
|
||||
; also seems to handle Alt+F4
|
||||
exit:
|
||||
mcall -1
|
||||
|
||||
|
||||
clear_offscreen_bitmap:
|
||||
mov edi, [image_pointer]
|
||||
movzx ecx, [y_max]
|
||||
movzx eax, [x_max]
|
||||
imul ecx, eax
|
||||
shr ecx, 2 ;dword is 4 bytes
|
||||
mov eax, 0
|
||||
rep stos dword [edi]
|
||||
ret
|
||||
|
||||
|
||||
DATA
|
||||
divider dw 5000
|
||||
|
||||
palette:
|
||||
background_cl_index = 0
|
||||
dd background_cl
|
||||
foreground_cl_index = 1
|
||||
dd foreground_cl
|
||||
|
||||
if defined debug
|
||||
red_cl_index = 2
|
||||
dd 0x00FF0000 ;Cleanup this!
|
||||
end if
|
||||
|
||||
UDATA
|
||||
image_pointer dd ?
|
||||
|
||||
initial_counter dd ?
|
||||
current_counter dd ? ;counter + current time
|
||||
|
||||
half_line_number dw ?
|
||||
|
||||
y_max dw ? ; screen size
|
||||
x_max dw ?
|
||||
|
||||
radius dw ?
|
||||
x_center dw ?
|
||||
|
||||
line_coords_array_pointer dd ?
|
||||
|
||||
; line_coords_array:
|
||||
; repeat 1000 ;line_number
|
||||
; dw ? ;start_x
|
||||
; dw ? ;end_x
|
||||
; dw ? ;start_y
|
||||
; dw ? ;end_y
|
||||
; dd ? ;line_start_pointer
|
||||
; end repeat
|
||||
|
||||
start_x_offset = 0
|
||||
end_x_offset = 2
|
||||
start_y_offset = 4
|
||||
end_y_offset = 6
|
||||
line_start_pointer_offset = 8
|
||||
line_coords_element_size = 12
|
||||
|
||||
MEOS_APP_END
|
Loading…
Reference in New Issue
Block a user