Subversion Repositories Kolibri OS

Rev

Rev 2659 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ; App written by randall ported to Kolibri and MenuetOS64 by macgub (www.macgub.hekko.pl).
  2. ; Now it use static memory, it is mixed 32bit code and SSE instructions.
  3.  
  4. include '../../../macros.inc'
  5. include '../../../KOSfuncs.inc'
  6.  
  7. use32
  8.                 org         0x0
  9.  
  10.                 db          'MENUET01'           ; 8 byte id
  11.                 dd          0x01                 ; header version
  12.                 dd          START                ; start of code
  13.                 dd          IMG_END              ; size of image
  14.                 dd          I_END ;0x100000      ; memory for app
  15.                 dd          I_END ;0xbffff       ; esp
  16.                 dd          0x0 , 0x0            ; I_Param , I_Icon
  17.  
  18. ; start of execution
  19. START:
  20.  
  21.                 call        draw_window
  22.                     call        draw_from_buffer
  23.                 call        Main
  24.                 call        draw_from_buffer
  25.                
  26.                 mcall       SF_SET_CAPTION,1,wintitle2
  27.  
  28. still:
  29.  
  30.                 mcall       SF_WAIT_EVENT
  31.  
  32.                 cmp         eax,EV_REDRAW
  33.                 je          .redraw
  34.                 cmp         eax,EV_KEY
  35.                 je          .key
  36.                 cmp         eax,EV_BUTTON
  37.                 je          .button
  38.                 jmp         still
  39.                
  40.       .redraw:
  41.                 call        draw_window
  42.                 call        draw_from_buffer
  43.                 jmp         still
  44.  
  45.       .key:
  46.                 mcall       SF_GET_KEY
  47.                 shr         eax,16                ; get scancode in 'al'
  48.                 cmp         al,1
  49.                 je          .exit
  50.                 cmp         al,66
  51.                 je          set_as_wallpaper
  52.                 jmp         still
  53.  
  54.       .button:
  55.                 mcall       SF_GET_BUTTON
  56.                 cmp         ah,1                   ; button id=1 ?
  57.                 jne         still
  58.  
  59.       .exit:
  60.                 mcall       SF_TERMINATE_PROCESS
  61.  
  62.  
  63. set_as_wallpaper:
  64.                 mcall       SF_BACKGROUND_SET,SSF_MODE_BG,2
  65.                 mcall       SF_BACKGROUND_SET,SSF_SIZE_BG,IMG_SIZE,IMG_SIZE
  66.                 mcall       SF_BACKGROUND_SET,SSF_IMAGE_BG,screen,0,3*IMG_SIZE*IMG_SIZE
  67.                 mcall       SF_BACKGROUND_SET,SSF_REDRAW_BG
  68.                 jmp         still
  69.  
  70. draw_from_buffer:
  71.                 pusha
  72.                 mcall       SF_PUT_IMAGE,screen,IMG_SIZE*65536+IMG_SIZE,0
  73.                     popa
  74. ret
  75.  
  76. ;-------------------------------------------------------------------------------
  77. ; NAME:         XORWOW
  78. ; DESC:         Pseudo random number generator.
  79. ; OUT:          eax         [0;2^32-1]
  80. ;-------------------------------------------------------------------------------
  81. macro           XORWOW      {
  82.                 mov         edx,[g_xorwow_x]    ; edx = x
  83.                 shr         edx,2               ; edx = x >> 2
  84.                 xor         edx,[g_xorwow_x]    ; t = x ^ (x >> 2)
  85.                 mov         eax,[g_xorwow_y]    ; eax = y
  86.                 mov         [g_xorwow_x],eax    ; x = y
  87.                 mov         eax,[g_xorwow_z]    ; eax = z
  88.                 mov         [g_xorwow_y],eax    ; y = z
  89.                 mov         eax,[g_xorwow_w]    ; eax = w
  90.                 mov         [g_xorwow_z],eax    ; z = w
  91.                 mov         eax,[g_xorwow_v]    ; eax = v
  92.                 mov         [g_xorwow_w],eax    ; w = v
  93.                 mov         edi,eax             ; edi = v
  94.                 shl         edi,4               ; edi = v << 4
  95.                 xor         edi,eax             ; edi = (v ^ (v << 4))
  96.                 mov         eax,edx             ; eax = t
  97.                 shl         eax,1               ; eax = t << 1
  98.                 xor         eax,edx             ; eax = (t ^ (t << 1))
  99.                 xor         eax,edi             ; eax = (v ^ (v << 4)) ^ (t ^ (t << 1))
  100.                 mov         [g_xorwow_v],eax    ; v = eax
  101.                 add         [g_xorwow_d],362437 ; d += 362437
  102.                 mov         eax,[g_xorwow_d]    ; eax = d
  103.                 add         eax,[g_xorwow_v]    ; eax = d + v
  104. }
  105. ;-------------------------------------------------------------------------------
  106. ; NAME:         RANDOM
  107. ; DESC:         Returns pseudo random number in the range [-0.5;0.5).
  108. ; OUT:          xmm0.x      [-0.5;0.5)
  109. ;-------------------------------------------------------------------------------
  110. macro           RANDOM {
  111.                 XORWOW
  112.                 cvtsi2ss    xmm0,eax
  113.                 mulss       xmm0,[g_rand_scale]
  114. }
  115. ;-------------------------------------------------------------------------------
  116.  
  117. ;-------------------------------------------------------------------------------
  118. ; NAME:         GenerateSequence
  119. ; IN:           xmm0.x      re (c0.x)
  120. ; IN:           xmm1.x      im (c0.y)
  121. ; IN:           edi         array size
  122. ; IN/OUT:       esi         pointer to the allocated array
  123. ; OUT:          eax         generated sequence size
  124. ;-------------------------------------------------------------------------------
  125. align 16
  126. GenerateSequence:
  127.                 xor         eax,eax     ; eax is index loop
  128.                 xorps       xmm4,xmm4   ; xmm4 is c.x
  129.                 xorps       xmm5,xmm5   ; xmm5 is c.y
  130. .Loop:
  131.                 ; cn.x = c.x * c.x - c.y * c.y + c0.x
  132.                 movaps      xmm2,xmm4
  133.                 movaps      xmm3,xmm5
  134.                 mulss       xmm2,xmm4
  135.                 mulss       xmm3,xmm5
  136.                 subss       xmm2,xmm3
  137.                 addss       xmm2,xmm0
  138.                 movaps      xmm6,xmm2   ; xmm6 is cn.x
  139.                 ; cn.y = 2.0 * c.x * c.y + c0.y
  140.                 movaps      xmm7,xmm4
  141.                 mulss       xmm7,xmm5
  142.                 addss       xmm7,xmm7
  143.                 addss       xmm7,xmm1   ; xmm7 is cn.y
  144.                 ; store cn
  145.                 movd        dword [esi+eax*8],xmm6
  146.                 movd        dword [esi+eax*8+4],xmm7
  147.                 ; if (cn.x * cn.x + cn.y * cn.y > 10.0) return eax;
  148.                 movaps      xmm2,xmm6
  149.                 movaps      xmm3,xmm7
  150.                 mulss       xmm2,xmm6
  151.                 mulss       xmm3,xmm7
  152.                 addss       xmm2,xmm3
  153.                 ucomiss     xmm2,[g_max_dist]
  154.                 ja          .EndLoop
  155.                 movaps      xmm4,xmm6   ; c.x = cn.x
  156.                 movaps      xmm5,xmm7   ; c.y = cn.y
  157.                 ; continue loop
  158.                 inc         eax
  159.                 cmp         eax,edi
  160.                 jb          .Loop
  161.                 ; return 0
  162.                 xor         eax,eax
  163. .EndLoop:
  164.                 ret
  165. ;-------------------------------------------------------------------------------
  166. ; NAME:         main
  167. ; DESC:         Program main function.
  168. ;-------------------------------------------------------------------------------
  169. align 16
  170. Main:
  171. img_ptr         equ         ebp-8
  172. seq_ptr         equ         ebp-16
  173. pixel           equ         ebp-24
  174. r13dd           equ         ebp-64
  175. r12dd           equ         ebp-68
  176. r15dd           equ         ebp-72
  177.  
  178.                 push        ebp
  179.                 mov         ebp,esp
  180.                 sub         esp,128
  181.                 ;  mem for the sequence
  182.                 lea         eax,[sequence]
  183.                 mov         [seq_ptr],eax
  184.                 ;  mem for the image
  185.                 lea         eax,[screen]
  186.                 mov         [img_ptr],eax
  187.                 ; begin loops
  188.                 mov         dword[r13dd],0         ; .LoopIterations counter
  189. .LoopIterations:
  190.                 mov         dword[r12dd],0         ; .LoopOneMillion counter
  191. .LoopOneMillion:
  192.                 RANDOM
  193.                 mulss       xmm0,[g_range]
  194.                 movaps      xmm1,xmm0
  195.                 RANDOM
  196.                 mulss       xmm0,[g_range]
  197.                 mov         edi,SEQ_SIZE
  198.                 mov         esi,[seq_ptr]
  199.                 call        GenerateSequence  ; eax = n sequence size
  200.                 test        eax,eax
  201.                 jz          .LoopSequenceEnd
  202.                 xor         ecx,ecx           ; ecx = i = 0 loop counter
  203.          ;       mov         r9dd,[seq_ptr]      ; r9 = sequence base address
  204.          ;       mov         r8dd,[img_ptr]      ; r8 = image base address
  205.                 movss       xmm2,[g_img_size]
  206.                 movaps      xmm3,xmm2
  207.                 mulss       xmm3,[g_0_5]      ; xmm3 = (g_img_size)/2
  208.                 movss       xmm4,[g_zoom]
  209.                 mulss       xmm4,xmm2         ; xmm4 = g_zoom * g_img_size
  210.                 movss       xmm5,[g_offsetx]  ; xmm5 = g_offsetx
  211.                 movss       xmm6,[g_offsety]  ; xmm6 = g_offsety
  212. .LoopSequence:
  213.                 cmp         ecx,eax           ; i < n
  214.                 je          .LoopSequenceEnd
  215.                 movd        xmm0,[sequence+ecx*8]   ; load re
  216.                 movd        xmm1,[sequence+ecx*8+4] ; load im
  217.                 addss       xmm0,xmm5         ; xmm0 = re+g_offsetx
  218.                 addss       xmm1,xmm6         ; xmm1 = im+g_offsety
  219.                 mulss       xmm0,xmm4         ; xmm0 = (re+g_offsetx)*g_img_size*g_zoom
  220.                 mulss       xmm1,xmm4         ; xmm1 = (im+g_offsety)*g_img_size*g_zoom
  221.                 addss       xmm0,xmm3         ; xmm0 = (re+g_offsetx)*g_img_size*g_zoom+g_img_size/2
  222.                 addss       xmm1,xmm3         ; xmm1 = (im+g_offsety)*g_img_size*g_zoom+g_img_size/2
  223.                 cvtss2si    edi,xmm0          ; edi = x = int(xmm0.x)
  224.                 cvtss2si    esi,xmm1          ; esi = y = int(xmm1.x)
  225.                 cmp         edi,0
  226.                 jl          @f
  227.                 cmp         edi,IMG_SIZE
  228.                 jge         @f
  229.                 cmp         esi,0
  230.                 jl          @f
  231.                 cmp         esi,IMG_SIZE
  232.                 jge         @f
  233.                 imul        esi,esi,IMG_SIZE
  234.                 add         esi,edi
  235.                 add         dword [screen+esi*4],1
  236. @@:
  237.                 inc         ecx
  238.                 jmp         .LoopSequence
  239. .LoopSequenceEnd:
  240.                 ; continue .LoopOneMillion
  241.                 add         dword[r12dd],1
  242.                 cmp         dword[r12dd],1000000
  243.                 jb          .LoopOneMillion
  244.                 ; continue .LoopIterations
  245.                 add         dword[r13dd],1
  246.                 cmp         dword[r13dd],ITERATIONS
  247.                 jb          .LoopIterations
  248.                 ; find max value
  249.                 mov         dword[r12dd],0
  250.                 xor         eax,eax      ; eax = i = loop counter
  251. .LoopMax:
  252.                 push        ecx
  253.                 mov         ecx,[r12dd]
  254.                 cmp         dword [screen+eax*4],ecx
  255.                 cmova       ecx,dword [screen+eax*4]
  256.                 mov         [r12dd],ecx
  257.                 pop         ecx
  258.                 inc         eax
  259.                 cmp         eax,IMG_SIZE*IMG_SIZE
  260.                 jb          .LoopMax
  261.                 ; find min value
  262.         ;        mov         r13d,r12d   ; r13d = min_val = max_val
  263.                 push        dword[r12dd]
  264.                 pop         dword[r13dd]
  265.                 xor         eax,eax     ; eax = i = loop counter
  266. .LoopMin:
  267.                 push        ecx
  268.                 mov         ecx,[r13dd]
  269.                 cmp         dword [screen+eax*4],ecx
  270.  
  271.                 cmovb       ecx,dword [screen+eax*4]
  272.                 mov         [r13dd],ecx
  273.                 pop         ecx
  274.                 inc         eax
  275.                 cmp         eax,IMG_SIZE*IMG_SIZE
  276.                 jb          .LoopMin
  277.                 ; write image pixels
  278.                 mov         byte [pixel+3],255
  279.        ;         mov         r14,[img_ptr]   ; r14 = image base address
  280.        ;         xor         r15d,r15d       ; r15d = i = loop counter
  281.                 mov         dword[r15dd],0
  282.                 cvtsi2ss    xmm0,[r12dd]       ; load max_value
  283.                 cvtsi2ss    xmm1,[r13dd]       ; load min_value
  284.                 movaps      xmm2,xmm0
  285.                 subss       xmm2,xmm1       ; xmm2 = r = max_value - min_value
  286.                 xor         ecx,ecx
  287. .LoopWrite:
  288.                 mov         eax,[screen+ecx*4] ; eax = image_value
  289.                 sub         eax,[r13dd]        ; eax = image_value - min_value
  290.                 cvtsi2ss    xmm0,eax        ; xmm0 = float(image_value - min_value)
  291.                 addss       xmm0,xmm0       ; xmm0 = 2.0f * float(image_value - min_value)
  292.                 divss       xmm0,xmm2       ; xmm0 = 2.0f * float(image_value - min_value) / r
  293.                 minss       xmm0,[g_1_0]    ; clamp to 1.0
  294.                 maxss       xmm0,[g_0_0]    ; clamp to 0.0
  295.                 mulss       xmm0,[g_255_0]  ; convert to 0 - 255
  296.                 cvtss2si    eax,xmm0
  297.                 ; write pixel data
  298.                 mov         [screen+ecx*3],eax
  299.                 inc         ecx
  300.                 cmp         ecx,IMG_SIZE*IMG_SIZE
  301.                 jb          .LoopWrite
  302.                 mov         esp,ebp
  303.                 pop         ebp
  304.                 ret
  305.        ;         restore     img_ptr,seq_ptr,pixel
  306. ;-------------------------------------------------------------------------------
  307. ;   *********************************************
  308. ;   *******  WINDOW DEFINITIONS AND DRAW ********
  309. ;   *********************************************
  310. draw_window:
  311.  
  312.                 mcall       SF_REDRAW, SSF_BEGIN_DRAW
  313.    
  314.                 mcall       SF_STYLE_SETTINGS, SSF_GET_SKIN_HEIGHT
  315.                 lea         ecx, [50*65536+IMG_SIZE+4+eax]            ; [y start] *65536 + [y size] + [skin_height]
  316.                 mcall       SF_CREATE_WINDOW,<50,IMG_SIZE+9>,,0x74000000,,wintitle1
  317.  
  318.                 mcall       SF_REDRAW, SSF_END_DRAW
  319.                 ret
  320.  
  321.  
  322. ;-------------------------------------------------------------------------------
  323. align 1
  324. wintitle1       db          'Buddhabrot - Calculating, please wait...',0
  325. wintitle2       db          'Buddhabrot - Press F8 to set image as wallpaper',0
  326.  
  327. align 4
  328. g_xorwow_x      dd          123456789
  329. g_xorwow_y      dd          362436069
  330. g_xorwow_z      dd          521288629
  331. g_xorwow_w      dd          88675123
  332. g_xorwow_v      dd          5783321
  333. g_xorwow_d      dd          6615241
  334. g_rand_scale    dd          2.3283064e-10 ; 1.0 / 2^32
  335.  
  336. IMG_SIZE        =           600
  337. SEQ_SIZE        =           50
  338. ITERATIONS      =           100
  339.  
  340. g_img_size      dd          600.0
  341. g_offsetx       dd          0.5
  342. g_offsety       dd          0.0
  343. g_zoom          dd          0.4
  344.  
  345. g_max_dist      dd          10.0
  346. g_range         dd          4.2
  347. g_0_5           dd          0.5
  348. g_0_0           dd          0.0
  349. g_1_0           dd          1.0
  350. g_255_0         dd          255.0
  351.  
  352. IMG_END:
  353. ;--------------------
  354. sequence:       rb          SEQ_SIZE*8
  355. screen:         rb          IMG_SIZE*IMG_SIZE*4
  356. memStack:       rd          1024
  357. I_END: