Subversion Repositories Kolibri OS

Rev

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