Subversion Repositories Kolibri OS

Rev

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