Subversion Repositories Kolibri OS

Rev

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

  1.  
  2. LOAD_FROM_FILE  equ 0
  3. LOAD_FROM_MEM   equ 1
  4. LOAD_INDIRECT   equ 2
  5. LOAD_SYSTEM     equ 3
  6. VIDEO_FREE      equ 2
  7.  
  8. struc BITMAPINFOHEADER {
  9.   .biSize          dd ? ; DWORD
  10.   .biWidth         dd ? ; LONG
  11.   .biHeight        dd ? ; LONG
  12.   .biPlanes        dw ? ; WORD
  13.   .biBitCount      dw ? ; WORD
  14.   .biCompression   dd ? ; DWORD
  15.   .biSizeImage     dd ? ; DWORD
  16.   .biXPelsPerMeter dd ? ; LONG
  17.   .biYPelsPerMeter dd ? ; LONG
  18.   .biClrUsed       dd ? ; DWORD
  19.   .biClrImportant  dd ? ; DWORD
  20. }
  21.  
  22. virtual at 0
  23.   BI BITMAPINFOHEADER
  24. end virtual
  25.  
  26. align 4
  27. proc vesa_init_cursor stdcall, dst:dword, src:dword
  28.            locals
  29.              rBase    dd ?
  30.              pQuad    dd ?
  31.              pBits    dd ?
  32.              pAnd     dd ?
  33.              width    dd ?
  34.              height   dd ?
  35.              counter  dd ?
  36.            endl
  37.  
  38.            mov esi, [src]
  39.            add esi,[esi+18]
  40.            mov eax,esi
  41.  
  42.            cmp [esi+BI.biBitCount], 24
  43.            je .img_24
  44.            cmp [esi+BI.biBitCount], 8
  45.            je .img_8
  46.            cmp [esi+BI.biBitCount], 4
  47.            je .img_4
  48.  
  49. .img_2:
  50.            add eax, [esi]
  51.            mov [pQuad],eax
  52.            add eax,8
  53.            mov [pBits],eax
  54.            add eax, 128
  55.            mov [pAnd],eax
  56.            mov eax,[esi+4]
  57.            mov [width],eax
  58.            mov ebx,[esi+8]
  59.            shr ebx,1
  60.            mov [height],ebx
  61.  
  62.            mov edi, [dst]
  63.            add edi, 32*31*4
  64.            mov [rBase],edi
  65.  
  66.            mov esi,[pQuad]
  67. .l21:
  68.            mov ebx, [pBits]
  69.            mov ebx, [ebx]
  70.            bswap ebx
  71.            mov eax, [pAnd]
  72.            mov eax, [eax]
  73.            bswap eax
  74.            mov [counter], 32
  75. @@:
  76.            xor edx, edx
  77.            shl eax,1
  78.            setc dl
  79.            dec edx
  80.  
  81.            xor ecx, ecx
  82.            shl ebx,1
  83.            setc cl
  84.            mov ecx, [esi+ecx*4]
  85.            and ecx, edx
  86.            and edx, 0xFF000000
  87.            or edx, ecx
  88.            mov [edi], edx
  89.  
  90.            add edi, 4
  91.            dec [counter]
  92.            jnz @B
  93.  
  94.            add [pBits], 4
  95.            add [pAnd], 4
  96.            mov edi,[rBase]
  97.            sub edi,128
  98.            mov [rBase],edi
  99.            sub [height],1
  100.            jnz .l21
  101.            ret
  102.  
  103. .img_4:
  104.            add eax, [esi]
  105.            mov [pQuad],eax
  106.            add eax,64
  107.            mov [pBits],eax
  108.            add eax, 0x200
  109.            mov [pAnd],eax
  110.            mov eax,[esi+4]
  111.            mov [width],eax
  112.            mov ebx,[esi+8]
  113.            shr ebx,1
  114.            mov [height],ebx
  115.  
  116.            mov edi, [dst]
  117.            add edi, 32*31*4
  118.            mov [rBase],edi
  119.  
  120.            mov esi,[pQuad]
  121.            mov ebx, [pBits]
  122. .l4:
  123.            mov eax, [pAnd]
  124.            mov eax, [eax]
  125.            bswap eax
  126.            mov [counter], 16
  127. @@:
  128.            xor edx, edx
  129.            shl eax,1
  130.            setc dl
  131.            dec edx
  132.  
  133.            movzx ecx, byte [ebx]
  134.            and cl, 0xF0
  135.            shr ecx, 2
  136.            mov ecx, [esi+ecx]
  137.            and ecx, edx
  138.            and edx, 0xFF000000
  139.            or edx, ecx
  140.            mov [edi], edx
  141.  
  142.            xor edx, edx
  143.            shl eax,1
  144.            setc dl
  145.            dec edx
  146.  
  147.            movzx ecx, byte [ebx]
  148.            and cl, 0x0F
  149.            mov ecx, [esi+ecx*4]
  150.            and ecx, edx
  151.            and edx, 0xFF000000
  152.            or edx, ecx
  153.            mov [edi+4], edx
  154.  
  155.            inc ebx
  156.            add edi, 8
  157.            dec [counter]
  158.            jnz @B
  159.  
  160.            add [pAnd], 4
  161.            mov edi,[rBase]
  162.            sub edi,128
  163.            mov [rBase],edi
  164.            sub [height],1
  165.            jnz .l4
  166.            ret
  167. .img_8:
  168.            add eax, [esi]
  169.            mov [pQuad],eax
  170.            add eax,1024
  171.            mov [pBits],eax
  172.            add eax, 1024
  173.            mov [pAnd],eax
  174.            mov eax,[esi+4]
  175.            mov [width],eax
  176.            mov ebx,[esi+8]
  177.            shr ebx,1
  178.            mov [height],ebx
  179.  
  180.            mov edi, [dst]
  181.            add edi, 32*31*4
  182.            mov [rBase],edi
  183.  
  184.            mov esi,[pQuad]
  185.            mov ebx, [pBits]
  186. .l81:
  187.            mov eax, [pAnd]
  188.            mov eax, [eax]
  189.            bswap eax
  190.            mov [counter], 32
  191. @@:
  192.            xor edx, edx
  193.            shl eax,1
  194.            setc dl
  195.            dec edx
  196.  
  197.            movzx ecx,  byte [ebx]
  198.            mov ecx, [esi+ecx*4]
  199.            and ecx, edx
  200.            and edx, 0xFF000000
  201.            or edx, ecx
  202.            mov [edi], edx
  203.  
  204.            inc ebx
  205.            add edi, 4
  206.            dec [counter]
  207.            jnz @B
  208.  
  209.            add [pAnd], 4
  210.            mov edi,[rBase]
  211.            sub edi,128
  212.            mov [rBase],edi
  213.            sub [height],1
  214.            jnz .l81
  215.            ret
  216. .img_24:
  217.            add eax, [esi]
  218.            mov [pQuad],eax
  219.            add eax, 0xC00
  220.            mov [pAnd],eax
  221.            mov eax,[esi+BI.biWidth]
  222.            mov [width],eax
  223.            mov ebx,[esi+BI.biHeight]
  224.            shr ebx,1
  225.            mov [height],ebx
  226.  
  227.            mov edi, [dst]
  228.            add edi, 32*31*4
  229.            mov [rBase],edi
  230.  
  231.            mov esi,[pAnd]
  232.            mov ebx, [pQuad]
  233. .row_24:
  234.            mov eax, [esi]
  235.            bswap eax
  236.            mov [counter], 32
  237. @@:
  238.            xor edx, edx
  239.            shl eax,1
  240.            setc dl
  241.            dec edx
  242.  
  243.            mov ecx, [ebx]
  244.            and ecx, 0x00FFFFFF
  245.            and ecx, edx
  246.            and edx, 0xFF000000
  247.            or edx, ecx
  248.            mov [edi], edx
  249.            add ebx, 3
  250.            add edi, 4
  251.            dec [counter]
  252.            jnz @B
  253.  
  254.            add esi, 4
  255.            mov edi,[rBase]
  256.            sub edi,128
  257.            mov [rBase],edi
  258.            sub [height],1
  259.            jnz .row_24
  260.            ret
  261. endp
  262.  
  263. align 4
  264. alloc_cursor:
  265.  
  266.            mov eax, CURSOR_SIZE
  267.            call malloc
  268.            test eax, eax
  269.            jz .fail
  270.  
  271.            xor ebx, ebx
  272.            mov [eax+CURSOR.magic], 'CURS'
  273.            mov [eax+CURSOR.size],  CURSOR_SIZE
  274.            mov [eax+CURSOR.pid], ebx
  275.            mov [eax+CURSOR.hot_x], ebx
  276.            mov [eax+CURSOR.hot_y], ebx
  277. .fail:
  278.            ret
  279.  
  280. if 0
  281.  
  282. align 4
  283. proc alloc_cursor
  284.  
  285.            pushfd
  286.            cli
  287.            mov ebx, [cursor_start]
  288.            mov ecx, [cursor_end]
  289. .l1:
  290.            bsf eax,[ebx];
  291.            jnz .found
  292.            add ebx,4
  293.            cmp ebx, ecx
  294.            jb .l1
  295.            popfd
  296.            xor eax,eax
  297.            ret
  298. .found:
  299.            btr [ebx], eax
  300.            popfd
  301.  
  302.            mov [cursor_start],ebx
  303.            sub ebx, cursor_map
  304.            lea eax,[eax+ebx*8]
  305.            shl eax,3
  306.            lea eax,[cursors+eax+eax*2]
  307.  
  308.            xor ebx, ebx
  309.            mov [eax+CURSOR.magic], 'CURS'
  310.            mov [eax+CURSOR.size],  CURSOR_SIZE
  311.            mov [eax+CURSOR.pid], ebx
  312.            mov [eax+CURSOR.hot_x], ebx
  313.            mov [eax+CURSOR.hot_y], ebx
  314.            ret
  315. endp
  316.  
  317.  
  318. align 4
  319. proc free_cursor
  320.            pushfd
  321.            cli
  322.            xor edx, edx
  323.            mov ecx, CURSOR_SIZE
  324.            sub eax, cursors
  325.            div ecx
  326.            test edx, edx
  327.            jnz .exit
  328.  
  329.            mov ebx, cursor_map
  330.            bts [ebx], eax
  331.            shr eax, 3
  332.            and eax, not 3
  333.            add eax, ebx
  334.            cmp [cursor_start], eax
  335.            ja @f
  336. .exit:
  337.            popfd
  338.            ret
  339. @@:
  340.            mov [cursor_start], eax
  341.            popfd
  342.            ret
  343. endp
  344.  
  345. end if
  346.  
  347. align 4
  348. proc set_cursor stdcall, hcursor:dword
  349.            mov eax, [hcursor]
  350.            cmp [eax+CURSOR.magic], 'CURS'
  351.            jne .fail
  352.            cmp [eax+CURSOR.size], CURSOR_SIZE
  353.            jne .fail
  354.            mov ebx, [CURRENT_TASK]
  355.            shl ebx, 8
  356.            xchg eax, [ebx+PROC_BASE+APPDATA.cursor]
  357.            ret
  358. .fail:
  359.            mov eax, [def_cursor]
  360.            mov ebx, [CURRENT_TASK]
  361.            shl ebx, 8
  362.            xchg eax, [ebx+PROC_BASE+APPDATA.cursor]
  363.            ret
  364. endp
  365.  
  366. proc vesa_cursor stdcall, hcursor:dword, src:dword, flags:dword
  367.  
  368.            stdcall kernel_alloc, 0x1000
  369.            test eax, eax
  370.            jz .fail
  371.  
  372.            mov edi, [hcursor]
  373.            mov [edi+CURSOR.base], eax
  374.  
  375.            mov esi, [src]
  376.            mov ebx, [flags]
  377.            cmp bx, LOAD_INDIRECT
  378.            je .indirect
  379.  
  380.            movzx ecx, word [esi+10]
  381.            movzx edx, word [esi+12]
  382.            mov [edi+CURSOR.hot_x], ecx
  383.            mov [edi+CURSOR.hot_y], edx
  384.  
  385.            stdcall vesa_init_cursor, eax, esi
  386.            mov eax, [hcursor]
  387. .fail:
  388.            ret
  389. .indirect:
  390.            shr ebx, 16
  391.            movzx ecx, bh
  392.            movzx edx, bl
  393.            mov [eax+CURSOR.hot_x], ecx
  394.            mov [eax+CURSOR.hot_y], edx
  395.  
  396.            xchg edi, eax
  397.            mov ecx, 1024
  398.            cld
  399.            rep movsd
  400.            ret
  401. endp
  402.  
  403. align 4
  404. proc load_cursor stdcall, src:dword, flags:dword
  405.            locals
  406.              handle  dd ?
  407.            endl
  408.  
  409.            xor eax, eax
  410.            mov [handle], eax
  411.            cmp word [flags], LOAD_FROM_FILE
  412.            jne @F
  413.  
  414.            stdcall load_file, [src]
  415.            test eax, eax
  416.            jz .exit
  417.            mov [src], eax
  418. @@:
  419.            call alloc_cursor
  420.            test eax, eax
  421.            jz .fail
  422.  
  423.            mov ebx, [CURRENT_TASK]
  424.            shl ebx, 5
  425.            mov ebx, [0x3000+ebx+4]
  426.            mov [eax+CURSOR.pid], ebx
  427.  
  428.            stdcall [create_cursor], eax, [src], [flags]
  429.            mov [handle], eax
  430. .fail:
  431.            cmp word [flags], LOAD_FROM_FILE
  432.            jne .exit
  433.            stdcall kernel_free, [src]
  434. .exit:
  435.            mov eax, [handle]
  436.            ret
  437. endp
  438.  
  439. align 4
  440. proc delete_cursor stdcall, hcursor:dword
  441.            locals
  442.              hsrv       dd ?
  443.              io_code    dd ?
  444.              input      dd ?
  445.              inp_size   dd ?
  446.              output     dd ?
  447.              out_size   dd ?
  448.            endl
  449.  
  450.            mov esi, [hcursor]
  451.            cmp [esi+CURSOR.magic], 'CURS'
  452.            jne .fail
  453.            cmp [esi+CURSOR.size], CURSOR_SIZE
  454.            jne .fail
  455.  
  456.            mov ebx, [CURRENT_TASK]
  457.            shl ebx, 5
  458.            mov ebx, [0x3000+ebx+4]
  459.            cmp ebx, [esi+CURSOR.pid]
  460.            jne .fail
  461.  
  462.            mov ebx, [CURRENT_TASK]
  463.            shl ebx, 8
  464.            cmp esi, [ebx+PROC_BASE+APPDATA.cursor]
  465.            jne @F
  466.            mov eax, [def_cursor]
  467.            mov [ebx+PROC_BASE+APPDATA.cursor], eax
  468. @@:
  469.            mov eax, [hw_cursor]
  470.            test eax, eax
  471.            jz @F
  472.  
  473.            xor ebx, ebx
  474.            mov ecx, [esi+CURSOR.base]
  475.            mov [hsrv], eax
  476.            mov [io_code], VIDEO_FREE
  477.            mov [input], ecx
  478.            mov [inp_size], 4
  479.            mov [output], ebx
  480.            mov [out_size], ebx
  481.  
  482.            lea eax, [hsrv]
  483.            stdcall srv_handler, eax
  484.            jmp .exit
  485. @@:
  486.            stdcall kernel_free, [esi+CURSOR.base]
  487. .exit:
  488.            mov eax, [hcursor]
  489.            call free
  490. .fail:
  491.            ret
  492. endp
  493.  
  494. align 4
  495. proc init_cursors
  496.            cmp [0xfe0c],word 0x13
  497.            jbe .fail
  498.  
  499.            movzx eax, byte [ScreenBPP]
  500.            mov ebx, [SCR_BYTES_PER_LINE]
  501.            cmp eax, 32
  502.            jne @F
  503.            sub ebx, 128
  504.            jmp .init
  505. @@:
  506.            cmp eax, 24
  507.            jne .fail
  508.            sub ebx, 96
  509. .init:
  510.            mov [cur_def_interl], ebx
  511.  
  512. if 0
  513.            xor eax, eax
  514.            mov edi, cursors
  515.            mov ecx, CURSOR_SIZE*16
  516.            cld
  517.            rep stosd
  518.  
  519.            not eax
  520.            mov [cursor_map], eax
  521.            mov [cursor_map+4], eax
  522.            mov edx, cursor_map
  523.            mov [cursor_start], edx
  524.            add edx, 8
  525.            mov [cursor_end], edx
  526. end if
  527.            stdcall load_driver, drv_hw_mouse
  528.            mov [hw_cursor], eax
  529.            test eax, eax
  530.            jz .sw_mouse
  531.  
  532.            stdcall load_cursor, def_arrow, dword LOAD_FROM_MEM
  533.            mov [def_cursor], eax
  534.            ret
  535. .sw_mouse:
  536.            mov [create_cursor], vesa_cursor
  537.  
  538.            stdcall load_cursor, def_arrow, dword LOAD_FROM_MEM
  539.            mov [def_cursor], eax
  540.  
  541.            mov ecx, [SCR_X_SIZE]
  542.            mov edx, [SCR_Y_SIZE]
  543.            inc ecx
  544.            inc edx
  545.            mov [scr_width], ecx
  546.            mov [scr_height], edx
  547.  
  548.            movzx ebx, byte [ScreenBPP]
  549.            cmp ebx, 32
  550.            jne @F
  551.  
  552.            mov dword [set_hw_cursor], cursor_32
  553.            mov dword [hw_restore], restore_32
  554.            ret
  555. @@:
  556.            mov dword [set_hw_cursor], cursor_24
  557.            mov dword [hw_restore], restore_24
  558.            ret
  559. .fail:
  560.            xor eax, eax
  561.            mov dword [set_hw_cursor], eax
  562.            mov dword [hw_restore], eax
  563.            ret
  564. endp
  565.  
  566. align 4
  567. proc restore_24 stdcall, x:dword, y:dword
  568.            locals
  569.              w  dd ?
  570.            endl
  571.  
  572.            mov edi, [cur_saved_base]
  573.            mov edx, [cur_saved_h]
  574.            mov ebx, [cur_saved_interl]
  575.  
  576.            mov esi, cur_saved_data
  577. @@:
  578.            mov ecx, [cur_saved_w]
  579.            lea ecx, [ecx+ecx*2]
  580.            rep movsb
  581.            add edi, ebx
  582.            dec edx
  583.            jnz @B
  584.            ret
  585. endp
  586.  
  587. align 4
  588. proc restore_32 stdcall, x:dword, y:dword
  589.            locals
  590.              w  dd ?
  591.            endl
  592.  
  593.            mov edi, [cur_saved_base]
  594.            mov edx, [cur_saved_h]
  595.            mov ebx, [cur_saved_interl]
  596.  
  597.            mov esi, cur_saved_data
  598. @@:
  599.            mov ecx, [cur_saved_w]
  600.            rep movsd
  601.            add edi, ebx
  602.            dec edx
  603.            jnz @B
  604.            ret
  605. endp
  606.  
  607. align 4
  608. proc cursor_24 stdcall, hcursor:dword, x:dword, y:dword
  609.            locals
  610.              w      dd ?
  611.              h      dd ?
  612.              st     dd ?
  613.              _dx     dd ?
  614.              _dy     dd ?
  615.            endl
  616.  
  617.            mov esi, [hcursor]
  618.            mov ecx, [x]
  619.            mov eax, [y]
  620.            mov ebx, [BytesPerScanLine]
  621.  
  622.            xor edx, edx
  623.            sub ecx, [esi+CURSOR.hot_x]
  624.            mov [x], ecx
  625.            sets dl
  626.            dec edx
  627.            and ecx, edx       ;clip x to 0<=x
  628.            mov edi, ecx
  629.            sub edi, [x]
  630.            mov [_dx], edi
  631.  
  632.            xor edx, edx
  633.            sub eax, [esi+CURSOR.hot_y]
  634.            mov [y], eax
  635.            sets dl
  636.            dec edx
  637.            and eax, edx       ;clip y to 0<=y
  638.            mov edi, eax
  639.            sub edi, [y]
  640.            mov [_dy], edi
  641.  
  642.            mul ebx
  643.            lea esi, [ecx+ecx*2]
  644.            add esi, [LFBAddress]
  645.            add esi, eax
  646.            mov [cur_saved_base],esi
  647.  
  648.            mov edi, [scr_width]
  649.            mov edx, [scr_height]
  650.            mov eax, 32
  651.  
  652.            sub edi, ecx
  653.            cmp edi, eax
  654.            jng @F
  655.            mov edi, eax
  656. @@:
  657.            sub edi, [_dx]
  658.  
  659.            sub edx, [y]
  660.            cmp edx, eax
  661.            jng @F
  662.            mov edx, eax
  663. @@:
  664.            sub edx, [_dy]
  665.  
  666.            mov [w], edi
  667.            mov [h], edx
  668.            mov [cur_saved_w], edi
  669.            mov [cur_saved_h], edx
  670.  
  671.            sub eax, edi
  672.            shl eax, 2       ;lea eax, [eax+eax*2]
  673.            lea edi, [edi+edi*2]
  674.            sub ebx, edi
  675.            mov [cur_saved_interl], ebx
  676.  
  677.            mov edi, cur_saved_data
  678. @@:
  679.            mov ecx, [w]
  680.            lea ecx, [ecx+ecx*2]
  681.            rep movsb
  682.            add esi, ebx
  683.            dec edx
  684.            jnz @B
  685.  
  686. ;draw cursor
  687.            mov edx, eax
  688.            mov edi, [cur_saved_base]
  689.            mov eax, [_dy]
  690.            shl eax, 5
  691.            add eax, [_dx]
  692.            shl eax, 2
  693.  
  694.            mov esi, [hcursor]
  695.            mov esi, [esi+CURSOR.base]
  696.            add esi, eax
  697. .row:
  698.            mov ecx, [w]
  699. .pix:
  700.            lodsd
  701.            test eax, 0xFF000000
  702.            jz @F
  703.  
  704.            mov word [edi], ax
  705.            shr eax, 16
  706.            mov [edi+2],al
  707. @@:
  708.            add edi, 3
  709.            dec ecx
  710.            jnz .pix
  711.  
  712.            add esi, edx
  713.            add edi, ebx
  714.            dec [h]
  715.            jnz .row
  716.            ret
  717. endp
  718.  
  719. align 4
  720. proc cursor_32 stdcall, hcursor:dword, x:dword, y:dword
  721.            locals
  722.              w      dd ?
  723.              h      dd ?
  724.              st     dd ?
  725.              _dx     dd ?
  726.              _dy     dd ?
  727.            endl
  728.  
  729.            mov esi, [hcursor]
  730.            mov ecx, [x]
  731.            mov eax, [y]
  732.            mov ebx, [BytesPerScanLine]
  733.  
  734.            xor edx, edx
  735.            sub ecx, [esi+CURSOR.hot_x]
  736.            mov [x], ecx
  737.            sets dl
  738.            dec edx
  739.            and ecx, edx       ;clip x to 0<=x
  740.            mov edi, ecx
  741.            sub edi, [x]
  742.            mov [_dx], edi
  743.  
  744.            xor edx, edx
  745.            sub eax, [esi+CURSOR.hot_y]
  746.            mov [y], eax
  747.            sets dl
  748.            dec edx
  749.            and eax, edx       ;clip y to 0<=y
  750.            mov edi, eax
  751.            sub edi, [y]
  752.            mov [_dy], edi
  753.  
  754.            mul ebx
  755.            lea esi, [eax+ecx*4]
  756.            add esi, [LFBAddress]
  757.            mov [cur_saved_base],esi
  758.  
  759.            mov edi, [scr_width]
  760.            mov edx, [scr_height]
  761.            mov eax, 32
  762.  
  763.            sub edi, ecx
  764.            cmp edi, eax
  765.            jng @F
  766.            mov edi, eax
  767. @@:
  768.            sub edi, [_dx]
  769.  
  770.            sub edx, [y]
  771.            cmp edx, eax
  772.            jng @F
  773.            mov edx, eax
  774. @@:
  775.            sub edx, [_dy]
  776.  
  777.            mov [w], edi
  778.            mov [h], edx
  779.            mov [cur_saved_w], edi
  780.            mov [cur_saved_h], edx
  781.  
  782.            sub eax, edi
  783.            shl eax, 2
  784.            shl edi, 2
  785.            sub ebx, edi
  786.            mov [cur_saved_interl], ebx
  787.  
  788.            mov edi, cur_saved_data
  789. @@:
  790.            mov ecx, [w]
  791.            rep movsd
  792.            add esi, ebx
  793.            dec edx
  794.            jnz @B
  795.  
  796. ;draw cursor
  797.            mov edx, eax
  798.            mov edi, [cur_saved_base]
  799.            mov eax, [_dy]
  800.            shl eax, 5
  801.            add eax, [_dx]
  802.            shl eax, 2
  803.  
  804.            mov esi, [hcursor]
  805.            mov esi, [esi+CURSOR.base]
  806.            add esi, eax
  807. .row:
  808.            mov ecx, [w]
  809. .pix:
  810.            lodsd
  811.            test eax, 0xFF000000
  812.            jz @F
  813.            mov [edi], eax
  814. @@:
  815.            add edi, 4
  816.            dec ecx
  817.            jnz .pix
  818.            add esi, edx
  819.            add edi, ebx
  820.            dec [h]
  821.            jnz .row
  822.            ret
  823. endp
  824.  
  825. align 4
  826. def_arrow:
  827.   file 'arrow.cur'
  828.  
  829.