kolibrios-fun/kernel/branches/gfx_kernel/vmode/clipping.asm
Mihail Semenyako (mike.dld) 8a1c0404e2 Updated gfx_kernel to revision #383
git-svn-id: svn://kolibrios.org@384 a494cfbc-eb01-0410-851d-a64ba20cac60
2007-03-03 17:43:42 +00:00

501 lines
11 KiB
NASM
Executable File

;-----------------------------------------------------------------------------
;///// PART OF ATi RADEON 9000 DRIVER ////////////////////////////////////////
;-----------------------------------------------------------------------------
; Copyright (c) 2004, mike.dld
; Using BeOS driver - Copyright (c) 2002, Thomas Kurschel
;-----------------------------------------------------------------------------
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
; DEALINGS IN THE SOFTWARE.
;-----------------------------------------------------------------------------
include 'clipping.inc'
struct RECT
left dd ?
top dd ?
right dd ?
bottom dd ?
ends
virtual at ebp
r RECT
end virtual
virtual at edi
r2 RECT
end virtual
SR = sizeof.RECT
macro movl val,reg {
mov reg,val
}
EQUAL_LEFT = 00000001b
EQUAL_BOTTOM = 00000010b
EQUAL_RIGHT = 00000100b
EQUAL_TOP = 00001000b
func calc_clipping_rects
begin
mov [cnt],0
movzx ebp,word[CURRENT_TASK]
shl ebp,5
cmp ebp,0x20
jne @f
mov esi,viewport
mov edi,rct
mov ecx,sizeof.RECT/4
cld
rep movsd
jmp .lp1
@@:
movsx eax,word[ebp+0x00]
mov [rct.left],eax
mov [rct.right],eax
movsx eax,word[ebp+0x04]
mov [rct.top],eax
mov [rct.bottom],eax
movzx eax,word[ebp+0x08]
inc eax
add [rct.right],eax
movzx eax,word[ebp+0x0C]
inc eax
add [rct.bottom],eax
.lp1:
mov esi,viewport
mov edi,tr
mov ecx,sizeof.RECT/4
cld
rep movsd
mov ebp,rct
call intersect_rect ; (ebp,tr)->(x1:edx,y1:eax,x2:ebx,y2:ecx)+CF
jc .exit
mov [rct.left],edx
mov [rct.top],eax
mov [rct.right],ebx
mov [rct.bottom],ecx
inc [cnt]
comment ^
movsx eax,word[ebp+0x00]
mov [rct.left],eax
mov [rct.right],eax
movsx eax,word[ebp+0x04]
mov [rct.top],eax
mov [rct.bottom],eax
movsx eax,word[ebp+0x08]
inc eax
add [rct.right],eax
movsx eax,word[ebp+0x0C]
inc eax
add [rct.bottom],eax
^
movzx ecx,word[TASK_COUNT] ; number of processes
jif ecx,be,1,.exit
; calculate clipping rectangles
mov esi,1
; go forward through all windows
.next_window:
movzx edi,word[CURRENT_TASK] ; calling process number
mov ax,[WIN_STACK+esi*2]
jif ax,be,[WIN_STACK+edi*2],.end_window.2
mov ebp,[cnt]
shl ebp,4 ; ebp *= SR
jz .exit
lea ebp,[rct+ebp-SR]
push esi ;ecx esi
shl esi,5
lodsd
mov [tr.left],eax
mov [tr.right],eax
lodsd
mov [tr.top],eax
mov [tr.bottom],eax
lodsd
jif eax,z,eax,.end_window,test
inc eax
add [tr.right],eax
lodsd
jif eax,z,eax,.end_window,test
inc eax
add [tr.bottom],eax
; go backward through all rectangles
.next_rect:
rc_top equ eax
rc_right equ ebx
rc_bottom equ ecx
rc_left equ edx
call intersect_rect ; (ebp,tr)->(x1:edx,y1:eax,x2:ebx,y2:ecx)+CF
jc .is_finish
xor edi,edi
jif rc_top,ne,[r.top],@f
or edi,EQUAL_TOP
@@: jif rc_right,ne,[r.right],@f
or edi,EQUAL_RIGHT
@@: jif rc_bottom,ne,[r.bottom],@f
or edi,EQUAL_BOTTOM
@@: jif rc_left,ne,[r.left],@f
or edi,EQUAL_LEFT
@@: jmp [jtable_intersect+edi*4]
.is_0000:
call copy_current
mov [r.left ],rc_right
mov [r2.right -SR],rc_left
mov [r2.left ],rc_left
mov [r2.right ],rc_right
mov [r2.bottom ],rc_top
mov [r2.left +SR],rc_left
mov [r2.right +SR],rc_right
mov [r2.top +SR],rc_bottom
movl [r.top ],esi
mov [r2.top ],esi
movl [r.bottom ],esi
mov [r2.bottom+SR],esi
add [cnt],2
jmp .is_finish
.is_0001:
call copy_current
mov [r.top ],rc_bottom
mov [r2.bottom-SR],rc_top
mov [r2.left ],rc_right
mov [r2.top ],rc_top
mov [r2.bottom ],rc_bottom
movl [r.right ],esi
mov [r2.right ],esi
inc [cnt]
jmp .is_finish
.is_0010:
call copy_current
mov [r.left ],rc_right
mov [r2.right -SR],rc_left
mov [r2.left ],rc_left
mov [r2.right ],rc_right
mov [r2.bottom ],rc_top
movl [r.top ],esi
mov [r2.top ],esi
inc [cnt]
jmp .is_finish
.is_0011:
call copy_current
mov [r.bottom ],rc_top
mov [r2.left -SR],rc_right
mov [r2.top -SR],rc_top
jmp .is_finish
.is_0100:
call copy_current
mov [r.top ],rc_bottom
mov [r2.bottom-SR],rc_top
mov [r2.right ],rc_left
mov [r2.top ],rc_top
mov [r2.bottom ],rc_bottom
movl [r.left ],esi
mov [r2.left ],esi
inc [cnt]
jmp .is_finish
.is_0101:
call copy_current
mov [r.top ],rc_bottom
mov [r2.bottom-SR],rc_top
jmp .is_finish
.is_0110:
call copy_current
mov [r.bottom ],rc_top
mov [r2.right -SR],rc_left
mov [r2.top -SR],rc_top
jmp .is_finish
.is_0111:
mov [r.bottom ],rc_top
jmp .is_finish
.is_1000:
call copy_current
mov [r.left ],rc_right
mov [r2.right -SR],rc_left
mov [r2.left ],rc_left
mov [r2.right ],rc_right
mov [r2.top ],rc_bottom
movl [r.bottom ],esi
mov [r2.bottom ],esi
inc [cnt]
jmp .is_finish
.is_1001:
call copy_current
mov [r.top ],rc_bottom
mov [r2.left -SR],rc_right
mov [r2.bottom-SR],rc_bottom
jmp .is_finish
.is_1010:
call copy_current
mov [r.left ],rc_right
mov [r2.right -SR],rc_left
jmp .is_finish
.is_1011:
mov [r.left ],rc_right
jmp .is_finish
.is_1100:
call copy_current
mov [r.top ],rc_bottom
mov [r2.right -SR],rc_left
mov [r2.bottom-SR],rc_bottom
jmp .is_finish
.is_1101:
mov [r.top ],rc_bottom
jmp .is_finish
.is_1110:
mov [r.right ],rc_left
jmp .is_finish
.is_1111:
call delete_current
.is_finish:
sub ebp,SR
jif ebp,ae,rct,.next_rect
.end_window:
pop esi; ecx
.end_window.2:
inc esi
jif esi,be,[TASK_COUNT],.next_window
; dec ecx
; jnz .next_window
; combine some rectangles if possible
; with Result do begin
; for i := cnt-1 downto 0 do if rct[i].Left >= 0 then
; for j := cnt-1 downto 0 do if (j <> i) and (rct[j].Left >= 0) then
; if (rct[i].Left = rct[j].Left) and (rct[i].Right = rct[j].Right) then begin
; end else if (rct[i].Top = rct[j].Top) and (rct[i].Bottom = rct[j].Bottom) then begin
; if (rct[i].Left = rct[j].Right) then begin
; rct[i].Left := rct[j].Left;
; rct[j].Left := -1;
; end else if (rct[i].Right = rct[j].Left) then begin
; rct[i].Right := rct[j].Right;
; rct[j].Left := -1;
; end;
; end;
; for i := cnt-1 downto 0 do if rct[i].Left < 0 then begin
; for j := i to cnt-2 do
; rct[j] := rct[j+1];
; dec(cnt);
; end;
; end;
.combine_rects:
mov esi,[cnt]
shl esi,4
add esi,rct
lea ebp,[esi-SR]
push ebp
.next_rect1:
sub esi,SR
jif esi,b,rct,.exit.combine
jif [esi+RECT.left],e,-1,.next_rect1
push ebp
.next_rect2:
jif ebp,e,esi,.next_rect2.ok
jif [ebp+RECT.left],e,-1,.next_rect2.ok
mov eax,[ebp+RECT.left]
mov ebx,[ebp+RECT.right]
mov ecx,[ebp+RECT.top]
mov edx,[ebp+RECT.bottom]
jif eax,ne,[esi+RECT.left],.not_left_right
jif ebx,ne,[esi+RECT.right],.not_left_right
jif edx,ne,[esi+RECT.top],@f
mov [esi+RECT.top],ecx
jmp .next_rect2.mark
@@: jif ecx,ne,[esi+RECT.bottom],.next_rect2.ok
mov [esi+RECT.bottom],edx
jmp .next_rect2.mark
.not_left_right:
jif ecx,ne,[esi+RECT.top],.next_rect2.ok
jif edx,ne,[esi+RECT.bottom],.next_rect2.ok
jif ebx,ne,[esi+RECT.left],@f
mov [esi+RECT.left],eax
jmp .next_rect2.mark
@@: jif eax,ne,[esi+RECT.right],.next_rect2.ok
mov [esi+RECT.right],ebx
.next_rect2.mark:
or [ebp+RECT.left],-1
.next_rect2.ok:
sub ebp,SR
jif ebp,ae,rct,.next_rect2
pop ebp
jmp .next_rect1
.exit.combine:
pop ebp
.next_rect3:
jif [ebp+RECT.left],ne,-1,@f
call delete_current
@@: sub ebp,SR
jif ebp,ae,rct,.next_rect3
; remove unnecessary rectangles
; for i := Result.cnt-1 downto 0 do with Result do
; if not IntersectRect(rc,rct[i],r2) then begin
; for j := i to cnt-2 do
; rct[j] := rct[j+1];
; dec(cnt);
; end;
.exit:
mov esi,rct
mov ecx,[cnt]
ret
delete_current:
push ecx
lea esi,[ebp+SR] ; esi = ebp+SR
mov edi,ebp ; edi = ebp
mov ecx,[cnt] ; ecx = cnt
shl ecx,4 ; ecx *= SR
add ecx,rct-SR ; ecx += rct-SR
sub ecx,ebp ; ecx -= ebp
cld
rep movsb
dec [cnt]
pop ecx
ret
copy_current:
push ecx
mov edi,[cnt]
shl edi,4
lea edi,[rct+edi]
mov esi,ebp
mov ecx,4
cld
rep movsd
pop ecx
inc [cnt]
ret
intersect_rect: ; ebp,tr
mov rc_top,[tr.top]
jif rc_top,ge,[r.bottom],.exit
mov rc_right,[tr.right]
jif rc_right,le,[r.left],.exit
mov rc_bottom,[tr.bottom]
jif rc_bottom,le,[r.top],.exit
mov rc_left,[tr.left]
jif rc_left,ge,[r.right],.exit
jif rc_top,ge,[r.top],@f
mov rc_top,[r.top]
@@: jif rc_right,le,[r.right],@f
mov rc_right,[r.right]
@@: jif rc_bottom,le,[r.bottom],@f
mov rc_bottom,[r.bottom]
@@: jif rc_left,ge,[r.left],@f
mov rc_left,[r.left]
@@: clc
ret
.exit:
stc
ret
endf
func FC
begin
.x00:
.x01:
.x02:
.x04:
.x05:
.x06:
.x08:
.x09:
.x0A:
.x10:
.x11:
.x12:
.x14:
.x15:
.x16:
.x18:
.x19:
.x1A:
.x20:
.x21:
.x22:
.x24:
.x25:
.x26:
.x28:
.x29:
.x2A:
.x40:
.x41:
.x42:
.x44:
.x45:
.x46:
.x48:
.x49:
.x4A:
.x50:
.x51:
.x52:
.x54:
.x55:
.x56:
.x58:
.x59:
.x5A:
.x60:
.x61:
.x62:
.x64:
.x65:
.x66:
.x68:
.x69:
.x6A:
.x80:
.x81:
.x82:
.x84:
.x85:
.x86:
.x88:
.x89:
.x8A:
.x90:
.x91:
.x92:
.x94:
.x95:
.x96:
.x98:
.x99:
.x9A:
.xA0:
.xA1:
.xA2:
.xA4:
.xA5:
.xA6:
.xA8:
.xA9:
.xAA:
ret
.xXX:
ret
endf
;-----------------------------------------------------------------------------
;///// END ///////////////////////////////////////////////////////////////////
;-----------------------------------------------------------------------------