Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Regard whitespace Rev 1769 → Rev 1770

/programs/demos/web/web.asm
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
/programs/demos/web
Property changes:
Added: tsvn:logminsize
+5
\ No newline at end of property