mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2025-01-15 12:30:53 +00:00
4325cdcc78
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
784 lines
25 KiB
Plaintext
784 lines
25 KiB
Plaintext
;
|
|
; File: DrawLine.m.a
|
|
;
|
|
; Contains: xxx put contents here (or delete the whole line) xxx
|
|
;
|
|
; Written by: xxx put name of writer here (or delete the whole line) xxx
|
|
;
|
|
; Copyright: © 1988-1990 by Apple Computer, Inc., all rights reserved.
|
|
;
|
|
; Change History (most recent first):
|
|
;
|
|
; <2> 10/10/90 JL Change FixRatio to MFixRatio to avoid conflict with Traps.a
|
|
; <1.1> 11/11/88 CCH Fixed Header.
|
|
; <1.0> 11/9/88 CCH Adding to EASE.
|
|
; <1.2> 10/12/88 CCH Changed Òm.GrafType.aÓ to ÒGrafType.m.aÓ.
|
|
; <1.1> 5/18/88 MSH Changed inclides to use m.GRAPHTYPES to work under EASE.
|
|
; <1.0> 2/11/88 BBM Adding file for the first time into EASEÉ
|
|
;
|
|
; To Do:
|
|
;
|
|
|
|
;EASE$$$ READ ONLY COPY of file ÒDRAWLINE.m.aÓ
|
|
; 1.1 CCH 11/11/1988 Fixed Header.
|
|
; 1.0 CCH 11/ 9/1988 Adding to EASE.
|
|
; OLD REVISIONS BELOW
|
|
; 1.2 CCH 10/12/1988 Changed Òm.GrafType.aÓ to ÒGrafType.m.aÓ.
|
|
; 1.1 MSH 5/18/88 Changed inclides to use m.GRAPHTYPES to work under EASE.
|
|
; 1.0 BBM 2/11/88 Adding file for the first time into EASEÉ
|
|
; END EASE MODIFICATION HISTORY
|
|
|
|
|
|
BLANKS ON
|
|
STRING ASIS
|
|
|
|
INCLUDE 'GRAFTYPES.m.a'
|
|
;-----------------------------------------------------------------
|
|
;
|
|
; --> DRAWLINE.TEXT
|
|
;
|
|
|
|
|
|
DrawLine PROC EXPORT
|
|
IMPORT RgnBlt,RSect,ShieldCursor,ShowCursor,TrimRect
|
|
IMPORT InitRgn,SeekRgn,PatExpand,ColorMap
|
|
IMPORT XorSlab,DrawSlab,SlabMode,FastSlabMode,MaskTab
|
|
;----------------------------------------------------------------
|
|
;
|
|
; PROCEDURE DRAWLINE(P1,P2: POINT);
|
|
;
|
|
; DRAWS A LINE CLIPPED TO CURRENT PORT'S CLIPRGN AND VISRGN
|
|
;
|
|
; P1 AND P2 ARE GIVEN IN LOCAL COORDINATES OF THEPORT.
|
|
;
|
|
|
|
|
|
;------------------------------------------------
|
|
;
|
|
; A6 OFFSETS OF PARAMETERS AFTER LINK:
|
|
;
|
|
PARAMSIZE EQU 8 ;SIZE OF PARAMETERS
|
|
P1 EQU PARAMSIZE+8-4 ;POINT
|
|
P2 EQU P1-4 ;POINT
|
|
|
|
|
|
;-------------------------------------------------
|
|
;
|
|
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
|
;
|
|
EXPAT EQU -64 ;16 LONGS
|
|
LINERECT EQU EXPAT-8 ;RECT
|
|
MINRECT EQU LINERECT-8 ;RECT
|
|
STATEA EQU MINRECT-RGNREC ;RGN STATE RECORD
|
|
STATEB EQU STATEA-RGNREC ;RGN STATE RECORD
|
|
STATEC EQU STATEB-RGNREC ;RGN STATE RECORD
|
|
SAVESTK EQU STATEC-4 ;LONG
|
|
RECTFLAG EQU SAVESTK-2 ;WORD
|
|
MASKBUF EQU RECTFLAG-4 ;LONG
|
|
BUFLEFT EQU MASKBUF-2 ;WORD
|
|
BUFSIZE EQU BUFLEFT-2 ;WORD
|
|
VERT EQU BUFSIZE-2 ;WORD
|
|
MODECASE EQU VERT-4 ;LONG
|
|
PAT EQU MODECASE-4 ;LONG, ADDR OF PAT
|
|
LEFTEDGE EQU PAT-4 ;LONG, FIXED POINT
|
|
RIGHTEDGE EQU LEFTEDGE-4 ;LONG, FIXED POINT
|
|
SLOPE EQU RIGHTEDGE-4 ;LONG, FIXED POINT
|
|
DSTLEFT EQU SLOPE-4 ;LONG
|
|
SAVEA5 EQU DSTLEFT-4 ;LONG
|
|
PORT EQU SAVEA5-4 ;LONG
|
|
MODE EQU PORT-2 ;WORD
|
|
FASTFLAG EQU MODE-2 ;BYTE
|
|
BIGRGN EQU FASTFLAG-4 ;LONG, RgnHandle
|
|
VARSIZE EQU BIGRGN ;SIZE OF LOCAL VARIABLES
|
|
|
|
|
|
|
|
LINK A6,#VARSIZE ;ALLOCATE LOCAL VARS
|
|
MOVEM.L D0-D7/A1-A5,-(SP) ;SAVE REGS
|
|
MOVE.L SP,SAVESTK(A6) ;REMEMBER STACK FOR LATER
|
|
MOVE.L A5,SAVEA5(A6) ;REMEMBER GLOBAL PTR
|
|
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
|
MOVE.L WIDEOPEN(A0),BIGRGN(A6) ;STASH WIDEOPEN IN BIGRGN
|
|
MOVE.L THEPORT(A0),A3 ;POINT TO CURRENT GRAFPORT
|
|
TST PNVIS(A3) ;IS PNVIS NEGATIVE ?
|
|
BLT GOHOME ;YES, QUIT
|
|
MOVE.L A3,PORT(A6) ;SAVE PORT FOR LATER
|
|
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; QUIT IF PEN MODE NOT IN 8..15
|
|
;
|
|
MOVEQ #-8,D0
|
|
AND PNMODE(A3),D0 ;GET ALL BUT 3 BITS OF PEN MODE
|
|
CMP #8,D0 ;IS PEN MODE 8..15 ?
|
|
BNE GOHOME ;NO, QUIT
|
|
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; Check for color filtering. Alter mode and pattern accordingly.
|
|
;
|
|
MOVE PNMODE(A3),-(SP) ;PUSH PEN MODE
|
|
PEA PNPAT(A3) ;PUSH ADDR OF PEN PATTERN
|
|
TST COLRBIT(A3) ;IS COLORBIT NEG ?
|
|
BMI.S NOCOLOR ;YES, DON'T MAP
|
|
JSR COLORMAP ;CHECK AGAINST THECOLOR, THEFILTER
|
|
NOCOLOR MOVE.L (SP)+,PAT(A6) ;GET (ALTERED) PATTERN
|
|
MOVE (SP)+,MODE(A6) ;AND (ALTERED) MODE
|
|
|
|
|
|
;---------------------------------------------------------
|
|
;
|
|
; GET CLIPRGN AND VISRGN HANDLES AND DE-REFERENCE THEM
|
|
;
|
|
MOVE.L A3,A5 ;PUT GRAFPTR IN A5
|
|
MOVE.L CLIPRGN(A5),A2 ;GET CLIPRGN HANDLE
|
|
MOVE.L (A2),A2 ;GET CLIPRGN POINTER
|
|
MOVE.L VISRGN(A5),A3 ;GET VISRGN HANDLE
|
|
MOVE.L (A3),A3 ;GET VISRGN POINTER
|
|
|
|
|
|
;-------------------------------------------------------------
|
|
;
|
|
; SET UP LINERECT, THE RECTANGLE BOUNDING THE LINE AND PEN
|
|
;
|
|
MOVEM.W P2(A6),D1/D2/D3/D4 ;GET D1=V1, D2=H1, D3=V2, D4=H2
|
|
CMP D3,D1 ;IS V1 > V2 ?
|
|
BLE.S VOK2 ;NO, CONTINUE
|
|
EXG D1,D3 ;YES, SWAP VERT
|
|
VOK2 CMP D4,D2 ;IS H1 > H2 ?
|
|
BLE.S HOK2 ;NO, CONTINUE
|
|
EXG D2,D4 ;NO SWAP HORIZ
|
|
HOK2 ADD PNSIZE+H(A5),D4 ;ADD PEN WIDTH TO RIGHT
|
|
ADD PNSIZE+V(A5),D3 ;ADD PEN HEIGHT TO BOTTOM
|
|
MOVEM.W D1/D2/D3/D4,LINERECT(A6) ;STORE TOP, LEFT, BOTTOM, RIGHT
|
|
|
|
|
|
;-----------------------------------------------------------------------
|
|
;
|
|
; CALC MINRECT, THE INTERSECTION OF LINERECT, BITMAP BOUNDS,
|
|
; CLIPRGN BBOX, AND VISRGN BBOX. QUIT IF NO INTERSECTION.
|
|
;
|
|
PEA LINERECT(A6) ;PUSH LINE RECT
|
|
PEA PORTBITS+BOUNDS(A5) ;PUSH BITMAP BOUNDS
|
|
PEA RGNBBOX(A2) ;PUSH CLIPRGN BBOX
|
|
PEA RGNBBOX(A3) ;PUSH VISRGN BBOX
|
|
MOVE #4,-(SP) ;PUSH NRECTS=4
|
|
PEA MINRECT(A6) ;PUSH DST ADDR
|
|
JSR RSECT ;CALC INTERSECTION
|
|
BEQ GOHOME ;QUIT IF NO INTERSECT
|
|
|
|
;
|
|
; HIDE CURSOR IF CURSOR INTERSECTS MINRECT.
|
|
;
|
|
PEA MINRECT(A6) ;PUSH SHIELDRECT PARAMETER
|
|
MOVE.L PORTBITS+BOUNDS+TOPLEFT(A5),-(SP) ;PUSH DELTA TO CONVERT TO GLOBAL
|
|
MOVE.L SAVEA5(A6),A5 ;GET GLOBAL PTR
|
|
JSR SHIELDCURSOR ;HIDE CURSOR IF IT INTERSECTS
|
|
MOVE.L PORT(A6),A5 ;GET BACK THEPORT
|
|
|
|
;
|
|
; CHECK FOR BOTH VISRGN AND CLIPRGN RECTANGULAR
|
|
;
|
|
CLR.B FASTFLAG(A6) ;FASTFLAG := FALSE
|
|
CMP #10,RGNSIZE(A2) ;IS CLIPRGN RECTANGULAR ?
|
|
BNE.S FLAGOK ;NO, CONTINUE
|
|
CMP #10,RGNSIZE(A3) ;IS VISRGN RECTANGULAR ?
|
|
BEQ.S CKPAT ;YES, CONTINUE
|
|
;
|
|
; If only visRgn is non-rectangular, then check if
|
|
; its intersection with minrect would be rectangular.
|
|
; IF TrimRect(visRgn,minRect) then treat as rectangular.
|
|
;
|
|
MOVE.L visRgn(A5),-(SP) ;push rgnHandle
|
|
PEA minRect(A6) ;push addr of minRect
|
|
JSR TrimRect ;call trimRect
|
|
BLT DONE ;quit if intersection empty
|
|
BGT.S FLAGOK ;continue if non-rectangular
|
|
;
|
|
; CHECK FOR BLACK OR WHITE PATTERN
|
|
;
|
|
CKPAT MOVE.L PAT(A6),A0 ;POINT TO PATTERN
|
|
MOVE.L (A0)+,D0 ;GET 1ST HALF OF PATTERN
|
|
CMP.L (A0)+,D0 ;IS IT SAME AS 2ND HALF ?
|
|
BNE.S FLAGOK ;NO, CONTINUE
|
|
NOT.L D0 ;IS PATTERN BLACK ?
|
|
BEQ.S YESFLAG ;YES, WE MADE IT
|
|
NOT.L D0 ;IS PATTERN WHITE ?
|
|
BNE.S FLAGOK ;NO, CONTINUE
|
|
EOR #4,MODE(A6) ;YES, ALTER MODE AS IF BLACK
|
|
YESFLAG ST FASTFLAG(A6) ;RECT CLIPPED AND BLACK
|
|
;
|
|
; fast case: map mode into black,xor,white, or do-nothing
|
|
;
|
|
MOVEQ #7,D0 ;GET 3 BIT MASK
|
|
AND MODE(A6),D0 ;GET 3 BITS OF MODE
|
|
MOVE.B MODEMAP(D0),D0 ;MAP TO BLACK,XOR,WHITE,NOP
|
|
BMI DONE ;QUIT IF DO-NOTHING MODE
|
|
MOVE D0,MODE(A6) ;UPDATE MODE
|
|
BRA.S FLAGOK ;AND CONTINUE
|
|
MODEMAP DC.B 0,0,1,2,2,255,255,255
|
|
FLAGOK
|
|
|
|
|
|
;
|
|
; GET THE TWO LINE ENDPOINTS INTO REGISTERS
|
|
; AND CHECK FOR HORIZONTAL OR VERTICAL LINE
|
|
;
|
|
MOVEM.W P2(A6),D1/D2/D3/D4 ;GET D1=V2, D2=H2, D3=V1, D4=H1
|
|
CMP D2,D4 ;H1=H2 ?
|
|
BEQ.S HVLINE ;YES, DO VERTICAL LINE
|
|
CMP D1,D3 ;NO, IS V2 > V1 ?
|
|
BGT.S SLANTED ;YES, DRAW SLANTED LINE
|
|
BLT.S VSWAP ;SWAP POINTS AND DRAW SLANTED
|
|
;ELSE V1=V2, DO HORIZONTAL
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; LINE IS EITHER HORIZONTAL OR VERTICAL.
|
|
; CHECK FOR ONE DOT LINE, BLACK OR WHITE PATTERN, AND
|
|
; CLIPRGN AND VISRGN BOTH RECTANGULAR. IF SO, OPTIMIZE FAST LINES.
|
|
;
|
|
HVLINE TST.B FASTFLAG(A6) ;RECT CLIPPED AND BLACK ?
|
|
BEQ.S NOTFAST ;NO, CONTINUE
|
|
CMP.L #$00010001,PNSIZE(A5) ;IS PEN 1 BY 1 ?
|
|
BEQ FASTLINE ;YES, DO IT FAST !
|
|
|
|
|
|
;--------------------------------------------------------------------
|
|
;
|
|
; NOT FASTLINE. PUSH PARAMS AND CALL RGNBLT FOR HORIZ OR VERT LINE.
|
|
;
|
|
NOTFAST PEA PORTBITS(A5) ;PUSH SRCBITS = DSTBITS
|
|
MOVE.L (SP),-(SP) ;PUSH DSTBITS
|
|
PEA MINRECT(A6) ;PUSH SRCRECT = DSTRECT
|
|
MOVE.L (SP),-(SP) ;PUSH DSTRECT
|
|
MOVE PNMODE(A5),-(SP) ;PUSH MODE
|
|
PEA PNPAT(A5) ;PUSH PATTERN
|
|
MOVE.L CLIPRGN(A5),-(SP) ;PUSH CLIPRGN HANDLE
|
|
MOVE.L VISRGN(A5),-(SP) ;PUSH VISRGN HANDLE
|
|
MOVE.L BIGRGN(A6),-(SP) ;PUSH SAVED WIDEOPEN
|
|
MOVE.L SAVEA5(A6),A5 ;GET GLOBAL PTR
|
|
JSR RGNBLT ;DRAW THE HORIZ OR VERT LINE
|
|
BRA DONE ;RESTORE CURSOR AND QUIT
|
|
|
|
|
|
;-------------------------------------------------------------
|
|
;
|
|
; THE LINE IS SLANTED. SORT VERTICALLY
|
|
; AND DRAW TOP TO BOTTOM AS HORIZONTAL SLABS.
|
|
;
|
|
VSWAP EXG D1,D3 ;SORT POINTS BY VERTICAL
|
|
EXG D2,D4 ;SWAP HORIZ TO MATCH
|
|
SLANTED MOVE D3,D0 ;COPY LINE BOTTOM
|
|
ADD PNSIZE+V(A5),D0 ;ADD PEN HEIGHT
|
|
CMP RGNBBOX+TOP(A2),D0 ;IS RESULT <= CLIP TOP ?
|
|
BLE DONE ;YES, RESTORE CURSOR AND QUIT
|
|
CMP RGNBBOX+BOTTOM(A2),D1 ;IS TOP >= CLIP BOTTOM ?
|
|
BGE DONE ;YES, RESTORE CURSOR AND QUIT
|
|
|
|
|
|
;-------------------------------------------------------------
|
|
;
|
|
; SET UP INITIAL FIXED POINT LEFTEDGE AND RIGHTEDGE
|
|
; AND CHECK FOR ZERO PENSIZE.
|
|
;
|
|
MOVE.W D2,LEFTEDGE(A6) ;LEFTEDGE.INT := TOP HORIZ
|
|
MOVE.W #$8000,LEFTEDGE+2(A6) ;LEFTEDGE.FRACT := 1/2
|
|
MOVE.L LEFTEDGE(A6),RIGHTEDGE(A6) ;RIGHTEDGE:=LEFTEDGE
|
|
MOVE PNSIZE+H(A5),D0 ;GET PEN WIDTH
|
|
BLE DONE ;QUIT IF PENWIDTH <= 0
|
|
ADD.W D0,RIGHTEDGE(A6) ;ADD TO RIGHTEDGE.INT
|
|
MOVE PNSIZE+V(A5),D6 ;GET PEN HEIGHT
|
|
BLE DONE ;QUIT IF PEN HEIGHT <= 0
|
|
|
|
|
|
;----------------------------------------------------
|
|
;
|
|
; CALC FIXED POINT SLOPE = FixRatio(dh,dv);
|
|
;
|
|
CLR.L -(SP) ;MAKE ROOM FOR FCN RESULT
|
|
MOVE D4,-(SP) ;PUSH BOTTOM HORIZ
|
|
SUB D2,(SP) ;CALC DH
|
|
MOVE D3,-(SP) ;PUSH BOTTOM VERT
|
|
SUB D1,(SP) ;CALC DV
|
|
_MFixRatio ;CALC FIXED POINT SLOPE DH/DV
|
|
MOVE.L (SP)+,D7 ;POP RESULT
|
|
MOVE.L D7,SLOPE(A6) ;SAVE FOR LATER
|
|
|
|
;
|
|
; CALC adjust := pen height * slope
|
|
;
|
|
CLR.L -(SP) ;PUSH ROOM FOR FCN RESULT
|
|
CLR.W -(SP) ;PUSH LOWORD = 0
|
|
MOVE.W D6,-(SP) ;PUSH HIWORD = PEN HEIGHT
|
|
MOVE.L D7,-(SP) ;PUSH SLOPE
|
|
_MFixMul ;CALC FixMul(pnSize.v,slope)
|
|
MOVE.L (SP)+,D6 ;POP ANSWER INTO D6
|
|
|
|
;
|
|
; ADJUST LEFTEDGE AND RIGHTEDGE DEPENDING ON SIGN AND MAGNITUDE OF SLOPE
|
|
;
|
|
MOVE.L D7,D0 ;COPY SLOPE
|
|
ASR.L #1,D0 ;CALC SLOPE/2
|
|
ADD.L D0,LEFTEDGE(A6) ;ADD SLOPE/2 TO LEFT EDGE
|
|
ADD.L D0,RIGHTEDGE(A6) ;ADD SLOPE/2 TO RIGHT EDGE
|
|
|
|
TST.L D7 ;IS SLOPE NEGATIVE ?
|
|
BMI.S NEGSLOPE ;YES, CONTINUE
|
|
SUB.L D6,LEFTEDGE(A6) ;SUBTRACT ADJUST FROM LEFTEDGE
|
|
CMP.L #$00010000,D7 ;IS SLOPE < ONE ?
|
|
BGE.S LESSV1 ;NO, BRANCH
|
|
|
|
MOREV1 ADD.L D7,LEFTEDGE(A6) ;ADD SLOPE TO LEFTEDGE
|
|
BRA.S SLOPEOK ;CONTINUE
|
|
|
|
LESSV1 SUB.W #1,RIGHTEDGE(A6) ;RIGHTEDGE := RIGHTEDGE - 1
|
|
BRA.S SLOPEOK ;CONTINUE
|
|
|
|
|
|
;----------------------------------------------------
|
|
;
|
|
; SLOPE IS NEGATIVE
|
|
;
|
|
NEGSLOPE SUB.L D6,RIGHTEDGE(A6) ;SUBTRACT ADJUST FROM RIGHTEDGE
|
|
CMP.L #$FFFF0000,D7 ;IS SLOPE > -ONE ?
|
|
|
|
BLT.S LESSV2 ;NO, CONTINUE
|
|
|
|
MOREV2 ADD.L D7,RIGHTEDGE(A6) ;ADD SLOPE TO RIGHTEDGE
|
|
BRA.S SLOPEOK
|
|
|
|
LESSV2 ADD.W #1,LEFTEDGE(A6) ;LEFTEDGE := LEFTEDGE + 1
|
|
|
|
|
|
|
|
SLOPEOK MOVEM.W MINRECT(A6),D1/D2/D3/D4 ;GET MINRECT TOP,LEFT,BOTTOM,RIGHT
|
|
;
|
|
; ADJUST LEFTEDGE AND RIGHTEDGE IF LINE WAS CLIPPED VERTICALLY
|
|
;
|
|
CMP LINERECT+TOP(A6),D1 ;DID TOP GET CLIPPED ?
|
|
BEQ.S TOPOK ;NO, CONTINUE
|
|
MOVE D1,D0
|
|
SUB LINERECT+TOP(A6),D0 ;CALC DISCARD AMMOUNT
|
|
MOVE.L D7,D5 ;GET 32 BIT SLOPE
|
|
SWAP D5 ;GET HI WORD OF SLOPE
|
|
MULS D0,D5 ;MULT TIMES DISCARD
|
|
SWAP D5 ;PUT RESULT IN HI WORD
|
|
CLR.W D5 ;CLEAR LO WORD
|
|
MOVE.L D7,D6 ;GET NEW COPY OF SLOPE
|
|
MULU D0,D6 ;MULT LO WORD TIMES DISCARD
|
|
ADD.L D6,D5 ;CALC 32BIT SLOPE*DISCARD
|
|
ADD.L D5,LEFTEDGE(A6) ;BUMP LEFTEDGE TO NEW TOP
|
|
ADD.L D5,RIGHTEDGE(A6) ;BUMP RIGHTEDGE TO NEW TOP
|
|
TOPOK
|
|
;
|
|
; CALC BUFLEFT
|
|
;
|
|
MOVE MINRECT+LEFT(A6),D2 ;GET MINRECT LEFT
|
|
SUB PORTBITS+BOUNDS+LEFT(A5),D2 ;CONVERT TO GLOBAL COORDS
|
|
AND #$FFF0,D2 ;TRUNC TO MULT OF 16
|
|
ADD PORTBITS+BOUNDS+LEFT(A5),D2 ;CONVERT BACK TO GLOBAL
|
|
MOVE D2,BUFLEFT(A6) ;SAVE AS BUFLEFT
|
|
;
|
|
; IF FASTFLAG, THEN SKIP REGION SETUP
|
|
;
|
|
TST.B FASTFLAG(A6) ;RECT CLIPPED AND BLACK ?
|
|
BNE SKIPSETUP ;YES, DON'T WASTE TIME WITH SETUP
|
|
;
|
|
; CALC BUFSIZE
|
|
;
|
|
MOVE MINRECT+RIGHT(A6),D0 ;GET MINRECT RIGHT
|
|
SUB D2,D0 ;CALC MAXH-BUFLEFT
|
|
LSR #5,D0 ;DIV BY 32 FOR LONGS
|
|
MOVE D0,BUFSIZE(A6) ;BUFSIZE = # LONGS - 1
|
|
;
|
|
; ALLOCATE AND CLEAR A SCANLINE BUFFER FOR THE COMPOSITE MASK
|
|
;
|
|
CLRMASK CLR.L -(SP) ;ALLOCATE AND CLEAR ONE LONG
|
|
DBRA D0,CLRMASK ;LOOP TILL DONE
|
|
MOVE.L SP,MASKBUF(A6) ;REMEMBER WHERE MASKBUF IS
|
|
|
|
|
|
;-------------------------------------------------------------------------
|
|
;
|
|
; INIT STATE RECORDS AND ALLOCATE BUFFERS FOR EACH NON-RECTANGULAR REGION
|
|
;
|
|
CLR D5 ;INIT BOTH ARE RECT
|
|
MOVE #-32767,STATEA+THISV(A6) ;INIT HARMLESS STATE
|
|
MOVE #32767,STATEA+NEXTV(A6) ;IN CASE RECTANGULAR
|
|
CMP #10,RGNSIZE(A2) ;IS CLIPRGN RECTANGULAR ?
|
|
BEQ.S ARECT ;YES, CONTINUE
|
|
ADD #2,D5 ;NO, SET ITS FLAG
|
|
MOVE.L A2,A0 ;POINT TO CLIPRGN
|
|
LEA STATEA(A6),A1 ;POINT TO STATE RECORD A
|
|
BSR.S INITONE ;INIT STATE, ALLOC BUFFER
|
|
ARECT
|
|
MOVE #-32767,STATEB+THISV(A6) ;INIT HARMLESS STATE
|
|
MOVE #32767,STATEB+NEXTV(A6) ;IN CASE RECTANGULAR
|
|
CMP #10,RGNSIZE(A3) ;IS VISRGN RECTANGULAR ?
|
|
BEQ.S BRECT ;YES, CONTINUE
|
|
ADD #4,D5 ;NO, SET ITS FLAG
|
|
MOVE.L A3,A0 ;POINT TO VISRGN
|
|
LEA STATEB(A6),A1 ;POINT TO STATE RECORD B
|
|
PEA BRECT ;PUSH FAKE RETURN ADDR
|
|
INITONE MOVE MINRECT+LEFT(A6),D0 ;GET MINH
|
|
MOVE MINRECT+RIGHT(A6),D1 ;GET MAXH
|
|
MOVE BUFLEFT(A6),D2 ;GET BUFLEFT
|
|
JMP INITRGN ;INIT STATE, ALLOC BUFFER
|
|
BRECT
|
|
|
|
|
|
;--------------------------------------------------------------------
|
|
;
|
|
; IF BOTH REGIONS ARE RECTANGULAR, THEN DRAW MINRECT INTO MASK BUFFER
|
|
;
|
|
MOVE.W D5,RECTFLAG(A6) ;ARE BOTH RGNS RECT ?
|
|
BNE.S NOTRECT ;NO, CONTNUE
|
|
MOVE.L MASKBUF(A6),A0 ;YES, POINT TO MASK BUFFER
|
|
MOVE MINRECT+LEFT(A6),D3 ;SET UP LEFT
|
|
SUB BUFLEFT(A6),D3 ;MAKE IT BUFFER RELATIVE
|
|
MOVE MINRECT+RIGHT(A6),D4 ;SET UP RIGHT
|
|
SUB BUFLEFT(A6),D4 ;MAKE IT BUFFER RELATIVE
|
|
JSR XorSlab ;AND XOR BETWEEN THEM
|
|
NOTRECT
|
|
|
|
|
|
SKIPSETUP
|
|
|
|
;------------------------------------
|
|
;
|
|
; CALC STARTING DSTLEFT
|
|
;
|
|
MOVE MINRECT+TOP(A6),D1
|
|
SUB PORTBITS+BOUNDS+TOP(A5),D1 ;CONVERT MINV TO GLOBAL COORDS
|
|
MULU PORTBITS+ROWBYTES(A5),D1 ;MULT BY DST ROWBYTES
|
|
ADD.L PORTBITS+BASEADDR(A5),D1 ;ADD START OF BITMAP
|
|
SUB PORTBITS+BOUNDS+LEFT(A5),D2 ;CONVERT BUFLEFT TO GLOBAL
|
|
LSR #3,D2 ;CALC BUFLEFT DIV 8
|
|
EXT.L D2 ;CLR HI WORD
|
|
ADD.L D2,D1 ;ADD HORIZ BYTE OFFSET
|
|
MOVE.L D1,DSTLEFT(A6) ;SAVE AS DSTLEFT
|
|
|
|
|
|
;----------------------------------------------------
|
|
;
|
|
; MAKE LEFTEDGE,RIGHTEDGE,MINRECT RELATIVE TO BUFFER LEFT
|
|
;
|
|
MOVE BUFLEFT(A6),D1
|
|
SUB.W D1,LEFTEDGE(A6) ;ADJUST LEFTEDGE.INT
|
|
SUB.W D1,RIGHTEDGE(A6) ;ADJUST RIGHTEDGE.INT
|
|
SUB D1,MINRECT+LEFT(A6)
|
|
SUB D1,MINRECT+RIGHT(A6)
|
|
|
|
|
|
;------------------------------------------------------------
|
|
;
|
|
; TAKE FAST OR SLOW OUTER CONTROL LOOP FOR SLANTED LINES:
|
|
;
|
|
TST.B fastFlag(A6) ;ARE WE RECT CLIPPED BLACK ?
|
|
BEQ.S GOSLOW ;NO, CONTINUE
|
|
MOVE MODE(A6),D2 ;GET (ALTERED) PEN MODE
|
|
JSR FastSlabMode ;Get fast case jump in A4
|
|
LEA MaskTab,A0 ;point to mask table
|
|
LEA MINRECT(A6),A3 ;POINT TO MINRECT
|
|
MOVE.L SLOPE(A6),D7 ;GET FIXED POINT SLOPE
|
|
MOVE PORTBITS+ROWBYTES(A5),D6 ;GET DST ROWBYTES
|
|
MOVE.L DSTLEFT(A6),A5 ;GET DSTLEFT
|
|
MOVE MINRECT+BOTTOM(A6),D5 ;GET MINRECT BOTTOM
|
|
SUB MINRECT+TOP(A6),D5 ;CALC HEIGHT
|
|
SUB #1,D5 ;MINUS 1 FOR DBRA COUNT
|
|
|
|
NXTFAST MOVE.W LEFTEDGE(A6),D1 ;GET LEFTEDGE.INT
|
|
MOVE.W RIGHTEDGE(A6),D2 ;GET RIGHTEDGE.INT
|
|
MOVE.L A5,A1 ;INIT DSTPTR TO LEFT
|
|
JSR DrawSlab ;DRAW ONE SLAB IN PENMODE
|
|
ADD D6,A5 ;BUMP DST TO NEXT ROW
|
|
ADD.L D7,LEFTEDGE(A6) ;ADD SLOPE TO LEFT EDGE
|
|
ADD.L D7,RIGHTEDGE(A6) ;ADD SLOPE TO RIGHT EDGE
|
|
DBRA D5,NXTFAST ;LOOP FOR ALL SCANLINES
|
|
BRA DONE ;AND QUIT
|
|
|
|
|
|
|
|
GOSLOW MOVE MODE(A6),D2 ;GET (ALTERED) PEN MODE
|
|
JSR SlabMode ;GET DrawSlab CASE JUMP IN A4
|
|
|
|
|
|
;------------------------------------------------------------------
|
|
;
|
|
; EXPAND 8 BYTE PATTERN TO 16 LONGS AND INIT PATTERN SELECTOR
|
|
;
|
|
CLR.L D7 ;SAY NOT INVERTED
|
|
MOVE MODE(A6),D2 ;GET (ALTERED) PEN MODE
|
|
BCLR #2,D2 ;TEST AND CLR INVERT BIT
|
|
BEQ.S NOTINV ;SKIP IF NOT INVERTED
|
|
NOT.L D7 ;INVERTED; D7 GETS ALL 1'S
|
|
NOTINV MOVE PORTBITS+BOUNDS+LEFT(A5),D2 ;GET GLOBAL-LOCAL OFFSET
|
|
MOVE.L PAT(A6),A0 ;POINT TO BYTE WIDE PATTERN
|
|
LEA EXPAT(A6),A1 ;POINT TO EXPANDED PATTERN
|
|
MOVE.L SAVEA5(A6),A5 ;GET GLOBAL PTR
|
|
JSR PATEXPAND ;EXPAND 8 BYTES TO 16 LONGS
|
|
MOVE.L PORT(A6),A5 ;RESTORE GRAFPTR IN A5
|
|
MOVEQ #$F,D7 ;TREAT COORD MOD 16
|
|
AND MINRECT+TOP(A6),D7 ;GET TOP VERT LOCAL COORD
|
|
LSL #2,D7 ;QUAD FOR LONG INDEX
|
|
|
|
|
|
;
|
|
; FOR EACH SLAB, MAKE MASK BUFFER CURRENT AND DRAW SLAB
|
|
;
|
|
LEA MINRECT(A6),A3 ;POINT TO MINRECT
|
|
MOVE PORTBITS+ROWBYTES(A5),D5 ;GET DST ROWBYTES
|
|
MOVE.L DSTLEFT(A6),A5 ;GET DSTLEFT
|
|
MOVE.L SLOPE(A6),D4 ;GET FIXED POINT SLOPE
|
|
MOVE MINRECT+TOP(A6),VERT(A6) ;INIT CURRENT VERT:=MINV
|
|
NXTMASK BSR.S SEEKMASK ;MAKE MASK BUFFER CURRENT
|
|
MOVE.L EXPAT(A6,D7),D6 ;GET PATTERN DATA
|
|
MOVE.W LEFTEDGE(A6),D1 ;GET LEFTEDGE.INT
|
|
MOVE.W RIGHTEDGE(A6),D2 ;GET RIGHTEDGE.INT
|
|
LEA MaskTab,A0 ;point to mask table
|
|
MOVE.L A5,A1 ;INIT DSTPTR TO LEFT
|
|
MOVE.L MASKBUF(A6),A2 ;INIT MASKPTR TO LEFT
|
|
JSR DrawSlab ;DRAW ONE SLAB IN PENMODE
|
|
ADD #4,D7 ;BUMP PATTERN SELECTOR
|
|
AND #$3F,D7 ;MOD 64 FOR 16 LONG REPEAT
|
|
ADD D5,A5 ;BUMP DST TO NEXT ROW
|
|
ADD.L D4,LEFTEDGE(A6) ;ADD SLOPE TO LEFT EDGE
|
|
ADD.L D4,RIGHTEDGE(A6) ;ADD SLOPE TO RIGHT EDGE
|
|
ADD #1,VERT(A6) ;BUMP CURRENT VERT
|
|
MOVE VERT(A6),D0 ;GET CURRENT VERT
|
|
CMP MINRECT+BOTTOM(A6),D0 ;ARE WE AT BOTTOM YET ?
|
|
BLT NXTMASK ;NO, LOOP ALL SCAN LINES
|
|
|
|
|
|
DONE MOVE.L SAVEA5(A6),A5 ;GET GLOBAL PTR
|
|
JSR SHOWCURSOR ;RESTORE CURSOR
|
|
GOHOME MOVE.L SAVESTK(A6),SP ;STRIP BUFFER
|
|
MOVEM.L (SP)+,D0-D7/A1-A5 ;RESTORE REGISTERS
|
|
UNLINK PARAMSIZE,'DRAWLINE'
|
|
|
|
|
|
|
|
;-----------------------------------------------------------------------------
|
|
;
|
|
; LOCAL ROUTINE TO UPDATE THE MASK BUFFER
|
|
; BASED ON WHICH REGIONS ARE RECTANGULAR
|
|
;
|
|
SEEKMASK MOVE VERT(A6),D0 ;GET CURRENT VERT COORD
|
|
MOVE RECTFLAG(A6),D1 ;GET RECTFLAG = 0,2,4
|
|
MOVE RECTJMP(D1),D1 ;GET OFFSET FROM TABLE
|
|
JMP RECTJMP(D1) ;TAKE CASE JUMP
|
|
|
|
RECTJMP DC.W IGNORE-RECTJMP ;DO NOTHING IF BOTH RECT
|
|
DC.W A-RECTJMP
|
|
DC.W B-RECTJMP
|
|
DC.W AB-RECTJMP
|
|
|
|
|
|
;--------------------------------------------------------------------
|
|
;
|
|
; ONLY REGION A IS NON RECTANGULAR. UPDATE IT AND USE IT AS THE MASK
|
|
;
|
|
A LEA STATEA(A6),A1
|
|
JSRSEEK JSR SEEKRGN
|
|
MOVE.L SCANBUF(A1),MASKBUF(A6)
|
|
IGNORE RTS
|
|
|
|
|
|
;--------------------------------------------------------------------
|
|
;
|
|
; ONLY REGION B IS NON RECTANGULAR. UPDATE IT AND USE IT AS THE MASK
|
|
;
|
|
B LEA STATEB(A6),A1
|
|
BRA.S JSRSEEK
|
|
|
|
|
|
;-------------------------------------------------------------------
|
|
;
|
|
; REGIONS A AND B ARE NON-RECTANGULAR. UPDATE EACH,
|
|
; THEN FORM INTERSECTION IN THE MASK BUFFER.
|
|
;
|
|
AB LEA STATEA(A6),A1
|
|
JSR SEEKRGN
|
|
LEA STATEB(A6),A1
|
|
JSR SEEKRGN
|
|
MOVE.L STATEA+SCANBUF(A6),A0
|
|
MOVE.L STATEB+SCANBUF(A6),A1
|
|
MOVE.L MASKBUF(A6),A2
|
|
MOVE BUFSIZE(A6),D1
|
|
ABLOOP MOVE.L (A0)+,D0
|
|
AND.L (A1)+,D0
|
|
MOVE.L D0,(A2)+
|
|
DBRA D1,ABLOOP
|
|
RTS
|
|
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; SET UP AND DRAW A FAST HORIZONTAL OR VERTICAL LINE.
|
|
;
|
|
FASTLINE CMP D1,D3 ;IS LINE HORIZONTAL ?
|
|
BNE VLINE ;NO, MUST BE VERTICAL
|
|
BSR HVSETUP ;GET DSTPTR,ROWBYTES,HGLOBAL
|
|
MOVE 32(A0,D0),D6 ;GET LEFTMASK IN D6
|
|
MOVE MINRECT+RIGHT(A6),D2 ;GET MINRECT RIGHT
|
|
SUB PORTBITS+BOUNDS+LEFT(A5),D2 ;CONVERT TO GLOBAL
|
|
MOVE D2,D0 ;MAKE A COPY OF RIGHT
|
|
AND #$F,D0 ;TREAT RIGHT MOD 16
|
|
ADD D0,D0 ;DOUBLE FOR TABLE
|
|
MOVE 0(A0,D0),D3 ;GET RIGHTMASK IN D3
|
|
LSR #4,D2 ;CONVERT DOTS TO WORDS
|
|
CMP #1,MODE(A6) ;WHICH MODIFIED MODE ?
|
|
BLT.S HSET ;BR IF BLACK
|
|
BEQ.S HTOGL ;BR IF XOR
|
|
;ELSE WHITE
|
|
|
|
;------------------------------------------------------
|
|
;
|
|
; DRAW A WHITE HORIZONTAL LINE
|
|
;
|
|
NOT D6 ;MAKE NOT LEFTMASK
|
|
NOT D3 ;MAKE NOT RIGHTMASK
|
|
SUB D1,D2 ;CALC WORDCOUNT
|
|
BEQ.S ENDCLR ;BR IF ALL IN ONE WORD
|
|
AND D6,(A4)+ ;DO LEFT WORD WITH MASK
|
|
CLR.L D6 ;FLUSH LEFTMASK FOR END
|
|
SUB #1,D2 ;DEC WORD COUNT
|
|
BEQ.S ENDCLR ;BR IF NO UNMASKED WORDS
|
|
LSR #1,D2 ;HALVE WORDCOUNT FOR LONGCOUNT
|
|
BCC.S CLRONE ;BR IF EVEN # WORDS LEFT
|
|
MOVE D6,(A4)+ ;ELSE MAKE EVEN BY DOING A WORD
|
|
SUB #1,D2 ;ADJUST LONGCOUNT
|
|
BRA.S CLRMORE ;SEE IF ANY LONGS LEFT TO DO
|
|
CLRTWO MOVE.L D6,(A4)+ ;FILL A LONG WITH BLACK
|
|
CLRONE MOVE.L D6,(A4)+ ;FILL ANOTHER LONG
|
|
SUB #2,D2 ;ANY UNMASKED LONGS LEFT ?
|
|
CLRMORE BGT CLRTWO ;YES, AT LEAST TWO LONGS
|
|
BEQ CLRONE ;YES, FINISH UP LAST LONG
|
|
ENDCLR OR D3,D6 ;COMBINE LEFT AND RIGHT MASK
|
|
AND D6,(A4) ;DRAW LINE
|
|
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
|
|
|
|
|
;--------------------------------------------------
|
|
;
|
|
; DRAW AN XOR HORIZONTAL LINE
|
|
;
|
|
HTOGL SUB D1,D2 ;CALC WORDCOUNT
|
|
BEQ.S ENDTOGL ;BR IF ALL IN ONE WORD
|
|
EOR D6,(A4)+ ;DO LEFT WORD WITH MASK
|
|
MOVEQ #-1,D6 ;FLUSH LEFTMASK FOR END
|
|
SUB #1,D2 ;DEC WORD COUNT
|
|
BEQ.S ENDTOGL ;BR IF NO UNMASKED WORDS
|
|
LSR #1,D2 ;HALVE WORDCOUNT FOR LONGCOUNT
|
|
BCC.S TOGLONE ;BR IF EVEN # WORDS LEFT
|
|
EOR D6,(A4)+ ;ELSE MAKE EVEN BY DOING A WORD
|
|
SUB #1,D2 ;ADJUST LONGCOUNT
|
|
BRA.S TOGLMORE ;SEE IF ANY LONGS LEFT TO DO
|
|
TOGLTWO NOT.L (A4)+ ;INVERT A LONG
|
|
TOGLONE NOT.L (A4)+ ;INVERT ANOTHER LONG
|
|
SUB #2,D2 ;ANY UNMASKED LONGS LEFT ?
|
|
TOGLMORE BGT TOGLTWO ;YES, AT LEAST TWO LONGS
|
|
BEQ TOGLONE ;YES, FINISH UP LAST LONG
|
|
ENDTOGL AND D3,D6 ;COMBINE LEFT AND RIGHT MASK
|
|
EOR D6,(A4) ;DRAW LINE
|
|
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
|
|
|
|
|
;--------------------------------------------
|
|
;
|
|
; DRAW A BLACK HORIZONTAL LINE
|
|
;
|
|
HSET SUB D1,D2 ;CALC WORDCOUNT
|
|
BEQ.S ENDSET ;BR IF ALL IN ONE WORD
|
|
OR D6,(A4)+ ;DO LEFT WORD WITH MASK
|
|
MOVEQ #-1,D6 ;FLUSH LEFTMASK FOR END
|
|
SUB #1,D2 ;DEC WORD COUNT
|
|
BEQ.S ENDSET ;BR IF NO UNMASKED WORDS
|
|
LSR #1,D2 ;HALVE WORDCOUNT FOR LONGCOUNT
|
|
BCC.S SETONE ;BR IF EVEN # WORDS LEFT
|
|
MOVE D6,(A4)+ ;ELSE MAKE EVEN BY DOING A WORD
|
|
SUB #1,D2 ;ADJUST LONGCOUNT
|
|
BRA.S SETMORE ;SEE IF ANY LONGS LEFT TO DO
|
|
SETTWO MOVE.L D6,(A4)+ ;FILL A LONG WITH BLACK
|
|
SETONE MOVE.L D6,(A4)+ ;FILL ANOTHER LONG
|
|
SUB #2,D2 ;ANY UNMASKED LONGS LEFT ?
|
|
SETMORE BGT SETTWO ;YES, AT LEAST TWO LONGS
|
|
BEQ SETONE ;YES, FINISH UP LAST LONG
|
|
ENDSET AND D3,D6 ;COMBINE LEFT AND RIGHT MASK
|
|
OR D6,(A4) ;DRAW LINE
|
|
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
|
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; DRAW A VERTICAL LINE.
|
|
;
|
|
VLINE BSR.S HVSETUP ;GET DSTPTR,ROWBYTES,HGLOBAL
|
|
MOVE 64(A0,D0),D0 ;GET BITMASK IN D0
|
|
MOVE MINRECT+BOTTOM(A6),D1 ;GET BOTTOM
|
|
SUB MINRECT+TOP(A6),D1 ;CALC HEIGHT
|
|
SUB #1,D1 ;INIT HEIGHT COUNT
|
|
CMP #1,MODE(A6) ;WHICH MODIFIED MODE ?
|
|
BLT.S VSET ;BR IF BLACK
|
|
BEQ.S VTOGL ;BR IF XOR
|
|
;ELSE WHITE
|
|
NOT D0 ;MAKE NOTMASK
|
|
VCLR AND D0,(A4) ;CLEAR ONE DOT
|
|
ADD D7,A4 ;BUMP TO NEXT ROW
|
|
DBRA D1,VCLR ;LOOP ALL DOTS
|
|
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
|
|
|
VTOGL EOR D0,(A4) ;TOGGLE ONE DOT
|
|
ADD D7,A4 ;BUMP TO NEXT ROW
|
|
DBRA D1,VTOGL ;LOOP ALL DOTS
|
|
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
|
|
|
VSET OR D0,(A4) ;SET ONE DOT
|
|
ADD D7,A4 ;BUMP TO NEXT ROW
|
|
DBRA D1,VSET ;LOOP ALL DOTS
|
|
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
|
|
|
|
|
|
|
;------------------------------------------------------------------------
|
|
;
|
|
; LOCAL ROUTINE TO SET UP POINTER TO FIRST WORD, BIT INDEX, AND ROWBYTES
|
|
;
|
|
; INPUTS: MINRECT
|
|
; A5: thePort
|
|
;
|
|
; OUTPUTS: D0: STARTING HORIZ GLOBAL COORDS
|
|
; D1: STARTING HORIZ GLOBAL DIV 16
|
|
; D7: ROWBYTES
|
|
; A0: MaskTab
|
|
; A4: POINTER TO FIRST WORD
|
|
;
|
|
; CLOBBERS: D0,D1,D7,A0,A4
|
|
;
|
|
HVSETUP MOVE.L PORTBITS+BASEADDR(A5),A4 ;GET BITMAP START
|
|
MOVE MINRECT+TOP(A6),D0 ;GET STARTING VERT
|
|
SUB PORTBITS+BOUNDS+TOP(A5),D0 ;CONVERT TO GLOBAL
|
|
MOVE PORTBITS+ROWBYTES(A5),D7 ;GET ROWBYTES
|
|
MULU D7,D0 ;MULT TOP BY ROWBYTES
|
|
ADD.L D0,A4 ;ADD TO BASEADDR
|
|
MOVE MINRECT+LEFT(A6),D0 ;GET STARTING HORIZ
|
|
SUB PORTBITS+BOUNDS+LEFT(A5),D0 ;CONVERT TO GLOBAL
|
|
MOVE D0,D1 ;MAKE A COPY
|
|
LSR #4,D1 ;CONVERT BITS TO WORDS
|
|
ADD D1,A4 ;ADD TO RUNNING TOTAL
|
|
ADD D1,A4 ;TWICE FOR BYTES
|
|
LEA MaskTab,A0 ;return with masktab in A0
|
|
AND #$F,D0 ;TREAT LEFT MOD 16
|
|
ADD D0,D0 ;DOUBLE FOR TABLE
|
|
RTS
|
|
|
|
|
|
END
|
|
|
|
|
|
|
|
|