Subversion Repositories Kolibri OS

Rev

Rev 1664 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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