Subversion Repositories Kolibri OS

Rev

Rev 1796 | Rev 9451 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;"Web" demo for KolibriOS, version 0.3
  2. ;Copyright Alexander Meshcheryakov (Self-Perfection), 2009
  3. ;Contact me: alexander.s.m@gmail.com
  4. ;distributed under BSD license
  5.  
  6. ;Used assumptions:
  7. ;   1) Screen resolution does not change while app is running
  8. ;   2) Screen width bigger than height
  9. ;   3) Screen width and height are even (2*k)
  10.  
  11. include '../../../macros.inc'
  12.  
  13. background_cl = 0x000000
  14. foreground_cl = 0xFFFFFF
  15.  
  16. delay = 4
  17.  
  18. ; debug = 1
  19.  
  20. MEOS_APP_START
  21.  
  22. CODE
  23.     ;Preinit. Randomize start counter
  24.     mcall 3
  25.     mov     [initial_counter], eax          ;init with system time
  26.  
  27.     ;Query screen size
  28.     mcall   14
  29.     add     eax, 0x00010001
  30.     mov     dword [y_max], eax      ;store x_max and y_max
  31.     shr     eax, 1
  32.     mov     dword [radius], eax     ;store radius and x_center
  33.    
  34.     ;Calc line_number
  35.     mov     ax, [y_max]
  36.     mov     dx, 0
  37.     mov     bx, 5
  38.     div     bx
  39.     mov     word [half_line_number], ax
  40.     movzx   edx, ax         ;edx = half_line_number
  41.     imul    edx, 2 * line_coords_element_size      ;Space needed for line_coords_array
  42.  
  43.     ;Demand memory
  44.     mcall   68, 11      ; Init heap
  45.     test    eax, eax    ; Is heap successfully inited?
  46.     jnz     @f
  47.     mcall   -1          ;   Netu pamjati?! Nu i nahuj vas
  48. @@:
  49.     movzx   ecx, [y_max]
  50.     inc     ecx
  51.     movzx   eax, [x_max]
  52.     imul    ecx, eax        ;[Remember to left here space for 1-2 emergency lines at bottom]
  53.     add     ecx, edx        ;And add space for line_coords_array
  54.     mcall   68, 12,
  55.     test    eax, eax    ; Did we get something non zero?
  56.     jnz     @f
  57.     mcall   -1
  58. @@:
  59.     mov     [line_coords_array_pointer], eax
  60.     add     eax, edx
  61.     mov     [image_pointer], eax
  62.  
  63.  
  64.     call    clear_offscreen_bitmap
  65.  
  66.  
  67.  
  68. ;Calc fixed line ends coords
  69.     fninit
  70.     fldpi
  71.     fidiv word [half_line_number]    ;Now st0 contains angle step of line start points
  72.    
  73.     mov eax, [line_coords_array_pointer]          ;cleanup: comment
  74.     movzx   ecx, word [half_line_number]
  75.     shl     ecx, 1
  76.     fld     st      ;skip zero angle to avoid 1px fixed line at right side
  77.  
  78.  
  79. calculate_next_line_start_point:
  80.     fld st
  81.  
  82.     ;Calculate line start points coords
  83.     fsincos
  84.     fimul [radius]
  85.     fiadd [x_center]
  86.     fistp word [eax+start_x_offset]
  87. ;     fchs                              ;affects direction, uncomment with corresponding line below
  88.     fimul [radius]
  89.     fiadd [radius]
  90.     fistp word [eax+start_y_offset]
  91.  
  92.     ;Calculate line start point pointer
  93.     movzx   ebx, word [eax+start_y_offset]
  94.     movzx   edx, word [x_max]
  95.     imul    ebx, edx
  96.     movzx   edx, word [eax+start_x_offset]
  97.     add     ebx, edx
  98.     add     ebx, [image_pointer]
  99.  
  100.     mov     [eax+line_start_pointer_offset], ebx
  101.  
  102.  
  103.     fadd st0, st1
  104.     add eax, line_coords_element_size    ;Move to next element in line_coords_array
  105.  
  106.     loop calculate_next_line_start_point
  107.  
  108.     fstp    st0          ;drop current angle
  109.     fidiv   [divider]   ;change angle step
  110.  
  111.  
  112. draw_window:
  113.  
  114. ;Start line coords calculation
  115.  
  116.     fld     st      ;skip zero angle to avoid 1px fixed line at right side
  117.  
  118.     ;Use time since start to get current counter value
  119.     mcall   26, 9
  120.     add     eax, [initial_counter]
  121.     mov     [current_counter], eax
  122.  
  123.     mov eax, [line_coords_array_pointer]          ;cleanup: comment
  124.     movzx   ecx, word [half_line_number]
  125.     shl     ecx, 1
  126.  
  127. calculate_next_line_end_point:
  128.     fld st
  129.  
  130.     ;Calculate line end points
  131.     fimul [current_counter]
  132.     fsincos
  133.     fimul [radius]
  134.     fiadd [x_center]
  135.     fistp word [eax+2]
  136. ;     fchs                              ;affects direction, uncomment with corresponding line above
  137.     fimul [radius]
  138.     fiadd [radius]
  139.     fistp word [eax+6]
  140.  
  141.     fadd st0, st1
  142.  
  143.     add eax, line_coords_element_size    ;Move to next element in line_coords_array
  144.     loop calculate_next_line_end_point
  145.  
  146.     fstp    st0     ;drop current angle
  147.  
  148.     inc dword [initial_counter]
  149.  
  150.  
  151. ;   *********************************************
  152. ;   *******Draw lines on offscreen bitmap********
  153. ;   *********************************************
  154.  
  155.     ;draw end points
  156.     movzx   edi, [half_line_number]
  157.     shl     edi, 1
  158.     mov esi, [line_coords_array_pointer]
  159.  
  160.   draw_next_line:
  161.  
  162.     if defined debug    ;Draw red points next to line ends in debug mode
  163.         movzx   ebx, word [esi+start_y_offset]
  164.         movzx   eax, word [x_max]
  165.         imul    eax, ebx
  166.         movzx   ebx, word [esi+start_x_offset]
  167.         add     eax, ebx
  168.         add     eax, dword [image_pointer]
  169.         inc     eax
  170.         mov     [eax], byte red_cl_index
  171.        
  172.         movzx   ebx, word [esi+end_y_offset]
  173.         movzx   eax, word [x_max]
  174.         imul    eax, ebx
  175.         movzx   ebx, word [esi+end_x_offset]
  176.         add     eax, ebx
  177.         add     eax, dword [image_pointer]
  178.         inc     eax                             ;Move one right to make more visible
  179.         mov     [eax], byte red_cl_index
  180.     end if
  181.  
  182.  
  183. ;Drawing lines. Need to keep esi and edi values in process
  184.  
  185.     mov     eax, [esi+line_start_pointer_offset]
  186.  
  187.   check_horizontal_line:
  188.  
  189.     mov     bx, word [esi+start_y_offset]
  190.     cmp     bx, word [esi+end_y_offset]
  191.     jnz     general_draw_line      ;Jump to next test if dy!=0
  192.    
  193.     pusha
  194.    
  195.     movzx   ecx, word [esi+end_x_offset]
  196.     sub     cx, word [esi+start_x_offset]
  197.  
  198.     jnc     @f
  199.     neg     cx
  200.     sub     eax, ecx
  201.   @@:
  202.  
  203.     cld
  204.     inc     cx
  205.  
  206.     mov     edi, eax
  207.     mov     al, foreground_cl_index
  208.     rep stos byte [edi]
  209.  
  210.     popa
  211.  
  212.     jmp     line_drawing_end
  213.  
  214.  
  215.  
  216.     ;General line draw algorithm. Based on Bresenham's algorithm (below) but heavily optimized
  217. ;  function line(x0, x1, y0, y1)
  218. ;      boolean steep := abs(y1 - y0) > abs(x1 - x0)
  219. ;      if steep then
  220. ;          swap(x0, y0)
  221. ;          swap(x1, y1)
  222. ;      if x0 > x1 then
  223. ;          swap(x0, x1)
  224. ;          swap(y0, y1)
  225. ;      int deltax := x1 - x0
  226. ;      int deltay := abs(y1 - y0)
  227. ;      int error := deltax / 2
  228. ;      int ystep
  229. ;      int y := y0
  230. ;      if y0 < y1 then ystep := 1 else ystep := -1
  231. ;      for x from x0 to x1
  232. ;          if steep then plot(y,x) else plot(x,y)
  233. ;          error := error - deltay
  234. ;          if error < 0 then
  235. ;              y := y + ystep
  236. ;              error := error + deltax
  237.  
  238.  
  239.  
  240. general_draw_line:
  241.     pusha
  242.  
  243.     ;init step_base and step_secondary
  244.     mov     edx, esi
  245.     mov     esi, 1
  246.     movzx   edi, word [x_max]
  247.  
  248.     ;calc initial delta_base & delta_secondary values
  249.     movzx   ebx, word [edx+end_x_offset]
  250.     sub     bx, [edx+start_x_offset]
  251.     jnc     @f
  252.     neg     bx
  253.     neg     esi
  254.   @@:
  255.     movzx   ecx, word [edx+end_y_offset]
  256.     sub     cx, [edx+start_y_offset]
  257.     jnc     @f
  258.     neg     cx
  259.     neg     edi
  260.   @@:
  261.    
  262.     ;compare abs(y1 - y0) and abs(x1 - x0)
  263.     cmp     bx, cx
  264.     jnc     @f
  265.     xchg    ebx, ecx
  266.     xchg    esi, edi
  267.   @@:
  268.  
  269.  
  270.     shl     ebx, 16
  271.     mov     bx, cx
  272.     rol     ebx, 16
  273.     mov     cx, bx      ;init counter
  274.     inc     cx
  275.     mov     dx, bx      ;init error
  276.     shr     dx, 1
  277.     rol     ebx, 16
  278.  
  279.  
  280. ;At current point:
  281. ;eax = current point pointer
  282. ;ebx = (delta_base shl 16) + delta_secondary
  283. ;ecx = counter
  284. ;[e]dx = error
  285. ;esi = step_base
  286. ;edi = step_secondary
  287.  
  288.  
  289.   brasenham_plot_point:
  290.     mov     byte [eax], foreground_cl_index
  291.     add     eax, esi
  292.  
  293.     sub     dx, bx
  294.  
  295.     jnc     end_loop
  296.  
  297. ;              y := y + ystep
  298. ;              error := error + deltax
  299.   change_y:
  300.     add     eax, edi
  301.     rol     ebx, 16
  302.     add     dx, bx
  303.     rol     ebx, 16
  304.  
  305.   end_loop:
  306.     loopw   brasenham_plot_point
  307.  
  308.     end_bresenham:
  309.  
  310.     popa
  311.  
  312. line_drawing_end:
  313.  
  314.     add esi, line_coords_element_size   ;Move to next element in line_coords_array
  315.     dec edi
  316.     jnz draw_next_line
  317.  
  318.  
  319. ;   *********************************************
  320. ;   *******  WINDOW DEFINITIONS AND DRAW ********
  321. ;   *********************************************
  322. ;     mcall 18, 14    ;Wait for scanning (it seems doesn't do any good now)
  323.  
  324.     ; start redraw  (without calling 12 proc our window overwrites window that above it)
  325.     mcall   12, 1
  326.     xor eax,eax
  327.     movzx ebx, [x_max]
  328.     movzx ecx, [y_max]
  329.     mov edx, 0x01000000     ;Window style       ;Draw nothing
  330. ;     mov edx, 0x00000000     ;Window style
  331. ;     mov esi, 0x00000000     ;Header color (prevent odd color line on top of window in random cases)
  332.     mcall           ;Define window
  333.  
  334.  
  335.     mov ebp, 0
  336.     mov ecx, dword [y_max]
  337.     mcall 65, [image_pointer], , <0,0>, 8, palette
  338.  
  339.  
  340.     mcall   12, 2       ; end redraw
  341.  
  342.  
  343.     call    clear_offscreen_bitmap
  344.  
  345. wait_event:
  346.     mcall 23, delay
  347. ;     mcall 10
  348.     test eax, 0xFFFF - 1    ;Test for 0 (delay passed) or 1 (redraw) event
  349.     jz  draw_window     ; Delay passed or redraw event
  350.     dec eax
  351.     dec eax
  352.     jnz  exit           ; If not key then Alt+F4
  353. ; key pressed, read it and ignore
  354.     mcall   2
  355.         cmp     ah, 27              ; Test Esc key press in ASCII
  356.         jne     wait_event
  357.  
  358. ; button pressed; we have only one button, close
  359. ; also seems to handle Alt+F4
  360. exit:
  361.     mcall   -1
  362.  
  363.  
  364. clear_offscreen_bitmap:
  365.     mov edi, [image_pointer]
  366.     movzx   ecx, [y_max]
  367.     movzx   eax, [x_max]
  368.     imul    ecx, eax
  369.     shr     ecx, 2      ;dword is 4 bytes
  370.     mov eax, 0
  371.     rep stos dword [edi]
  372.     ret
  373.  
  374.  
  375. DATA
  376. divider             dw 5000
  377.  
  378. palette:
  379.     background_cl_index = 0
  380.     dd      background_cl
  381.     foreground_cl_index = 1
  382.     dd      foreground_cl
  383.  
  384.     if defined debug
  385.         red_cl_index = 2
  386.         dd      0x00FF0000          ;Cleanup this!
  387.     end if
  388.  
  389. UDATA
  390. image_pointer       dd ?
  391.  
  392. initial_counter     dd ?
  393. current_counter     dd ?        ;counter + current time
  394.  
  395. half_line_number    dw ?
  396.  
  397. y_max            dw ?     ; screen size
  398. x_max            dw ?
  399.  
  400. radius          dw ?
  401. x_center        dw ?
  402.  
  403. line_coords_array_pointer       dd ?
  404.  
  405. ; line_coords_array:
  406. ;     repeat 1000 ;line_number
  407. ;         dw      ?       ;start_x
  408. ;         dw      ?       ;end_x
  409. ;         dw      ?       ;start_y
  410. ;         dw      ?       ;end_y
  411. ;         dd      ?       ;line_start_pointer
  412. ;     end repeat
  413.  
  414.     start_x_offset = 0
  415.     end_x_offset = 2
  416.     start_y_offset = 4
  417.     end_y_offset = 6
  418.     line_start_pointer_offset = 8
  419.     line_coords_element_size = 12
  420.  
  421. MEOS_APP_END