Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
1859 art_zh 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;;  GRAPH32.INC                                                 ;;
7
;;                                                              ;;
8
;;            32bpp graph engine for Kolibri-A                  ;;
9
;;                                                              ;;
10
;;  art_zh (kolibri@jerdev.co.uk) Dec. 2010 :                   ;;
11
;;      - 4x2 granularity & tiled winmap structure              ;;
12
;;      - speed-optimized line/box graphics                     ;;
13
;;                                                              ;;
14
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
15
 
16
$Revision: 1708 $
17
 
18
 
19
;*************************************************
20
; getpixel
21
;
22
; in:
23
; eax = x coordinate
24
; ebx = y coordinate
25
;
26
; ret:
27
; ecx = 00 RR GG BB
28
 
29
 
30
get_pixel:
31
     mov     ecx, [BytesPerScanLine]
32
     imul    ecx, ebx
33
     lea     ecx, [ecx+eax*4]		; ecx = x*4+(y*y multiplier)
34
     mov     ecx, [ecx+LFB_BASE]
35
     and     ecx, 0xffffff
36
     ret
37
 
38
;-----------------------------------------------------------------------------------
39
; esi : Buffer origin
40
; edi : Screen origin
41
; ebp : Map origin
42
; ecx : block height (pix)
43
; ebx : bit[24] = odd line; bh = temp; bl = current task
44
 
45
align 4
46
draw_aligned_box:
47
        pushad
48
        xor     edx, edx
49
.new_line:
50
        btr     ebx, 26
51
        mov     eax, [img_map_x]
52
        xor     ecx, ecx
53
        cmp	bl, byte[ebp]		        ; check the left tile first
1899 art_zh 54
        je      .new_tile
55
        bts     ebx, 26                         ; ebx[26] = 1 if edi/esi pushed
1859 art_zh 56
        push    edi
57
        push    esi
1899 art_zh 58
        push    [img_bitoffset]
1859 art_zh 59
        jmp     .seek_visible
60
.new_tile:
61
        inc     ecx			        ; visible - scan the open space
62
        cmp     ecx, eax
63
        jz      .end_of_line
1899 art_zh 64
        cmp     bl, byte[ebp+ecx]
1859 art_zh 65
        je      .new_tile
1899 art_zh 66
                                                ; overlapped? draw the last visible segment if so
67
        bts     ebx, 26                         ; check if edi/esi already pushed
68
        jc      @f
69
        push    edi
70
        push    esi
71
        push    [img_bitoffset]
72
@@:     call    [img_draw_core_fn]	        ; bpp-specific helper (see below)
1859 art_zh 73
 
74
.seek_visible:
75
        inc     ecx
76
        cmp     ecx, eax
77
        je      .next_line
78
        cmp     bl, byte[ebp+ecx]
79
        jne     .seek_visible
80
.got_visible:
81
        sub     eax, ecx
82
	shl     ecx, 4
1899 art_zh 83
        add	edi, ecx                        ; shift the left edge
84
        bt      ebx, 25                         ; 1bpp?
85
        jc      @f
1859 art_zh 86
        shr     ecx, 2
1899 art_zh 87
        imul    ecx, [img_bytes_per_pix]
88
        jmp     .new_visible
89
@@:     shr     ecx, 8                          ; 2 tiles = 1 byte
90
        jnc     .new_visible
91
        rol     [img_bitoffset], 4
92
        jnc     .new_visible
93
        inc     ecx
94
.new_visible:
1859 art_zh 95
        add     esi, ecx
96
        xor     ecx, ecx
97
        jmp     .new_tile
98
 
99
.end_of_line:
100
        call    [img_draw_core_fn]
101
 
102
.next_line:
103
        bt      ebx, 26
104
        jnc     @f
1899 art_zh 105
        pop     [img_bitoffset]
1859 art_zh 106
        pop     esi
107
        pop     edi
108
@@:	inc	edx
109
	cmp	edx, [esp+24]                   ; stacked ecx = image height
110
	je	.finish
111
	add	edi, [BytesPerScanLine]
112
        add     esi, [img_buf_line_size]
113
	btc	ebx, 24			        ; odd line?
114
	jnc	.new_line
115
        add     ebp, [_WinMapWidth]
116
	jmp     .new_line
117
 
118
.finish:
119
        popad
120
        ret
121
 
122
;--------------------------------
123
; ebx : bit[24] = odd line; bh = reserved; bl = current task
124
; ecx : column height (pix)
125
; edx : max tile offset: 0, 4, 8, or 12 bytes (1,2,3 or 4 pix to draw)
126
; ebp : map origin
127
; esi : buffer image origin
128
; edi : LFB-origin (4byte-aligned)
129
 
130
align 4
131
draw_unaligned_edge:
132
        pushad
133
        mov     eax, [img_buf_line_size]
134
        mov     bh, dl                  ; store the 1st tile offset
1899 art_zh 135
        btr     ebx, 24                 ; check if the 1st line odd
1859 art_zh 136
        jnc     .new_tile
137
        cmp     bl, byte[ebp]
138
        jne     @f
139
        call    [img_draw_edge_fn]      ; bpp-specific helper (see below)
140
@@:
141
        dec     ecx
142
        jz      .exit
143
        add     edi, [BytesPerScanLine]
144
        add     ebp, [_WinMapWidth]
145
        add     esi, eax
146
.new_tile:
147
        cmp     bl, byte[ebp]
148
        jne     .skip_tile
149
        call    [img_draw_edge_fn]
150
        dec     ecx
151
        jz      .exit
152
        add     edi, [BytesPerScanLine]
153
        add     esi, eax
154
        call    [img_draw_edge_fn]
155
        dec     ecx
156
        jz      .exit
157
        add     edi, [BytesPerScanLine]
158
        add     ebp, [_WinMapWidth]
159
        add     esi, eax
160
        jmp     .new_tile
161
.skip_tile:
162
        sub     cx, 2
163
        jbe     .exit
164
        add     edi, [BytesPerScanLine]
165
        add     edi, [BytesPerScanLine]
166
        add     esi, eax
167
        add     esi, eax
168
        add     ebp, [_WinMapWidth]
169
        jmp     .new_tile
170
.exit:
171
        popad
172
        ret
173
 
174
 
175
 
176
;-------------
177
; unaligned edge helpers
178
; esi -> left point of the image edge
179
; edi -> left point of the screen edge
180
; bh = edx = tile offset (0, 4, 8 or 12 bytes)
181
 
182
align 4
1899 art_zh 183
draw_edge_0bpp:
184
        push    eax
185
        mov     eax, [esi]
186
.putpix:
187
        mov     [edi+edx], eax
188
        sub     dl,  4
189
        jae     .putpix
190
.exit:
191
	movzx	edx, bh
192
        pop     eax
193
        ret
194
align 4
1859 art_zh 195
draw_edge_32bpp:
196
        push    eax
197
.putpix:
198
        mov     eax, [esi+edx]
199
        mov     [edi+edx], eax
200
        sub     dl,  4
201
        jae     .putpix
202
.exit:
1899 art_zh 203
	movzx	edx, bh
1859 art_zh 204
        pop     eax
205
        ret
206
align 4
207
draw_edge_24bpp:
208
        push    eax esi
209
	xor	dl, dl
210
.putpix:
211
        mov     eax, [esi]
212
        and     eax, 0x00FFFFFF
213
        mov     [edi+edx], eax
1899 art_zh 214
        cmp     dl, bh
215
        je      .exit
1859 art_zh 216
        add     dl,  4
217
        add     esi, 3
218
        jmp     .putpix
219
.exit:
220
        pop     esi eax
221
        ret
222
align 4
223
draw_edge_8bpp:
224
        push    eax esi ebp
225
	xor	dl, dl
226
        mov     ebp, [img_palette]
227
.putpix:
228
        movzx   eax, byte[esi]
229
        mov     eax, [ebp+eax*4]
230
        mov     [edi+edx], eax
1899 art_zh 231
        cmp     dl, bh
232
        je      .exit
1859 art_zh 233
        add     dl,  4
234
        inc     esi
235
        jmp     .putpix
236
.exit:
237
        pop     ebp esi eax
238
        ret
239
align 4
240
draw_edge_1bpp:
1899 art_zh 241
        pushad
242
        movzx   edx, bh
243
        add     edx, edi
1859 art_zh 244
        mov     ebp, [img_palette]
245
        mov     ebx, [ebp+4]            ; forecolor
246
        mov     ebp, [ebp]              ; backcolor
247
        mov     ecx, [img_edgeoffset]    ; cl = 1 << left_edge_pix_num
1899 art_zh 248
        mov     eax, [esi]
1859 art_zh 249
.testbit:
1899 art_zh 250
        test    eax, ecx
1859 art_zh 251
        jnz     @f
252
        mov     eax, ebp
253
        jmp     .putpix
254
@@:     mov     eax, ebx
255
.putpix:
1899 art_zh 256
        mov     [edi], eax
257
        cmp     edi, edx
258
        je      .exit
259
        add     edi, 4
260
        rol     ecx, 1
1859 art_zh 261
        jmp     .testbit
262
.exit:
1899 art_zh 263
        popad
1859 art_zh 264
        ret
265
 
266
draw_edge_16bpp:
267
draw_core_16bpp:
268
        ret
269
 
270
;-------------
271
; aligned core helpers
1899 art_zh 272
; esi -> left point address (buffer)
1859 art_zh 273
; edi -> left point address (screen)
1899 art_zh 274
; ecx =  number of tiles to draw
1859 art_zh 275
align 4
1899 art_zh 276
draw_core_0bpp:
277
        push    eax ecx edi
278
        pushfd
279
;        cli
280
        cld
281
        mov     eax, [esi]
282
        shl     ecx, 2
283
        rep     stosd
284
        popfd
285
        pop     edi ecx eax
286
        ret
287
align 4
1859 art_zh 288
draw_core_32bpp:
1899 art_zh 289
        push    ecx esi edi
290
        pushfd
291
;        cli
292
        cld
293
        shl     ecx, 2
294
        rep     movsd
295
        popfd
296
        pop     edi esi ecx
1859 art_zh 297
        ret
298
align 4
299
draw_core_24bpp:
1899 art_zh 300
        push    eax ecx edx
301
        shl     ecx, 2                  ; ecx = numpixels
1859 art_zh 302
        dec     ecx
1899 art_zh 303
        lea     edx, [ecx*2+ecx]        ; edx = buffer byte offset
1859 art_zh 304
.putpix:
1899 art_zh 305
        mov     eax, [esi+edx]
1859 art_zh 306
        and     eax, 0x00FFFFFF
307
        mov     [edi+ecx*4], eax
1899 art_zh 308
        dec     ecx
309
        sub     edx, 3
1859 art_zh 310
        jnb     .putpix
1899 art_zh 311
        pop     edx ecx eax
1859 art_zh 312
        ret
313
align 4
314
draw_core_8bpp:
315
        pushad
316
        mov     ebp, [img_palette]
317
.putpix:
318
        xor     edx, edx
319
        mov     eax, dword[esi]         ; block of 4 pixels
320
.putone:
321
        movzx   ebx, al
322
        mov     ebx, [ebp+ebx*4]
323
        mov     [edi+edx*4], ebx
324
        shr     eax, 8
325
        inc     dl
326
        cmp     dl, 4
327
        jnz     .putone
328
        add     esi, edx        ;-)
329
        add     edi, 16
1899 art_zh 330
        dec     ecx
1859 art_zh 331
        jnz     .putpix
332
.exit:
333
        popad
334
        ret
335
align 4
336
draw_core_1bpp:
337
        pushad
338
        mov     ebp, [img_palette]
339
        mov     edx, [ebp+4]            ; foreground color
340
        mov     ebp, [ebp]              ; background color
341
        mov     ebx, [img_bitoffset]
342
        shl     ecx, 2                  ; 1 tyle = 4 pix
343
.newblock:
344
        mov     eax, [esi]
345
.putpix:
346
        test    ebx, eax
347
        jz      .bkcolor
348
        mov     [edi], edx
349
        jmp     .nextpix
350
.bkcolor:
351
        mov     [edi], ebp
352
.nextpix:
1899 art_zh 353
        dec     ecx
354
        jz      .exit
1859 art_zh 355
        rol     ebx, 1
356
        jc      .nextblock
357
        add     edi, 4
358
        jmp     .putpix
359
.nextblock:
360
        add     esi, 4
361
        jmp     .newblock
362
.exit:
363
        popad
364
        ret
365
 
366
;-----------------------------------------
367
virtual at esp
368
 putimg:
369
   .image_sx	   dd ?		; X-size (pix)
370
   .image_sy	   dd ?		; Y-size
371
   .stack_data = 2*4
372
end virtual
373
 
374
align 4
375
; ebx -> Buffer origin
376
; ecx = packed size [x|y]
377
; edx = packed coordinates [x|y]
1899 art_zh 378
; static variables required:
379
; [img_draw_core_fn],  [img_draw_edge_fn]
380
; [img_bytes_per_pix], [img_buf_line_size]
381
; [img_palette]  (1bpp and 8bpp only)
1859 art_zh 382
 
383
_putimage:
384
;     	call    [_display.disable_mouse]
385
	pushad
386
     	sub     esp, putimg.stack_data
387
     	mov     [img_buf_origin], ebx		; save pointer to image buffer
388
     	mov     esi, ebx		        ; pointer to image
389
.unpack_coords:
390
     	mov     eax, ecx
391
    	and     ecx, 0xFFFF			; Ysize
392
     	shr     eax, 16	                        ; Xsize
393
     	mov     [putimg.image_sy], ecx
394
     	mov     [putimg.image_sx], eax
395
    	mov     eax, edx
396
     	and     edx, 0xFFFF			; Ytop
397
     	shr     eax, 16			        ; Xleft
398
.calculate_abs_coords:
1899 art_zh 399
        mov     edi, [TASK_BASE]
400
     	mov     ebx, [edi-twdw + WDATA.box.left]
401
     	mov     ecx, [edi-twdw + WDATA.box.top]
1859 art_zh 402
        add     ebx, eax
403
     	add     ecx, edx
404
     	mov     [img_screen_x], ebx		; abs Xleft
405
;     	mov     [img_screen_y], ecx		; ecx = abs Ytop        ; hold it !
406
.check_x_size:
1899 art_zh 407
     	mov     ebx, [edi-twdw + WDATA.box.width]
1859 art_zh 408
     	inc     ebx				; ebx = window Xsize
409
     	sub     ebx, eax                        ; eax = rel Xleft
410
     	jbe     .finish				; image is out of the window
411
        mov     eax, [putimg.image_sx]
412
     	cmp     ebx, eax		        ; real_sx = MIN(wnd_sx-image_cx, image_sx);
413
     	jae     @f
414
        mov     eax, ebx
415
@@:    	dec     eax
416
        mov     [img_pix_x], eax
417
.check_y_size:
1899 art_zh 418
     	mov     ebx, [edi-twdw + WDATA.box.height]
1859 art_zh 419
     	inc     ebx				; ebx = real window y-size
420
     	sub     ebx, edx                        ; edx = rel Ytop
421
     	jbe     .finish				; image isn't visible
422
        mov     edx, [putimg.image_sy]
423
        cmp     ebx, edx
424
        jae     @f
425
        mov     edx, ebx
426
@@:     mov     [img_pix_y], edx
427
 
428
.calculate_lfb_origin:
429
     	mov     edi, ecx                        ; ecx = absY
430
     	imul    edi, [BytesPerScanLine]
431
     	mov     eax, [img_screen_x]             ; eax = absX
432
     	lea     edi, [edi+eax*4]
433
     	add     edi, LFB_BASE			; edi -> Screen origin
434
	mov	[img_lfb_origin], edi
435
.calculate_map_origin:
436
	xor	ebx, ebx
437
        mov     bl,  byte [img_bytes_per_pix]
438
        or      bl,  bl
439
        jnz     @f
1899 art_zh 440
        mov     ecx, [img_buf_line_size]
441
        or      cl, cl
442
        je      @f
1859 art_zh 443
        bts     ebx, 25
444
@@:    	mov     bl,  byte [CURRENT_TASK]	; get process number
445
    	mov     ebp, ecx                        ; ecx = absY
446
	shr	ebp, 1				; CF= odd line
447
	jnc	@f
448
	bts	ebx, 24				; ebx[24] = odd start line
449
@@:    	imul    ebp, [_WinMapWidth]
450
	add	ebp, [_WinMapAddress]
451
     	mov     ecx, eax                        ; eax = absX
452
	shr	ecx, 2
453
	add     eax, [img_pix_x]
1899 art_zh 454
        inc     eax
1859 art_zh 455
        shr     eax, 2
456
        add     eax, ebp
1899 art_zh 457
;        mov     [img_map_right], eax		; right edge tile
1859 art_zh 458
     	add     ebp, ecx			; left edge Map origin
459
        mov	ecx, [img_pix_y]
460
        sub     eax, ebp
461
        jz      .thin_bar                       ; special case: all image is 1 tile  thick
462
        mov     [img_map_x], eax                ; tiles in row (excluding the right one)
463
 
464
; ----- at this point:
465
; esi = [img_buf_origin] -> buffered image
466
; edi = [img_lfb_origin] -> LFB image (corner point, 0RGB format)
467
; ebp -> corner tile position
468
; ecx = [img_pix_y] =  image height
469
;  bl = task #
1899 art_zh 470
; ebx[24] = 1 if Ytop is odd
471
; ebx[25] = 1 if 1bpp image
1859 art_zh 472
 
473
.start:
474
        bt      ebx, 25
475
        jnc     @f
476
        xor     eax, eax
477
        inc     al
478
	mov	[img_bitoffset], eax		; 1bpp image must be byte-aligned
479
	mov	[img_edgeoffset], eax
480
@@:
481
	mov	edx, edi
1899 art_zh 482
	mov	dh, 0x0C
483
        and     dl, dh
1859 art_zh 484
        jz      .go_right                       ; left edge already aligned
485
.left_edge:
486
        sub     dh, dl
487
        movzx   edx, dh
488
	call	draw_unaligned_edge
489
        dec     [img_map_x]
490
	shr	edi, 4
491
        inc     edi                             ; align edi to the next 16-byte tile
492
	shl	edi, 4
493
	mov	[img_lfb_origin], edi           ; core Screen origin
494
        shr     edx, 2
495
        inc     edx
496
        sub     [img_pix_x], edx                ; shrink image width
497
        bt      ebx, 25
498
        jnc     @f
499
        xchg    dl, cl
500
        mov     eax, [img_edgeoffset]           ; that's for 1bpp images only
501
        shl     eax, cl
502
        mov     [img_edgeoffset], eax
503
        mov     [img_bitoffset],  eax
504
        xchg    dl, cl
505
@@:     mov     eax, edx
506
        imul    eax, [img_bytes_per_pix]        ; 0 for 1bbp bitmaps
507
        add     esi, eax
508
        mov     [img_buf_origin], esi           ; core Buffer origin
509
        inc     ebp                             ; core Map origin
510
.go_right:
511
        mov     eax, [img_map_x]
512
        mov     edx, eax
513
        bt      ebx, 25                         ; 1bpp image ?
514
        jc      .shift_mono
515
        shl     eax, 2
516
        imul    eax, [img_bytes_per_pix]
517
        jmp     .get_right
518
.shift_mono:
519
        shr     eax, 1                          ; 2 tiles = 1 byte Buffer offset
520
        jnc     .get_right
521
        rol     byte [img_edgeoffset], 4        ; odd number of tiles: shift 4bits
522
.get_right:
523
        add     esi, eax                        ; rightEdge Buffer origin
524
        push    ebp
525
        add     ebp, edx                        ; rightEdge Map origin
526
        mov     eax, [img_pix_x]
527
        shl     eax, 2                          ; 1 pix = 4 bytes
528
        add     eax, edi                        ; rightEdge last pix (LFB addr)
1899 art_zh 529
        shl     edx, 4
530
        add     edi, edx                        ; rightEdge Screen origin
1859 art_zh 531
        movzx   edx, al
1899 art_zh 532
        mov     eax, [img_map_x]
1859 art_zh 533
        and     dl, 0x0C
1899 art_zh 534
        cmp     dl, 0x0C
535
        je      .core_block             	; rightEdge is already tile-aligned
1859 art_zh 536
.right_edge:
537
        call    draw_unaligned_edge
538
.core_block:
1899 art_zh 539
        or      eax, eax                        ; empty central core?
540
        jz      .finish
541
        mov     ebp, [esp]
1859 art_zh 542
    	mov	edi, [img_lfb_origin]
543
	mov	esi, [img_buf_origin]
544
 
545
	call	draw_aligned_box
546
 
547
.finish:
1899 art_zh 548
     	add     esp, (putimg.stack_data + 4)
1859 art_zh 549
;	call	[_display.enable_mouse]
550
	popad
551
	ret
552
 
553
.thin_bar:                                      ; < a special case > :  one-tile-wide image
554
        mov     edx, [img_pix_x]
555
        shl     edx, 2                          ; edx = rightmost tile offset (0, 4, 8, or 12 bytes)
556
        call    draw_unaligned_edge
1899 art_zh 557
     	add     esp, putimg.stack_data
558
	popad
559
	ret
1859 art_zh 560
 
561
 
1899 art_zh 562
;align 64
563
;img_test_struct_32:     ; 8 x 10
564
;        dd      0x112233, 0x223344, 0x334455, 0x445566, 0x556677, 0x667788, 0x778899, 0x887766
565
;        dd      0x223344, 0x334455, 0x445566, 0x556677, 0x667788, 0x777799, 0x887766, 0x997755
566
;        dd      0x334455, 0x445566, 0x556677, 0x667788, 0x777799, 0x887766, 0x997755, 0xAA7744
567
;        dd      0x445566, 0x556677, 0x667788, 0x777799, 0x887766, 0x997755, 0xAA7744, 0xBB7733
568
;        dd      0x334455, 0x445566, 0x556677, 0x667788, 0x777799, 0x887766, 0x997755, 0xAA7744
569
;        dd      0x223344, 0x334455, 0x445566, 0x556677, 0x667788, 0x777799, 0x887766, 0x997755
570
;        dd      0x112233, 0x223344, 0x334455, 0x445566, 0x556677, 0x667788, 0x777799, 0x887766
571
;        dd      0x001122, 0x112233, 0x223344, 0x334455, 0x445566, 0x556677, 0x667788, 0x777799
572
;        dd      0x220000, 0x001122, 0x112233, 0x223344, 0x334455, 0x445566, 0x556677, 0x667788
573
;        dd      0x441100, 0x220000, 0x001122, 0x112233, 0x223344, 0x334455, 0x445566, 0x556677
1859 art_zh 574
 
1899 art_zh 575
;align 64
576
;img_test_struct_24:     ; 8 x 16
577
;        dw      0x1100, 0x0022, 0x2211, 0x1100, 0x0022, 0x2211, 0xBBAA, 0xAACC, 0xCCBB, 0xBBAA, 0xAACC, 0xCCBB
578
;        dw      0xBBAA, 0xAACC, 0xCCBB, 0xBBAA, 0xAACC, 0xCCBB, 0x1100, 0x0022, 0x2211, 0x1100, 0x0022, 0x2211
579
;        dw      0x1100, 0x0022, 0x2211, 0x1100, 0x0022, 0x2211, 0xBBAA, 0xAACC, 0xCCBB, 0xBBAA, 0xAACC, 0xCCBB
580
;        dw      0xBBAA, 0xAACC, 0xCCBB, 0xBBAA, 0xAACC, 0xCCBB, 0x1100, 0x0022, 0x2211, 0x1100, 0x0022, 0x2211
581
;        dw      0x1100, 0x0022, 0x2211, 0x1100, 0x0022, 0x2211, 0xBBAA, 0xAACC, 0xCCBB, 0xBBAA, 0xAACC, 0xCCBB
582
;        dw      0xBBAA, 0xAACC, 0xCCBB, 0xBBAA, 0xAACC, 0xCCBB, 0x1100, 0x0022, 0x2211, 0x1100, 0x0022, 0x2211
583
;        dw      0x1100, 0x0022, 0x2211, 0x1100, 0x0022, 0x2211, 0xBBAA, 0xAACC, 0xCCBB, 0xBBAA, 0xAACC, 0xCCBB
584
;        dw      0xBBAA, 0xAACC, 0xCCBB, 0xBBAA, 0xAACC, 0xCCBB, 0x1100, 0x0022, 0x2211, 0x1100, 0x0022, 0x2211
585
;        dw      0x1100, 0x0022, 0x2211, 0x1100, 0x0022, 0x2211, 0xBBAA, 0xAACC, 0xCCBB, 0xBBAA, 0xAACC, 0xCCBB
586
;        dw      0xBBAA, 0xAACC, 0xCCBB, 0xBBAA, 0xAACC, 0xCCBB, 0x1100, 0x0022, 0x2211, 0x1100, 0x0022, 0x2211
587
;        dw      0x1100, 0x0022, 0x2211, 0x1100, 0x0022, 0x2211, 0xBBAA, 0xAACC, 0xCCBB, 0xBBAA, 0xAACC, 0xCCBB
588
;        dw      0xBBAA, 0xAACC, 0xCCBB, 0xBBAA, 0xAACC, 0xCCBB, 0x1100, 0x0022, 0x2211, 0x1100, 0x0022, 0x2211
589
;        dw      0x1100, 0x0022, 0x2211, 0x1100, 0x0022, 0x2211, 0xBBAA, 0xAACC, 0xCCBB, 0xBBAA, 0xAACC, 0xCCBB
590
;        dw      0xBBAA, 0xAACC, 0xCCBB, 0xBBAA, 0xAACC, 0xCCBB, 0x1100, 0x0022, 0x2211, 0x1100, 0x0022, 0x2211
591
;        dw      0x1100, 0x0022, 0x2211, 0x1100, 0x0022, 0x2211, 0xBBAA, 0xAACC, 0xCCBB, 0xBBAA, 0xAACC, 0xCCBB
592
;        dw      0xBBAA, 0xAACC, 0xCCBB, 0xBBAA, 0xAACC, 0xCCBB, 0x1100, 0x0022, 0x2211, 0x1100, 0x0022, 0x2211
593
 
594
;align 64
595
;img_test_struct_8:     ; 20 x 10
596
;        db      0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0
597
;        db      0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0
598
;        db      0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0
599
;        db      0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0
600
;        db      0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0
601
;        db      0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0
602
;        db      0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0
603
;        db      0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0
604
;        db      0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0
605
;        db      0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0
606
 
607
;align 64
608
;img_test_struct_1:     ; 16 x 10
609
;        db      0x0F, 0xF0
610
;        db      0x0F, 0xF0
611
;        db      0x3C, 0xC3
612
;        db      0x3C, 0xC3
613
;        db      0xF0, 0x0F
614
;        db      0xF0, 0x0F
615
;        db      0x3C, 0xC3
616
;        db      0x3C, 0xC3
617
;        db      0x0F, 0xF0
618
;        db      0x0F, 0xF0
619
 
620
;align 64
621
;img_test_palette:     ; 6 colors
622
;        dd      0x00BB2233, 0xAA4466, 0x995555, 0x00339966, 0x00884455, 0x00775566, 0x00664455, 0x00553344, 0x0
623
 
1859 art_zh 624
;**************************************************************************************
625
align 4
626
__sys_putpixel:
1899 art_zh 627
        push    edx
628
	mov	edx, [TASK_BASE]
629
	add	eax, [edx-twdw+WDATA.box.left]
630
	add	ebx, [edx-twdw+WDATA.box.top]
631
        pop     edx
1859 art_zh 632
_putpixel:
633
 
634
; eax = x coordinate
635
; ebx = y coordinate
636
; ecx = ?? RR GG BB    ; 0x01000000 negation
637
; edi = 0x00000001 force
638
 
639
     	cmp   [Screen_Max_X], eax
640
     	jb    .exit0
641
     	cmp   [Screen_Max_Y], ebx
642
     	jb    .exit0
643
.check_forced:
644
     	test    edi,1		 ; force ?
645
     	jnz     .checked
646
 
647
.not_forced:
648
     	push    ebx eax
1899 art_zh 649
	shr	eax, 2
1859 art_zh 650
     	shr  	ebx, 1
651
     	imul    ebx, [_WinMapWidth]	  ; win_map (X size)/2
652
	add	ebx, eax
653
	mov	al, byte [CURRENT_TASK]
1899 art_zh 654
     	mov   	ah, byte [_WinMapAddress+ebx]
655
     	cmp     ah, al
1859 art_zh 656
     	pop     eax ebx
657
     	jne     .exit0
658
.checked:
659
	push	ebx
660
     	imul    ebx, [BytesPerScanLine]
661
     	lea     ebx, [ebx+eax*4]
662
     	bt      ecx, 24
663
     	jnc     .noneg
664
     	mov     ecx, [LFB_BASE+ebx]
665
	xor     ecx, 0x00FFFFFF
666
.noneg:
667
     	mov     [LFB_BASE+ebx], ecx
668
	pop	ebx
669
.exit0:
670
     ret
671
 
672
 
673
 
1899 art_zh 674
;align 4
675
;_put_pixel:	; left for compatibility with Vesa20_putpixel32
676
;; eax = x
677
;; ebx = y
678
;     imul    ebx, [BytesPerScanLine]	 ; ebx = y * y multiplier
679
;     lea     edi, [ebx+eax*4]  ; edi = x*4+(y*y multiplier)
680
;;     mov     eax, [esp+32-8+4] ; eax = color
681
;     mov     [LFB_BASE+edi], ecx
682
;     ret
1859 art_zh 683
 
684
 
685
; DRAWLINE
686
 
687
align 4
688
__sys_draw_line:
689
     call    [_display.disable_mouse]
690
 
691
; draw a line
692
; eax = HIWORD = x1
693
;       LOWORD = x2
694
; ebx = HIWORD = y1
695
;       LOWORD = y2
696
; ecx = color
697
; edi = force ?
698
	pusha
699
 
700
dl_x1 equ esp+20
701
dl_y1 equ esp+16
702
dl_x2 equ esp+12
703
dl_y2 equ esp+8
704
dl_dx equ esp+4
705
dl_dy equ esp+0
706
 
707
     xor     edx, edx	   ; clear edx
708
     xor     esi, esi	   ; unpack arguments
709
     xor     ebp, ebp
710
     mov     si, ax	   ; esi = x2
711
     mov     bp, bx	   ; ebp = y2
712
     shr     eax, 16	   ; eax = x1
713
     shr     ebx, 16	   ; ebx = y1
714
     push    eax	   ; save x1
715
     push    ebx	   ; save y1
716
     push    esi	   ; save x2
717
     push    ebp	   ; save y2
718
 
719
; checking x-axis...
720
     sub     esi, eax	   ; esi = x2-x1
721
     push    esi	   ; save y2-y1
722
     jl      .x2lx1	   ; is x2 less than x1 ?
723
     jg      .no_vline	   ; x1 > x2 ?
724
     mov     edx, ebp	   ; else (if x1=x2)
725
     call    vline
726
     push    edx    ; necessary to rightly restore stack frame at .exit
727
     jmp     .exit
728
.x2lx1:
729
     neg     esi	    ; get esi absolute value
730
.no_vline:
731
; checking y-axis...
732
     sub     ebp, ebx	    ; ebp = y2-y1
733
     push    ebp	    ; save y2-y1
734
     jl      .y2ly1	    ; is y2 less than y1 ?
735
     jg      .no_hline	    ; y1 > y2 ?
736
     mov     edx, [dl_x2]   ; else (if y1=y2)
737
     call    hline
738
     jmp     .exit
739
 
740
.y2ly1:
741
     neg     ebp	    ; get ebp absolute value
742
.no_hline:
743
     cmp     ebp, esi
744
     jle     .x_rules	    ; |y2-y1| < |x2-x1|  ?
745
     cmp     [dl_y2], ebx   ; make sure y1 is at the begining
746
     jge     .no_reverse1
747
     neg     dword [dl_dx]
748
     mov     edx, [dl_x2]
749
     mov     [dl_x2], eax
750
     mov     [dl_x1], edx
751
     mov     edx, [dl_y2]
752
     mov     [dl_y2], ebx
753
     mov     [dl_y1], edx
754
.no_reverse1:
755
     mov     eax, [dl_dx]
756
     cdq		    ; extend eax sing to edx
757
     shl     eax, 16	    ; using 16bit fix-point maths
758
     idiv    ebp	    ; eax = ((x2-x1)*65536)/(y2-y1)
759
     mov     edx, ebp	    ; edx = counter (number of pixels to draw)
760
     mov     ebp, 1 *65536  ; <<16   ; ebp = dy = 1.0
761
     mov     esi, eax	    ; esi = dx
762
     jmp     .y_rules
763
 
764
.x_rules:
765
     cmp     [dl_x2], eax    ; make sure x1 is at the begining
766
     jge     .no_reverse2
767
     neg     dword [dl_dy]
768
     mov     edx, [dl_x2]
769
     mov     [dl_x2], eax
770
     mov     [dl_x1], edx
771
     mov     edx, [dl_y2]
772
     mov     [dl_y2], ebx
773
     mov     [dl_y1], edx
774
.no_reverse2:
775
     xor     edx, edx
776
     mov     eax, [dl_dy]
777
     cdq		    ; extend eax sing to edx
778
     shl     eax, 16	    ; using 16bit fix-point maths
779
     idiv    esi	    ; eax = ((y2-y1)*65536)/(x2-x1)
780
     mov     edx, esi	    ; edx = counter (number of pixels to draw)
781
     mov     esi, 1 *65536  ;<< 16   ; esi = dx = 1.0
782
     mov     ebp, eax	    ; ebp = dy
783
.y_rules:
784
     mov     eax, [dl_x1]
785
     mov     ebx, [dl_y1]
786
     shl     eax, 16
787
     shl     ebx, 16
788
align 4
789
.draw:
790
     push    eax ebx
791
     shr     eax, 16
792
     shr     ebx, 16
793
     call    _putpixel
794
     pop     ebx eax
795
     add     ebx, ebp	     ; y = y+dy
796
     add     eax, esi	     ; x = x+dx
797
     dec     edx
798
     jnz     .draw
799
; force last drawn pixel to be at (x2,y2)
800
     mov     eax, [dl_x2]
801
     mov     ebx, [dl_y2]
802
     call    _putpixel
803
.exit:
804
     add     esp, 6*4
805
     popa
806
     call   [draw_pointer]	; mouse
807
     ret
808
 
809
align 4
810
hline:
811
; ------------  draw a horizontal line -------------
812
; eax = x1
813
; edx = x2
814
; ebx = y
815
; ecx = color
816
; edi = force ?
817
     cmp     ebx, [Screen_Max_Y]
818
     jge     .out
819
     pushad
820
 
821
     bt      ecx, 24			; color inversion check
822
     rcl     edi,1			; forced graphics check
823
 
824
     mov     ebp, ebx
825
     shr     ebp, 1
826
     imul    ebp, [_WinMapWidth]	; ebp = screen map base
827
     add     ebp, [_WinMapAddress]
828
 
829
     cmp     edx, eax			; to make sure x2 > x1
830
     jge     @f
831
     xchg    eax, edx
832
@@:
833
     cmp     eax, [Screen_Max_X]
834
     jge     .exit
835
 
836
     mov     esi, eax
837
     shr     esi, 4
838
     add     ebp, esi			; ebp -> win_map element
839
 
840
     imul    ebx, [BytesPerScanLine]	; ebx -> LFB pix_line
841
     add     ebx, LFB_BASE
842
 
843
     cmp     edx, [Screen_Max_X]	; last check
844
     jb      @f
845
     mov     edx, [Screen_Max_X]
846
 
847
@@:  mov     esi, ecx			; store color here
848
     mov     cl, byte [CURRENT_TASK]	;
849
     mov     ch, cl
850
     mov     [CURRENT_TASK+2], cx
851
     mov     [CURRENT_TASK+1], cl	; replicate byte to dword
852
 
853
.newsegment:
854
     mov     ecx, [ebp] 		; check the line segment (16 pixels!)
855
     xor     ecx, [CURRENT_TASK]
856
; -- the line ---
1899 art_zh 857
     jmp     dword [hline.drawtable + edi*4]	; (C) Serge, 2010
1859 art_zh 858
 
859
 
860
align 4 				; internal loop
861
.invert_color:
862
     mov     esi, [ebx+eax*4]
863
     xor     esi, 0x00FFFFFF
864
align 4
865
.check_overlap:
866
     or      cl, cl
867
     jz      .putpixel
868
     jmp     .nextpixel
869
align 4
870
.invert_force:
871
     mov     esi, [ebx+eax*4]
872
     xor     esi, 0x00FFFFFF
873
align 4
874
.putpixel:
875
     mov     [ebx+eax*4], esi
876
align 4
877
.nextpixel:
878
     inc     eax
879
     cmp     eax, edx
880
     ja      .exit				; line drawn -- exit all loops
881
     test    al, 3
882
     jz     .newtile
883
.newpixel:
884
     jmp     dword [hline.drawtable + edi*4]	; the internal loop
885
.newtile:
886
     inc     ebp
887
     test    ebp, 3
888
     jz     .newsegment				; the external loop
889
     shr     ecx, 8
890
     jmp     dword [hline.drawtable + edi*4]
891
 
892
.exit:
893
     mov    eax, 0x0FF
894
     and    [CURRENT_TASK], eax
895
     popad
896
.out:
897
     ret
898
align 4
899
.drawtable:
900
dd	.check_overlap	; general case
901
dd	.invert_color
902
dd	.putpixel	; force to draw it
903
dd	.invert_force
904
 
905
 
906
align 4
907
vline:
908
; ---------  draw a vertical line  ------------
909
; eax = x
910
; ebx = y1
911
; edx = y2
912
; ecx = color
913
; edi = force ?
914
     cmp     eax, [Screen_Max_X]
915
     jge     .out
916
     pushad
917
     bt      ecx, 24			; color inversion check
918
     rcl     edi, 1			; forced graphics check
919
 
920
     cmp     edx, ebx			; to make sure y2 > y1
921
     jge     @f
922
     xchg    ebx, edx
923
@@:
924
     cmp     ebx, [Screen_Max_Y]
925
     jge     .exit
926
     mov     ebp, ebx
927
     shr     ebp, 1
928
     imul    ebp, [_WinMapWidth]
929
     add     ebp, [_WinMapAddress]
930
     mov     esi, eax
931
     shr     esi, 1
932
     shr     esi, 1
933
     add     ebp, esi			; ebp = screen map at (x, y1)
934
     push    ebx
935
 
936
     imul    ebx, [BytesPerScanLine]
937
     shl     eax, 1
938
     shl     eax, 1
939
     add     eax, ebx
940
     add     eax, LFB_BASE
941
     pop     ebx			; restore ebx = y1
942
     cmp     edx, [Screen_Max_Y]	; the last check
943
     jb     .draw
944
     mov     edx, [Screen_Max_Y]	; to prevent off-screen drawing
945
 
946
.draw:
947
     jmp     dword [vline.drawtable + edi*4]
948
align 4
949
.invert_color:
950
     mov     ecx, [eax]
951
     xor     ecx, 0x00FFFFFF
952
align 4
953
.check_overlap:
954
     movzx   esi, byte [ebp]
955
     cmp     esi, [CURRENT_TASK]
956
     je      .putpixel
957
     jmp     .nextpixel
958
 
959
align 4
960
.invert_force:
961
     mov     ecx, [eax]
962
     xor     ecx, 0x00FFFFFF
963
align 4
964
.putpixel:
965
     mov     [eax], ecx
966
align 4
967
.nextpixel:
968
     add     eax, [BytesPerScanLine]
969
     inc     ebx
970
     test    bl, 1
971
     jnz     @f
972
     add     ebp, [_WinMapWidth]
973
@@:
974
     cmp     ebx, edx
975
     ja     .exit
976
     jmp     dword [vline.drawtable + edi*4]
977
.exit:
978
     shr     edi, 1
979
     popad
980
 
981
.out:
982
     ret
983
align 4
984
.drawtable:
985
dd	.check_overlap	; general case
986
dd	.invert_color
987
dd	.putpixel	; force to draw it
988
dd	.invert_force
989
 
990
 
991
;*************************************************
992
 
993
 
994
 
995
align 4
1899 art_zh 996
; eax   xOrigin
997
; ebx   yOrigin
998
; ecx   xSize
999
; edx   ySize
1859 art_zh 1000
; edi   color
1001
 
1899 art_zh 1002
_drawbar:
1003
        pushad
1004
        sub     esp, putimg.stack_data
1005
	mov     [img_bytes_per_pix], 0
1006
	mov     [img_buf_line_size], 0
1007
	mov	[img_draw_core_fn],  draw_core_0bpp
1008
	mov	[img_draw_edge_fn],  draw_edge_0bpp
1009
     	mov     [putimg.image_sx], ecx
1010
     	mov     [putimg.image_sy], edx
1011
        mov     edx, ebx
1012
        mov     [img_palette], edi
1013
        mov     esi, img_palette
1014
        mov     [img_buf_origin], esi
1859 art_zh 1015
 
1899 art_zh 1016
	jmp     _putimage.calculate_abs_coords
1017
;       ret
1859 art_zh 1018
 
1019
 
1899 art_zh 1020
draw_background:
1021
        pushad
1022
	pushfd
1023
	cld	; increment edi here!
1024
        mov     ebp, [_WinMapAddress]
1025
        mov	eax, 0x00337766		; bgndcolor
1026
	mov	bl, 1
1027
	mov	edx, [Screen_Max_X]
1859 art_zh 1028
	shr	edx, 1
1899 art_zh 1029
	mov	edi, LFB_BASE
1030
	mov	esi, [BytesPerScanLine]
1031
.new_row:
1032
	xor	ecx, ecx
1033
.fill:
1034
	cmp	byte [ebp+ecx], bl
1035
	jne	.next
1036
 
1037
	mov	[edi+esi], eax		; fill all 8 pixels of this tile
1038
	stosd
1039
	mov	[edi+esi], eax
1040
	stosd
1041
	mov	[edi+esi], eax
1042
	stosd
1043
	mov	[edi+esi], eax
1044
	stosd
1045
.next:	inc	ecx
1046
	cmp	ecx, [_WinMapWidth]
1047
	jb	.fill
1048
	dec	edx
1049
	jz	.done
1050
	add	ebp, ecx		; += [_WinMapWidth]
1051
	add	edi, esi 		; += [BytesPerScanLine]
1052
	jmp	.new_row
1053
.done:
1054
	popfd
1055
        popad
1056
        ret
1859 art_zh 1057
 
1058
 
1059
drawbackground_stretch:		; left for future development
1060
	call	drawbackground
1061
	ret
1062
drawbackground_tiled:		; left for future development
1063
	call	drawbackground
1064
	ret
1065
 
1066
uglobal
1067
align 4
1068
bgr_cur_line	rd	1920	; maximum width of screen
1069
bgr_next_line	rd	1920
1070
endg
1071
 
1072
 
1899 art_zh 1073
_init_background:
1074
;	mov	edi, BgrAuxTable
1075
;	xor	edx, edx
1076
;.loop2:
1077
;	mov	eax, edx
1078
;	shl	eax, 8
1079
;	neg	eax
1080
;	mov	ecx, 0x200
1081
;.loop1:
1082
;	mov	byte [edi], ah
1083
;	inc	edi
1084
;	add	eax, edx
1085
;	loop	.loop1
1086
;	add	dl, 4
1087
;	jnz	.loop2
1088
        mov     byte [REDRAW_BACKGROUND], 1
1089
;        mov     dword[BgrAuxTable], 0x00337766
1859 art_zh 1090
	ret
1091
 
1092
 
1093
diff16 "GRAPH32 code end ",0,$
1094
diff10 "GRAPH32 code size",get_pixel,$
1095