From c34ffaac705e84d6375a84e605ba68936378b224 Mon Sep 17 00:00:00 2001 From: Yogev Ezra Date: Fri, 28 Jan 2011 13:12:05 +0000 Subject: [PATCH] Added sources of 'web' demo to SVN. git-svn-id: svn://kolibrios.org@1770 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/demos/web/web.asm | 421 +++++++++++++++++++++++++++++++++++++ 1 file changed, 421 insertions(+) create mode 100644 programs/demos/web/web.asm diff --git a/programs/demos/web/web.asm b/programs/demos/web/web.asm new file mode 100644 index 0000000000..7fbb4194e4 --- /dev/null +++ b/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 \ No newline at end of file