Subversion Repositories Kolibri OS

Rev

Rev 1859 | 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.         je      .new_tile
  55.         bts     ebx, 26                         ; ebx[26] = 1 if edi/esi pushed
  56.         push    edi
  57.         push    esi
  58.         push    [img_bitoffset]
  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]  
  65.         je      .new_tile
  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)
  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
  83.         add     edi, ecx                        ; shift the left edge
  84.         bt      ebx, 25                         ; 1bpp?
  85.         jc      @f
  86.         shr     ecx, 2
  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:
  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
  105.         pop     [img_bitoffset]
  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
  135.         btr     ebx, 24                 ; check if the 1st line odd
  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
  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
  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:
  203.         movzx   edx, bh
  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
  214.         cmp     dl, bh
  215.         je      .exit
  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
  231.         cmp     dl, bh
  232.         je      .exit
  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:
  241.         pushad
  242.         movzx   edx, bh
  243.         add     edx, edi
  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
  248.         mov     eax, [esi]    
  249. .testbit:
  250.         test    eax, ecx
  251.         jnz     @f
  252.         mov     eax, ebp
  253.         jmp     .putpix
  254. @@:     mov     eax, ebx
  255. .putpix:
  256.         mov     [edi], eax
  257.         cmp     edi, edx
  258.         je      .exit
  259.         add     edi, 4
  260.         rol     ecx, 1
  261.         jmp     .testbit
  262. .exit:
  263.         popad
  264.         ret
  265.  
  266. draw_edge_16bpp:
  267. draw_core_16bpp:
  268.         ret
  269.  
  270. ;-------------
  271. ; aligned core helpers
  272. ; esi -> left point address (buffer)
  273. ; edi -> left point address (screen)
  274. ; ecx =  number of tiles to draw
  275. align 4
  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
  288. draw_core_32bpp:
  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
  297.         ret
  298. align 4
  299. draw_core_24bpp:
  300.         push    eax ecx edx
  301.         shl     ecx, 2                  ; ecx = numpixels
  302.         dec     ecx
  303.         lea     edx, [ecx*2+ecx]        ; edx = buffer byte offset
  304. .putpix:
  305.         mov     eax, [esi+edx]
  306.         and     eax, 0x00FFFFFF
  307.         mov     [edi+ecx*4], eax
  308.         dec     ecx
  309.         sub     edx, 3
  310.         jnb     .putpix
  311.         pop     edx ecx eax
  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
  330.         dec     ecx
  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:
  353.         dec     ecx
  354.         jz      .exit  
  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]
  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)
  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:
  399.         mov     edi, [TASK_BASE]
  400.         mov     ebx, [edi-twdw + WDATA.box.left]
  401.         mov     ecx, [edi-twdw + WDATA.box.top]
  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:
  407.         mov     ebx, [edi-twdw + WDATA.box.width]
  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:
  418.         mov     ebx, [edi-twdw + WDATA.box.height]
  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
  440.         mov     ecx, [img_buf_line_size]
  441.         or      cl, cl
  442.         je      @f
  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]
  454.         inc     eax
  455.         shr     eax, 2
  456.         add     eax, ebp       
  457. ;        mov     [img_map_right], eax           ; right edge tile
  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 #
  470. ; ebx[24] = 1 if Ytop is odd
  471. ; ebx[25] = 1 if 1bpp image
  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
  482.         mov     dh, 0x0C
  483.         and     dl, dh      
  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)
  529.         shl     edx, 4
  530.         add     edi, edx                        ; rightEdge Screen origin
  531.         movzx   edx, al
  532.         mov     eax, [img_map_x]
  533.         and     dl, 0x0C
  534.         cmp     dl, 0x0C
  535.         je      .core_block                     ; rightEdge is already tile-aligned
  536. .right_edge:
  537.         call    draw_unaligned_edge
  538. .core_block:
  539.         or      eax, eax                        ; empty central core?
  540.         jz      .finish            
  541.         mov     ebp, [esp]
  542.         mov     edi, [img_lfb_origin]
  543.         mov     esi, [img_buf_origin]
  544.        
  545.         call    draw_aligned_box
  546.        
  547. .finish:
  548.         add     esp, (putimg.stack_data + 4)
  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
  557.         add     esp, putimg.stack_data
  558.         popad
  559.         ret
  560.  
  561.  
  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
  574.  
  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.  
  624. ;**************************************************************************************
  625. align 4
  626. __sys_putpixel:
  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
  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
  649.         shr     eax, 2
  650.         shr     ebx, 1
  651.         imul    ebx, [_WinMapWidth]       ; win_map (X size)/2
  652.         add     ebx, eax
  653.         mov     al, byte [CURRENT_TASK]
  654.         mov     ah, byte [_WinMapAddress+ebx]
  655.         cmp     ah, al
  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.  
  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
  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 ---
  857.      jmp     dword [hline.drawtable + edi*4]    ; (C) Serge, 2010
  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
  996. ; eax   xOrigin
  997. ; ebx   yOrigin
  998. ; ecx   xSize
  999. ; edx   ySize
  1000. ; edi   color
  1001.  
  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    
  1015.  
  1016.         jmp     _putimage.calculate_abs_coords
  1017. ;       ret
  1018.  
  1019.  
  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]
  1028.         shr     edx, 1
  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
  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.  
  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
  1090.         ret
  1091.  
  1092.  
  1093. diff16 "GRAPH32 code end ",0,$
  1094. diff10 "GRAPH32 code size",get_pixel,$
  1095.  
  1096.  
  1097.