;----------------------------------------------------------------------------- ;///// 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 /////////////////////////////////////////////////////////////////// ;-----------------------------------------------------------------------------