Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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
  54.         jz      .new_tile
  55.         bts     ebx, 26                         ; ebx[26] = 1 if edi/esi already pushed
  56.         jc      .seek_visible
  57.         push    edi
  58.         push    esi
  59.         jmp     .seek_visible
  60. .new_tile:
  61.         inc     ecx                             ; visible - scan the open space
  62.         cmp     ecx, eax      
  63.         jz      .end_of_line
  64.         cmp     bl, byte[ebp+ecx]               ; overlapped? draw the visible segment if so
  65.         je      .new_tile
  66.  
  67.         call    [img_draw_core_fn]              ; bpp-specific helper (see below)
  68.  
  69. .seek_visible:
  70.         inc     ecx
  71.         cmp     ecx, eax       
  72.         je      .next_line
  73.         cmp     bl, byte[ebp+ecx]
  74.         jne     .seek_visible
  75. .got_visible:
  76.         sub     eax, ecx
  77.         shl     ecx, 4
  78.         add     edi, ecx                        ; shift the left edge
  79.         shr     ecx, 2
  80.         imul    ecx, [img_bytes_per_pix]
  81.         add     esi, ecx
  82.         xor     ecx, ecx
  83.         jmp     .new_tile
  84.  
  85. .end_of_line:
  86.         call    [img_draw_core_fn]
  87.  
  88. .next_line:  
  89.         bt      ebx, 26
  90.         jnc     @f
  91.         pop     esi
  92.         pop     edi                                  
  93. @@:     inc     edx
  94.         cmp     edx, [esp+24]                   ; stacked ecx = image height
  95.         je      .finish
  96.         add     edi, [BytesPerScanLine]
  97.         add     esi, [img_buf_line_size]
  98.         btc     ebx, 24                         ; odd line?
  99.         jnc     .new_line
  100.         add     ebp, [_WinMapWidth]
  101.         jmp     .new_line
  102.  
  103. .finish:
  104.         popad
  105.         ret
  106.  
  107. ;--------------------------------
  108. ; ebx : bit[24] = odd line; bh = reserved; bl = current task
  109. ; ecx : column height (pix)
  110. ; edx : max tile offset: 0, 4, 8, or 12 bytes (1,2,3 or 4 pix to draw)
  111. ; ebp : map origin
  112. ; esi : buffer image origin
  113. ; edi : LFB-origin (4byte-aligned)
  114.  
  115. align 4
  116. draw_unaligned_edge:
  117.         pushad
  118.         mov     eax, [img_buf_line_size]
  119.         mov     bh, dl                  ; store the 1st tile offset
  120.         bt      ebx, 24                 ; check if the 1st line odd
  121.         jnc     .new_tile          
  122.         cmp     bl, byte[ebp]
  123.         jne     @f
  124.         call    [img_draw_edge_fn]      ; bpp-specific helper (see below)
  125. @@:    
  126.         dec     ecx
  127.         jz      .exit
  128.         add     edi, [BytesPerScanLine]
  129.         add     ebp, [_WinMapWidth]
  130.         add     esi, eax
  131.         btr     ebx, 24                
  132. .new_tile:
  133.         cmp     bl, byte[ebp]
  134.         jne     .skip_tile
  135.         call    [img_draw_edge_fn]      
  136.         dec     ecx
  137.         jz      .exit
  138.         add     edi, [BytesPerScanLine]
  139.         add     esi, eax
  140.         call    [img_draw_edge_fn]      
  141.         dec     ecx
  142.         jz      .exit
  143.         add     edi, [BytesPerScanLine]
  144.         add     ebp, [_WinMapWidth]
  145.         add     esi, eax
  146.         jmp     .new_tile
  147. .skip_tile:
  148.         sub     cx, 2
  149.         jbe     .exit
  150.         add     edi, [BytesPerScanLine]
  151.         add     edi, [BytesPerScanLine]
  152.         add     esi, eax
  153.         add     esi, eax
  154.         add     ebp, [_WinMapWidth]
  155.         jmp     .new_tile
  156. .exit:
  157.         popad
  158.         ret              
  159.  
  160.              
  161.  
  162. ;-------------
  163. ; unaligned edge helpers
  164. ; esi -> left point of the image edge
  165. ; edi -> left point of the screen edge
  166. ; bh = edx = tile offset (0, 4, 8 or 12 bytes)
  167.  
  168. align 4
  169. draw_edge_32bpp:
  170.         push    eax
  171. .putpix:
  172.         mov     eax, [esi+edx]
  173.         mov     [edi+edx], eax
  174.         sub     dl,  4
  175.         jae     .putpix
  176. .exit:
  177.         mov     dl, bh
  178.         pop     eax
  179.         ret
  180. align 4
  181. draw_edge_24bpp:
  182.         push    eax esi
  183.         xor     dl, dl
  184. .putpix:
  185.         mov     eax, [esi]
  186.         and     eax, 0x00FFFFFF
  187.         mov     [edi+edx], eax
  188.         test    dl, bh
  189.         jz      .exit
  190.         add     dl,  4
  191.         add     esi, 3
  192.         jmp     .putpix
  193. .exit:
  194.         pop     esi eax
  195.         ret
  196. align 4
  197. draw_edge_8bpp:
  198.         push    eax esi ebp
  199.         xor     dl, dl
  200.         mov     ebp, [img_palette]
  201. .putpix:
  202.         movzx   eax, byte[esi]
  203.         mov     eax, [ebp+eax*4]
  204.         mov     [edi+edx], eax
  205.         test    dl, bh
  206.         jz      .exit
  207.         add     dl,  4
  208.         inc     esi
  209.         jmp     .putpix
  210. .exit:
  211.         pop     ebp esi eax
  212.         ret
  213. align 4
  214. draw_edge_1bpp:
  215.         push    eax ecx ebx ebp
  216.         mov     ebp, [img_palette]
  217.         mov     ebx, [ebp+4]            ; forecolor
  218.         mov     ebp, [ebp]              ; backcolor
  219.         mov     ecx, [img_edgeoffset]    ; cl = 1 << left_edge_pix_num
  220.         mov     ebp, [esi]    
  221.         xor     dl, dl
  222. .testbit:
  223.         test    ebp, ecx
  224.         jnz     @f
  225.         mov     eax, ebp
  226.         jmp     .putpix
  227. @@:     mov     eax, ebx
  228. .putpix:
  229.         mov     [edi+edx], eax
  230.         test    dl, bh
  231.         jz      .exit
  232.         add     dl, 4
  233.         shl     ecx, 1
  234.         jmp     .testbit
  235. .exit:
  236.         pop     ebp ebx ecx eax
  237.         ret
  238.  
  239. draw_edge_16bpp:
  240. draw_core_16bpp:
  241.         ret
  242.  
  243. ;-------------
  244. ; aligned core helpers
  245. ; esi -> left point address (image)
  246. ; edi -> left point address (screen)
  247. ; cx  =  number of tiles to draw
  248. align 4
  249. draw_core_32bpp:
  250.         push    ecx
  251.         shl     ecx, 1
  252.         dec     ecx
  253. .putpix:
  254.         fld     qword[esi+ecx*8]        ; 2 qwords = 1 tile
  255.         fstp    qword[edi+ecx*8]
  256.         dec     cx
  257.         jnb     .putpix
  258.         pop     ecx
  259.         ret
  260. align 4
  261. draw_core_24bpp:
  262.         push    eax ecx
  263.         shl     ecx, 2
  264.         dec     ecx
  265.         lea     eax, [ecx*2+ecx]
  266. .putpix:
  267.         mov     eax, [esi+eax]
  268.         and     eax, 0x00FFFFFF
  269.         mov     [edi+ecx*4], eax
  270.         sub     dx, 3
  271.         dec     cx
  272.         jnb     .putpix
  273.         pop     ecx eax
  274.         ret
  275. align 4
  276. draw_core_8bpp:
  277.         pushad
  278.         mov     ebp, [img_palette]
  279. .putpix:
  280.         xor     edx, edx
  281.         mov     eax, dword[esi]         ; block of 4 pixels
  282. .putone:
  283.         movzx   ebx, al
  284.         mov     ebx, [ebp+ebx*4]
  285.         mov     [edi+edx*4], ebx
  286.         shr     eax, 8
  287.         inc     dl
  288.         cmp     dl, 4
  289.         jnz     .putone
  290.         add     esi, edx        ;-)
  291.         add     edi, 16
  292.         dec     cx
  293.         jnz     .putpix
  294. .exit:
  295.         popad
  296.         ret
  297. align 4
  298. draw_core_1bpp:
  299.         pushad  
  300.         mov     ebp, [img_palette]      
  301.         mov     edx, [ebp+4]            ; foreground color
  302.         mov     ebp, [ebp]              ; background color
  303.         mov     ebx, [img_bitoffset]
  304.         shl     ecx, 2                  ; 1 tyle = 4 pix
  305.         dec     ecx
  306.         jb      .exit
  307. .newblock:
  308.         mov     eax, [esi]
  309. .putpix:
  310.         test    ebx, eax
  311.         jz      .bkcolor
  312.         mov     [edi], edx
  313.         jmp     .nextpix
  314. .bkcolor:
  315.         mov     [edi], ebp
  316. .nextpix:
  317.         dec     cx
  318.         jb      .exit  
  319.         rol     ebx, 1
  320.         jc      .nextblock
  321.         add     edi, 4
  322.         jmp     .putpix
  323. .nextblock:
  324.         add     esi, 4
  325.         jmp     .newblock
  326. .exit:
  327.         popad    
  328.         ret
  329.  
  330. ;-----------------------------------------
  331. virtual at esp
  332.  putimg:
  333.    .image_sx       dd ?         ; X-size (pix)
  334.    .image_sy       dd ?         ; Y-size
  335.    .stack_data = 2*4
  336. end virtual
  337.  
  338. align 4
  339. ; ebx -> Buffer origin
  340. ; ecx = packed size [x|y]
  341. ; edx = packed coordinates [x|y]
  342.  
  343. _putimage:
  344. ;       call    [_display.disable_mouse]
  345.         pushad
  346.         sub     esp, putimg.stack_data
  347.         mov     [img_buf_origin], ebx           ; save pointer to image buffer
  348.         mov     esi, ebx                        ; pointer to image
  349. .unpack_coords:
  350.         mov     eax, ecx
  351.         and     ecx, 0xFFFF                     ; Ysize
  352.         shr     eax, 16                         ; Xsize
  353.         mov     [putimg.image_sy], ecx
  354.         mov     [putimg.image_sx], eax
  355.         mov     eax, edx
  356.         and     edx, 0xFFFF                     ; Ytop
  357.         shr     eax, 16                         ; Xleft
  358. .calculate_abs_coords:
  359.         mov     ebx, [TASK_BASE-twdw + WDATA.box.left]
  360.         mov     ecx, [TASK_BASE-twdw + WDATA.box.top]
  361.         add     ebx, eax
  362.         add     ecx, edx
  363.         mov     [img_screen_x], ebx             ; abs Xleft
  364. ;       mov     [img_screen_y], ecx             ; ecx = abs Ytop        ; hold it !
  365. .check_x_size:
  366.         mov     ebx, [TASK_BASE-twdw + WDATA.box.width]
  367.         inc     ebx                             ; ebx = window Xsize
  368.         sub     ebx, eax                        ; eax = rel Xleft
  369.         jbe     .finish                         ; image is out of the window
  370.         mov     eax, [putimg.image_sx]
  371.         cmp     ebx, eax                        ; real_sx = MIN(wnd_sx-image_cx, image_sx);
  372.         jae     @f
  373.         mov     eax, ebx
  374. @@:     dec     eax
  375.         mov     [img_pix_x], eax
  376. .check_y_size:
  377.         mov     ebx, [TASK_BASE-twdw + WDATA.box.height]
  378.         inc     ebx                             ; ebx = real window y-size
  379.         sub     ebx, edx                        ; edx = rel Ytop
  380.         jbe     .finish                         ; image isn't visible
  381.         mov     edx, [putimg.image_sy]
  382.         cmp     ebx, edx
  383.         jae     @f
  384.         mov     edx, ebx
  385. @@:     mov     [img_pix_y], edx
  386.  
  387. .calculate_lfb_origin:
  388.         mov     edi, ecx                        ; ecx = absY
  389.         imul    edi, [BytesPerScanLine]
  390.         mov     eax, [img_screen_x]             ; eax = absX
  391.         lea     edi, [edi+eax*4]               
  392.         add     edi, LFB_BASE                   ; edi -> Screen origin
  393.         mov     [img_lfb_origin], edi
  394. .calculate_map_origin:
  395.         xor     ebx, ebx
  396.         mov     bl,  byte [img_bytes_per_pix]
  397.         or      bl,  bl
  398.         jnz     @f
  399.         bts     ebx, 25
  400. @@:     mov     bl,  byte [CURRENT_TASK]        ; get process number
  401.         mov     ebp, ecx                        ; ecx = absY
  402.         shr     ebp, 1                          ; CF= odd line
  403.         jnc     @f
  404.         bts     ebx, 24                         ; ebx[24] = odd start line
  405. @@:     imul    ebp, [_WinMapWidth]    
  406.         add     ebp, [_WinMapAddress]
  407.         mov     ecx, eax                        ; eax = absX
  408.         shr     ecx, 2                
  409.         add     eax, [img_pix_x]
  410.         shr     eax, 2
  411.         add     eax, ebp       
  412.         mov     [img_map_right], eax            ; right edge tile
  413.         add     ebp, ecx                        ; left edge Map origin
  414.         mov     ecx, [img_pix_y]
  415.         sub     eax, ebp
  416.         jz      .thin_bar                       ; special case: all image is 1 tile  thick
  417.         mov     [img_map_x], eax                ; tiles in row (excluding the right one)
  418.  
  419. ; ----- at this point:
  420. ; esi = [img_buf_origin] -> buffered image
  421. ; edi = [img_lfb_origin] -> LFB image (corner point, 0RGB format)
  422. ; ebp -> corner tile position
  423. ; ecx = [img_pix_y] =  image height
  424. ;  bl = task #
  425. ; ebx[24] = 1 if the core Y is odd
  426. ; ebx[25] = 1bpp image
  427.  
  428. .start:
  429.         bt      ebx, 25
  430.         jnc     @f
  431.         xor     eax, eax
  432.         inc     al
  433.         mov     [img_bitoffset], eax            ; 1bpp image must be byte-aligned
  434.         mov     [img_edgeoffset], eax          
  435. @@:
  436.         mov     edx, edi
  437.         and     edx, 0x0C      
  438.         jz      .go_right                       ; left edge already aligned
  439. .left_edge:
  440.         mov     dh, 0x0C
  441.         sub     dh, dl
  442.         movzx   edx, dh
  443.         call    draw_unaligned_edge
  444.         dec     [img_map_x]
  445.         shr     edi, 4
  446.         inc     edi                             ; align edi to the next 16-byte tile
  447.         shl     edi, 4
  448.         mov     [img_lfb_origin], edi           ; core Screen origin
  449.         shr     edx, 2
  450.         inc     edx
  451.         sub     [img_pix_x], edx                ; shrink image width      
  452.         bt      ebx, 25
  453.         jnc     @f  
  454.         xchg    dl, cl
  455.         mov     eax, [img_edgeoffset]           ; that's for 1bpp images only
  456.         shl     eax, cl
  457.         mov     [img_edgeoffset], eax
  458.         mov     [img_bitoffset],  eax
  459.         xchg    dl, cl
  460. @@:     mov     eax, edx
  461.         imul    eax, [img_bytes_per_pix]        ; 0 for 1bbp bitmaps
  462.         add     esi, eax
  463.         mov     [img_buf_origin], esi           ; core Buffer origin
  464.         inc     ebp                             ; core Map origin
  465. .go_right:
  466.         mov     eax, [img_map_x]
  467.         mov     edx, eax
  468.         bt      ebx, 25                         ; 1bpp image ?
  469.         jc      .shift_mono
  470.         shl     eax, 2
  471.         imul    eax, [img_bytes_per_pix]
  472.         jmp     .get_right
  473. .shift_mono:
  474.         shr     eax, 1                          ; 2 tiles = 1 byte Buffer offset
  475.         jnc     .get_right
  476.         rol     byte [img_edgeoffset], 4        ; odd number of tiles: shift 4bits
  477. .get_right:
  478.         add     esi, eax                        ; rightEdge Buffer origin
  479.         push    ebp
  480.         add     ebp, edx                        ; rightEdge Map origin
  481.         mov     eax, [img_pix_x]
  482.         shl     eax, 2                          ; 1 pix = 4 bytes
  483.         add     eax, edi                        ; rightEdge last pix (LFB addr)
  484.         movzx   edx, al
  485.         and     dl, 0x0C
  486.         jz      .core_block                     ; rightEdge is already tile-aligned
  487.         and     al, 0xF0
  488.         mov     edi, eax                        ; rightEdge Screen origin
  489. .right_edge:
  490.         call    draw_unaligned_edge
  491.         dec     [img_map_x]            
  492. .core_block:
  493.         pop     ebp
  494.         mov     eax, [img_map_x]
  495.         or      eax, eax                        ; empty central core?
  496.         jz      .finish
  497.         mov     edi, [img_lfb_origin]
  498.         mov     esi, [img_buf_origin]
  499.        
  500.         call    draw_aligned_box
  501.        
  502. .finish:
  503.         add     esp, putimg.stack_data
  504. ;       call    [_display.enable_mouse]
  505.         popad
  506.         ret
  507.  
  508. .thin_bar:                                      ; < a special case > :  one-tile-wide image
  509.         mov     edx, [img_pix_x]
  510.         shl     edx, 2                          ; edx = rightmost tile offset (0, 4, 8, or 12 bytes)
  511.         call    draw_unaligned_edge
  512.         jmp     .finish
  513.  
  514.  
  515. align 64
  516. img_test_struct:
  517.         dd      0x00112233, 0x00223344, 0x00334455, 0x00445566
  518.         dd      0x00223344, 0x00334455, 0x00445566, 0x00334455
  519.         dd      0x00334455, 0x00445566, 0x00334455, 0x00223344
  520.         dd      0x00445566, 0x00334455, 0x00223344, 0x00112233
  521.  
  522. ;**************************************************************************************
  523. align 4
  524. __sys_putpixel:
  525. _putpixel:
  526.  
  527. ; eax = x coordinate
  528. ; ebx = y coordinate
  529. ; ecx = ?? RR GG BB    ; 0x01000000 negation
  530. ; edi = 0x00000001 force
  531.  
  532.         cmp   [Screen_Max_X], eax
  533.         jb    .exit0
  534.         cmp   [Screen_Max_Y], ebx
  535.         jb    .exit0
  536. .check_forced:
  537.         test    edi,1            ; force ?
  538.         jnz     .checked
  539.  
  540. .not_forced:
  541.         push    ebx eax
  542.         shr     eax, 1
  543.         shr     eax, 1
  544.         shr     ebx, 1
  545.         imul    ebx, [_WinMapWidth]       ; win_map (X size)/2
  546.         add     ebx, eax
  547.         mov     al, byte [CURRENT_TASK]
  548.         mov     bl, byte [_WinMapAddress+ebx]
  549.         cmp     bl, al
  550.         pop     eax ebx
  551.         jne     .exit0
  552. .checked:
  553.         push    ebx
  554.         imul    ebx, [BytesPerScanLine]
  555.         lea     ebx, [ebx+eax*4]
  556.         bt      ecx, 24
  557.         jnc     .noneg
  558.         mov     ecx, [LFB_BASE+ebx]
  559.         xor     ecx, 0x00FFFFFF
  560. .noneg:
  561.         mov     [LFB_BASE+ebx], ecx
  562.         pop     ebx
  563. .exit0:
  564.      ret
  565.  
  566.  
  567.  
  568. align 4
  569. put_pixel:      ; left for compatibility with Vesa20_putpixel32
  570. ; eax = x
  571. ; ebx = y
  572.      imul    ebx, [BytesPerScanLine]     ; ebx = y * y multiplier
  573.      lea     edi, [ebx+eax*4]  ; edi = x*4+(y*y multiplier)
  574. ;     mov     eax, [esp+32-8+4] ; eax = color
  575.      mov     [LFB_BASE+edi], ecx
  576.      ret
  577.  
  578.  
  579. ; DRAWLINE
  580.  
  581. align 4
  582. __sys_draw_line:
  583.      call    [_display.disable_mouse]
  584.  
  585. ; draw a line
  586. ; eax = HIWORD = x1
  587. ;       LOWORD = x2
  588. ; ebx = HIWORD = y1
  589. ;       LOWORD = y2
  590. ; ecx = color
  591. ; edi = force ?
  592.         pusha
  593.  
  594. dl_x1 equ esp+20
  595. dl_y1 equ esp+16
  596. dl_x2 equ esp+12
  597. dl_y2 equ esp+8
  598. dl_dx equ esp+4
  599. dl_dy equ esp+0
  600.  
  601.      xor     edx, edx      ; clear edx
  602.      xor     esi, esi      ; unpack arguments
  603.      xor     ebp, ebp
  604.      mov     si, ax        ; esi = x2
  605.      mov     bp, bx        ; ebp = y2
  606.      shr     eax, 16       ; eax = x1
  607.      shr     ebx, 16       ; ebx = y1
  608.      push    eax           ; save x1
  609.      push    ebx           ; save y1
  610.      push    esi           ; save x2
  611.      push    ebp           ; save y2
  612.  
  613. ; checking x-axis...
  614.      sub     esi, eax      ; esi = x2-x1
  615.      push    esi           ; save y2-y1
  616.      jl      .x2lx1        ; is x2 less than x1 ?
  617.      jg      .no_vline     ; x1 > x2 ?
  618.      mov     edx, ebp      ; else (if x1=x2)
  619.      call    vline
  620.      push    edx    ; necessary to rightly restore stack frame at .exit
  621.      jmp     .exit
  622. .x2lx1:
  623.      neg     esi            ; get esi absolute value
  624. .no_vline:
  625. ; checking y-axis...
  626.      sub     ebp, ebx       ; ebp = y2-y1
  627.      push    ebp            ; save y2-y1
  628.      jl      .y2ly1         ; is y2 less than y1 ?
  629.      jg      .no_hline      ; y1 > y2 ?
  630.      mov     edx, [dl_x2]   ; else (if y1=y2)
  631.      call    hline
  632.      jmp     .exit
  633.  
  634. .y2ly1:
  635.      neg     ebp            ; get ebp absolute value
  636. .no_hline:
  637.      cmp     ebp, esi
  638.      jle     .x_rules       ; |y2-y1| < |x2-x1|  ?
  639.      cmp     [dl_y2], ebx   ; make sure y1 is at the begining
  640.      jge     .no_reverse1
  641.      neg     dword [dl_dx]
  642.      mov     edx, [dl_x2]
  643.      mov     [dl_x2], eax
  644.      mov     [dl_x1], edx
  645.      mov     edx, [dl_y2]
  646.      mov     [dl_y2], ebx
  647.      mov     [dl_y1], edx
  648. .no_reverse1:
  649.      mov     eax, [dl_dx]
  650.      cdq                    ; extend eax sing to edx
  651.      shl     eax, 16        ; using 16bit fix-point maths
  652.      idiv    ebp            ; eax = ((x2-x1)*65536)/(y2-y1)
  653.      mov     edx, ebp       ; edx = counter (number of pixels to draw)
  654.      mov     ebp, 1 *65536  ; <<16   ; ebp = dy = 1.0
  655.      mov     esi, eax       ; esi = dx
  656.      jmp     .y_rules
  657.  
  658. .x_rules:
  659.      cmp     [dl_x2], eax    ; make sure x1 is at the begining
  660.      jge     .no_reverse2
  661.      neg     dword [dl_dy]
  662.      mov     edx, [dl_x2]
  663.      mov     [dl_x2], eax
  664.      mov     [dl_x1], edx
  665.      mov     edx, [dl_y2]
  666.      mov     [dl_y2], ebx
  667.      mov     [dl_y1], edx
  668. .no_reverse2:
  669.      xor     edx, edx
  670.      mov     eax, [dl_dy]
  671.      cdq                    ; extend eax sing to edx
  672.      shl     eax, 16        ; using 16bit fix-point maths
  673.      idiv    esi            ; eax = ((y2-y1)*65536)/(x2-x1)
  674.      mov     edx, esi       ; edx = counter (number of pixels to draw)
  675.      mov     esi, 1 *65536  ;<< 16   ; esi = dx = 1.0
  676.      mov     ebp, eax       ; ebp = dy
  677. .y_rules:
  678.      mov     eax, [dl_x1]
  679.      mov     ebx, [dl_y1]
  680.      shl     eax, 16
  681.      shl     ebx, 16
  682. align 4
  683. .draw:
  684.      push    eax ebx
  685.      shr     eax, 16
  686.      shr     ebx, 16
  687.      call    _putpixel
  688.      pop     ebx eax
  689.      add     ebx, ebp        ; y = y+dy
  690.      add     eax, esi        ; x = x+dx
  691.      dec     edx
  692.      jnz     .draw
  693. ; force last drawn pixel to be at (x2,y2)
  694.      mov     eax, [dl_x2]
  695.      mov     ebx, [dl_y2]
  696.      call    _putpixel
  697. .exit:
  698.      add     esp, 6*4
  699.      popa
  700.      call   [draw_pointer]      ; mouse
  701.      ret
  702.  
  703. align 4
  704. hline:
  705. ; ------------  draw a horizontal line -------------
  706. ; eax = x1
  707. ; edx = x2
  708. ; ebx = y
  709. ; ecx = color
  710. ; edi = force ?
  711.      cmp     ebx, [Screen_Max_Y]
  712.      jge     .out
  713.      pushad
  714.  
  715.      bt      ecx, 24                    ; color inversion check
  716.      rcl     edi,1                      ; forced graphics check
  717.  
  718.      mov     ebp, ebx
  719.      shr     ebp, 1
  720.      imul    ebp, [_WinMapWidth]        ; ebp = screen map base
  721.      add     ebp, [_WinMapAddress]
  722.  
  723.      cmp     edx, eax                   ; to make sure x2 > x1
  724.      jge     @f
  725.      xchg    eax, edx
  726. @@:
  727.      cmp     eax, [Screen_Max_X]
  728.      jge     .exit
  729.  
  730.      mov     esi, eax
  731.      shr     esi, 4
  732.      add     ebp, esi                   ; ebp -> win_map element
  733.  
  734.      imul    ebx, [BytesPerScanLine]    ; ebx -> LFB pix_line
  735.      add     ebx, LFB_BASE
  736.  
  737.      cmp     edx, [Screen_Max_X]        ; last check
  738.      jb      @f
  739.      mov     edx, [Screen_Max_X]
  740.  
  741. @@:  mov     esi, ecx                   ; store color here
  742.      mov     cl, byte [CURRENT_TASK]    ;
  743.      mov     ch, cl
  744.      mov     [CURRENT_TASK+2], cx
  745.      mov     [CURRENT_TASK+1], cl       ; replicate byte to dword
  746.  
  747. .newsegment:
  748.      mov     ecx, [ebp]                 ; check the line segment (16 pixels!)
  749.      xor     ecx, [CURRENT_TASK]
  750. ; -- the line ---
  751.      jmp     dword [hline.drawtable + edi*4]    ; a coolhack (C) Serge
  752.  
  753.  
  754. align 4                                 ; internal loop
  755. .invert_color:
  756.      mov     esi, [ebx+eax*4]
  757.      xor     esi, 0x00FFFFFF
  758. align 4
  759. .check_overlap:
  760.      or      cl, cl
  761.      jz      .putpixel
  762.      jmp     .nextpixel
  763. align 4
  764. .invert_force:
  765.      mov     esi, [ebx+eax*4]
  766.      xor     esi, 0x00FFFFFF
  767. align 4
  768. .putpixel:
  769.      mov     [ebx+eax*4], esi
  770. align 4
  771. .nextpixel:
  772.      inc     eax
  773.      cmp     eax, edx
  774.      ja      .exit                              ; line drawn -- exit all loops
  775.      test    al, 3
  776.      jz     .newtile
  777. .newpixel:
  778.      jmp     dword [hline.drawtable + edi*4]    ; the internal loop
  779. .newtile:
  780.      inc     ebp
  781.      test    ebp, 3
  782.      jz     .newsegment                         ; the external loop
  783.      shr     ecx, 8
  784.      jmp     dword [hline.drawtable + edi*4]
  785.  
  786. .exit:
  787.      mov    eax, 0x0FF
  788.      and    [CURRENT_TASK], eax
  789.      popad
  790. .out:
  791.      ret
  792. align 4
  793. .drawtable:
  794. dd      .check_overlap  ; general case
  795. dd      .invert_color
  796. dd      .putpixel       ; force to draw it
  797. dd      .invert_force
  798.  
  799.  
  800. align 4
  801. vline:
  802. ; ---------  draw a vertical line  ------------
  803. ; eax = x
  804. ; ebx = y1
  805. ; edx = y2
  806. ; ecx = color
  807. ; edi = force ?
  808.      cmp     eax, [Screen_Max_X]
  809.      jge     .out
  810.      pushad
  811.      bt      ecx, 24                    ; color inversion check
  812.      rcl     edi, 1                     ; forced graphics check
  813.  
  814.      cmp     edx, ebx                   ; to make sure y2 > y1
  815.      jge     @f
  816.      xchg    ebx, edx
  817. @@:
  818.      cmp     ebx, [Screen_Max_Y]
  819.      jge     .exit
  820.      mov     ebp, ebx
  821.      shr     ebp, 1
  822.      imul    ebp, [_WinMapWidth]
  823.      add     ebp, [_WinMapAddress]
  824.      mov     esi, eax
  825.      shr     esi, 1
  826.      shr     esi, 1
  827.      add     ebp, esi                   ; ebp = screen map at (x, y1)
  828.      push    ebx
  829.  
  830.      imul    ebx, [BytesPerScanLine]
  831.      shl     eax, 1
  832.      shl     eax, 1
  833.      add     eax, ebx
  834.      add     eax, LFB_BASE
  835.      pop     ebx                        ; restore ebx = y1
  836.      cmp     edx, [Screen_Max_Y]        ; the last check
  837.      jb     .draw
  838.      mov     edx, [Screen_Max_Y]        ; to prevent off-screen drawing
  839.  
  840. .draw:
  841.      jmp     dword [vline.drawtable + edi*4]
  842. align 4
  843. .invert_color:
  844.      mov     ecx, [eax]
  845.      xor     ecx, 0x00FFFFFF
  846. align 4
  847. .check_overlap:
  848.      movzx   esi, byte [ebp]
  849.      cmp     esi, [CURRENT_TASK]
  850.      je      .putpixel
  851.      jmp     .nextpixel
  852.  
  853. align 4
  854. .invert_force:
  855.      mov     ecx, [eax]
  856.      xor     ecx, 0x00FFFFFF
  857. align 4
  858. .putpixel:
  859.      mov     [eax], ecx
  860. align 4
  861. .nextpixel:
  862.      add     eax, [BytesPerScanLine]
  863.      inc     ebx
  864.      test    bl, 1
  865.      jnz     @f
  866.      add     ebp, [_WinMapWidth]       
  867. @@:    
  868.      cmp     ebx, edx
  869.      ja     .exit
  870.      jmp     dword [vline.drawtable + edi*4]
  871. .exit:
  872.      shr     edi, 1
  873.      popad
  874.  
  875. .out:
  876.      ret
  877. align 4
  878. .drawtable:
  879. dd      .check_overlap  ; general case
  880. dd      .invert_color
  881. dd      .putpixel       ; force to draw it
  882. dd      .invert_force
  883.  
  884.  
  885. ;*************************************************
  886.  
  887.  
  888. virtual at esp
  889. drbar:
  890.      .bar_sx       dd ?
  891.      .bar_sy       dd ?
  892.      .bar_cx       dd ?
  893.      .bar_cy       dd ?
  894.      .abs_cx       dd ?
  895.      .abs_cy       dd ?
  896.      .real_sx      dd ?
  897.      .real_sy      dd ?
  898.      .color        dd ?
  899.      .line_inc_scr dd ?
  900.      .line_inc_map dd ?
  901.      .stack_data = 4*11
  902. end virtual
  903.  
  904. align 4
  905. ; eax   cx
  906. ; ebx   cy
  907. ; ecx   xe
  908. ; edx   ye
  909. ; edi   color
  910. vesa20_drawbar:
  911.      pushad
  912.      call    [_display.disable_mouse]
  913.      sub     esp, drbar.stack_data
  914.      mov     [drbar.color], edi
  915.      sub     edx, ebx
  916.      jle     .exit
  917.      sub     ecx, eax
  918.      jle     .exit
  919.      mov     [drbar.bar_sy], edx
  920.      mov     [drbar.bar_sx], ecx
  921.      mov     [drbar.bar_cx], eax
  922.      mov     [drbar.bar_cy], ebx
  923.      mov     edi, [TASK_BASE]
  924.      add     eax, [edi-twdw + WDATA.box.left] ; win_cx
  925.      add     ebx, [edi-twdw + WDATA.box.top] ; win_cy
  926.      mov     [drbar.abs_cx], eax
  927.      mov     [drbar.abs_cy], ebx
  928. ; real_sx = MIN(wnd_sx-bar_cx, bar_sx);
  929.      mov     ebx, [edi-twdw + WDATA.box.width] ; ebx = wnd_sx
  930. ; note that WDATA.box.width is one pixel less than real window x-size
  931.      inc     ebx
  932.      sub     ebx, [drbar.bar_cx]
  933.      ja      @f
  934. .exit:
  935.      add     esp, drbar.stack_data
  936.      popad
  937.      xor     eax, eax
  938.      inc     eax
  939.      ret
  940. @@:
  941.      cmp     ebx, [drbar.bar_sx]
  942.      jbe     .end_x
  943.      mov     ebx, [drbar.bar_sx]
  944. .end_x:
  945.      mov     [drbar.real_sx], ebx
  946. ; real_sy = MIN(wnd_sy-bar_cy, bar_sy);
  947.      mov     ebx, [edi-twdw + WDATA.box.height] ; ebx = wnd_sy
  948.      inc     ebx
  949.      sub     ebx, [drbar.bar_cy]
  950.      ja      @f
  951.      add     esp, drbar.stack_data
  952.      popad
  953.      xor     eax, eax
  954.      inc     eax
  955.      ret
  956. @@:
  957.      cmp     ebx, [drbar.bar_sy]
  958.      jbe     .end_y
  959.      mov     ebx, [drbar.bar_sy]
  960. .end_y:
  961.      mov     [drbar.real_sy], ebx
  962. ; line_inc_map
  963.      mov     eax, [Screen_Max_X]
  964.      sub     eax, [drbar.real_sx]
  965.      inc     eax
  966.      shr     eax, 1                     ; <<<<<<
  967.      shr     eax, 1
  968.      mov     [drbar.line_inc_map], eax  ; vertical increment: map
  969. ; line_inc_scr
  970.      mov     eax, [drbar.real_sx]
  971.      shl     eax, 1
  972.      shl     eax, 1
  973.      neg     eax
  974.      add     eax, [BytesPerScanLine]
  975.      mov     [drbar.line_inc_scr], eax  ; vertical increment: screen
  976. ; pointer to screen
  977.      mov     edx, [drbar.abs_cy]
  978.      mov     ebx, edx
  979.      imul    edx, [BytesPerScanLine]    ; edx = LFB line offset
  980.      mov     eax, [drbar.abs_cx]
  981.      shl     eax, 1
  982.      shl     eax, 1
  983.      add     edx, eax                   ; edx = LFB corner offset
  984. ; pointer to pixel map
  985.      shr     ebx, 1
  986.      imul    ebx, [_WinMapWidth]        ; eax = Wmap corner pos
  987.      mov     eax, [drbar.abs_cx]
  988.      shr     eax, 1
  989.      shr     eax, 1
  990.      add     eax, ebx
  991.      add     eax, [_WinMapAddress]
  992.      xchg    eax, ebp                   ; ebp = Wmap corner
  993. ; get process number
  994.      mov     ebx, [CURRENT_TASK]
  995.  
  996. ; eax - RGB-color  
  997. ; bl - process num
  998. ; ecx - pix counter (in a tile)
  999. ; edx - pointer to screen
  1000. ; esi - counter
  1001. ; edi - counter
  1002.  
  1003.         mov     eax, [drbar.color]    ;; BBGGRR00
  1004.         mov     esi, 0
  1005. align   4
  1006. .new_y:
  1007.         mov     edi, [drbar.real_sx]
  1008.         movzx   ecx, dl
  1009.         shr     cl, 2           ; pix# = edx/4
  1010.         and     cl, 3           ; pix position in a tile
  1011. .new_tile:
  1012.         cmp     byte [ebp], bl
  1013.         jne     .skip
  1014. .new_x:
  1015.         mov     [LFB_BASE+edx], eax
  1016.         add     edx, 4
  1017.         dec     edi
  1018.         jz      .add_line
  1019.         inc     cl
  1020.         and     cl, 3
  1021.         jnz     .new_x
  1022.         jmp     .new_tile      
  1023. .skip:
  1024.         add     edx, 4*4
  1025.         and     dl, 0xF0        ; LFB align 16
  1026.         inc     ebp
  1027.         sub     edi, 4          ; <<<<<
  1028.         add     edi, ecx        ; left tile may be 1,2 or 3px only
  1029.         jae     .new_tile
  1030.  
  1031. .add_line:
  1032.         add     edx, [drbar.line_inc_scr]
  1033. ; gradient-filled bars
  1034.      test    eax, 0x80000000
  1035.      jz      @f
  1036.      test    al, al
  1037.      jz      @f
  1038.      dec     al
  1039. @@:
  1040.         inc     esi
  1041.         test    esi, 1
  1042.         jne     @f
  1043.         add     ebp, [drbar.line_inc_map]
  1044. @@:    
  1045.         cmp     esi, [drbar.real_sy]
  1046.         jbe     .new_y
  1047.         add     esp, drbar.stack_data
  1048.         popad
  1049.         xor     eax, eax
  1050.      ret
  1051.  
  1052.  
  1053. align 4
  1054. ;drawbackground:
  1055.         call    [_display.disable_mouse]
  1056.         pushad
  1057. ; External loop for all y from start to end
  1058.         mov     ebx, [draw_data+32+RECT.top]    ; y start
  1059. .fill_line:
  1060.         mov     edi, [draw_data+32+RECT.left]   ; x start
  1061.         shl     edi, 1
  1062.         shl     edi, 1
  1063.         mov     eax, [BytesPerScanLine]
  1064.         mul     ebx
  1065.         xchg    edi, eax
  1066.         add     edi, eax
  1067.         add     edi, LFB_BASE
  1068.  
  1069.         mov     ebp, ebx
  1070.         shr     ebp, 1
  1071.         imul    ebp, [_WinMapWidth]
  1072.         mov     edx, eax
  1073.         shr     edx, 1
  1074.         shr     edx, 1
  1075.         add     ebp, edx
  1076.         add     ebp, [_WinMapAddress]
  1077.         xor     edx, edx
  1078.         inc     edx
  1079.         mov     esi, 0x0336677          ; <<< RGB
  1080. ; eax = x, ebx = y (screen coordinates)
  1081. ; ecx - aux. var
  1082. ; edx = 1
  1083. ; esi = 0RGB, edi -> output
  1084. ; ebp = offset in WinMapAddress
  1085. .fill_tile:
  1086.         cmp     [ebp], dl
  1087.         jnz     .next_tile
  1088.         mov     [edi],   esi
  1089.         mov     [edi+4], esi
  1090.         mov     [edi+8], esi
  1091.         mov     [edi+12],esi
  1092.         mov     ecx, [BytesPerScanLine]
  1093.         mov     [ecx+edi],   esi
  1094.         mov     [ecx+edi+4], esi
  1095.         mov     [ecx+edi+8], esi
  1096.         mov     [ecx+edi+12],esi
  1097. .next_tile:
  1098.         add     edi, 4*4
  1099.         add     ebp, edx
  1100.         add     ax, 4
  1101.         mov     ecx, [draw_data+32+RECT.right]
  1102.         shr     ecx, 1
  1103.         shr     ecx, 1
  1104.         cmp     eax, ecx
  1105.         jbe     .fill_tile
  1106.  
  1107. .next_line:
  1108.         inc     ebx
  1109.         mov     ecx, [draw_data+32+RECT.bottom]
  1110.         shr     ecx, 1
  1111.         jbe     .fill_line
  1112.         popad
  1113.         ret
  1114.  
  1115. ; ----------
  1116.  
  1117.  
  1118. drawbackground_stretch:         ; left for future development
  1119.         call    drawbackground
  1120.         ret
  1121. drawbackground_tiled:           ; left for future development
  1122.         call    drawbackground
  1123.         ret
  1124.  
  1125. uglobal
  1126. align 4
  1127. bgr_cur_line    rd      1920    ; maximum width of screen
  1128. bgr_next_line   rd      1920
  1129. endg
  1130.  
  1131. smooth_line:
  1132.         mov     al, [esi+2]
  1133.         shl     eax, 16
  1134.         mov     ax, [esi]
  1135.         test    ecx, ecx
  1136.         jz      @f
  1137.         mov     ebx, [esi+2]
  1138.         shr     ebx, 8
  1139.         call    [overlapping_of_points_ptr]
  1140. @@:
  1141.         stosd
  1142.         mov     eax, [esp+20+8]
  1143.         inc     eax
  1144.         mov     [esp+20+8], eax
  1145.         cmp     eax, [draw_data+32+RECT.right]
  1146.         ja      @f
  1147.         add     ecx, [esp+36+8]
  1148.         mov     eax, edx
  1149.         adc     edx, [esp+40+8]
  1150.         sub     eax, edx
  1151.         lea     eax, [eax*3]
  1152.         sub     esi, eax
  1153.         jmp     smooth_line
  1154. @@:
  1155.         mov     eax, [draw_data+32+RECT.left]
  1156.         mov     [esp+20+8], eax
  1157.         ret
  1158.  
  1159. align 16
  1160. overlapping_of_points:
  1161.         push    ecx edx
  1162.         mov     edx, eax
  1163.         push    esi
  1164.         shr     ecx, 26
  1165.         mov     esi, ecx
  1166.         mov     ecx, ebx
  1167.         shl     esi, 9
  1168.         movzx   ebx, dl
  1169.         movzx   eax, cl
  1170.         sub     eax, ebx
  1171.         movzx   ebx, dh
  1172.         add     dl, [BgrAuxTable+(eax+0x100)+esi]
  1173.         movzx   eax, ch
  1174.         sub     eax, ebx
  1175.         add     dh, [BgrAuxTable+(eax+0x100)+esi]
  1176.         ror     ecx, 16
  1177.         ror     edx, 16
  1178.         movzx   eax, cl
  1179.         movzx   ebx, dl
  1180.         sub     eax, ebx
  1181.         add     dl, [BgrAuxTable+(eax+0x100)+esi]
  1182.         pop     esi
  1183.         mov     eax, edx
  1184.         pop     edx
  1185.         ror     eax, 16
  1186.         pop     ecx
  1187.         ret
  1188.  
  1189. iglobal
  1190. align 4
  1191. overlapping_of_points_ptr       dd      overlapping_of_points
  1192. endg
  1193.  
  1194. init_background:
  1195.         mov     edi, BgrAuxTable
  1196.         xor     edx, edx
  1197. .loop2:
  1198.         mov     eax, edx
  1199.         shl     eax, 8
  1200.         neg     eax
  1201.         mov     ecx, 0x200
  1202. .loop1:
  1203.         mov     byte [edi], ah
  1204.         inc     edi
  1205.         add     eax, edx
  1206.         loop    .loop1
  1207.         add     dl, 4
  1208.         jnz     .loop2
  1209.         test    byte [cpu_caps+(CAPS_MMX/8)], 1 shl (CAPS_MMX mod 8)
  1210.         jz      @f
  1211.         mov     [overlapping_of_points_ptr], overlapping_of_points_mmx
  1212. @@:
  1213.         ret
  1214.  
  1215. align 16
  1216. overlapping_of_points_mmx:
  1217.         movd    mm0, eax
  1218.         movd    mm4, eax
  1219.         movd    mm1, ebx
  1220.         pxor    mm2, mm2
  1221.         punpcklbw mm0, mm2
  1222.         punpcklbw mm1, mm2
  1223.         psubw   mm1, mm0
  1224.         movd    mm3, ecx
  1225.         psrld   mm3, 24
  1226.         packuswb mm3, mm3
  1227.         packuswb mm3, mm3
  1228.         pmullw  mm1, mm3
  1229.         psrlw   mm1, 8
  1230.         packuswb mm1, mm2
  1231.         paddb   mm4, mm1
  1232.         movd    eax, mm4
  1233.         ret
  1234. diff16 "GRAPH32 code end ",0,$
  1235. diff10 "GRAPH32 code size",get_pixel,$
  1236.  
  1237.  
  1238.