Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2659 leency 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'
9525 leency 5
include '../../../KOSfuncs.inc'
2659 leency 6
 
7
use32
9525 leency 8
                org         0x0
2659 leency 9
 
9525 leency 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
2659 leency 17
 
9525 leency 18
; start of execution
19
START:
2659 leency 20
 
9525 leency 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
2659 leency 27
 
28
still:
29
 
9525 leency 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
2659 leency 44
 
9525 leency 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
2659 leency 53
 
9525 leency 54
      .button:
55
                mcall       SF_GET_BUTTON
56
                cmp         ah,1                   ; button id=1 ?
57
                jne         still
2659 leency 58
 
9525 leency 59
      .exit:
60
                mcall       SF_TERMINATE_PROCESS
2659 leency 61
 
62
 
9525 leency 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
2659 leency 69
 
70
draw_from_buffer:
9525 leency 71
                pusha
72
                mcall       SF_PUT_IMAGE,screen,IMG_SIZE*65536+IMG_SIZE,0
73
		    popa
2659 leency 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
 
9525 leency 312
                mcall       SF_REDRAW, SSF_BEGIN_DRAW
2659 leency 313
 
9525 leency 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
2659 leency 317
 
9525 leency 318
                mcall       SF_REDRAW, SSF_END_DRAW
319
                ret
2659 leency 320
 
321
 
322
;-------------------------------------------------------------------------------
323
align 1
9525 leency 324
wintitle1       db          'Buddhabrot - Calculating, please wait...',0
325
wintitle2       db          'Buddhabrot - Press F8 to set image as wallpaper',0
2659 leency 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
 
9525 leency 336
IMG_SIZE        =           600
337
SEQ_SIZE        =           50
338
ITERATIONS      =           100
339
 
2659 leency 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
;--------------------
9525 leency 354
sequence:       rb          SEQ_SIZE*8
355
screen:         rb          IMG_SIZE*IMG_SIZE*4
356
memStack:       rd          1024
2659 leency 357
I_END: