Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1778 yogev_ezra 1
;"Web" demo for KolibriOS, version 0.3
2
;Copyright Alexander Meshcheryakov (Self-Perfection), 2009
3
;Contact me: alexander.s.m@gmail.com
4
;distributed under BSD license
5
 
6
;Used assumptions:
7
;   1) Screen resolution does not change while app is running
8
;   2) Screen width bigger than height
9
;   3) Screen width and height are even (2*k)
10
 
9451 leency 11
use32
12
    org 0
13
    db  'MENUET01'
14
    dd  0x01,__start,__end,__memory,__stack,param,0
15
 
1796 yogev_ezra 16
include '../../../macros.inc'
1778 yogev_ezra 17
 
18
background_cl = 0x000000
19
foreground_cl = 0xFFFFFF
20
 
21
delay = 4
22
 
23
; debug = 1
24
 
9451 leency 25
;KOS_APP_START
1778 yogev_ezra 26
 
27
CODE
9469 leency 28
	;Check if the app is running in screensaver mode or not
9451 leency 29
	cmp dword [param], '@ss'
30
	setz [screensaver]
31
    mov     ebx, EVM_REDRAW + EVM_KEY + EVM_BUTTON
32
    cmovz   ebx, EVM_REDRAW + EVM_KEY + EVM_BUTTON + EVM_MOUSE
33
    mcall   40
34
 
9469 leency 35
	;Make cursor transparent
36
    mov     edi, transparent_cursor
37
    xor     eax, eax
38
    mov     ecx, 32*32
39
    rep     stosd
40
    mcall   37, 4, transparent_cursor, 2
41
    mov     ecx, eax
42
    mcall   37, 5
43
 
1778 yogev_ezra 44
    ;Preinit. Randomize start counter
45
    mcall 3
46
    mov     [initial_counter], eax          ;init with system time
47
 
48
    ;Query screen size
49
    mcall   14
50
    add     eax, 0x00010001
51
    mov     dword [y_max], eax      ;store x_max and y_max
52
    shr     eax, 1
53
    mov     dword [radius], eax     ;store radius and x_center
54
 
55
    ;Calc line_number
56
    mov     ax, [y_max]
57
    mov     dx, 0
58
    mov     bx, 5
59
    div     bx
60
    mov     word [half_line_number], ax
61
    movzx   edx, ax         ;edx = half_line_number
62
    imul    edx, 2 * line_coords_element_size      ;Space needed for line_coords_array
63
 
64
    ;Demand memory
65
    mcall   68, 11      ; Init heap
66
    test    eax, eax    ; Is heap successfully inited?
67
    jnz     @f
9451 leency 68
    jmp     exit          ;   Netu pamjati?! Nu i nahuj vas
1778 yogev_ezra 69
@@:
70
    movzx   ecx, [y_max]
71
    inc     ecx
72
    movzx   eax, [x_max]
73
    imul    ecx, eax        ;[Remember to left here space for 1-2 emergency lines at bottom]
74
    add     ecx, edx        ;And add space for line_coords_array
75
    mcall   68, 12,
76
    test    eax, eax    ; Did we get something non zero?
77
    jnz     @f
9451 leency 78
    jmp     exit
1778 yogev_ezra 79
@@:
80
    mov     [line_coords_array_pointer], eax
81
    add     eax, edx
82
    mov     [image_pointer], eax
83
 
84
 
85
    call    clear_offscreen_bitmap
86
 
87
 
88
 
89
;Calc fixed line ends coords
90
    fninit
91
    fldpi
92
    fidiv word [half_line_number]    ;Now st0 contains angle step of line start points
93
 
94
    mov eax, [line_coords_array_pointer]          ;cleanup: comment
95
    movzx   ecx, word [half_line_number]
96
    shl     ecx, 1
97
    fld     st      ;skip zero angle to avoid 1px fixed line at right side
98
 
99
 
100
calculate_next_line_start_point:
101
    fld st
102
 
103
    ;Calculate line start points coords
104
    fsincos
105
    fimul [radius]
106
    fiadd [x_center]
107
    fistp word [eax+start_x_offset]
108
;     fchs                              ;affects direction, uncomment with corresponding line below
109
    fimul [radius]
110
    fiadd [radius]
111
    fistp word [eax+start_y_offset]
112
 
113
    ;Calculate line start point pointer
114
    movzx   ebx, word [eax+start_y_offset]
115
    movzx   edx, word [x_max]
116
    imul    ebx, edx
117
    movzx   edx, word [eax+start_x_offset]
118
    add     ebx, edx
119
    add     ebx, [image_pointer]
120
 
121
    mov     [eax+line_start_pointer_offset], ebx
122
 
123
 
124
    fadd st0, st1
125
    add eax, line_coords_element_size    ;Move to next element in line_coords_array
126
 
127
    loop calculate_next_line_start_point
128
 
129
    fstp    st0          ;drop current angle
130
    fidiv   [divider]   ;change angle step
131
 
132
 
133
draw_window:
134
 
135
;Start line coords calculation
136
 
137
    fld     st      ;skip zero angle to avoid 1px fixed line at right side
138
 
139
    ;Use time since start to get current counter value
140
    mcall   26, 9
141
    add     eax, [initial_counter]
142
    mov     [current_counter], eax
143
 
144
    mov eax, [line_coords_array_pointer]          ;cleanup: comment
145
    movzx   ecx, word [half_line_number]
146
    shl     ecx, 1
147
 
148
calculate_next_line_end_point:
149
    fld st
150
 
151
    ;Calculate line end points
152
    fimul [current_counter]
153
    fsincos
154
    fimul [radius]
155
    fiadd [x_center]
156
    fistp word [eax+2]
157
;     fchs                              ;affects direction, uncomment with corresponding line above
158
    fimul [radius]
159
    fiadd [radius]
160
    fistp word [eax+6]
161
 
162
    fadd st0, st1
163
 
164
    add eax, line_coords_element_size    ;Move to next element in line_coords_array
165
    loop calculate_next_line_end_point
166
 
167
    fstp    st0     ;drop current angle
168
 
169
    inc dword [initial_counter]
170
 
171
 
172
;   *********************************************
173
;   *******Draw lines on offscreen bitmap********
174
;   *********************************************
175
 
176
    ;draw end points
177
    movzx   edi, [half_line_number]
178
    shl     edi, 1
179
    mov esi, [line_coords_array_pointer]
180
 
181
  draw_next_line:
182
 
183
    if defined debug    ;Draw red points next to line ends in debug mode
184
        movzx   ebx, word [esi+start_y_offset]
185
        movzx   eax, word [x_max]
186
        imul    eax, ebx
187
        movzx   ebx, word [esi+start_x_offset]
188
        add     eax, ebx
189
        add     eax, dword [image_pointer]
190
        inc     eax
191
        mov     [eax], byte red_cl_index
192
 
193
        movzx   ebx, word [esi+end_y_offset]
194
        movzx   eax, word [x_max]
195
        imul    eax, ebx
196
        movzx   ebx, word [esi+end_x_offset]
197
        add     eax, ebx
198
        add     eax, dword [image_pointer]
199
        inc     eax                             ;Move one right to make more visible
200
        mov     [eax], byte red_cl_index
201
    end if
202
 
203
 
204
;Drawing lines. Need to keep esi and edi values in process
205
 
206
    mov     eax, [esi+line_start_pointer_offset]
207
 
208
  check_horizontal_line:
209
 
210
    mov     bx, word [esi+start_y_offset]
211
    cmp     bx, word [esi+end_y_offset]
212
    jnz     general_draw_line      ;Jump to next test if dy!=0
213
 
214
    pusha
215
 
216
    movzx   ecx, word [esi+end_x_offset]
217
    sub     cx, word [esi+start_x_offset]
218
 
219
    jnc     @f
220
    neg     cx
221
    sub     eax, ecx
222
  @@:
223
 
224
    cld
225
    inc     cx
226
 
227
    mov     edi, eax
228
    mov     al, foreground_cl_index
229
    rep stos byte [edi]
230
 
231
    popa
232
 
233
    jmp     line_drawing_end
234
 
235
 
236
 
237
    ;General line draw algorithm. Based on Bresenham's algorithm (below) but heavily optimized
238
;  function line(x0, x1, y0, y1)
239
;      boolean steep := abs(y1 - y0) > abs(x1 - x0)
240
;      if steep then
241
;          swap(x0, y0)
242
;          swap(x1, y1)
243
;      if x0 > x1 then
244
;          swap(x0, x1)
245
;          swap(y0, y1)
246
;      int deltax := x1 - x0
247
;      int deltay := abs(y1 - y0)
248
;      int error := deltax / 2
249
;      int ystep
250
;      int y := y0
251
;      if y0 < y1 then ystep := 1 else ystep := -1
252
;      for x from x0 to x1
253
;          if steep then plot(y,x) else plot(x,y)
254
;          error := error - deltay
255
;          if error < 0 then
256
;              y := y + ystep
257
;              error := error + deltax
258
 
259
 
260
 
261
general_draw_line:
262
    pusha
263
 
264
    ;init step_base and step_secondary
265
    mov     edx, esi
266
    mov     esi, 1
267
    movzx   edi, word [x_max]
268
 
269
    ;calc initial delta_base & delta_secondary values
270
    movzx   ebx, word [edx+end_x_offset]
271
    sub     bx, [edx+start_x_offset]
272
    jnc     @f
273
    neg     bx
274
    neg     esi
275
  @@:
276
    movzx   ecx, word [edx+end_y_offset]
277
    sub     cx, [edx+start_y_offset]
278
    jnc     @f
279
    neg     cx
280
    neg     edi
281
  @@:
282
 
283
    ;compare abs(y1 - y0) and abs(x1 - x0)
284
    cmp     bx, cx
285
    jnc     @f
286
    xchg    ebx, ecx
287
    xchg    esi, edi
288
  @@:
289
 
290
 
291
    shl     ebx, 16
292
    mov     bx, cx
293
    rol     ebx, 16
294
    mov     cx, bx      ;init counter
295
    inc     cx
296
    mov     dx, bx      ;init error
297
    shr     dx, 1
298
    rol     ebx, 16
299
 
300
 
301
;At current point:
302
;eax = current point pointer
303
;ebx = (delta_base shl 16) + delta_secondary
304
;ecx = counter
305
;[e]dx = error
306
;esi = step_base
307
;edi = step_secondary
308
 
309
 
310
  brasenham_plot_point:
311
    mov     byte [eax], foreground_cl_index
312
    add     eax, esi
313
 
314
    sub     dx, bx
315
 
316
    jnc     end_loop
317
 
318
;              y := y + ystep
319
;              error := error + deltax
320
  change_y:
321
    add     eax, edi
322
    rol     ebx, 16
323
    add     dx, bx
324
    rol     ebx, 16
325
 
326
  end_loop:
327
    loopw   brasenham_plot_point
328
 
329
    end_bresenham:
330
 
331
    popa
332
 
333
line_drawing_end:
334
 
335
    add esi, line_coords_element_size   ;Move to next element in line_coords_array
336
    dec edi
337
    jnz draw_next_line
338
 
339
 
340
;   *********************************************
341
;   *******  WINDOW DEFINITIONS AND DRAW ********
342
;   *********************************************
343
;     mcall 18, 14    ;Wait for scanning (it seems doesn't do any good now)
344
 
345
    ; start redraw  (without calling 12 proc our window overwrites window that above it)
346
    mcall   12, 1
347
    xor eax,eax
348
    movzx ebx, [x_max]
349
    movzx ecx, [y_max]
350
    mov edx, 0x01000000     ;Window style       ;Draw nothing
351
;     mov edx, 0x00000000     ;Window style
352
;     mov esi, 0x00000000     ;Header color (prevent odd color line on top of window in random cases)
353
    mcall           ;Define window
354
 
355
 
356
    mov ebp, 0
357
    mov ecx, dword [y_max]
358
    mcall 65, [image_pointer], , <0,0>, 8, palette
359
 
360
 
361
    mcall   12, 2       ; end redraw
362
 
363
 
364
    call    clear_offscreen_bitmap
365
 
366
wait_event:
367
    mcall 23, delay
368
;     mcall 10
369
    test eax, 0xFFFF - 1    ;Test for 0 (delay passed) or 1 (redraw) event
370
    jz  draw_window     ; Delay passed or redraw event
371
    dec eax
372
    dec eax
373
    jnz  exit           ; If not key then Alt+F4
374
; key pressed, read it and ignore
375
    mcall   2
6160 leency 376
	cmp	ah, 27		    ; Test Esc key press in ASCII
377
	jne	wait_event
1778 yogev_ezra 378
 
379
; button pressed; we have only one button, close
380
; also seems to handle Alt+F4
381
exit:
9451 leency 382
    cmp     [screensaver], 0
383
    jz      @f
384
    mcall   70, f70
385
@@:
1778 yogev_ezra 386
    mcall   -1
387
 
388
 
389
clear_offscreen_bitmap:
390
    mov edi, [image_pointer]
391
    movzx   ecx, [y_max]
392
    movzx   eax, [x_max]
393
    imul    ecx, eax
394
    shr     ecx, 2      ;dword is 4 bytes
395
    mov eax, 0
396
    rep stos dword [edi]
397
    ret
398
 
399
 
400
DATA
401
divider             dw 5000
402
 
403
palette:
404
    background_cl_index = 0
405
    dd      background_cl
406
    foreground_cl_index = 1
407
    dd      foreground_cl
408
 
409
    if defined debug
410
        red_cl_index = 2
411
        dd      0x00FF0000          ;Cleanup this!
412
    end if
413
 
414
UDATA
415
image_pointer       dd ?
416
 
417
initial_counter     dd ?
418
current_counter     dd ?        ;counter + current time
419
 
420
half_line_number    dw ?
421
 
422
y_max            dw ?     ; screen size
423
x_max            dw ?
424
 
425
radius          dw ?
426
x_center        dw ?
427
 
428
line_coords_array_pointer       dd ?
429
 
430
; line_coords_array:
431
;     repeat 1000 ;line_number
432
;         dw      ?       ;start_x
433
;         dw      ?       ;end_x
434
;         dw      ?       ;start_y
435
;         dw      ?       ;end_y
436
;         dd      ?       ;line_start_pointer
437
;     end repeat
438
 
439
    start_x_offset = 0
440
    end_x_offset = 2
441
    start_y_offset = 4
442
    end_y_offset = 6
443
    line_start_pointer_offset = 8
444
    line_coords_element_size = 12
445
 
9451 leency 446
__params:
447
param rb 40
448
 
449
f70: ; run
450
    dd 7, 0, 0, 0, 0
451
    db '/sys/@SS',0
452
 
453
screensaver db ?
9469 leency 454
transparent_cursor rd 32*32
9451 leency 455
 
1778 yogev_ezra 456
MEOS_APP_END