Subversion Repositories Kolibri OS

Rev

Rev 7125 | Rev 7277 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1547 Asper 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7125 dunkaist 2
; A firework demo
3
; Programmed by Yaniv LEVIATHAN
4
; http://yaniv.leviathanonline.com
5
; Converted to DexOS, By Dex
1547 Asper 6
; Converted to KolibriOS, By Asper
7
; Optimized for KolibriOS, By Diamond
8
; Assemble with
9
; c:fasm firework.asm firework.kex
7276 dunkaist 10
; NOTE: Needs MMX & SSE,
11
; optionally AVX, AVX2, AVX512
7125 dunkaist 12
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
13
use32
14
        org     0x0
1547 Asper 15
 
7125 dunkaist 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
1547 Asper 23
 
2095 dunkaist 24
include '../../../macros.inc'
7125 dunkaist 25
SCREEN_WIDTH   = 320
26
SCREEN_HEIGHT  = 200
7276 dunkaist 27
SIMD equ AVX
28
SIMD_BYTES = 16
29
; SSE    8
30
; AVX    16
31
; AVX2   32
32
; AVX512 64
7125 dunkaist 33
assert SCREEN_WIDTH mod SIMD_BYTES = 0
1547 Asper 34
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7125 dunkaist 35
; Global defines
36
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1547 Asper 37
 
7125 dunkaist 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
1547 Asper 45
 
7125 dunkaist 46
macro shade
1547 Asper 47
{
7125 dunkaist 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
1547 Asper 90
}
91
 
7125 dunkaist 92
macro blur_prepare
1547 Asper 93
{
7125 dunkaist 94
        mov     ecx, (SCREEN_WIDTH * SCREEN_HEIGHT - SCREEN_WIDTH * 2 - SIMD_BYTES*2) / SIMD_BYTES
95
        mov     edi, buffer + SCREEN_WIDTH + SIMD_BYTES
1547 Asper 96
}
97
 
7125 dunkaist 98
macro blur
1547 Asper 99
{
100
local .lop
7125 dunkaist 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]
1547 Asper 109
 
7125 dunkaist 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),
1547 Asper 115
 
7125 dunkaist 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
1547 Asper 165
}
166
 
7125 dunkaist 167
macro blur_right
1547 Asper 168
{
169
local .lop
7125 dunkaist 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
1547 Asper 213
}
214
 
215
STARTAPP:
216
 
217
init_palette:
7125 dunkaist 218
        mov     edi, pal
219
        xor     eax, eax
1547 Asper 220
red_loop:
7125 dunkaist 221
        stosd
222
        stosd
223
        add     eax, 0x040000
224
        and     eax, 0xFFFFFF
225
        jnz     red_loop
1547 Asper 226
 
7125 dunkaist 227
        mov     eax, 63*4 SHL 16
1547 Asper 228
@@:
7125 dunkaist 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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1547 Asper 243
virtual at esp
7125 dunkaist 244
        global_x        dd ?
245
        global_y        dd ?
246
        seed            dd ?
1547 Asper 247
end virtual
248
 
7125 dunkaist 249
        rdtsc
250
        push    eax      ; seed
251
        push    100 * 64 ; global_y
252
        push    160 * 64 ; global_x
1547 Asper 253
 
7125 dunkaist 254
   jmp MAIN
1547 Asper 255
 
256
 
257
red:
7125 dunkaist 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
 
1547 Asper 280
MAIN:
7125 dunkaist 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]
1547 Asper 288
 
7125 dunkaist 289
        sar     eax, 6
290
        sar     ebx, 6
1547 Asper 291
 
7125 dunkaist 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
1547 Asper 300
 
7125 dunkaist 301
  .new_particle:
302
        call    init_particle
303
        jmp     .advance_particles
1547 Asper 304
 
7125 dunkaist 305
  .part_ok:
306
        imul    edi, ebx, SCREEN_WIDTH
307
        mov     dl, [ebp+COLOR_OFFSET]
308
        mov     [buffer+eax+edi], dl
1547 Asper 309
 
7125 dunkaist 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
1547 Asper 314
 
7125 dunkaist 315
        rdtsc
316
        and     al, 0x7F
317
        jnz     .dont_inc_y_speed
318
        inc     dword [ebp+Y_SPEED_OFFSET]
319
    .dont_inc_y_speed:
1547 Asper 320
 
7125 dunkaist 321
        add     ebp, PART_SIZE
322
        loop    .advance_particles
1547 Asper 323
 
7125 dunkaist 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:
1547 Asper 339
 
7125 dunkaist 340
    .copy_buffer_to_video:
1547 Asper 341
 
7125 dunkaist 342
        mcall   48, 4
343
        lea     edx, [(5 SHL 16) + eax]
1547 Asper 344
 
7125 dunkaist 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
1547 Asper 353
 
7125 dunkaist 354
 
1547 Asper 355
still:
7125 dunkaist 356
        mov     eax, 11             ; Test if there is an event in the queue.
357
        int     0x40
1547 Asper 358
 
7125 dunkaist 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
1547 Asper 365
 
7125 dunkaist 366
        jmp     MAIN
1547 Asper 367
 
368
 
369
key:
7125 dunkaist 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
1547 Asper 377
 
378
button:
379
; we have only one button, close
380
close_app:
7125 dunkaist 381
        mov     eax, -1         ; close this program
382
        int     0x40
1547 Asper 383
 
7125 dunkaist 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
1547 Asper 426
 
7125 dunkaist 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
1547 Asper 434
 
435
; DATA AREA
7125 dunkaist 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
1547 Asper 442
I_END:
7125 dunkaist 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: