forked from KolibriOS/kolibrios
5620ba7561
git-svn-id: svn://kolibrios.org@871 a494cfbc-eb01-0410-851d-a64ba20cac60
501 lines
11 KiB
NASM
501 lines
11 KiB
NASM
;-----------------------------------------------------------------------------
|
|
;///// 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 ///////////////////////////////////////////////////////////////////
|
|
;----------------------------------------------------------------------------- |