Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1928 art_zh 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;  VESA20.INC                                                  ;;
7
;;                                                              ;;
8
;;  Vesa 2.0 functions for MenuetOS                             ;;
9
;;                                                              ;;
10
;;  Copyright 2002 Ville Turjanmaa                              ;;
11
;;  Alexey, kgaz@crosswindws.net                                ;;
12
;;  - Voodoo compatible graphics                                ;;
13
;;  Juan M. Caravaca                                            ;;
14
;;  - Graphics optimimizations eg. drawline                     ;;
15
;;                                                              ;;
16
;;  See file COPYING for details                                ;;
17
;;                                                              ;;
18
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19
 
20
$Revision: 1708 $
21
 
22
 
23
;*************************************************
24
; getpixel
25
;
26
; in:
27
; eax = x coordinate
28
; ebx = y coordinate
29
;
30
; ret:
31
; ecx = 00 RR GG BB
32
 
33
 
34
get_pixel:
35
     mov     ecx, [BytesPerScanLine]
36
     imul    ecx, ebx
37
     lea     ecx, [ecx+eax*4]		; ecx = x*4+(y*y multiplier)
38
     mov     ecx, [ecx+LFB_BASE]
39
     and     ecx, 0xffffff
40
     ret
41
 
42
;*************************************************
43
 
44
virtual at esp
45
 putimg:
46
   .real_sx	   dd ?
47
   .real_sy	   dd ?
48
   .image_sx	   dd ?
49
   .image_sy	   dd ?
50
   .image_cx	   dd ?
51
   .image_cy	   dd ?
52
   .pti 	   dd ?
53
   .abs_cx	   dd ?
54
   .abs_cy	   dd ?
55
   .line_increment dd ?
56
   .winmap_newline dd ?
57
   .screen_newline dd ?
58
   .stack_data = 4*12
59
   .edi 	dd	?
60
   .esi 	dd	?
61
   .ebp 	dd	?
62
   .esp 	dd	?
63
   .ebx 	dd	?
64
   .edx 	dd	?
65
   .ecx 	dd	?
66
   .eax 	dd	?
67
   .ret_addr	dd	?
68
   .arg_0	dd	?
69
end virtual
70
 
71
align 16
72
; ebx = pointer
73
; ecx = size [x|y]
74
; edx = coordinates [x|y]
75
; ebp = pointer to 'get' function
76
; esi = pointer to 'init' function
77
; edi = parameter for 'get' function
78
 
79
vesa20_putimage:
80
     pushad
81
     call    [_display.disable_mouse]
82
     sub     esp, putimg.stack_data
83
; save pointer to image
84
     mov     [putimg.pti], ebx
85
; unpack the size
86
     mov     eax, ecx
87
     and     ecx, 0xFFFF
88
     shr     eax, 16
89
     mov     [putimg.image_sx], eax
90
     mov     [putimg.image_sy], ecx
91
; unpack the coordinates
92
     mov     eax, edx
93
     and     edx, 0xFFFF
94
     shr     eax, 16
95
     mov     [putimg.image_cx], eax
96
     mov     [putimg.image_cy], edx
97
; calculate absolute (i.e. screen) coordinates
98
     mov     eax, [TASK_BASE]
99
     mov     ebx, [eax-twdw + WDATA.box.left]
100
     add     ebx, [putimg.image_cx]
101
     mov     [putimg.abs_cx], ebx
102
     mov     ebx, [eax-twdw + WDATA.box.top]
103
     add     ebx, [putimg.image_cy]
104
     mov     [putimg.abs_cy], ebx
105
; real_sx = MIN(wnd_sx-image_cx, image_sx);
106
     mov     ebx, [eax-twdw + WDATA.box.width] ; ebx = wnd_sx
107
     inc     ebx	; WDATA.box.width is one pixel less than real window x-size
108
     sub     ebx, [putimg.image_cx]
109
     ja      @f
110
     add     esp, putimg.stack_data
111
     popad
112
     ret
113
@@:
114
     cmp     ebx, [putimg.image_sx]
115
     jbe     .end_x
116
     mov     ebx, [putimg.image_sx]
117
.end_x:
118
     mov     [putimg.real_sx], ebx
119
; init real_sy
120
     mov     ebx, [eax-twdw + WDATA.box.height] ; ebx = wnd_sy
121
     inc     ebx
122
     sub     ebx, [putimg.image_cy]
123
     ja      @f
124
     add     esp, putimg.stack_data
125
     popad
126
     ret
127
@@:
128
     cmp     ebx, [putimg.image_sy]
129
     jbe     .end_y
130
     mov     ebx, [putimg.image_sy]
131
.end_y:
132
     mov     [putimg.real_sy], ebx
133
; line increment
134
     mov     eax, [putimg.image_sx]
135
     mov     ecx, [putimg.real_sx]
136
     sub     eax, ecx
137
     call    esi
138
     add     eax, [putimg.arg_0]
139
     mov     [putimg.line_increment], eax
140
; winmap new line increment
141
     mov     eax, [Screen_Max_X]
142
     inc     eax
143
     sub     eax, [putimg.real_sx]
144
     mov     [putimg.winmap_newline], eax
145
; screen new line increment
146
     mov     eax, [BytesPerScanLine]
147
     shl     ecx, 1
148
     shl     ecx, 1
149
     sub     eax, ecx
150
     mov     [putimg.screen_newline], eax
151
; pointer to image
152
     mov     esi, [putimg.pti]
153
; pointer to screen
154
     mov     edx, [putimg.abs_cy]
155
     imul    edx, [BytesPerScanLine]
156
     mov     eax, [putimg.abs_cx]
157
     shl     eax, 1
158
     shl     eax, 1
159
     add     edx, eax
160
; pointer to pixel map
161
     mov     eax, [putimg.abs_cy]
162
     imul    eax, [Screen_Max_X]
163
     add     eax, [putimg.abs_cy]
164
     add     eax, [putimg.abs_cx]
165
     add     eax, [_WinMapAddress]
166
     xchg    eax, ebp
167
; get process number
168
     mov     ebx, [CURRENT_TASK]
169
 
170
put_image_end_32:
171
     mov     edi, [putimg.real_sy]
172
align	4
173
.new_line:
174
     mov     ecx, [putimg.real_sx]
175
align	4
176
.new_x:
177
     push    [putimg.edi]
178
     mov     eax, [putimg.ebp+4]
179
     call    eax
180
     cmp     [ebp], bl
181
     jne     .skip
182
     mov     [LFB_BASE+edx], eax
183
.skip:
184
     add     edx, 4
185
     inc     ebp
186
     dec     ecx
187
     jnz     .new_x
188
     add     esi, [putimg.line_increment]
189
     add     edx, [putimg.screen_newline] ;[BytesPerScanLine]
190
     add     ebp, [putimg.winmap_newline] ;[Screen_Max_X]
191
     cmp     [putimg.ebp], putimage_get1bpp
192
     jz      .correct
193
     cmp     [putimg.ebp], putimage_get2bpp
194
     jz      .correct
195
     cmp     [putimg.ebp], putimage_get4bpp
196
     jnz     @f
197
.correct:
198
     mov     eax, [putimg.edi]
199
     mov     byte [eax], 80h
200
@@:
201
     dec     edi
202
     jnz     .new_line
203
.finish:
204
     add     esp, putimg.stack_data
205
     popad
206
     ret
207
 
208
;*************************************************
209
align 4
210
__sys_putpixel:
211
 
212
; eax = x coordinate
213
; ebx = y coordinate
214
; ecx = ?? RR GG BB    ; 0x01000000 negation
215
; edi = 0x00000001 force
216
 
217
     cmp   [Screen_Max_X], eax
218
     jb    .exit
219
     cmp   [Screen_Max_Y], ebx
220
     jb    .exit
221
.check_forced:
222
     test    edi,1		 ; force ?
223
     jnz     .checked
224
 
225
.not_forced:
226
     push     edx
227
     mov      edx,[_display.width]	   ; screen x size
228
     imul     edx, ebx
229
     add      edx, [_WinMapAddress]
230
     movzx    edx, byte [eax+edx]
231
     cmp      edx, [CURRENT_TASK]
232
     pop      edx
233
     jne      .exit
234
 
235
; OK to set pixel
236
.checked:
237
     push  ebx
238
     imul  ebx, [BytesPerScanLine]
239
     lea   ebx, [ebx+eax*4]
240
     test  ecx,0x01000000
241
     jz    .noneg
242
     mov   ecx, [LFB_BASE+ebx]
243
     not   ecx
244
     and   ecx, 0x01FFFFFF
245
.noneg:
246
     mov   [LFB_BASE+ebx], ecx
247
     pop   ebx
248
.exit:
249
     ret
250
 
251
 
252
 
253
align 4
254
put_pixel:	; left for compatibility with Vesa20_putpixel32
255
; eax = x
256
; ebx = y
257
     imul    ebx, [BytesPerScanLine]	 ; ebx = y * y multiplier
258
     lea     edi, [ebx+eax*4]  ; edi = x*4+(y*y multiplier)
259
;     mov     eax, [esp+32-8+4] ; eax = color
260
     mov     [LFB_BASE+edi], ecx
261
     ret
262
 
263
 
264
;*************************************************
265
 
266
;align 4
267
calculate_edi:
268
     mov     edi, ebx
269
     imul    edi, [Screen_Max_X]
270
     add     edi, ebx
271
     add     edi, eax
272
     ret
273
 
274
;*************************************************
275
 
276
; DRAWLINE
277
 
278
align 4
279
__sys_draw_line:
280
     call    [_display.disable_mouse]
281
 
282
; draw a line
283
; eax = HIWORD = x1
284
;       LOWORD = x2
285
; ebx = HIWORD = y1
286
;       LOWORD = y2
287
; ecx = color
288
; edi = force ?
289
	pusha
290
 
291
dl_x1 equ esp+20
292
dl_y1 equ esp+16
293
dl_x2 equ esp+12
294
dl_y2 equ esp+8
295
dl_dx equ esp+4
296
dl_dy equ esp+0
297
 
298
     xor     edx, edx	   ; clear edx
299
     xor     esi, esi	   ; unpack arguments
300
     xor     ebp, ebp
301
     mov     si, ax	   ; esi = x2
302
     mov     bp, bx	   ; ebp = y2
303
     shr     eax, 16	   ; eax = x1
304
     shr     ebx, 16	   ; ebx = y1
305
     push    eax	   ; save x1
306
     push    ebx	   ; save y1
307
     push    esi	   ; save x2
308
 
309
     push    ebp	   ; save y2
310
; checking x-axis...
311
     sub     esi, eax	   ; esi = x2-x1
312
     push    esi	   ; save y2-y1
313
     jl      .x2lx1	   ; is x2 less than x1 ?
314
     jg      .no_vline	   ; x1 > x2 ?
315
     mov     edx, ebp	   ; else (if x1=x2)
316
     call    vline
317
     push    edx    ; necessary to rightly restore stack frame at .exit
318
     jmp     .exit
319
.x2lx1:
320
     neg     esi	    ; get esi absolute value
321
.no_vline:
322
; checking y-axis...
323
     sub     ebp, ebx	    ; ebp = y2-y1
324
     push    ebp	    ; save y2-y1
325
     jl      .y2ly1	    ; is y2 less than y1 ?
326
     jg      .no_hline	    ; y1 > y2 ?
327
     mov     edx, [dl_x2]   ; else (if y1=y2)
328
     call    hline
329
     jmp     .exit
330
 
331
.y2ly1:
332
     neg     ebp	    ; get ebp absolute value
333
.no_hline:
334
     cmp     ebp, esi
335
     jle     .x_rules	    ; |y2-y1| < |x2-x1|  ?
336
     cmp     [dl_y2], ebx   ; make sure y1 is at the begining
337
     jge     .no_reverse1
338
     neg     dword [dl_dx]
339
     mov     edx, [dl_x2]
340
     mov     [dl_x2], eax
341
     mov     [dl_x1], edx
342
     mov     edx, [dl_y2]
343
     mov     [dl_y2], ebx
344
     mov     [dl_y1], edx
345
.no_reverse1:
346
     mov     eax, [dl_dx]
347
     cdq		    ; extend eax sing to edx
348
     shl     eax, 16	    ; using 16bit fix-point maths
349
     idiv    ebp	    ; eax = ((x2-x1)*65536)/(y2-y1)
350
     mov     edx, ebp	    ; edx = counter (number of pixels to draw)
351
     mov     ebp, 1 *65536  ; <<16   ; ebp = dy = 1.0
352
     mov     esi, eax	    ; esi = dx
353
     jmp     .y_rules
354
 
355
.x_rules:
356
     cmp     [dl_x2], eax    ; make sure x1 is at the begining
357
     jge     .no_reverse2
358
     neg     dword [dl_dy]
359
     mov     edx, [dl_x2]
360
     mov     [dl_x2], eax
361
     mov     [dl_x1], edx
362
     mov     edx, [dl_y2]
363
     mov     [dl_y2], ebx
364
     mov     [dl_y1], edx
365
.no_reverse2:
366
     xor     edx, edx
367
     mov     eax, [dl_dy]
368
     cdq		    ; extend eax sing to edx
369
     shl     eax, 16	    ; using 16bit fix-point maths
370
     idiv    esi	    ; eax = ((y2-y1)*65536)/(x2-x1)
371
     mov     edx, esi	    ; edx = counter (number of pixels to draw)
372
     mov     esi, 1 *65536  ;<< 16   ; esi = dx = 1.0
373
     mov     ebp, eax	    ; ebp = dy
374
.y_rules:
375
     mov     eax, [dl_x1]
376
     mov     ebx, [dl_y1]
377
     shl     eax, 16
378
     shl     ebx, 16
379
align 4
380
.draw:
381
     push    eax ebx
382
     shr     eax, 16
383
     shr     ebx, 16
384
     call    [putpixel]
385
     pop     ebx eax
386
     add     ebx, ebp	     ; y = y+dy
387
     add     eax, esi	     ; x = x+dx
388
     dec     edx
389
     jnz     .draw
390
; force last drawn pixel to be at (x2,y2)
391
     mov     eax, [dl_x2]
392
     mov     ebx, [dl_y2]
393
     call    [putpixel]
394
.exit:
395
     add     esp, 6*4
396
     popa
397
     call   [draw_pointer]
398
     ret
399
 
400
align 4
401
hline:
402
; ------------  draw a horizontal line -------------
403
; eax = x1
404
; edx = x2
405
; ebx = y
406
; ecx = color
407
; edi = force ?
408
     cmp     ebx, [Screen_Max_Y]
409
     jge     .out
410
     push    eax ebp esi ebx edx
411
     bt      ecx, 24			; color inversion check
412
     rcl     edi,1			; forced graphics check
413
 
414
     mov     ebp, [_display.width]	; ebp = screen co-ords base
415
     imul    ebp, ebx
416
     add     ebp, [_WinMapAddress]
417
 
418
     cmp     edx, eax		; to make sure x2 > x1
419
     jge     @f
420
     xchg    eax, edx
421
@@:
422
     cmp     eax, [Screen_Max_X]
423
     jge     .exit
424
     imul    ebx, [BytesPerScanLine]
425
     add     ebx, LFB_BASE
426
     cmp     edx, [Screen_Max_X]	; last check
427
     jb      .draw
428
     mov     edx, [Screen_Max_X]
429
 
430
.draw:	; -- the line ---
431
     jmp     dword [hline.drawtable + edi*4]	; a coolhack (C) Serge
432
 
433
align 4
434
.invert_color:
435
     mov     ecx, [ebx+eax*4]
436
     xor     ecx, 0x00FFFFFF
437
     or      ecx, 0x01000000		; keep bit[24] high !
438
align 4
439
.check_overlap:
440
     movzx   esi, byte [ebp+eax]	; check whether the line covered by other windows
441
     cmp     esi, [CURRENT_TASK]
442
     je      .putpixel
443
     jmp     .nextpixel
444
align 4
445
.invert_force:
446
     mov     ecx, [ebx+eax*4]
447
     xor     ecx, 0x00FFFFFF
3168 art_zh 448
     bts     ecx, 24		; keep bit[24] high !
1928 art_zh 449
align 4
450
.putpixel:
451
     mov     [ebx+eax*4], ecx
452
align 4
453
.nextpixel:
454
     inc     eax
455
     cmp     eax, edx
456
     ja     .exit
457
     jmp     dword [hline.drawtable + edi*4]	; close the loop
458
 
459
.exit:
460
     shr     edi, 1			; restore the 'force' bit
461
     pop     edx ebx esi ebp eax
462
.out:
463
     ret
464
align 4
465
.drawtable:
2014 art_zh 466
dd	.check_overlap	; general case
1928 art_zh 467
dd	.invert_color
468
dd	.putpixel	; force to draw it
469
dd	.invert_force
470
 
471
 
472
align 4
473
vline:
474
; ---------  draw a vertical line  ------------
475
; eax = x
476
; ebx = y1
477
; edx = y2
478
; ecx = color
479
; edi = force ?
480
     cmp     eax, [Screen_Max_X]
481
     jge     .out
482
     push    eax ebp esi ebx edx
483
     mov     ebp, [_display.width]	; ebp = screen co-ords base
484
     imul    ebp, ebx
485
     add     ebp, [_WinMapAddress]
486
     add     ebp, eax
487
 
488
     cmp     edx, ebx			; to make sure y2 > y1
489
     jge     @f
490
     xchg    ebx, edx
491
@@:
492
     cmp     ebx, [Screen_Max_Y]
493
     jge     .exit
494
     push    ebx
495
     imul    ebx, [BytesPerScanLine]
496
     shl     eax, 1
497
     shl     eax, 1
498
     add     eax, ebx
499
     add     eax, LFB_BASE
2014 art_zh 500
     pop     ebx			; restore ebx = y1
1928 art_zh 501
     cmp     edx, [Screen_Max_Y]	; the last check
502
     jb     .draw
503
     mov     edx, [Screen_Max_Y]	; to prevent off-screen drawing
504
 
2014 art_zh 505
.draw:
506
     jmp     dword [vline.drawtable + edi*4]
1928 art_zh 507
align 4
508
.invert_color:
509
     mov     ecx, [eax]
510
     xor     ecx, 0x00FFFFFF
2014 art_zh 511
     or      ecx, 0x01000000
1928 art_zh 512
align 4
513
.check_overlap:
514
     movzx   esi, byte [ebp]
515
     cmp     esi, [CURRENT_TASK]
516
     je      .putpixel
517
     jmp     .nextpixel
518
 
519
align 4
520
.invert_force:
521
     mov     ecx, [eax]
522
     xor     ecx, 0x00FFFFFF
2014 art_zh 523
     or      ecx, 0x01000000
1928 art_zh 524
align 4
525
.putpixel:
526
     mov     [eax], ecx
527
align 4
528
.nextpixel:
529
     add     eax, [BytesPerScanLine]
530
     add     ebp, [_display.width]
531
     inc     ebx
532
     cmp     ebx, edx
533
     ja     .exit
2014 art_zh 534
     jmp     dword [vline.drawtable + edi*4]
1928 art_zh 535
.exit:
536
     shr     edi, 1
537
     pop     edx ebx esi ebp eax
538
.out:
539
     ret
540
align 4
541
.drawtable:
2014 art_zh 542
dd	.check_overlap	; general case
1928 art_zh 543
dd	.invert_color
544
dd	.putpixel	; force to draw it
545
dd	.invert_force
546
 
547
 
548
;*************************************************
549
 
550
 
551
virtual at esp
552
drbar:
553
     .bar_sx	   dd ?
554
     .bar_sy	   dd ?
555
     .bar_cx	   dd ?
556
     .bar_cy	   dd ?
557
     .abs_cx	   dd ?
558
     .abs_cy	   dd ?
559
     .real_sx	   dd ?
560
     .real_sy	   dd ?
561
     .color	   dd ?
562
     .line_inc_scr dd ?
563
     .line_inc_map dd ?
564
     .stack_data = 4*11
565
end virtual
566
 
567
align 4
568
; eax   cx
569
; ebx   cy
570
; ecx   xe
571
; edx   ye
572
; edi   color
573
vesa20_drawbar:
574
     pushad
575
     call    [_display.disable_mouse]
576
     sub     esp, drbar.stack_data
577
     mov     [drbar.color], edi
578
     sub     edx, ebx
2014 art_zh 579
     jle     .exit
1928 art_zh 580
     sub     ecx, eax
2014 art_zh 581
     jle     .exit
1928 art_zh 582
     mov     [drbar.bar_sy], edx
583
     mov     [drbar.bar_sx], ecx
584
     mov     [drbar.bar_cx], eax
585
     mov     [drbar.bar_cy], ebx
586
     mov     edi, [TASK_BASE]
587
     add     eax, [edi-twdw + WDATA.box.left] ; win_cx
588
     add     ebx, [edi-twdw + WDATA.box.top] ; win_cy
589
     mov     [drbar.abs_cx], eax
590
     mov     [drbar.abs_cy], ebx
591
; real_sx = MIN(wnd_sx-bar_cx, bar_sx);
592
     mov     ebx, [edi-twdw + WDATA.box.width] ; ebx = wnd_sx
593
; note that WDATA.box.width is one pixel less than real window x-size
594
     inc     ebx
595
     sub     ebx, [drbar.bar_cx]
596
     ja      @f
2014 art_zh 597
.exit:
1928 art_zh 598
     add     esp, drbar.stack_data
599
     popad
600
     xor     eax, eax
601
     inc     eax
602
     ret
603
@@:
604
     cmp     ebx, [drbar.bar_sx]
605
     jbe     .end_x
606
     mov     ebx, [drbar.bar_sx]
607
.end_x:
608
     mov     [drbar.real_sx], ebx
609
; real_sy = MIN(wnd_sy-bar_cy, bar_sy);
610
     mov     ebx, [edi-twdw + WDATA.box.height] ; ebx = wnd_sy
611
     inc     ebx
612
     sub     ebx, [drbar.bar_cy]
613
     ja      @f
614
     add     esp, drbar.stack_data
615
     popad
616
     xor     eax, eax
617
     inc     eax
618
     ret
619
@@:
620
     cmp     ebx, [drbar.bar_sy]
621
     jbe     .end_y
622
     mov     ebx, [drbar.bar_sy]
623
.end_y:
624
     mov     [drbar.real_sy], ebx
625
; line_inc_map
626
     mov     eax, [Screen_Max_X]
627
     sub     eax, [drbar.real_sx]
628
     inc     eax
629
     mov     [drbar.line_inc_map], eax
630
; line_inc_scr
631
     mov     eax, [drbar.real_sx]
632
     shl     eax, 1
633
     shl     eax, 1
634
     neg     eax
635
     add     eax, [BytesPerScanLine]
636
     mov     [drbar.line_inc_scr], eax
637
; pointer to screen
638
     mov     edx, [drbar.abs_cy]
639
     imul    edx, [BytesPerScanLine]
640
     mov     eax, [drbar.abs_cx]
641
     shl     eax, 1
642
     shl     eax, 1
643
     add     edx, eax
644
; pointer to pixel map
645
     mov     eax, [drbar.abs_cy]
646
     imul    eax, [Screen_Max_X]
647
     add     eax, [drbar.abs_cy]
648
     add     eax, [drbar.abs_cx]
649
     add     eax, [_WinMapAddress]
650
     xchg    eax, ebp
651
; get process number
652
     mov     ebx, [CURRENT_TASK]
653
 
654
draw_bar_end_32:
655
; eax - color high   RRGG
656
; bl - process num
657
; bh - color low    BB
658
; ecx - temp
659
; edx - pointer to screen
660
; esi - counter
661
; edi - counter
662
     mov     eax, [drbar.color]    ;; BBGGRR00
663
     mov     esi, [drbar.real_sy]
664
align	4
665
.new_y:
666
     mov     edi, [drbar.real_sx]
667
align	4
668
.new_x:
669
     cmp     byte [ebp], bl
670
     jne     .skip
671
 
672
     mov     [LFB_BASE+edx], eax
673
.skip:
674
; add pixel
675
     add     edx, 4
676
     inc     ebp
677
     dec     edi
678
     jnz     .new_x
679
; add line
680
     add     edx, [drbar.line_inc_scr]
681
     add     ebp, [drbar.line_inc_map]
682
;  drawing gradient bars
683
     test    eax, 0x80000000
684
     jz      @f
685
     test    al, al
686
     jz      @f
687
     dec     al
688
@@:
689
; 
690
     dec     esi
691
     jnz     .new_y
692
     add     esp, drbar.stack_data
693
     popad
694
     xor     eax, eax
695
     ret
696
 
697
 
698
align 4
699
vesa20_drawbackground_tiled:
700
	call	[_display.disable_mouse]
701
	pushad
702
; External loop for all y from start to end
703
	mov	ebx, [draw_data+32+RECT.top]	; y start
704
dp2:
705
	mov	ebp, [draw_data+32+RECT.left]	; x start
706
; 1) Calculate pointers in WinMapAddress (does pixel belong to OS thread?) [ebp]
707
;                       and LFB data (output for our function) [edi]
708
	mov	eax, [BytesPerScanLine]
709
	mul	ebx
710
	xchg	ebp, eax
711
	add	ebp, eax
712
	add	ebp, eax
713
	add	ebp, eax
714
	add	ebp, eax
715
	add	ebp, LFB_BASE
716
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
717
	call	calculate_edi
718
	xchg	edi, ebp
719
	add ebp, [_WinMapAddress]
720
; Now eax=x, ebx=y, edi->output, ebp=offset in WinMapAddress
721
; 2) Calculate offset in background memory block
722
	push	eax
723
	xor	edx, edx
724
	mov	eax, ebx
725
	div	dword [BgrDataHeight]	; edx := y mod BgrDataHeight
726
	pop	eax
727
	push	eax
728
	mov	ecx, [BgrDataWidth]
729
	mov	esi, edx
730
	imul	esi, ecx		; esi := (y mod BgrDataHeight) * BgrDataWidth
731
	xor	edx, edx
732
	div	ecx		; edx := x mod BgrDataWidth
733
	sub	ecx, edx
734
	add	esi, edx	; esi := (y mod BgrDataHeight)*BgrDataWidth + (x mod BgrDataWidth)
735
	pop	eax
736
	lea	esi, [esi*3]
737
	add	esi, [img_background]
738
	xor	edx, edx
739
	inc	edx
740
; 3) Loop through redraw rectangle and copy background data
741
; Registers meaning:
742
; eax = x, ebx = y (screen coordinates)
743
; ecx = deltax - number of pixels left in current tile block
744
; edx = 1
745
; esi -> bgr memory, edi -> output
746
; ebp = offset in WinMapAddress
747
dp3:
748
	cmp	[ebp], dl
749
	jnz	nbgp
750
	movsb
751
	movsb
752
	movsb
753
	jmp	@f
754
nbgp:
755
	add	esi, 3
756
	add	edi, 3
757
@@:
2014 art_zh 758
	inc	edi		; +1 for 32 bpp
1928 art_zh 759
	add	ebp, edx
760
	add	eax, edx
761
	cmp	eax, [draw_data+32+RECT.right]
762
	ja	dp4
763
	sub	ecx, edx
764
	jnz	dp3
765
; next tile block on x-axis
766
	mov	ecx, [BgrDataWidth]
767
	sub	esi, ecx
768
	sub	esi, ecx
769
	sub	esi, ecx
770
	jmp	dp3
771
dp4:
772
; next scan line
773
	inc	ebx
774
	cmp	ebx, [draw_data+32+RECT.bottom]
775
	jbe	dp2
776
	popad
777
	ret
778
 
779
; ----------
780
 
781
 
782
vesa20_drawbackground_stretch:
783
	call	[_display.disable_mouse]
784
	pushad
785
; Helper variables
786
; calculate 2^32*(BgrDataWidth-1) mod (ScreenWidth-1)
787
	mov	eax, [BgrDataWidth]
788
	dec	eax
789
	xor	edx, edx
790
	div	dword [Screen_Max_X]
791
	push	eax	; high
792
	xor	eax, eax
793
	div	dword [Screen_Max_X]
794
	push	eax	; low
795
; the same for height
796
	mov	eax, [BgrDataHeight]
797
	dec	eax
798
	xor	edx, edx
799
	div	dword [Screen_Max_Y]
800
	push	eax	; high
801
	xor	eax, eax
802
	div	dword [Screen_Max_Y]
803
	push	eax	; low
804
; External loop for all y from start to end
805
	mov	ebx, [draw_data+32+RECT.top]	; y start
806
	mov	ebp, [draw_data+32+RECT.left]	; x start
807
; 1) Calculate pointers in WinMapAddress (does pixel belong to OS thread?) [ebp]
808
;                       and LFB data (output for our function) [edi]
809
	mov	eax, [BytesPerScanLine]
810
	mul	ebx
811
	xchg	ebp, eax
812
	add	ebp, eax
813
	add	ebp, eax
814
	add	ebp, eax
815
	add	ebp, eax
816
 
817
; ebp:=Y*BytesPerScanLine+X*BytesPerPixel+AddrLFB
818
	call	calculate_edi
819
	xchg	edi, ebp
820
; Now eax=x, ebx=y, edi->output, ebp=offset in WinMapAddress
821
	push	ebx
822
	push	eax
823
; 2) Calculate offset in background memory block
824
	mov	eax, ebx
825
	imul	ebx, dword [esp+12]
826
	mul	dword [esp+8]
827
	add	edx, ebx	; edx:eax = y * 2^32*(BgrDataHeight-1)/(ScreenHeight-1)
828
	mov	esi, edx
829
	imul	esi, [BgrDataWidth]
830
	push	edx
831
	push	eax
832
	mov	eax, [esp+8]
833
	mul	dword [esp+28]
834
	push	eax
835
	mov	eax, [esp+12]
836
	mul	dword [esp+28]
837
	add	[esp], edx
838
	pop	edx		; edx:eax = x * 2^32*(BgrDataWidth-1)/(ScreenWidth-1)
839
	add	esi, edx
840
	lea	esi, [esi*3]
841
	add	esi, [img_background]
842
	push	eax
843
	push	edx
844
	push	esi
845
; 3) Smooth horizontal
846
bgr_resmooth0:
847
	mov	ecx, [esp+8]
848
	mov	edx, [esp+4]
849
	mov	esi, [esp]
850
	push	edi
851
	mov	edi, bgr_cur_line
852
	call	smooth_line
853
bgr_resmooth1:
854
	mov	eax, [esp+16+4]
855
	inc	eax
856
	cmp	eax, [BgrDataHeight]
857
	jae	bgr.no2nd
858
	mov	ecx, [esp+8+4]
859
	mov	edx, [esp+4+4]
860
	mov	esi, [esp+4]
861
	add	esi, [BgrDataWidth]
862
	add	esi, [BgrDataWidth]
863
	add	esi, [BgrDataWidth]
864
	mov	edi, bgr_next_line
865
	call	smooth_line
866
bgr.no2nd:
867
	pop	edi
868
sdp3:
869
	xor	esi, esi
870
	mov	ecx, [esp+12]
871
; 4) Loop through redraw rectangle and copy background data
872
; Registers meaning:
873
; esi = offset in current line, edi -> output
874
; ebp = offset in WinMapAddress
875
; dword [esp] = offset in bgr data
876
; qword [esp+4] = x * 2^32 * (BgrDataWidth-1) / (ScreenWidth-1)
877
; qword [esp+12] = y * 2^32 * (BgrDataHeight-1) / (ScreenHeight-1)
878
; dword [esp+20] = x
879
; dword [esp+24] = y
880
; precalculated constants:
881
; qword [esp+28] = 2^32*(BgrDataHeight-1)/(ScreenHeight-1)
882
; qword [esp+36] = 2^32*(BgrDataWidth-1)/(ScreenWidth-1)
883
sdp3a:
884
	mov eax, [_WinMapAddress]
885
	cmp	[ebp+eax], byte 1
886
	jnz	snbgp
887
	mov	eax, [bgr_cur_line+esi]
888
	test	ecx, ecx
889
	jz	.novert
890
	mov	ebx, [bgr_next_line+esi]
891
	call	[overlapping_of_points_ptr]
892
.novert:
893
 
894
	mov	[LFB_BASE+edi], ax
895
	shr	eax, 16
896
 
897
	mov	[LFB_BASE+edi+2], al
898
snbgp:
899
	add	edi, 4
900
	inc	ebp
901
	mov	eax, [esp+20]
902
	inc	eax
903
	mov	[esp+20], eax
904
	add	esi, 4
905
	cmp	eax, [draw_data+32+RECT.right]
906
	jbe	sdp3a
907
sdp4:
908
; next y
909
	mov	ebx, [esp+24]
910
	inc	ebx
911
	mov	[esp+24], ebx
912
	cmp	ebx, [draw_data+32+RECT.bottom]
913
	ja	sdpdone
914
; advance edi, ebp to next scan line
915
	sub	eax, [draw_data+32+RECT.left]
916
	sub	ebp, eax
917
	add	ebp, [Screen_Max_X]
918
	inc	ebp
919
	sub	edi, eax
920
	sub	edi, eax
921
	sub	edi, eax
922
	sub	edi, eax
923
	add	edi, [BytesPerScanLine]
924
; restore ecx,edx; advance esi to next background line
925
	mov	eax, [esp+28]
926
	mov	ebx, [esp+32]
927
	add	[esp+12], eax
928
	mov	eax, [esp+16]
929
	adc	[esp+16], ebx
930
	sub	eax, [esp+16]
931
	mov	ebx, eax
932
	lea	eax, [eax*3]
933
	imul	eax, [BgrDataWidth]
934
	sub	[esp], eax
935
	mov	eax, [draw_data+32+RECT.left]
936
	mov	[esp+20], eax
937
	test	ebx, ebx
938
	jz	sdp3
939
	cmp	ebx, -1
940
	jnz	bgr_resmooth0
941
	push	edi
942
	mov	esi, bgr_next_line
943
	mov	edi, bgr_cur_line
944
	mov	ecx, [Screen_Max_X]
945
	inc	ecx
946
	rep	movsd
947
	jmp	bgr_resmooth1
948
sdpdone:
949
	add	esp, 44
950
	popad
951
	ret
952
 
953
uglobal
954
align 4
955
bgr_cur_line	rd	1920	; maximum width of screen
956
bgr_next_line	rd	1920
957
endg
958
 
3168 art_zh 959
 
1928 art_zh 960
smooth_line:
961
	mov	al, [esi+2]
962
	shl	eax, 16
963
	mov	ax, [esi]
964
	test	ecx, ecx
965
	jz	@f
966
	mov	ebx, [esi+2]
967
	shr	ebx, 8
968
	call	[overlapping_of_points_ptr]
969
@@:
970
	stosd
971
	mov	eax, [esp+20+8]
972
	inc	eax
973
	mov	[esp+20+8], eax
974
	cmp	eax, [draw_data+32+RECT.right]
975
	ja	@f
976
	add	ecx, [esp+36+8]
977
	mov	eax, edx
978
	adc	edx, [esp+40+8]
979
	sub	eax, edx
980
	lea	eax, [eax*3]
981
	sub	esi, eax
982
	jmp	smooth_line
983
@@:
984
	mov	eax, [draw_data+32+RECT.left]
985
	mov	[esp+20+8], eax
986
	ret
987
 
988
align 16
989
overlapping_of_points:
990
	push	ecx edx
991
	mov	edx, eax
992
	push	esi
993
	shr	ecx, 26
994
	mov	esi, ecx
995
	mov	ecx, ebx
996
	shl	esi, 9
997
	movzx	ebx, dl
998
	movzx	eax, cl
999
	sub	eax, ebx
1000
	movzx	ebx, dh
1001
	add	dl, [BgrAuxTable+(eax+0x100)+esi]
1002
	movzx	eax, ch
1003
	sub	eax, ebx
1004
	add	dh, [BgrAuxTable+(eax+0x100)+esi]
1005
	ror	ecx, 16
1006
	ror	edx, 16
1007
	movzx	eax, cl
1008
	movzx	ebx, dl
1009
	sub	eax, ebx
1010
	add	dl, [BgrAuxTable+(eax+0x100)+esi]
1011
	pop	esi
1012
	mov	eax, edx
1013
	pop	edx
1014
	ror	eax, 16
1015
	pop	ecx
1016
	ret
1017
 
1018
iglobal
1019
align 4
1020
overlapping_of_points_ptr	dd	overlapping_of_points
1021
endg
1022
 
3168 art_zh 1023
align 16
1024
overlapping_of_points_mmx:
1025
	movd	mm0, eax
1026
	movd	mm4, eax
1027
	movd	mm1, ebx
1028
	pxor	mm2, mm2
1029
	punpcklbw mm0, mm2
1030
	punpcklbw mm1, mm2
1031
	psubw	mm1, mm0
1032
	movd	mm3, ecx
1033
	psrld	mm3, 24
1034
	packuswb mm3, mm3
1035
	packuswb mm3, mm3
1036
	pmullw	mm1, mm3
1037
	psrlw	mm1, 8
1038
	packuswb mm1, mm2
1039
	paddb	mm4, mm1
1040
	movd	eax, mm4
1041
	ret
1042
 
1043
 
1044
 
1928 art_zh 1045
init_background:
1046
	mov	edi, BgrAuxTable
1047
	xor	edx, edx
1048
.loop2:
1049
	mov	eax, edx
1050
	shl	eax, 8
1051
	neg	eax
1052
	mov	ecx, 0x200
1053
.loop1:
1054
	mov	byte [edi], ah
1055
	inc	edi
1056
	add	eax, edx
1057
	loop	.loop1
1058
	add	dl, 4
1059
	jnz	.loop2
1060
	test	byte [cpu_caps+(CAPS_MMX/8)], 1 shl (CAPS_MMX mod 8)
1061
	jz	@f
1062
	mov	[overlapping_of_points_ptr], overlapping_of_points_mmx
1063
@@:
1064
	ret
1065
 
3168 art_zh 1066
 
2014 art_zh 1067
;diff16 "VESA2 code end ",0,$
1068
diff10 "VESA2 code size",get_pixel,$
1928 art_zh 1069