Subversion Repositories Kolibri OS

Rev

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