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:50,IMG_SIZE+9>>><>><>><>><>><>><> |