Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ; A firework demo
  3. ; Programmed by Yaniv LEVIATHAN
  4. ; http://yaniv.leviathanonline.com
  5. ; Converted to DexOS, By Dex
  6. ; Converted to KolibriOS, By Asper
  7. ; Optimized for KolibriOS, By Diamond
  8. ; Assemble with
  9. ; c:fasm firework.asm firework.kex
  10. ; NOTE: Needs MMX & SSE, optionally AVX
  11. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  12. use32
  13.         org     0x0
  14.  
  15.         db      'MENUET01'      ; 8 byte id
  16.         dd      0x01            ; version
  17.         dd      STARTAPP        ; program start
  18.         dd      I_END           ; program image size
  19.         dd      E_END           ; required amount of memory
  20.         dd      stacktop        ; reserved=no extended header
  21.         dd      0, 0
  22.  
  23. include '../../../macros.inc'
  24. SCREEN_WIDTH   = 320
  25. SCREEN_HEIGHT  = 200
  26. SIMD equ SSE
  27. SIMD_BYTES = 8
  28. assert SCREEN_WIDTH mod SIMD_BYTES = 0
  29. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  30. ; Global defines
  31. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  32.  
  33. NUM_PARTS      = 150
  34. X_OFFSET       = 0
  35. Y_OFFSET       = 4
  36. X_SPEED_OFFSET = 8
  37. Y_SPEED_OFFSET = 12
  38. COLOR_OFFSET   = 16
  39. PART_SIZE      = 20
  40.  
  41. macro shade
  42. {
  43. local .lop
  44. if SIMD eq SSE
  45.         mov     ecx, SCREEN_WIDTH * SCREEN_HEIGHT / SIMD_BYTES
  46.         mov     edi, buffer
  47.         movq    mm1, qword [sub_mask]
  48.   .lop:
  49.         movq    mm0, [edi]
  50.         psubusb mm0, mm1
  51.         movq    [edi], mm0
  52.         add     edi, SIMD_BYTES
  53.         loop    .lop
  54. else if SIMD eq AVX
  55.         mov     ecx, SCREEN_WIDTH * SCREEN_HEIGHT / SIMD_BYTES
  56.         mov     edi, buffer
  57.         vmovdqa xmm1, xword [sub_mask]
  58.   .lop:
  59.         vmovdqa xmm0, [edi]
  60.         vpsubusb xmm0, xmm0, xmm1
  61.         vmovdqa [edi], xmm0
  62.         add     edi, SIMD_BYTES
  63.         loop    .lop
  64. else if SIMD eq AVX2
  65.         mov     ecx, SCREEN_WIDTH * SCREEN_HEIGHT / SIMD_BYTES
  66.         mov     edi, buffer
  67.         vmovdqa ymm1, yword [sub_mask]
  68.   .lop:
  69.         vmovdqa ymm0, [edi]
  70.         vpsubusb ymm0, ymm0, ymm1
  71.         vmovdqa [edi], ymm0
  72.         add     edi, SIMD_BYTES
  73.         loop    .lop
  74. else if SIMD eq AVX512
  75.         mov     ecx, SCREEN_WIDTH * SCREEN_HEIGHT / SIMD_BYTES
  76.         mov     edi, buffer
  77.         vmovdqa64 zmm1, zword [sub_mask]
  78.   .lop:
  79.         vmovdqa64 zmm0, [edi]
  80.         vpsubusb zmm0, zmm0, zmm1
  81.         vmovdqa64 [edi], zmm0
  82.         add     edi, SIMD_BYTES
  83.         loop    .lop
  84. end if
  85. }
  86.  
  87. macro blur_prepare
  88. {
  89.         mov     ecx, (SCREEN_WIDTH * SCREEN_HEIGHT - SCREEN_WIDTH * 2 - SIMD_BYTES*2) / SIMD_BYTES
  90.         mov     edi, buffer + SCREEN_WIDTH + SIMD_BYTES
  91. }
  92.  
  93. macro blur
  94. {
  95. local .lop
  96. if SIMD eq SSE
  97. .lop:
  98.         movq    mm0, [edi]
  99.         movq    mm1, [edi + 1]
  100.         movq    mm2, [edi - 1]
  101.         movq    mm3, mm0
  102.         movq    mm4, [edi - SCREEN_WIDTH]
  103.         movq    mm5, [edi + SCREEN_WIDTH]
  104.  
  105.         pavgb   mm0, mm1 ; mm0 = avg(cur,cur+1)
  106.         pavgb   mm3, mm2 ; mm3 = avg(cur,cur-1)
  107.         pavgb   mm4, mm5 ; mm4 = avg(cur+width,cur-width)
  108.         pavgb   mm3, mm4 ; mm3 = avg(avg(cur,cur-1),avg(cur+width,cur-width))
  109.         pavgb   mm0, mm3 ; mm0 = avg(avg(cur,cur+1),
  110.  
  111.         movq    [edi], mm0
  112.         add     edi, SIMD_BYTES
  113.         loop    .lop
  114. else if SIMD eq AVX
  115. .lop:
  116.         vmovdqa xmm0, [edi]
  117.         vmovdqa xmm1, xmm0
  118.         vmovdqa xmm2, [edi - SCREEN_WIDTH]
  119.  
  120.         vpavgb  xmm0, xmm0, [edi + 1]
  121.         vpavgb  xmm1, xmm1, [edi - 1]
  122.         vpavgb  xmm2, xmm2, [edi + SCREEN_WIDTH]
  123.         vpavgb  xmm1, xmm1, xmm2
  124.         vpavgb  xmm0, xmm0, xmm1
  125.  
  126.         vmovdqa [edi], xmm0
  127.         add     edi, SIMD_BYTES
  128.         loop    .lop
  129. else if SIMD eq AVX2
  130. .lop:
  131.         vmovdqa ymm0, [edi]
  132.         vmovdqa ymm1, ymm0
  133.         vmovdqa ymm2, [edi - SCREEN_WIDTH]
  134.  
  135.         vpavgb  ymm0, ymm0, [edi + 1]
  136.         vpavgb  ymm1, ymm1, [edi - 1]
  137.         vpavgb  ymm2, ymm2, [edi + SCREEN_WIDTH]
  138.         vpavgb  ymm1, ymm1, ymm2
  139.         vpavgb  ymm0, ymm0, ymm1
  140.  
  141.         vmovdqa [edi], ymm0
  142.         add     edi, SIMD_BYTES
  143.         loop    .lop
  144. else if SIMD eq AVX512
  145. .lop:
  146.         vmovdqa64 zmm0, [edi]
  147.         vmovdqa64 zmm1, zmm0
  148.         vmovdqa64 zmm2, [edi - SCREEN_WIDTH]
  149.  
  150.         vpavgb  zmm0, zmm0, [edi + 1]
  151.         vpavgb  zmm1, zmm1, [edi - 1]
  152.         vpavgb  zmm2, zmm2, [edi + SCREEN_WIDTH]
  153.         vpavgb  zmm1, zmm1, zmm2
  154.         vpavgb  zmm0, zmm0, zmm1
  155.  
  156.         vmovdqa64 [edi], zmm0
  157.         add     edi, SIMD_BYTES
  158.         loop    .lop
  159. end if
  160. }
  161.  
  162. macro blur_right
  163. {
  164. local .lop
  165. if SIMD eq SSE
  166.   .lop:
  167.         movq    mm0, [edi]
  168.         movq    mm1, [edi + 1]
  169.         movq    mm2, [edi + SCREEN_WIDTH]
  170.         movq    mm3, [edi + SCREEN_WIDTH + 1]
  171.         pavgb   mm0, mm1
  172.         pavgb   mm3, mm2
  173.         pavgb   mm0, mm3
  174.         movq    [edi], mm0
  175.         add     edi, SIMD_BYTES
  176.         loop    .lop
  177. else if SIMD eq AVX
  178.   .lop:
  179.         vmovdqa xmm0, [edi]
  180.         vmovdqu xmm1, [edi + SCREEN_WIDTH + 1]
  181.         vpavgb  xmm2, xmm0, [edi + 1]
  182.         vpavgb  xmm3, xmm1, [edi + SCREEN_WIDTH]
  183.         vpavgb  xmm4, xmm2, xmm3
  184.         vmovdqa [edi], xmm4
  185.         add     edi, SIMD_BYTES
  186.         loop    .lop
  187. else if SIMD eq AVX2
  188.   .lop:
  189.         vmovdqa ymm0, [edi]
  190.         vmovdqu ymm1, [edi + SCREEN_WIDTH + 1]
  191.         vpavgb  ymm2, ymm0, [edi + 1]
  192.         vpavgb  ymm3, ymm1, [edi + SCREEN_WIDTH]
  193.         vpavgb  ymm4, ymm2, ymm3
  194.         vmovdqa [edi], ymm4
  195.         add     edi, SIMD_BYTES
  196.         loop    .lop
  197. else if SIMD eq AVX512
  198.   .lop:
  199.         vmovdqa64 zmm0, [edi]
  200.         vmovdqu64 zmm1, [edi + SCREEN_WIDTH + 1]
  201.         vpavgb  zmm2, zmm0, [edi + 1]
  202.         vpavgb  zmm3, zmm1, [edi + SCREEN_WIDTH]
  203.         vpavgb  zmm4, zmm2, zmm3
  204.         vmovdqa64 [edi], zmm4
  205.         add     edi, SIMD_BYTES
  206.         loop    .lop
  207. end if
  208. }
  209.  
  210. STARTAPP:
  211.  
  212. init_palette:
  213.         mov     edi, pal
  214.         xor     eax, eax
  215. red_loop:
  216.         stosd
  217.         stosd
  218.         add     eax, 0x040000
  219.         and     eax, 0xFFFFFF
  220.         jnz     red_loop
  221.  
  222.         mov     eax, 63*4 SHL 16
  223. @@:
  224.         stosd
  225.         stosd
  226.         add     ax, 0x0404
  227.         jnc     @b
  228.  
  229. ;zero_buffer:
  230.         mov     ecx, SCREEN_WIDTH * SCREEN_HEIGHT / 4
  231. ;       mov     edi, buffer
  232.         xor     eax, eax
  233.         rep     stosd
  234.  
  235. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  236. ; Main Functions
  237. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  238. virtual at esp
  239.         global_x        dd ?
  240.         global_y        dd ?
  241.         seed            dd ?
  242. end virtual
  243.  
  244.         rdtsc
  245.         push    eax      ; seed
  246.         push    100 * 64 ; global_y
  247.         push    160 * 64 ; global_x
  248.  
  249.    jmp MAIN
  250.  
  251.  
  252. red:
  253.         mcall   9, proc_info, -1
  254. x = 100
  255. y = 70
  256. xsize = SCREEN_WIDTH+9
  257. ysize = SCREEN_HEIGHT+4
  258. areacolor = 0x54224466
  259.         mov     eax, 12                 ; function 12:tell os about windowdraw
  260.         mov     ebx, 1                  ; 1, start of draw
  261.         int     0x40
  262.         mov     eax, 48
  263.         mov     ebx, 4
  264.         int     0x40
  265.         lea     ecx, [(y SHL 16) + ysize + eax]
  266.         xor     eax, eax                ; function 0 : define and draw window
  267.         mov     ebx, (x SHL 16) + xsize ; [x start] *65536 + [x size]
  268.         mov     edx, areacolor          ; color of work area RRGGBB
  269.         mov     edi, window_title
  270.         int     0x40
  271.         mov     eax, 12                 ; end of redraw
  272.         mov     ebx, 2
  273.         int     0x40
  274.  
  275. MAIN:
  276.         test    [proc_info.wnd_state], 0x04
  277.         jnz     still
  278.         mov     ecx, NUM_PARTS
  279.         mov     ebp, particles
  280.   .advance_particles:
  281.         mov     eax, [ebp + X_OFFSET]
  282.         mov     ebx, [ebp + Y_OFFSET]
  283.  
  284.         sar     eax, 6
  285.         sar     ebx, 6
  286.  
  287.         cmp     eax, 5
  288.         jb      .new_particle
  289.         cmp     eax, SCREEN_WIDTH - 5
  290.         jge     .new_particle
  291.         cmp     ebx, 5
  292.         jb      .new_particle
  293.         cmp     ebx, SCREEN_HEIGHT - 5
  294.         jl      .part_ok
  295.  
  296.   .new_particle:
  297.         call    init_particle
  298.         jmp     .advance_particles
  299.  
  300.   .part_ok:
  301.         imul    edi, ebx, SCREEN_WIDTH
  302.         mov     dl, [ebp+COLOR_OFFSET]
  303.         mov     [buffer+eax+edi], dl
  304.  
  305.         mov     eax, [ebp+X_SPEED_OFFSET]
  306.         add     [ebp+X_OFFSET], eax
  307.         mov     eax, [ebp+Y_SPEED_OFFSET]
  308.         add     [ebp+Y_OFFSET], eax
  309.  
  310.         rdtsc
  311.         and     al, 0x7F
  312.         jnz     .dont_inc_y_speed
  313.         inc     dword [ebp+Y_SPEED_OFFSET]
  314.     .dont_inc_y_speed:
  315.  
  316.         add     ebp, PART_SIZE
  317.         loop    .advance_particles
  318.  
  319.         shade
  320. ;       jmp     .copy_buffer_to_video
  321.         blur_prepare
  322.         test    dword [blur_right_flag] , 0x800000
  323.         jnz     .do_blur_right
  324.         blur
  325.         rdtsc
  326.         and     al, 1
  327.         jz      .blur_ok
  328.         jmp     .dont_blur
  329.     .do_blur_right:
  330.         blur_right
  331.     .blur_ok:
  332.         add     dword [blur_right_flag], 0x1000
  333.     .dont_blur:
  334.  
  335.     .copy_buffer_to_video:
  336.  
  337.         mcall   48, 4
  338.         lea     edx, [(5 SHL 16) + eax]
  339.  
  340.         mov     eax, 65
  341.         mov     ebx, buffer
  342.         mov     ecx, (SCREEN_WIDTH SHL 16) + SCREEN_HEIGHT
  343.         push    8
  344.         pop     esi
  345.         mov     edi, pal
  346.         xor     ebp, ebp
  347.         int     0x40
  348.  
  349.  
  350. still:
  351.         mov     eax, 11             ; Test if there is an event in the queue.
  352.         int     0x40
  353.  
  354.         dec     eax                   ; redraw request ?
  355.         jz      red
  356.         dec     eax                   ; key in buffer ?
  357.         jz      key
  358.         dec     eax                   ; button in buffer ?
  359.         jz      button
  360.  
  361.         jmp     MAIN
  362.  
  363.  
  364. key:
  365.         mov     eax, 2
  366.         int     0x40
  367. ;       cmp     ah, 1               ; Test Esc in Scan
  368. ;       je      close_app
  369.         cmp     ah, 27              ; Test Esc in ASCII
  370.         je      close_app
  371.         jmp     MAIN
  372.  
  373. button:
  374. ; we have only one button, close
  375. close_app:
  376.         mov     eax, -1         ; close this program
  377.         int     0x40
  378.  
  379. init_particle:
  380.         rdtsc
  381.         and     al, 0x1F
  382.         jnz     .dont_re_init_globals
  383.         ; init x
  384.         call    rand
  385.         cdq
  386.         ;xor dx, dx
  387.         mov     ebx, SCREEN_WIDTH
  388.         div     ebx
  389.         shl     edx, 6
  390.         mov     [4 + global_x], edx
  391.         ; init y
  392.         call    rand
  393.         cdq
  394.         ;xor    dx, dx
  395.         mov     ebx, SCREEN_HEIGHT
  396.         div     ebx
  397.         shl     edx, 6
  398.         mov     [4 + global_y], edx
  399.   .dont_re_init_globals:
  400.         ; init x
  401.         mov     eax, [4 + global_x]
  402.         mov     [ebp + X_OFFSET], eax
  403.         ; init y
  404.         mov     eax, [4 + global_y]
  405.         mov     [ebp + Y_OFFSET], eax
  406.         ; init x speed
  407.         call    rand
  408.         and     eax, 31
  409.         sub     eax, 15
  410.         ;shl    ax, 6
  411.         mov     [ebp + X_SPEED_OFFSET], eax
  412.         ; init y speed
  413.         call    rand
  414.         and     eax, 31
  415.         sub     eax, 15
  416.         ;shl    ax, 6
  417.         mov     [ebp + Y_SPEED_OFFSET], eax
  418.         ; init color
  419.         mov     [ebp + COLOR_OFFSET], dword 255
  420.         ret
  421.  
  422. rand:
  423.         mov     eax, [8 + seed]
  424.         imul    eax, 214013
  425.         add     eax, 2531011
  426.         mov     [8 + seed], eax
  427.         shr     eax, 16
  428.         ret
  429.  
  430. ; DATA AREA
  431. window_title    db 'Firework demo',0
  432. align SIMD_BYTES
  433. sub_mask        db SIMD_BYTES dup 0x01
  434. ;                             x, y, x_speed, y_speed, color
  435. particles: times NUM_PARTS dd 0, 0, 0,       0,       0
  436. blur_right_flag dd 0
  437. I_END:
  438. proc_info       process_information
  439. align 16
  440. pal             rb 256 * 4
  441. align SIMD_BYTES
  442. buffer          rb SCREEN_WIDTH * SCREEN_HEIGHT
  443. E_END:
  444. rd 0x200
  445. stacktop:
  446.