Subversion Repositories Kolibri OS

Rev

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