Subversion Repositories Kolibri OS

Rev

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